Guida passo-passo allo sfruttamento della RCE da deserializzazione di Fastjson CVE-2017-18349, che copre l'identificazione della superficie d'attacco, il fingerprinting, l'iniezione JNDI e l'acquisizione di una reverse shell in un ambiente di laboratorio Docker.
Iniziamo vedendo cosa è in esecuzione nell'ambiente. Elenco tutti i contenitori attivi:
docker ps

La vittima espone solo una singola porta: 8090
Al momento, non ho ancora completamente chiaro l'obiettivo. Dai risultati di docker ps, il sistema pubblica solo un servizio notevole esternamente sulla porta 8090, mappato sul servizio interno del contenitore. Questa è la principale superficie di attacco da analizzare.
⇒ Lo interrogo direttamente con Curl per ottenere maggiori informazioni
curl -i 192.168.3.137:8090/

Analisi della risposta:
Content-Type: application/json;charset=UTF-8.{"age": 25, "name": "Bob"}.⇒ Riflessione: Quando si accede alla porta 8090, il server restituisce dati JSON. Ciò indica che l'endpoint non serve solo una pagina web statica, ma ha un backend che elabora le richieste e serializza i dati in JSON da restituire al client. Dai risultati di docker ps, il comando in esecuzione all'interno del contenitore mostra segni di essere un'applicazione Java, quindi la prossima direzione di ispezione è quella di identificare i parser JSON comuni in Java.
In Java, librerie JSON popolari come Jackson, Gson e Fastjson si comportano tutte in modo diverso quando incontrano input insoliti. Pertanto, possiamo utilizzare la tecnica di Fingerprinting basata sugli errori. L'errore restituito a volte rivela direttamente la libreria o il meccanismo di elaborazione interno. Tra queste, Fastjson è un obiettivo che necessita di una verifica tempestiva perché le versioni precedenti presentavano molteplici vulnerabilità critiche relative alla deserializzazione AutoType.
Qui, non affermo immediatamente che il backend utilizzi Fastjson. Scelgo solo Fastjson come prima direzione di controllo perché ha un'impronta digitale chiara attraverso la chiave @type, e se si tratta effettivamente di una vecchia versione di Fastjson, la capacità di sfruttamento può andare molto oltre un errore di parsing standard, portando potenzialmente a RCE.
Fastjson ha una caratteristica molto utile per il fingerprinting: riconosce la chiave speciale @type. Se il backend utilizza Fastjson e il corpo della richiesta inviato nel flusso di deserializzazione supporta AutoType, il parser potrebbe tentare di interpretare il valore di @type come un nome di classe Java.
Pertanto, invio un payload contenente @type che punta a una classe inesistente. L'obiettivo di questo passaggio non è sfruttare immediatamente, ma osservare se il backend reagisce a @type.
curl -i -X POST -H "Content-Type: application/json" \
-d '{"@type":"com.non.existent.Class"}' \
http://192.168.3.137:8090/

Se il backend avesse utilizzato un parser JSON standard e non si fosse preoccupato di @type, questo campo potrebbe essere semplicemente ignorato o trattato come una chiave normale nel JSON. Tuttavia, qui il backend reagisce con un comportamento relativo al tipo (type not match), il che significa che la richiesta è entrata nel flusso di elaborazione del mapping classe/tipo.
Il messaggio "type not match" è una firma caratteristica spesso riscontrata quando Fastjson elabora @type ma la classe specificata non corrisponde al tipo di dati previsto dall'endpoint, oppure la classe non esiste/non è consentita per la deserializzazione.
⇒ Riflessione: Il backend analizza realmente il corpo JSON della richiesta POST, il campo @type non viene ignorato, il parser ha un meccanismo di elaborazione dei metadati di tipo e l'errore restituito corrisponde al comportamento di Alibaba Fastjson. Pertanto, possiamo concludere con alta probabilità che il backend stia utilizzando Alibaba Fastjson.**
Dopo il passo di fingerprinting, non posso concludere immediatamente che il sistema sia sfruttabile. Il fatto che il backend utilizzi Fastjson dimostra solo che la richiesta JSON entra nel flusso di elaborazione di @type.
Per eseguire un exploit RCE, è necessario verificare quanto segue:
⇒ Riflessione: L'errore type not match mostra che il backend reagisce a @type, ma il payload corrente utilizza solo una classe fittizia per innescare un errore. Per uno sfruttamento effettivo, dobbiamo sostituire quella classe fittizia con una classe reale presente in Java/JDK che sia in grado di creare comportamenti verso l'esterno, come una ricerca JNDI.
Per determinare la versione, controllo direttamente all'interno del contenitore/applicazione.

Dopo aver identificato che l'applicazione è impacchettata come file /usr/src/fastjsondemo.jar, procedo con un'analisi approfondita della struttura del pacchetto per cercare la libreria di elaborazione JSON. Controllando la struttura della directory BOOT-INF/lib/ emerge il file fastjson-1.2.24.jar (Figura X).
L'uso esatto della versione 1.2.24 — la prima e più famosa versione affetta dalla vulnerabilità di deserializzazione senza alcun meccanismo di difesa autoType — ci permette di confermare che il sistema è vulnerabile a CVE-2017-18349.
Trovare fastjson-1.2.24.jar conferma che l'applicazione utilizza una versione molto vecchia di Fastjson, appartenente al gruppo affetto dal difetto di deserializzazione AutoType. In questa versione, il meccanismo di controllo su AutoType non era stato rafforzato come nelle versioni successive, quindi per quanto riguarda le condizioni della libreria, il sistema è suscettibile allo sfruttamento tramite classi gadget come JdbcRowSetImpl.
Tuttavia, la reale sfruttabilità dipende ancora da come l'endpoint invoca Fastjson. Se l'applicazione analizza JSON in una classe fissa, impostare il payload @type nell'oggetto radice potrebbe portare all'errore "type not match". Pertanto, dopo aver identificato la versione, dobbiamo continuare ad analizzare la JVM, la classe gadget e il comportamento di callback LDAP per confermare se la catena di sfruttamento raggiunge effettivamente la ricerca JNDI.
1. Analisi delle Barriere JVM
Oltre alla versione di Fastjson, anche la versione Java è un fattore determinante. Controllo la JVM all'interno del contenitore:
java -version

Questa è un'informazione critica perché le catene di sfruttamento di Fastjson solitamente si basano sull'Iniezione JNDI. Le versioni più recenti di Java hanno bloccato il caricamento di classi da codebase esterne tramite LDAP/RMI per impostazione predefinita. Tuttavia, Java 8u102 è una versione precedente che non ha ancora questi meccanismi di blocco.
Pertanto, se l'attaccante può innescare una ricerca JNDI, la JVM della vittima ha la capacità di scaricare la classe da un server HTTP esterno e caricarla nel runtime.