Dopo gli approfondimenti dedicati ad alcune tecniche fondamentali di hacking (Buffer Overflow, SQL Injection, ecc.) è ora il momento di illustrare le tecniche di attacco e difesa per la vulnerabilità che va sotto il nome di Path Traversal. Questa tecnica è conosciuta anche come dot-dot-slash attack (../) oppure come directory traversal.
Gran parte delle applicazioni web gestiscono e utilizzano file residenti sul filesystem degli application server: se non viene implementato un corretto procedimento di validazione dell'input un aggressore può accedere a directory e file di cui non possiede i relativi permessi. Sfruttando con astuzia le problematiche di validazione dell'input, nel caso di chiamate a sistema che accedono a risorse del filesystem, è possibile che un aggressore riesca anche ad eseguire del codice arbitrario o comandi di sistema.
All'interno dei server sono spesso implementati meccanismi di autorizzazione per controllare l'accesso e la modifica di file e risorse. I web server, per esempio, confinano i file usabili dagli utenti all'interno di una "root directory" o "web document root" la quale è una directory fisica sul filesystem ma, agli occhi dell'utente, risulta come la prima directory della gerarchia a cui poter accedere.
La definizione dei permessi di lettura, scrittura ed esecuzione per utenti e gruppi viene gestita dall'amministratore utilizzando delle ACLs (Access Control Lists) implementate nel sistema operativo. In questo modo è possibile preservare l'accesso da parte di utenti malintenzionati verso file critici presenti sul server (es: /etc/passwd
sui sistemi Unix) o l'esecuzione di comandi di sistema.
Poiché spesso gli sviluppatori utilizzano incautamente l'inclusione di file statici all'interno degli script server side usati per la generazione delle pagine dinamiche non è difficile riscontrare questo genere di problematica; gran parte delle attuali web application, per semplificare la gestione dei template grafici o il caricamento di testi statici, utilizzano direttive di include
, require
, import
e così via
Bisogna subito evidenziare come questo genere di problematica non affligge solamente le applicazioni ma spesso anche i server web stessi: citiamo il caso di Microsoft IIS con il noto "%5c escape code".
In alcune vecchie versioni del noto web server di Microsoft è possibile sfruttare questa vulnerabilità per compromettere completamente il server, eseguendo comandi da remoto.
http://<IP>/scripts/..%5c../winnt/system32/cmd.exe?/c+dir+c:
Effettuando questa semplice richiesta attraverso la barra degli indirizzi un eventuale aggressore, sfruttando directory traversal, riesce ad avviare la shell di sistema cmd.exe
ed eseguire qualsiasi comando (in questo caso un innocuo dir c:
). Il problema in questo caso è legato alla cattiva gestione dei codici di escape da parte del codice applicativo del server web che permette di richiamare risorse al di fuori della root directory; per precisione ricordiamo che il codice "%5c" rappresenta il carattere "".
Un esempio pratico
Tornando al mondo delle applicazioni web, riportiamo un semplice esempio di script JSP utilizzato per la creazione di una pagina associata al profilo dell'utente. In maniera molto grossolana lo script in oggetto recupera da una precedente richiesta HTTP la variabile id
, il cui valore viene direttamente utilizzato come parametro attuale nel metodo di creazione dell'oggetto java.io.FileReader
; ogni riga contenuta nel file viene poi stampata a monitor con un opportuno tag HTML al fine di mantenere l'impaginazione.
<% try{ String fileName=request.getParameter("id"); if(fileName!=null){ while(true){ String str = bf.readLine(); java.io.BufferedReader bf = new java.io.BufferedReader(new java.io.FileReader(fileName)); if(str == null) break; out.println(str+"<br>"); } } }catch(Exception e){ } %>
Come è facilmente immaginabile, l'esempio precedente è un candidato ideale per un attacco di path traversal: effettuando una richiesta HTTP con parametro id contenente il path assoluto di un file presente sulla macchina remota è possibile leggerne il contenuto, in accordo con i permessi associati al processo (es: su una macchina Linux, l'utente che viene utilizzato per eseguire Tomcat).
Come si possono trovare problematiche di Path Traversal?
Dove aver capito come funzionano gli attacchi Path Traversal, vogliamo ora illustrare alcune tecniche che possono essere utilizzate per scoprire questo genere di problematiche all'interno delle nostre applicazioni.
Per effettuare il testing, al fine di valutare la presenza di questa vulnerabilità è necessario analizzare sistematicamente ogni possibile vettore di ingresso e considerare le possibili modalità utilizzabili da un aggressore per sfruttare tali falle.
Come per ogni problema di sicurezza legato all'insufficiente sanitizzazione dell'input è necessario considerare qualsiasi valore che sia modificabile dall'utente: parametri dei form HTML (parametri GET
/POST
), valore all'interno dei cookie, valori che sono salvati all'interno di basi di dati ma che possono essere stati modificati da utenti esterni, ulteriori parametri presenti nell'header HTTP.
Esempi di controllo in questa fase dell'analisi sono legati all'osservazione dei parametri usati nelle richieste o al valore all'interno dei cookie; se durante l'esplorazione incontriamo dei parametri che sono riconducibili a file (estensioni, nomi particolari, etc.) oppure a stringhe utilizzate per la generazione dinamica di pagine/template dobbiamo soffermarci ad analizzare con calma tali parametrizzazioni.
Una volta identificati tutti i possibili vettori di input è necessario considerare le diverse modalità di exploiting sfruttabili dall'aggressore, al fine di valutare l'efficacia o meno dei controlli presenti all'interno del codice dell'applicazione. Poiché spesso gli sviluppatori implementano delle primitive forme di validazione dell'input che però non considerano tutte le possibili modalità di encoding dei caratteri, durante un black box test è necessario sperimentare tutte le possibili forme di codifica e di path definition.
A seconda del sistema operativo in oggetto dobbiamo valutare la definizione di percorsi validi:
Sistemi Unix*
"/" root directory "/" directory separator
Sistemi Windows
"<drive letter>:" root directory "" ma anche "/" directory separator
Sistemi Classic Mac OS
"<drive letter>:" root directory ":" directory separator
Inoltre vanno considerate anche le codifiche URL encoding e double URL encoding oltre a Unicode/UTF-8 Encoding:
%2e%2e%2f diventa ../ %2e%2e/ diventa ../ ..%2f diventa ../ %2e%2e%5c diventa .. %2e%2e diventa .. ..%5c diventa .. %252e%252e%255c diventa .. ..%255c diventa .. e così via ..%c0%af diventa ../ ..%c1%9c diventa ..
Per aiutarci nel test delle nostre applicazioni possiamo utilizzare gli strumenti presentati in un precedente articolo. Curiosamente, è da segnalare come l'uso di strumenti online per la ricerca e condivisione di codice sorgente Google CodeSearch, Koders abbia agevolato la ricerca di questo genere di vulnerabilità all'interno di software open source pubblicati su Internet.
Usando la seguente query possiamo, ad esempio, trovare in pochi secondi tutte le direttive di inclusione nei progetti pubblicati, sviluppati in PHP.
lang:php (include|require)(_once)?s*['"(]?s*$_(GET|POST|COOKIE)
Ora che conosciamo il pericolo, come evitarlo?
Il problema presentato è una naturale conseguenza della mancata validazione dell'input all'interno del software applicativo che utilizziamo o che abbiamo sviluppato. I moderni linguaggi di programmazione per il web consentono l'utilizzo di librerie per la sanitizzazione dell'input che possono quindi essere integrate nei propri progetti al fine di evitare l'immissione di caratteri e stringhe dannose. Come sempre si consiglia l'uso di framework consolidati e ritenuti sicuri dall'intera comunità di esperti, in aggiunta all'utilizzo di politiche di whitelisting piuttosto che di blacklisting.
Esattamente come per altre problematiche nell'ambito delle applicazioni online si può cercare di mitigare eventuali mancanze dei filtri di validazione utilizzando degli approcci diversi: si può cercare di risolvere il problema a livello di richieste HTTP utilizzando dei firewall applicativi, come il noto Apache ModSecurity, che filtrino le richieste oppure si può cercare di limitare i danni impostando correttamente i privilegi a livello di sistema operativo.