Directory Traversal oder die unzulässige Beschränkung eines Pfadnamens auf ein eingeschränktes Verzeichnis (auch als „Path Traversal“ oder unter dem Kürzel CWE-22 bekannt) ist eine Schwachstelle in Webanwendungen, die es Angreifern ermöglicht, auf unbeabsichtigte Dateien in einem zugrunde liegenden Dateisystem zuzugreifen. Je nachdem, wie und wo diese Schwachstelle auftaucht, kann ein Angreifer Lese- oder Schreibzugriff auf beliebige Dateien auf dem Webserver erhalten. So kann er möglicherweise sensible Daten oder Dateien lesen, Anwendungsdaten ändern oder die vollständige Kontrolle über den Webserver an sich reißen.
Traversal-Schwachstellen werden üblicherweise danach unterschieden, ob sie Lese- oder Schreibzugriff auf Dateien ermöglichen. In den folgenden Abschnitten gehen wir näher auf die möglichen Auswirkungen jeder dieser Schwachstellen ein.
Stellen Sie sich eine Anwendung vor, bei der ein Nutzer Fotos speichern und später mit einer GET-Anfrage abrufen kann, wobei ein Dateinamenparameter angibt, welche Datei abgerufen werden soll. Wenn die Anwendung keinen Schutzmechanismus gegen Path Traversal beinhaltet und den Dateipfad mit dem angegebenen Dateinamenparameter erstellt, ist es unter Umständen möglich, beliebige Dateien von dem zugrunde liegenden Webserver abzurufen. Abbildung 1 veranschaulicht diesen Ablauf in der Praxis:
Selbst wenn die Anwendung für das oben beschriebene Traversal anfällig ist, können Einschränkungen wie Anwendungsberechtigungen als Schutzmaßnahme herangezogen werden. Wenn zum Beispiel ein Least-Privilege-Modell zum Einsatz kommt, das den Zugriff auf Anwendungen auf dem Webserver einschränkt, können die im Rahmen des Modells gewährten Berechtigungen die Anzahl der Dateien limitieren, auf die der Angreifer über die Sicherheitslücke zugreifen kann. Dies ist auch einer der Gründe, warum Traversal Payloads häufig „/etc/passwd“ als Ziel verwenden. Schließlich muss die Datei für alle Nutzer lesbar sein. Es gibt aber auch noch weitere Möglichkeiten, um den Zugriff auf Anwendungen (mittels Sandboxing) zu beschränken. Auf diese gehen wir im Abschnitt zum Thema Prävention noch genauer ein.
Nehmen wir wieder unsere Anwendung zum Speichern von Fotos. Diesmal erlaubt sie es dem Nutzer aber, jedes der gespeicherten Fotos zu benennen. Beim Speichern der Datei nutzt die Anwendung den vorgegebenen Dateinamen im Pfad der Fotodatei. Wenn es keine ausreichenden Schutzmaßnahmen gibt, kann ein Angreifer Traversal-Sequenzen (z. B. „../“) an den angegebenen Dateinamen anhängen und so kontrollieren, in welchem Verzeichnis die Datei gespeichert wird.
Das mag zwar harmlos erscheinen, da es sich nur um das Speichern eines Fotos handelt, es gibt aber weitere Missbrauchsmöglichkeiten. Wenn der Dateityp nicht validiert wird (z. B. JPEG, PNG), kann ein Angreifer jeden beliebigen Dateityp hochladen, was zu verschiedenen Angriffsszenarien führen kann:
Hinzufügen des Public Key des Angreifers zur „authorized_keys“-Datei eines Nutzers (z. B. „/root/.ssh/authorized_keys“), um dauerhaften Zugriff zu erhalten
Überschreiben von Anwendungsdateien, um das Verhalten der Anwendung zu ändern
Hochladen einer Web-Shell in das Root-Verzeichnis
Herbeiführen eines Denial of Service durch Überschreiben benötigter Systemdateien
Hochladen von ausführbaren Dateien (z. B. Malware oder Ransomware)
Abhängig von der Tiefe des Zugriffs auf die Anwendung können die Auswirkungen eines willkürlichen Schreibvorgangs auf eine Datei durch Directory Traversal verheerend sein.
Nachdem wir nun mit den Grundlagen von Directory Traversal vertraut sind, können wir uns genauer ansehen, wie diese Schwachstelle in der Praxis derzeit ausgenutzt wird.
In Gitlab Version 16.0.0 gibt es eine Directory-Traversal-Schwachstelle, die Lesezugriff auf beliebige Dateien bietet. Wenn Sie eine Datei als Anhang zu einem Issue in einer Standardinstallation von Gitlab hochladen, speichert Gitlab die Datei in einem Unterverzeichnis zehnten Grades nach dem unten abgebildeten Muster:
/var/opt/gitlab/gitlab-rails/uploads/@hashed/<directory>/<directory>/<directory>/<directory>/<filename>
Nach dem Hochladen bietet Gitlab auch einen Endpoint zum Abrufen der hochgeladenen Datei unter
/<repo-name>/uploads/<file-id>/<filename>
Bei einer Anfrage an diesen Endpoint überprüft Gitlab den Parameter „filename“ nicht, was einen Angriff über das Verzeichnis ermöglicht. Um die Traversal-Schwachstelle auszunutzen, muss das Repository in mindestens 5 Gruppen verschachtelt sein, wobei die Anzahl der Gruppen direkt mit der Anzahl der Verzeichnisse korreliert, auf die man mit der Schwachstelle zugreifen kann.
Bei einer Standardinstallation bedeutet das, dass das Repository in 11 Gruppen verschachtelt werden muss, um das Stammverzeichnis des Dateisystems erreichen zu können. In einem solchen Szenario könnte eine Angriffs-Payload zum Abrufen der Datei „/etc/passwd“ zum Beispiel wie folgt aussehen:
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%2fpasswd
Nicht authentifizierte Angreifer können die Schwachstelle nur dann ausnutzen, wenn ein öffentliches Repository die Anforderung der verschachtelten Gruppen erfüllt. Da dies aber eher unwahrscheinlich ist, ist es wahrscheinlicher, dass ein authentifizierter Nutzer, der die Berechtigung hat, verschachtelte Gruppen und Repositories zu erstellen, die Voraussetzungen für die Ausnutzung der Schwachstelle erfüllt. Eine vollständige Exploit-Kette kann zunächst die benötigten Gruppen und das Repository erstellen, eine Datei hochladen und dann die Traversal-Schwachstelle ausnutzen, um beliebige Dateien zu lesen, wie im Proof of Concept zu sehen ist.
Bei Builds von ManageEngine Desktop Central älter als 10.1.2127.1 begünstigte ein Directory Traversal beim Datei-Upload Schreibzugriff auf beliebige Dateien, indem der Parameter „computerName“ (oder einige andere) manipuliert wurde, um Traversal-Sequenzen einzuschließen.
Zum Zeitpunkt ihrer Entdeckung wurde diese Sicherheitslücke aktiv ausgenutzt und mit einer Authentifizierungsumgehung (CVE-2021-44515) kombiniert, um Remote-Codeausführung zu ermöglichen. Der Kürze halber konzentrieren wir uns auf den Directory-Traversal-Anteil des Exploits, da er den Schreibzugriff auf eine Datei ermöglicht und die grobe Validierung umgeht.
In einer Funktion namens „doPost“ verarbeitet Desktop Central mehrere Parameter als Teil eines Datei-Uploads, unter anderem „computerName“ and „filename”. Aus dieser Funktion ergeben sich zwei Schwachstellen, die zu einem erfolgreichen Directory Traversal mit Schreibzugriff auf Dateien führen:
Nur der Parameter „filename” wird auf Traversal-Sequenzen überprüft. Andere Parameter wie „domainName“, „computerName“ oder „customerId“ werden verwendet, um den absoluten Pfad für die Datei zu erstellen, werden allerdings nicht auf Traversal-Sequenzen geprüft. „computerName“ ist der letzte Parameter in dem verketteten String und wäre daher der ideale Ort, um eine Traversal-Sequenz zu platzieren, da keine weiteren Inhalte angehängt werden.
Beim Hochladen von Dateien sind Dateinamen mit den folgenden Erweiterungen zulässig: „zip“, „7z“ und „gz“. Auf den ersten Blick mag dies sicher erscheinen. Da Desktop Central aber eine Java Anwendung ist und JAR-Dateien auf dem ZIP-Format beruhen, handelt es sich hier jedoch um eine Schwachstelle, die Remote-Codeausführung ermöglicht. So können geschickte Angreifer durch das Hochladen einer ZIP-Datei in das Verzeichnis C:\Programme\DesktopCentral_Server\lib
und das Erzwingen eines Neustarts die „Class“-Dateien in der Anwendung überschreiben, um ihren eigenen Code einzubinden und Codeausführung zu erwirken.
Diese Sicherheitslücke verdeutlicht die schwerwiegenden Auswirkungen, die eine Traversal-Schwachstelle haben kann, und zeigt gleichzeitig, wie ein unvollständiger Schutz unbeabsichtigt ein Directory Traversal begünstigen kann.
Directory Traversal gehört zu den am häufigsten beobachteten Angriffstechniken, wie in unserem Bericht „Der Netzwerkeffekt in der Bedrohungsabwehr“ aus dem zweiten Quartal 2023 beschrieben wird.
Dafür gibt es mehrere Gründe, zum Beispiel die Schwere der Auswirkungen im Erfolgsfall oder die Größe der Payload-Listen, die Angreifer und Scanner möglicherweise verwenden. Ein Snippet aus einer der „PayloadsAllTheThings“-Directory-Traversal-Listen versucht beispielsweise, dieselbe Datei mit unterschiedlichen Traversal-Tiefen zu lesen:
../../../../../../../../../etc/passwd
../../../../../../../../etc/passwd
../../../../../../../etc/passwd
../../../../../../etc/passwd
../../../../../etc/passwd
../../../../etc/passwd
../../../etc/passwd
In den meisten Fällen weiß ein Angreifer wahrscheinlich nicht, wo im Dateisystem sich die Anwendung befindet, wenn er nach einer Traversal-Schwachstelle sucht. Deshalb verwenden Angreifer längere Sequenzen im Stil von („../“), um sicherzustellen, dass das Root-Verzeichnis erreicht wird, und schließen auch kürzere Sequenzen mit ein, falls längere Sequenzen blockiert werden oder die Funktionalität der Anwendung unterbrechen.
Andere Angriffsarten wie Cross-Site Scripting (XSS) bedienen sich möglicherweise polyglotter Payloads, die mehrere Techniken in einer einzigen Payload kombinieren. Dies führt dazu, dass Angreifer und Scanner auf der Jagd nach Traversal viel mehr Payloads senden müssen als bei XSS. Unsere Beispieldatei aus „PayloadsAllTheThings“ enthält 140 Payloads, verglichen mit ihrer „XSS_Polyglots“-Datei, die gerade einmal 16 enthält. Die größte Payload-Datei für Traversal in „PayloadsAllTheThings“ hat über 21.000 Einträge, verglichen mit der größten für XSS Command Injection mit über 600, SQLi Command Injection mit über 400 (obwohl man davon ausgehen sollte, dass diese Zahl in der Praxis größer wäre, wenn der Datenbanktyp unbekannt ist, da mehrere Typen getestet werden müssten) und über 400 für OS Command Injection.
Während die Größe der Traversal-Payload-Listen eine Hypothese für die weit verbreitete Traversal-Angriffstechnik darstellt, kann die Schwere der Auswirkungen auch dazu führen, dass die Technik häufiger genutzt wird. Wie das obige Beispiel zu CVE-2022-48362 zeigt, ermöglichte diese Technik die Remote-Codeausführung und ihre Verwendung für Angriffe war zum Zeitpunkt ihrer Entdeckung bereits bekannt.
Es gibt verschiedene Strategien, um Traversal-Schwachstellen zu verhindern. Dazu gehören Designänderungen, die die Erstellung von Dateipfaden mit Nutzereingaben unterbinden, die strikte Validierung von Eingaben, die Verwendung von Pfadkanonisierung und die Beschränkung des Zugriffs auf die Anwendung. Auf die einzelnen Strategien gehen wir im Folgenden genauer ein.
Anstatt den Dateipfad über Nutzereingaben zu erstellen, sollten Sie eine entsprechende „file-id“ oder einen Namen verwenden, um die Datei zu referenzieren. Anschließend können Sie die „file-id“ dem entsprechenden Speicherpfad zuordnen. Wenn ein Nutzer diese Datei anfordert oder eine Datei hochlädt, erhält er ausschließlich Kontrolle über ihre ID, sodass der Nutzer niemals auf die Inhalte zugreifen kann, die zum Aufbau des Dateipfads verwendet wurden. Damit entfällt die Traversal-Gefahr vollständig, da die Nutzereingaben nicht mehr dazu verwendet werden können, den Dateipfad der abgerufenen Datei zu erstellen.
Eine strikte Validierung ist nicht mit einer Bereinigung gleichzusetzen. Anstatt die Eingaben zu bereinigen, indem Sie versuchen, Traversal-Sequenzen wie „../“ zu entfernen, die auf unzählige Arten umgangen werden können, sollten Sie überprüfen, dass nur erwartete Inhalte in den Nutzereingaben enthalten sind, und alles zurückweisen, was die strikte Validierung nicht besteht. Hier einige Beispiele für Validierungen, die dazu beitragen können, Directory Traversal zu verhindern:
Validierung, ob ein Dateiname nur alphanumerische Werte enthält
Validierung, dass nur ein einzelner „.“ im Dateinamen enthalten ist
Validierung, ob unerwünschte Zeichen enthalten sind (z. B. „/“ oder „\“)
Validierung des Dateityps einer hochgeladenen Datei (nicht anhand der Erweiterung, die leicht umgangen werden kann)
Durch Pfadkanonisierung wird der Dateipfad im Wesentlichen auf seinen tatsächlichen Pfad verkürzt, wobei Symlinks, „../“-Sequenzen und andere symbolische Inhalte entfernt werden. Nachdem ein kanonischer Pfad vorliegt, können Sie überprüfen, ob er weiterhin mit dem erwarteten Basisverzeichnis beginnt (z. B. „uploads/photos/“). Hier einige Beispiele für Funktionen, die zu einem kanonischen Pfad führen:
Java: getCanonicalPath
PHP: realpath
C: realpath
ASP.NET: GetFullPath
Im Allgemeinen sollte eine Anwendung nur auf Dateien und Verzeichnisse zugreifen können, auf die sie Zugriff benötigt, um ordnungsgemäß zu funktionieren. Sollte eine Directory-Traversal-Schwachstelle dennoch entdeckt werden, hilft diese Maßnahme, die Auswirkungen möglicher Angriffe zu begrenzen. Eine Webanwendung sollte zum Beispiel nie unter dem Root-Nutzer laufen und idealerweise nur auf die Dateien zugreifen können, die sie für die Ausführung benötigt.
Directory Traversal (auch als „Path Traversal“ bekannt) ist eine Schwachstelle in Webanwendungen, die es Angreifern ermöglicht, auf unbeabsichtigte Dateien in einem zugrunde liegenden Dateisystem zuzugreifen. Je nach Art der Schwachstelle kann ein Angreifer dadurch Lesezugriff auf sensible Daten oder Dateien erhalten, Anwendungsdaten verändern oder die vollständige Kontrolle über den Webserver an sich reißen. Traversal-Schwachstellen können schwerwiegende Auswirkungen haben und sind, wie unsere Beispiele aus der Praxis und die Daten unserer Next-Gen WAF zeigen, ein ernstzunehmender Angriffsvektor. Path-Traversal-Schwachstellen in Anwendungen lassen sich jedoch verhindern, indem Sie die von uns vorgestellten Lösungen anwenden. Wenn Sie Schwierigkeiten haben, Directory Traversal zu verhindern, oder ein Produkt einsetzen, das in der Vergangenheit von diesen Schwachstellen betroffen war, sollten Sie sich mit der Next-Gen WAF von Fastly vertraut machen, die vor diesen und weiteren Angriffen schützt.