Blog

Gefahren von Archivdateien in Applikationen

Dokument-Archive erlauben das Speichern von mehreren Dateien, samt Metadaten, in einer einzelnen Datei. Vergleichbar mit einer Umzugskiste wird somit sowohl die Lagerung als auch der Transport der Dokumente erleichtert. Es gibt viele verschiedene Archiv-Typen, zu den bekanntesten zählen ZIP, RAR, 7z und tar.

Abhängig von dem Archivtyp werden verschiedene Eigenschaften unterstützt, wie beispielsweise Komprimierung, Verschlüsselung oder Fehlererkennung und -korrektur.

Durch die praktische Handhabung und zahlreiche Funktionen erfüllen Dateiarchive die unterschiedlichsten Einsatzzwecke. Auch in modernen Anwendungen, egal ob im Web, als Rich-Client oder im IoT-Bereich, werden diese eingesetzt, um bestimmte Funktionen zu erlauben oder die Benutzerfreundlichkeit zu steigern.

Diese scheinbar unschuldigen Dateitypen bergen aber bei unsicherer Handhabung Gefahren verschiedenster Ausmaße. Bei unkontrollierter Weiterverarbeitung der benutzerkontrollierten Dateien kann der Diebstahl oder die Manipulation von Daten auf dem Webserver, eine Denial of Service (DoS) oder sogar eine Remote Code Execution (RCE) die Folge sein.

Für die Veranschaulichung von verschiedenen Problemen wird in diesem Blog-Eintrag das ZIP-Format verwendet. Das Dateiformat bietet u.a. Komprimierung, Verschlüsselung, das Speichern von symbolischen Verknüpfungen (vergleichbar mit Verknüpfungen unter Windows – später mehr dazu) und einer eigenen Dokumentstruktur an. Jegliche Beispiele wurden auf Ubuntu 16.04.3 LTS durchgeführt.

Ein typisches Einsatzszenario ist der Transport von mehreren Dateien oder die Komprimierung. Dazu werden die Archive auf dem Server extrahiert und anschließend angezeigt oder weiterverarbeitet.

Eine alternative Anwendungsmöglichkeit wäre, wenn die Applikation Benutzerdaten sammelt oder den Upload von Dateien ermöglicht und diese dann in ein Archiv packt und zum Download anbietet.

Je nachdem, wie ZIP-Archive eingesetzt werden, ergeben sich verschiedene Angriffsszenarien, die im Folgenden dargestellt werden sollen.

Schwachstelle: Denial of Service (DoS)

Speziell präparierte Archive können auf den ersten Blick unscheinbar aussehen, aber sich beim Entpacken als Alptraum entpuppen. Ein klassisches Beispiel hierfür sind sogenannte ZIP-Bomben. Hierbei handelt es sich um Archive, die sich beim Entpacken extrem ressourcenhungrig verhalten. Die Ressourcen können beispielsweise Zeit, Speicherplatz oder Rechenleistung sein. Das Resultat ist im schlimmsten Fall eine Nichterreichbarkeit des Dienstes.

Ein konkretes Beispiel ist die bekannte „42.zip“-Datei, die nur 42 Kilobyte groß ist. Wird das Archiv entpackt, beträgt die finale Dateigröße des Inhalts 4,5 PB (zirka 10714285714286% der Originaldatei).

Eine Methode für das Erstellen solcher Archive ist es, ein Archiv zu kreieren, das sich rekursiv selbst enthält. Wenn eine Applikation nun versuchen würde, die Daten des Archivs zu entpacken, kann es sein, dass der Prozess in einer Endlos-Schleife gefangen ist.

Alternativ werden extrem große Dateien mit sich ständig wiederholendem Inhalt archiviert. Durch die Komprimierung des Dokuments beim Archivieren schrumpft der benötigte Speicherplatz des Archivs immens. Das Extrahieren der Datei führt dann jedoch wieder zu dem originalen Speicherplatzverbrauch.

Eine einfache Textdatei, die beispielsweise 10 Millionen Mal den Text „securai“ enthält, verbraucht etwa 67 MB. Ein normales ZIP-Archiv davon verbraucht wiederum nur 100KB, also steigt der Speicherplatzverbrauch in diesem Beispiel auf ca. 67000% der Archivdatei.

Außerdem ist es möglich, über weitere Archiveigenschaften einen Extrahierungsprozess aufzuhalten oder gar lahmzulegen.

Verschiedene Archivdateitypen unterstützen die Verschlüsselung der Inhalte und sogar der Dateinamen. Wenn diese Möglichkeit nicht im Konzept der Anwendung beachtet wird, kann der Prozess für die Extrahierung blockiert werden. Der Prozess kann nicht erfolgreich beendet werden, da dieser eine Passworteingabe erwartet oder schlichtweg nicht mit verschlüsselten Archiven arbeiten kann.

Sichere Handhabung

Leider reicht es hier nicht, die Größe von Archivinhalten vor dem Entpacken zu prüfen. Diese Größenangabe wird nicht von allen Archivtypen unterstützt und die Methode schützt auch nicht vor rekursiv verpackten Archiven.

Um solche Schwachstellen erfolgreich zu verhindern, ist es sinnvoll, die verfügbaren Ressourcen des Prozesses zu limitieren. Der Prozess, der ein Archiv entpackt, sollte also nach einer definierten Zeit beendet werden und nur ein vorgegebenes Festplattenkontingent zur Verfügung haben.

In Python kann man eine zeitliche Einschränkung beispielsweise mit Signals erreichen. PHP bietet hierfür die set-time-limit Funktion an. In Java kann man dafür ExecutorService’s verwenden.

Ein Festplattenkontingent kann im einfachsten Fall mit einer limitierten Partition für Uploads realisiert werden. Somit würde im Notfall nur diese Partition überfüllt werden, nicht der gesamte Speicher des Servers.

Außerdem ist zu beachten, dass die Anzahl an wiederholten Extraktionen, also für Archive, die Archive enthalten, sinnvollerweise zu limitieren ist.

Noch besser ist es, wenn die Inhalte nicht entpackt werden, sondern direkt aus dem Archiv gelesen werden. Der Lesevorgang kann dann auf eine vorgegebene Länge (Speicherplatzverbrauch) oder Zeit limitiert werden.

Konkrete Empfehlungen für verschiedene Funktionen zum Streamen von Archivinhalten finden Sie unter den generellen Empfehlungen am Ende des Blogartikels.

Schwachstelle: Remote Code Execution (RCE)

Nicht nur die Handhabung der Archivdateien selbst kann Quelle einer Schwachstelle sein, sondern auch das verwendete Packprogramm. In speziellen Fällen können Archivdateien verwendet werden, um Code auf dem Applikations-Server auszuführen.

Ein konkretes Beispiel ist 7Zip bzw. p7zip in den Versionen vor 16.00. Die Anwendung wies eine Buffer Overflow-Schwachstelle (CVE-2016-2334) auf, die ausgenutzt werden konnte, um beliebigen Code im Kontext der Anwendung auszuführen.

Sichere Handhabung

Grundsätzlich sollte das Prinzip der geringsten Rechte gelten, um eventuelle Auswirkungen von Schwachstellen zu verringern. Außerdem wird empfohlen, renommierte Pack-Programme, Bibliotheken oder Methoden zu verwenden und diese auf dem aktuellen Stand zu halten, da man sich gegen Zero-Day-Exploits sonst leider nicht schützen kann.

Python: zipfile

PHP: ziparchive

Java: zip

Schwachstelle: Local File Inclusion (LFI)

Eine Local File Inclusion (LFI)-Schwachstelle entsteht, wenn es einem Benutzer möglich ist, beliebige Dateien des Applikationsservers zu lesen. In Bezug auf Dateiarchive kann diese Schwachstelle auftreten, wenn die Applikation gepackte Dateien entgegennimmt und die Inhalte davon dem Benutzer wieder anbietet.

Entpackt die Applikation die Archive des Benutzers und stellt diese später wieder zur Verfügung, können symbolische Verknüpfungen zu einem Problem führen.

Eine symbolische Verknüpfung, vergleichbar mit einer Verknüpfung unter Windows, ist eine Referenz auf eine Datei.

Wie diese Schwachstelle ausgenutzt werden kann, soll anhand des folgenden Beispiels demonstriert werden. Für die Demonstration wurde ein Ordner „Dokumente“ im Hauptverzeichnis des Benutzers „securai“ angelegt. Dieser enthält einen Unterordner „Dokumente“, der die Datei „datei.txt“ mit dem Inhalt „text“ enthält.

$ pwd
/home/securai

$ ls -R
.:
Dokumente

./ Dokumente:
datei.txt

$ cat Dokumente/datei.txt
text

Wenn eine symbolische Verknüpfung zu „datei.txt“ erstellt wird, kann diese Verknüpfung genauso wie die referenzierte Datei verwendet werden.

$ ln -s /home/securai/Dokumente/datei.txt sym_link.ln

$ cat sym_link.ln
text

$ ls -lah
[…]
lrwxrwxrwx  1 securai securai 21 Sep 29 12:00 sym_link.ln -> /home/securai/Dokumente/datei.txt

Bestimmte Archivtypen, wie z.B. ZIP, erlauben das Speichern dieser symbolischen Verknüpfungen. Beispielsweise kann die folgende Verknüpfung auf die Datei „/etc/hostname“ erstellt werden:

$ ln -s /etc/hostname sym_link_hostname.ln

$ ls -lah
[…]
lrwxrwxrwx  1 securai securai 21 Sep 29 12:00 sym_link_hostname.ln -> /etc/hostname

$ cat sym_link_hostname.ln
gibson

Eine ZIP-Datei, die einen solchen symbolischen Link archiviert, enthält dadurch den Namen des Links und die Referenz auf die Originaldatei – nicht den Inhalt dieser referenzierten Datei. Das zeigt sich, wenn man eine solche Datei mit einem Hex-Editor betrachtet.

$ zip --symlinks sym_link_hostname.zip sym_link_hostname.ln

$ hexedit sym_link_hostname.zip

Wenn nun eine Applikation ein vom Benutzer erstelltes Archiv entgegennimmt, unkontrolliert entpackt und dem Benutzer wieder anbietet, können beliebige lokale Dateien ausgelesen werden.

Sichere Handhabung

Wie immer sollte das Prinzip der geringsten Rechte gelten. Weiterhin sollten Archive nicht unkontrolliert verarbeitet werden, sondern Pfade beim Packen und Entpacken verifiziert werden.

Wie bei anderen Schwachstellen ist ein sicherer Ansatz, wenn man Dateien nicht einfach extrahiert, sondern direkt aus dem Archiv streamt, überprüft und weiterverarbeitet.

In den generellen Empfehlungen am Ende des Artikels finden Sie konkrete Beispiele für Methoden zum Streamen von Archivinhalten.

Schwachstelle: Directory Traversal

Applikationen, die es einem Benutzer erlauben, Archive hochzuladen und dann für den Benutzer auf dem Server zu extrahieren, können ein Directory Traversal aufweisen. Das kann dazu führen, dass Dateien auf dem Dateisystem des Servers überschrieben werden. Es ist möglich, Dateien in Archiven mit deren Pfad zu speichern, sodass bei der Extrahierung diese Pfade wiederhergestellt werden. Hier können allerdings auch relative Pfade verwendet werden, was wiederum bedeutet, dass bei der Extrahierung in dieses relative Verzeichnis geschrieben werden kann.

Beispielsweise kann eine ZIP-Datei erstellt werden, die auf dem Server eine Datei in einem beliebigen Verzeichnis speichert oder eine vorhandene überschreiben kann. Das soll im Folgenden gezeigt werden. Die Datei wird zur Veranschaulichung von Pfaden in einem Unterverzeichnis „etc“ im Hauptverzeichnis des Benutzers abgelegt.

$ pwd
/home/securai

$ mkdir etc

$ echo "securai" > etc/hostname

$ zip -r hostname.zip hostname

Dieses ZIP-Archiv enthält dann den Dateiinhalt und dessen Dateinamen inklusive Pfad.

Um ein ZIP-Archiv nun so zu präparieren, dass bei der Extrahierung in relatives Verzeichnis geschrieben wird, bietet sich das Python Script evilarc an.

Das Script wird verwendet, um ein Archiv zu erstellen, das die angegebene Datei mit einem relativen Pfad und dem Zielordner „etc“ speichert.

$  python evilarc.py hostname -f evil_hostname.zip -o unix -p etc
Creating evil_hostname.zip containing ../../../../../../../../etc/hostname

In einem Hexadezimal-Editor betrachtet, wird deutlich, dass die Datei mit einem relativen Pfad gespeichert wird. Dieser relative Pfad zeigt auf acht übergeordnete Verzeichnisse (abhängig von den angegebenen Optionen für evilarc) und dann auf das „etc“-Verzeichnis.

Extrahiert eine Anwendung nun dieses Archiv mit ausreichenden Rechten und ohne weitere Prüfungen, kann die Datei in den referenzierten Pfad geschrieben werden bzw. überschreibt dort die angegebene Datei.

In diesem Beispiel würde bei erfolgreicher Ausnutzung der Schwachstelle der Hostname des Servers mit „securai“ überschrieben werden.

Sichere Handhabung

Falls möglich sollten benutzergenerierte Archivdateien nicht extrahiert werden, sondern deren Inhalte direkt gelesen werden. Damit kann diese Schwachstelle verhindert werden. Alternativ müssen Pfade vor der Extrahierung geprüft und eventuell angepasst werden.

Funktionen zum Lesen der Archivinhalte ohne Extrahierung finden Sie in den generellen Empfehlungen am Ende des Blogartikels.

Die Empfehlung für das Prinzip der geringsten Rechte gilt nach wie vor.

Schwachstelle: Umgehung von Dateityp-Limitierung oder Malware-Scans

Archivdateien können auch verwendet werden, um Sicherheitsmaßnahmen einer Applikation zu umgehen. Anwendungen mit Upload-Funktion sollten diese auf bestimmte Dateitypen einschränken und die hochgeladenen Dateien auf Malware überprüfen.

Wenn diese Prüfungen nach der Extrahierung eines hochgeladenen Archivs nicht auch für die enthaltenen Dateien wiederholt werden, können die vorher erwähnten Schutzmaßnahmen einfach umgangen werden.

Beispielsweise erlaubt eine Anwendung nur .doc, .docx, .pdf oder .zip für den Dokumentupload. Die Upload-Funktion prüft korrekt, ob die vom Benutzer gesendeten Dateien den erlaubten Dateitypen entsprechen und scannt diese auf Malware. Für Archivdateien wird diese Funktion jedoch auf die .zip-Datei angewandt und danach extrahiert. Die extrahierten Dateien entsprechen dann möglicherweise nicht den erlaubten Dateitypen oder enthalten sogar Malware.

Sichere Handhabung

In diesem Szenario ist es wichtig, dass die geltenden Sicherheitsmaßnahmen auch für Dateien in Archiven umgesetzt werden.

Generelle Empfehlungen

Das Prinzip der geringsten Rechte ist global einsetzbar und bietet bereits einen gewissen Grundschutz bzw. dämmt eventuelle Schäden ein. Ebenso allgemeingültig ist die Empfehlung, alle Systeme und Softwarekomponenten mit Updates auf dem aktuellen Sicherheitsstand zu halten.

Wenn möglich sollten Applikation die Inhalte von Archivdateien nicht blind extrahieren, sondern aus dem Archiv streamen, die Daten validieren und dann schreiben. Hierfür bieten sich folgende Funktionen an:

Java Klasse: ZipInputStream

PHP Funktionen: zip_

Python Bibliothek: zipfile

Wenn eine direkte Extrahierung von Dateien aus Archiven nötig ist, muss der Prozess limitiert werden, um Ressourcen wie Zeit und Speicherplatz zu schützen. Außerdem darf den Benutzerdaten nicht vertraut werden und jegliche Pfade und Inhalte müssen kontrolliert werden. Schutzmaßnahmen für Dateiuploads müssen auch für extrahierte Archivinhalte geltend gemacht werden.

Sollte für das Extrahieren ein separates Programm gestartet werden, muss im Übrigen sichergestellt werden, dass dieses nicht für eine RCE verwendet werden kann. Dies ist z.B. dann der Fall, wenn beim Aufruf Shell-Befehle eingeschleust werden können.

Vorheriger Beitrag
Binary Patching von .NET für Rich-Client-Penetrationstests
Nächster Beitrag
Agile Penetrationstests – was ist das denn?

Ähnliche Beiträge

Es wurden keine Ergebnisse gefunden, die deinen Suchkriterien entsprechen.