Potrebbe essere un po’ impopolare come opinione, sono comunque convinto che per capirci veramente qualcosa nel mondo del Penetration Testing bisogna veramente immergerti nella melma e dedicare tempo a cose che hanno a che fare con l’informatica molto prima di iniziare a toccare i temi info. security.
Non mi avventuro in una spiegazione teorica di questo concetto, molto più utile mettere in pratica raccontando un micro-task: il testing in lavoratorio di un exploit per una versione vulnerabile di Tomcat.
Edit: ho registrato un video di sintesi con piccola dimostrazione.
Intro
L’obiettivo del test è verificare le condizione che rendono alcune versioni di Apache Tomcat effettivamente exploitable tramite l’utilizzo di alcuni payload noti e facilmente reperibili in rete.
Durante una sessione di PenTesting, una volta individuata una vulnerabilità sfruttabile, solitamente si procedere con la verifica tecnica: si tenta di eseguire l’exploit per guadagnare un accesso al sistema target o ottenere nuove informazioni utili. Il fatto che la versione del software (Apache Tomcat in questo caso) corrisponda ad una release che risulta avere delle vulnerabilità non rende automaticamente il sistema attaccabile/manipolabile.
L’effettiva sfruttabilità della falla è legata a diversi fattori:
- l’eventuale applicazione di patch che non hanno alterato la release version (ingannando l’analista nel processo di enumeration)
- l’utilizzo di configurazioni non vulnerabili
- la presenza di sistemi di protezione o mitigazione
- fattori esterni non direttamente legati al sistema target
Il contesto condiziona l’utilizzo dell’exploit e non è detto che il PenTester abbia tutte le informazioni necessarie ad una valutazione completa rispetto a quanto viene osservato.
In parole povere il fatto che la scansione approfondita, anche utilizzando tools di mercato che ci danno la certezza della presenza della vulnerabilità, non può mai essere l’elemento determinante finale.
Analisi della vulnerabilità
Supponiamo di avere un risultato preciso da parte del nostro scan tool e di avere la certezza che sia presente la vulnerabilità (spesso studiata in molti lab) CVE-2020-1938.

Nota tecnica: nel mio lab ho predisposto la più classica delle installazioni kali per avere un punto comodo di controllo con il più vasto set di utilities concentrato in una unica macchina. Il risultato della scansione di nmap tramite il set di script disponibili nella repo base restituisce un risultato abbastanza chiaro.

La prima cosa da fare è studiare nel dettaglio la CVE che abbiamo identificato per capire cosa potenzialmente si può fare.
La vulnerabilità è ampiamente documentata ed è relativa ad una specifica componente del servizio: AJP (Apache JServ Protocol) il protocollo binario (non HTTP testuale) usato per far parlare un web server front-end (es: Apache HTTPD o un load balancer)
con il Tomcat che esegue applicazioni Java. Possiamo quindi dire che parlare con AJP ci consente di interagire con il Tomcat che esegue l’applicazione Java e solitamente non è il client ad accedere direttamente a questa componente.
Questa componente è di default attiva e nelle classiche configurazioni che spesso si trovato in giro il servizio (di default in ascolto sulla porta 8009) è attivo sull’interfaccia dell’host assieme al servizio httpd che solitamente, nel caso di Tomcat, è disponibile sulla porta 8080.

La vulnerabilità che riguarda questo servizio è così descritta su NIST:
“This vulnerability report identified a mechanism that allowed: – returning arbitrary files from anywhere in the web application – processing any file in the web application as a JSP Further, if the web application allowed file upload and stored those files within the web application (or the attacker was able to control the content of the web application by some other means) then this, along with the ability to process a file as a JSP, made remote code execution possible.”
In questo post devo muovere qualche critica su come vengono descritte alcune CVE. Sulla prima parte della descrizione nulla da eccepire: il falla consente di accedere in lettura ai file dell’applicazione, cosa che consente all’attaccante di entrare in possesso di informazioni potenzialmente sensibile come dati e configurazioni. È quindi possibile ottenere informazioni che consentano ulteriori azioni verso il sistema.
Poi viene la parte sulla RCE che personalmente la trovo superflua e persino forviante. Cito (mia traduzione): se l’applicazione consente l’upload di file salvati all’interno dell’applicazione […] in combinazione con la possibilità di elaborare file come JSP è possibile eseguire codice da remoto. Ora, ovviamente quanto scritto è corretto ma se trovo una vulnerabilità che mi consente di eseguire l’upload di JSP all’interno dell’applicazione è molto probabile che li possa anche chiamare direttamente via http.
Questo dettaglio mi ha fatto venire voglia di approfondire questa CVE in particolare. Ho fatto un po’ di ricerche per cercare qualche opinione ed esempi: la CVE è stata usata come esempio in diverse “box” ed in tutti gli scenari l’azione era limitata alla raccolta di informazioni in stile CTF a supporto dello scenario di utilizzo della falla per scovare dati usabili in step successivi dell’attacco. Vi suggerisco la lettura di questo articolo ben scritto. Quello che è certo è che è possibile leggere ed eseguire file tramite questa falla.
Dettaglio tecnico del bug
Dobbiamo un po’ addentrarci nel funzionamento del software per capirci veramente qualcosa (a quanto parte lo sport di approfondire è diventato per pochi) altrimenti rischiamo di fare cose un po’ a caso senza capire perché un exploit funziona o non funziona.
Il bug da cui dipende la vulnerabilità è relativo ad un comportamento di AJP che sostanzialmente accetta degli attributi da parte di chi lo interpella (solitamente Apache). Il problema è che alcuni attributi consentono appunto di accedere a file di configurazione o a contenuti dell’applicazione anche senza meccanismi di sicurezza o autenticazione.
L’exploit deve quindi aprire una sessione direttamente verso AJP (spacciandosi per una richiesta lecita) utilizzando il protocollo di comunicazione come descritto nelle specifiche (qui un po’ di documentazione: https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html) considerando che si tratta appunto di un protocollo binario e non è utilizzabile con semplici messaggi di testo come solitamente siamo abituati con protocolli come HTTP.
Una volta ottenuta la sessione è possibile utilizzare alcuni attributi per chiedere specifiche informazioni. In particolare gli attributi responsabile della falla sono:
- javax.servlet.include.request_uri che dice a Tomcat la URI da cui arriva la richiesta
- javax.servlet.include.servlet_path che indica la servlet che dovrà gestire la richiesta
- javax.servlet.include.path_info che indica il contenuto da servire
La cosa interessante da considerare è che quello che viene passato come file all’attributo servlet_path viene trattato come un JSP: Tomcat accede al contenuto, lo compila come JSP (anche se è .txt, .log, qualsiasi estensione), lo esegee come codice Java e restituisce l’output dell’esecuzione.
Il tal senso la CVE può essere utilizzata in combinazione con un altra vulnerabilità che consenta un File Upload per ottenere una RCE, ma la CVE di per se non è di tipo RCE.
Exploit test
Partiamo dalla verifica della vuln. in senso stretto, ovvero cerchiamo di leggere qualcosa dentro l’applicazione considerando la struttura di Tomcat.
Gli exploit ed i proof-of-concept che si trovano in rete sono abbastanza complessi in quanto la richiesta che viene inviata ad AJP deve essere convertita nel relativo protocollo binario, di conseguenza negli esempi si trova solitamente il codice che ricostruisce la richiesta AJP secondo le specifiche del protocollo.
Se si esamina il codice dell’exploit disponibile su Exploit-DB (https://www.exploit-db.com/exploits/48143) si noterà la presenza di diverse classi tra cui AjpForwardRequest() che ha proprio lo scopo di definire la richiesta AJP. Questo exploit in particolare consente di definire come parametri l’host di destinazione, la porta ed il file da leggere/includere. Per un test efficace solitamente si definisce come target un file presente di default in una installazione Tomcat ma posizionato in un path solitamente non accessibile direttamente via http: “WEB-INF/web.xml”.

Nel mio esempio in laboratorio il file è stato modificato per riconoscerlo in fase di test: sulla sinistra si vede la directory in cui è posizionato il file ed il suo contenuto, sulla destra l’exploit di test che legge il file xml target.
Accedendo a questo contenuto siamo sicuri che la falla è presente e sfruttabile nel sistema target, sapendo quindi la posizione di altri file potremmo leggerli o eseguirli.
Nota: il p-o-c di Exploit-DB contiene un errore – credo voluto – che porta alla sola modalità di lettura di un file. Con l’occasione ci mettiamo le mani.
Facciamo un passo in più e diamo uno sguardo al codice che stiamo utilizzando. Prendiamo in esame solo le ultime linee di codice in cui vengono definiti gli attributi:

Se lo utilizziamo così come lo vediamo otteniamo la lettura di un file dell’applicazione come nel precedente screenshot ma in questo script, come accennavo c’è un errore introdotto probabilmente per consentire la sola lettura di un contenuto.
Se andiamo a posizionare un file JSP nell’app con del semplice codice e proviamo ad eseguirlo usando l’exploit otterremo infatti la lettura del file e non l’esecuzione:

Questo comportamento è causato dall’errore dello script in cui è stato definiti come target della request il path /asdf, ovviamente inesistente di dafault in Tomcat. È quindi sufficiente correggere il path con / per ottenere il comportamento corretto:

Come si diceva per ottenere una RCE bisogna avere anche la possibilità di portare del contenuto sulla macchina target ed in particolare deve essere posizionato dentro il path della webapp altrimenti non sarebbe richiamabile attraverso l’exploit. I file con contenuto JSP possono essere eseguiti anche se posizionati all’interno di path come WEB-INF anche se teoricamente non accessibili direttamente via http e questo prescinde dall’estensione.
Conclusioni (per questa prima parte)
La vulnerabilità è indubbiamente interessante in quanto consente di accedere, potenzialmente, al codice delle applicazioni pubblicate se si conosce il corretto path e filename dei contenuti. Prima di strapparsi le vesti e parlare di RCE bisogna ragionare bene su cosa l’applicazione o il sistema consente veramente di fare considerando che in presenza di vulnerabilità di tipo File Upload, talmente gravi da consentire di caricare file .jsp in path accessibili via http, l’esecuzione di codice non richiede la presenza della vuln. in oggetto. Se siamo invece in presenza di una vulnerabilità di tipo File Upload che riguarda formati difficili da gestire come gli SVG (che di fatto sono file xml) allora la situazione cambia: è molto semplice infilare del codice JSP in un XML.
Ho in programma un altro post sul tema in cui approfondire il tema detection per questa CVE.
Se ti interessano i miei contenuti ed i miei approfondimenti seguimi su Patreon e YouTube, seguiranno dei video di approfondimento tecnico.
Iscriviti al blog per restare aggiornato:



![Info Sec Unplugged [1e] – Gestione delle configurazioni](https://roccosicilia.com/wp-content/uploads/2024/12/podcast.png?w=541)
Lascia un commento