Samstag, 16. Juni 2012


Topthema

Donnerstag, 20. November 2008 | Topthema

About Security #182: Schwachstellen-Suche: Directory-Traversal (6)

(Link zum Artikel: http://www.entwickler.de/entwicklerde/kolumnen/046154)
  • Teilen
  • kommentieren
  • empfehlen
  • Bookmark and Share

Nach der Beschreibung von Directory-Traversal-Schwachstellen sowie der Suche danach geht es in dieser Folge um die Verhinderung von Directory-Traversal-Angriffen.

Sicher: Keine Dateisystemaufrufe mit Benutzerdaten

Manipulationen am Dateisystem verhindert man am einfachsten, indem man keine vom Benutzer manipulierbaren Parameter für Zugriffe aufs Dateisystem verwendet: Werden für den Aufruf von Dateisystemfunktionen keine vom Client gelieferten Parameter als Bestandteil von Pfad und/oder Dateinamen verwendet, kann die Funktion auch nicht auf eine andere Datei umgelenkt werden.

Als Beispiel soll ein Skript dienen, das eine Bilddatei anzeigt. Die anzuzeigende Datei wird dabei über einen URL-Parameter definiert:

http://www.server.example/anwendung/zeigeBild.php?bild=irgendwas.gif

Ist keine Zugriffskontrolle oder besondere Präsentation des Bilds notwendig, kann die Bilddatei auch direkt verlinkt werden:

http://www.server.example/daten/bilder/irgendwas.gif

Manchmal ist die direkte Ausgabe nicht möglich oder erwünscht, z.B. weil eine Zugriffskontrolle notwendig ist oder weitere Informationen angezeigt werden sollen. Dann kann eine Liste zulässiger Dateinamen erstellt und die einzelnen Dateien daraus über einen eindeutigen Identifier, z.B. eine Indexnummer, ausgewählt werden:

http://www.server.example/anwendung/zeigeBild.php?bild=123

Requests mit ungültiger Indexnummer können verworfen werden, ein Angriff ist nicht mehr möglich.

Entsprechendes gilt für alle Fälle, in denen nur eine bestimmte Menge fest vorgegebener Dateien zur Auswahl steht. Ein berühmt-berüchtigtes Beispiel ist (vor allem in PHP-Skripten) eine Datei mit den Sprachanpassungen nach dem Muster

http://www.server.example/anwendung/machwas.php?sprache=deutsch
http://www.server.example/anwendung/machwas.php?sprache=englisch
...

wobei die Sprachanpassung dann nach dem Muster

include("pfad/zum/sprachverzeichnis".$sprache.".inc");

oder

include($sprache.".inc");

erfolgt.

Es besteht keinerlei Notwendigkeit, hier mit dem vom Benutzer gelieferten Parameter auf das Dateisystem zuzugreifen. Stattdessen kann der Parameter verwendet werden, um über z.B. eine if- oder switch-Anweisung die entsprechende Datei auszuwählen.

if ($sprache = 'deutsch') {
  include(deutsch.inc)
}
elsif($sprache = 'englisch')  {
  include(englisch.inc) 
}
...
Riskant: Zugriff über benutzerkontrollierte Parameter

In manchen Fällen lassen sich Dateisystemaufrufe mit vom Benutzer manipulierbaren Parametern nicht vermeiden. Dann müssen die verwendeten Parameter sehr gründlich geprüft werden, um Directory-Traversal-Angriffe zu verhindern. Im folgenden werden einige Schutzmaßnahmen beschrieben, die einzeln oder miteinander kombiniert eingesetzt werden können. Je mehr Schutzmaßnahmen eingesetzt werden, desto besser.

Nachdem die Benutzereingabe dekodiert und kanonisiert wurde, wird darin nach den Directory-Traversal-Sequenzen ../ und ..\ sowie nach Nullbytes gesucht. Wird etwas gefunden, wird die Eingabe verworfen und nicht weiter bearbeitet. Jeder Versuch, die Eingabe zu bereinigen, ist ein überflüssiges Risiko, weil auch nach der Bereinigung noch eine Directory-Traversal-Sequenz enthalten sein könnte (siehe About Security #181). Außerdem wurde gerade sehr wahrscheinlich ein Angriff festgestellt, und den muss man nicht unterstützen.

Ebenso wird auch die Dateiendung geprüft: Nur Endungen, die auf einer vorgegebenen Liste zulässiger Endungen enthalten sind, werden akzeptiert, alle anderen Eingaben verworfen. Dabei ist besonders auf evtl. vorhandene doppelte Endungen zu achten. Wenn die Anwendung irgendwas.php.gif als .gif erkennt, muss das beim späteren Zugriff auf das Dateisystem nicht zwingend genau so sein.

Alle akzeptierten Eingaben werden vor ihrer Verwendung mit Hilfe der Dateisystem-API daraufhin geprüft, ob wirklich auf eine Datei im vorgegebenen Verzeichnis zugegriffen wird. In Java kann dazu ein java.io.File-Objekt mit dem vom Benutzer gelieferten Dateinamen instantiiert und danach die Methode getCanonicalPath() darauf angewendet werden. Beginnt der zurückgelieferte String nicht mit dem Namen des Startverzeichnisses, stimmt etwas nicht und die Eingabe wird verworfen. In ASP.NET erfüllt die Methode System.Io.Path.GetFullPath() den gleichen Zweck.

Sollte trotz alles Vorsicht einmal ein Directory-Traversal-Angriff gelingen, kann die Verwendung einer chrooted Umgebung den Schaden begrenzen. Das chrooted Verzeichnis stellt dann für die Dateizugriffe das Wurzelverzeichnis dar, darüber hinaus führende Directory-Traversal-Sequenzen werden ignoriert.

Zu guter Letzt sollten alle erkannten und abgewehrten Angriffe protokolliert und entsprechend darauf reagiert werden. Je nach den jeweiligen Umständen wird dann die Session des Angreifers beendet, der entsprechende Benutzer gesperrt und/oder der Administrator informiert, der dann ggf. weitere Maßnahmen ergreifen kann.

Damit ist das Thema "Directory Traversal" abgeschlossen. In der nächsten Folge geht es um eine damit verwandte Schwachstelle: Das Einbinden entfernter Dateien in PHP-Skripten, die sog. Remote File Inclusion, RFI.

Wenn Sie Fragen oder Themenvorschläge haben, können Sie diese gerne an die angegebene E-Mail-Adresse senden oder im Security-Forum einbringen!

Carsten Eilers

About Security - Übersicht zum aktuellen Thema:

Kommentare

Folgende Links könnten Sie auch interessieren