
Estudio reproducible de CVE-2024-36401: RCE no autenticado en GeoServer mediante inyección de evaluación JXPath. Incluye informe técnico, exploit/verificador funcional y entorno Docker que demuestra la vulnerabilidad en instancias vulnerables frente a parcheadas.
Un estudio completo y reproducible de la vulnerabilidad CVE-2024-36401, un fallo de ejecución remota de código no autenticado en GeoServer — el servidor de código abierto más utilizado para datos geoespaciales. El error es una inyección de eval: a través de los parámetros de los estándares OGC, GeoServer pasa nombres de propiedades controlados por el atacante a GeoTools, donde Apache Commons JXPath los evalúa como expresiones XPath y, por diseño, puede invocar métodos Java arbitrarios mediante reflexión. Una solicitud no autenticada como exec(java.lang.Runtime.getRuntime(),'id') por lo tanto ejecuta comandos en el host.
Este repositorio contiene el informe técnico, un exploit/verificador funcional y un entorno Docker de un solo comando que demuestra la RCE en una instancia vulnerable y muestra el mismo exploit fallando en la instancia parcheada.
Proyecto educativo. Desarrollado para un curso universitario (Privacidad y Seguridad de Datos, LUISS DASMA). Todo se ejecuta solo contra contenedores locales y aislados — consulte Uso responsable.
| Campo | Valor |
|---|---|
| CVE (GeoServer) | CVE-2024-36401 |
| Causa raíz (GeoTools) | CVE-2024-36404 |
| Tipo | Ejecución Remota de Código No Autenticada |
| CWE | CWE-95, Inyección de Eval |
| CVSS v3.1 | 9.8 Crítica (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) |
| Afectado | GeoServer < 2.25.2 / GeoTools < 31.2 (y ramas anteriores) |
| CISA KEV | Sí (15 de julio de 2024) |
| Versiones estudiadas | Vulnerable 2.25.1, parcheada 2.25.2 |
.
├── report/
│ ├── report.pdf # the full technical report (read this first)
│ ├── report.md # report source (Pandoc/XeLaTeX)
│ └── images/ # figures and screenshots
├── docker/
│ ├── vulnerable/Dockerfile # GeoServer 2.25.1 (vulnerable)
│ └── patched/Dockerfile # GeoServer 2.25.2 (fixed)
├── docker-compose.yml # vuln on :8080, patched on :8081
├── exploit/
│ ├── exploit.py # exploit + vuln/patched verifier (stdlib only)
│ ├── exploit.sh # curl-based PoC (GET + POST variants)
│ ├── payloads.md # payload catalogue per OGC endpoint
│ └── output/ # captured proof logs and transcripts
└── run-reproduction.sh # one command: build + exploit both + collect proofs
Requisitos: Docker Desktop en ejecución, python3, curl.
# Build both containers, run the exploit against each, and collect the proofs
chmod +x run-reproduction.sh
./run-reproduction.sh
O paso a paso:
docker compose up -d --build # vuln on :8080, patched on :8081
# Vulnerable (expected: VULNERABLE, ~8s delay)
python3 exploit/exploit.py -t http://localhost:8080/geoserver --label vuln -o exploit/output
# Patched (expected: PATCHED, immediate rejection)
python3 exploit/exploit.py -t http://localhost:8081/geoserver --label patched -o exploit/output
docker compose down # when finished
Dos sondas independientes hacen que el resultado sea inequívoco:
java.lang.Thread.sleep(8000) bloquea el hilo que evalúa la XPath, por lo que la respuesta HTTP se retrasa ~8 s — medible desde el cliente, sin necesidad de acceso al contenedor. Es el mismo canario usado por las pruebas oficiales de la corrección.exec(java.lang.Runtime.getRuntime(),'touch /tmp/<marker>') crea un archivo dentro del contenedor, verificable con docker exec.En la instancia vulnerable, enviar el payload manualmente devuelve una ClassCastException en ProcessImpl — la JVM ejecutó Runtime.exec y luego falló al usar el objeto Process resultante como atributo. Esa excepción es la prueba de ejecución:

El commit de GeoTools e53e5170 (en GeoServer 2.25.2, 2.24.4, 2.23.6, 2.22.6) aplica defensa en profundidad en ambas mitades del error:
JXPathUtils.newSafeContext(...) instala una FunctionLibrary vacía, por lo que JXPath ya no puede resolver exec/Thread.sleep como funciones — la cadena sigue siendo un nombre de propiedad simple.FeaturePropertyAccessorFactory ahora también verifica SimpleFeatureType, por lo que las características simples ya no alcanzan el accesor vulnerable.En la instancia parcheada, el mismo payload devuelve No such attribute: ... y no se ejecuta nada.
Los detalles completos — código afectado con referencias de archivo/línea, explotación, diff de mitigación y la reproducción lado a lado — están en report/report.pdf.
Este CVE es público, ha sido parcheado durante más de 18 meses, está en el catálogo de Vulnerabilidades Explotadas Conocidas de CISA y tiene PoCs públicos (Vulhub, Nuclei, Metasploit). El código aquí se dirige solo a localhost y a los contenedores de estudio aislados en este repositorio. No lo use contra sistemas que no posea o para los que no esté explícitamente autorizado a probar.
MIT © 2026 Daniele Giovanardi
Daniele Giovanardi — Ciencia de Datos y Gestión (DASMA), LUISS Guido Carli. Trabajo del curso Privacidad y Seguridad de Datos.