La directory traversal, nota anche come “path traversal” (e identificata con CWE-22), è una vulnerabilità delle applicazioni web che consente agli hacker di accedere a file non previsti in un filesystem sottostante. A seconda di come e dove avviene l'attraversamento, questo potrebbe consentire a un hacker di leggere o scrivere file arbitrari sul server web, permettendogli potenzialmente di leggere dati sensibili o file, modificare i dati dell'applicazione o assumere il controllo "full" del server web.
Le vulnerabilità di traversal sono in genere descritte in base al fatto che consentano di leggere file o di scrivere file. Nelle sottosezioni seguenti dimostreremo l'impatto che ciascuno può avere.
Traversal di directory che consente letture arbitrarie di file
Considera un'applicazione che consente a un utente di archiviare foto e recuperarle in seguito con una richiesta GET usando un parametro filename per specificare quale file recuperare. Se l'applicazione non include protezioni contro l'attraversamento del percorso e costruisce il percorso del file utilizzando il parametro filename fornito, potrebbe essere possibile recuperare file arbitrari dal server web sottostante. La figura 1 mostra questa sequenza nella pratica:

Anche se l'applicazione è vulnerabile al traversal descritto, ci sono comunque limitazioni da considerare, come le autorizzazioni dell'applicazione. Ad esempio, se viene applicato un modello di privilegio minimo che limita l'accesso dell'applicazione sul server web, le sue autorizzazioni possono limitare i file a cui l'hacker può accedere tramite la vulnerabilità. Questo è uno dei motivi per cui i payload di traversal usano spesso /etc/passwd come target: il file deve essere leggibile da tutti gli utente. Esistono altri modi per creare sandbox e limitare l'accesso delle applicazioni, che tratteremo più approfonditamente nella sezione dedicata alla prevenzione.
Traversal di directory che consente scritture arbitrarie di file
Considera la stessa applicazione per l’archiviazione di foto, ma ora consente all’utente di assegnare un nome a ciascuna delle foto che archivia. Quando salva il file sul disco, l'applicazione usa il nome fornito per costruire il percorso del file della foto. A meno che non vi siano protezioni sufficienti, un hacker può aggiungere sequenze di traversal (ad esempio, ../) al nome fornito, controllando in quale directory viene archiviato il file.
Anche se può sembrare innocuo, dato che si limita ad archiviare una foto, esistono modi per portare avanti lo sfruttamento. Se il tipo di file non viene convalidato (ad esempio, JPEG, PNG), un hacker potrebbe caricare qualsiasi tipo di file, causando diversi scenari di sfruttamento, come:
L’aggiunta della chiave pubblica dell’hacker al file authorized_keys di un utente (ad es., /root/.ssh/authorized_keys) per ottenere un accesso persistente
Sovrascrittura dei file dell'applicazione per modificare il comportamento dell'applicazione
Caricamento di una web shell all'interno della root web
Causare un Denial of Service sovrascrivendo i file di sistema necessari
Caricamento di file eseguibili (ad es., malware, ransomware)
A seconda del livello di accesso dell'applicazione, l'impatto di una scrittura arbitraria di file dovuta a directory traversal può essere devastante.
Esempi reali di directory traversal
Dopo aver trattato le basi del Directory Traversal, vediamo alcuni casi recenti di sfruttamento di questa vulnerabilità nel mondo reale.
Common Vulnerability and Exposure-2023-2825: attraversamento di directory in Gitlab
Nella versione 16.0.0 di Gitlab, c’è una vulnerabilità di directory traversal che consente letture arbitrarie di file. Il caricamento di un file come allegato a un Issue in un'installazione Gitlab predefinita fa sì che Gitlab archivi il file a una profondità di 10 directory secondo uno schema come mostrato di seguito:
/var/opt/gitlab/gitlab-rails/uploads/@hashed/<directory>/<directory>/<directory>/<directory>/<filename>Dopo il caricamento, Gitlab fornisce anche un endpoint per recuperare il file caricato all'indirizzo
/<repo-name>/uploads/<file-id>/<filename>In una richiesta a quell'endpoint, Gitlab non sanifica né convalida il parametro filename, il che consente un attacco di directory traversal. Per sfruttare l'exploit, il repository deve essere nidificato all'interno di almeno 5 gruppi, con il numero di gruppi direttamente correlato al numero di directory che puoi attraversare usando la vulnerabilità.
In un'installazione Standard, questo significa che devi annidare il repository in 11 gruppi per poter raggiungere la radice del filesystem. In questo scenario, un payload di attacco per recuperare il file /etc/passwd potrebbe apparire come segue:
GET /Group-1/Group-2/Group-3/Group-4/Group-5/Group-6/Group-7/Group-8/Group-9/Group-10/Group-11/<repo-name>/uploads/<file-id>/..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswdGli hacker non autenticati possono exploit la vulnerabilità solo se un repository pubblico soddisfa il requisito dei gruppi nidificati. È improbabile che ciò accada, rendendo più probabile lo sfruttamento da parte di un utente autenticato con privilegi per creare gruppi e repository nidificati al fine di soddisfare i requisiti di sfruttamento. Una catena di exploit completa può prima creare i gruppi e il repository necessari, caricare un file e quindi sfruttare il traversal per leggere file arbitrari, come mostrato in questa POC.
Common Vulnerability and Exposure-2022-48362: directory traversal in ManageEngine Desktop Central
Nelle build di ManageEngine Desktop Central precedenti alla 10.1.2127.1, un directory traversal nella funzionalità di caricamento dei file consentiva scritture arbitrarie di file manipolando il parametro “computerName” (o alcuni altri) per includere sequenze di attraversamento.
Al momento della sua scoperta, questa vulnerabilità veniva sfruttata attivamente e combinata con un bypass dell'autenticazione (CVE-2021-44515) per consentire l'esecuzione di codice remoto. Per brevità, ci concentreremo sulla parte di sfruttamento relativa al traversal del percorso, poiché consente la scrittura di un file e aggira una convalida permissiva.
In una funzione denominata “doPost”, Desktop Central gestisce diversi parametro come parte del caricamento di un file, tra cui “computerName” e “filename”, tra gli altri. Da questa funzione derivano due vulnerabilità che portano a un directory traversal riuscito, che consente la scrittura di file:
Viene controllato solo il parametro filename per le sequenze di traversal. Altri parametro come “domainName”, “computerName” o “customerId” vengono usati per costruire il percorso assoluto del file, ma non vengono controllati per le sequenze di traversal. Il “computerName” è l'ultimo parametro utilizzato nella stringa concatenata, quindi sarebbe il punto ideale in cui inserire una sequenza di attraversamento perché non verrà aggiunto altro contenuto.
Il caricamento dei file consente file con estensioni zip, 7z e gz. A prima vista, forse sembra sicuro. Tuttavia, poiché Desktop Central è un'applicazione Java e i file JAR sono costruiti sul formato zip, ciò consente l'esecuzione di codice remoto. Caricando un file zip nella directory
C:\Program Files\DesktopCentral_Server\libe forzando un riavvio, un hacker esperto può sovrascrivere i file di classe nell'applicazione per includere il proprio codice e ottenere l'esecuzione di codice.
Questa vulnerabilità evidenzia il grave impatto che una vulnerabilità di traversal può consentire, mostrando anche come una prevenzione incompleta possa consentire involontariamente il directory traversal.
Directory traversal come visto dai WAF
L’attraversamento delle directory è una delle tecniche di attacco osservate più comunemente, come evidenziato nel nostro Report sulle minacce di Fastly Network Effect del secondo trimestre del 2023.
Questo potrebbe dipendere da diversi motivi, tra cui la gravità dell'impatto in caso di esito positivo o la dimensione degli elenchi di payload che hacker e scanner possono utilizzare. Ad esempio, un frammento di uno degli elenchi di directory traversal di PayloadsAllTheThings tenta di leggere lo stesso file con profondità di traversal variabili, come mostrato di seguito:
../../../../../../../../../etc/passwd
../../../../../../../../etc/passwd
../../../../../../../etc/passwd
../../../../../../etc/passwd
../../../../../etc/passwd
../../../../etc/passwd
../../../etc/passwdNella maggior parte dei casi, è probabile che un hacker non sappia dove si trova l'applicazione nel filesystem quando verifica la presenza di una vulnerabilità di traversal. Tuttavia, le applicazione non andranno oltre la radice del sistema (ovvero /), quindi gli hacker utilizzano sequenze più lunghe di “../” per assicurarsi di raggiungere la radice, includendo anche sequenze più brevi nel caso in cui quelle più lunghe vengano bloccate o compromettano la funzionalità dell'applicazione.
Altri tipi di attacco, come il Cross-Site Scripting (XSS), possono utilizzare payload poliglotti che combinano più tecniche in un singolo payload. Questo porta gli hacker e gli scanner a inviare molti più payload per testare la traversal rispetto a quando testano per XSS. Il nostro file di esempio di PayloadsAllTheThings contiene 140 payload, rispetto al loro file XSS_Polyglots che ne contiene 16. Il file di payload più grande per traversal in PayloadsAllTheThings contiene oltre 21.000 voci, rispetto al più grande per XSS con oltre 600, a SQLi con oltre 400 (anche se si dovrebbe presumere che in pratica questo numero sia maggiore se il tipo di database è sconosciuto, poiché sarebbe necessario testare più tipi), e a oltre 400 per l'iniezione di comandi OS.
Sebbene la dimensione degli elenchi di payload di traversal offra un'ipotesi per la tecnica di attacco traversal ampiamente osservata, anche la gravità dell'impatto può far sì che la tecnica venga utilizzata più frequentemente. , come dimostrato nella discussione precedente su Common Vulnerability and Exposure-2022-48362, che consentiva l'esecuzione di codice remoto e che, al momento della scoperta, risultava essere sfruttata.
Prevenire le vulnerabilità di directory traversal
Esistono diverse strategie che possono essere utilizzate per prevenire le vulnerabilità di traversal, tra cui modifiche di progettazione per evitare di creare percorsi di file con input dell'utente, la convalida rigorosa dell'input, l'uso della canonicalizzazione del percorso e la limitazione dell'accesso dell'applicazione. Di seguito esamineremo ciascuno di questi elementi.
Evita di creare percorso di file con input dell'utente
Anziché utilizzare l'input dell'utente per costruire il percorso del file, valuta l'utilizzo di un ID o nome file corrispondente per fare riferimento al file. Quindi, mappa i file-id al percorso di storage corrispondente. Quando un utente richiede questo file o carica un file, può controllarne solo l'id, impedendogli così di accedere ai contenuti usati per costruire il percorso del file. Questo elimina completamente la possibilità di traversal, poiché l'input dell'utente non viene più usato per costruire il percorso del file recuperato.
Convalida rigorosa dell'input dell'utente
La convalida rigorosa è diversa dalla sanitizzazione. Anziché sanificare l'input tentando di rimuovere le sequenze di attraversamento (ad esempio, ../), che possono essere aggirate in innumerevoli modi, verifica che nell'input dell'utente siano presenti solo i contenuti previsti e rifiuta tutto ciò che non supera la convalida rigorosa. Esempi di convalida che possono aiutare a prevenire il directory traversal:
Convalida che un nome file contenga solo caratteri alfanumerici
Convalida che nel nome file fornito sia presente un solo carattere “.”
Convalida che i caratteri indesiderati non siano inclusi nell'input fornito (ad esempio, /, \\)
Convalida del tipo di file di un file caricato (non in base all'estensione, che può essere facilmente aggirata)
Usa le funzionalità di canonicalizzazione del percorso per una convalida rigorosa
La canonicalizzazione del percorso essenzialmente abbrevia il percorso del file al suo percorso effettivo, rimuovendo di fatto i collegamenti simbolici, le sequenze ../ e altri contenuti simbolici. Dopo aver ottenuto un percorso canonico, puoi verificare che inizi ancora con la directory di base prevista (ad esempio, uploads/photos/). Alcuni esempi di funzioni per ottenere un percorso canonico sono:
Java:
getCanonicalPathPHP:
realpathC:
percorso realeASP.NET:
GetFullPath
Limita l'accesso all'applicazione
In generale, un'applicazione dovrebbe avere accesso solo ai file e alle directory necessari per funzionare correttamente. Questo aiuta in alcuni casi di directory traversal limitando l'impatto della vulnerabilità, se ne viene scoperta una. Ad esempio, un'applicazione web non dovrebbe mai essere eseguita con l'utente root e, idealmente, dovrebbe essere limitata ad accedere solo ai file necessari per fornire l'applicazione.
Riepilogo
La directory traversal, nota anche come “percorso traversal”, è una vulnerabilità delle applicazioni web che consente agli hacker di accedere a file non previsti in un filesystem sottostante. A seconda della vulnerabilità di attraversamento, questo potrebbe consentire a un hacker di leggere dati sensibili o file, modificare i dati dell’applicazione o assumere il controllo "full" del server web. Le vulnerabilità di traversal possono avere impatti gravi e, come mostrano i nostri esempi reali e i dati del Next-Gen WAF, rappresentano un importante vettore di attacco. Tuttavia, le applicazioni possono prevenire le vulnerabilità di path traversal seguendo le soluzioni che abbiamo delineato. Se hai difficoltà a prevenire il directory traversal o utilizzi un prodotto che in passato ha sofferto di queste vulnerabilità, dai un'occhiata al Next-Gen WAF di Fastly per proteggerti da questi attacchi e altro ancora.