LANGSEC (language-theoretic security): Difference between revisions

From
Jump to navigation Jump to search
(→‎Weiterführende Literatur: mehr info zu PoC||GTFO)
 
(30 intermediate revisions by 2 users not shown)
Line 1: Line 1:
==LANGSEC==
(IN PROGRESS)

LANGSEC – language-theoretic security – ist ein relativ neuer Ansatz zur
Betrachtung von Sicherheitsproblemen und ihren Ursachen. Im Kern steht die
Erkenntnis, dass Eingaben (Dateien, Pakete, …) als Code aufgefasst werden
können, der auf den durch das verarbeitende System zur Verfügung gestellten
Berechnungsprimitiven ausgeführt wird.<ref>
Sergey Bratus, Michael E. Locasto, Meredith L. Patterson, Len Sassaman, Anna Shubina.
[http://langsec.org/papers/Bratus.pdf Exploit Programming: From Buffer Overflows to "Weird Machines" and Theory of Computation]
''''';login:''' December 2011, Volume 36, Number 6''
</ref> Die Struktur der Eingabedaten
bestimmt, welche Codepfade des interpretierenden Programms durchlaufen und
welche Aktionen dadurch ausgeführt werden.

Als sehr vereinfachtes Beispiel lässt sich eine PNG-Datei als ein "Programm"
betrachten, welches, "ausgeführt" von einem Bildbetrachter, ein Bild auf den
Bildschirm malt. Enthalten im Bildbetrachter wiederum ist üblicherweise
''libpng'', auf welcher eine PNG-Datei als ein Programm zur Befüllung eines
Speicherbereichs mit einer bestimmten Folge von Bytes verstanden werden kann –
oberflächlich betrachtet relativ langweilig, jedoch hängt die Größe des
Speicherbereichs dabei von Informationen in bestimmten Bereichen der Datei ab
und Teile des Datenstroms sind "Unterprogramme" die von ''libz'' interpretiert
werden.<br/>
Existiert nun z. B. in ''libz'' ein Bug (z. B. ein Heap Buffer Overflow), so
können durch diesen andere Programmzustände und -pfade erreicht werden.
Verwendet der Bildbetrachter die GPU (z. B. ein Browser), so kann es u. U.
dazu kommen, dass diese aus einem seltsamen Programmzustand heraus mit
invaliden Daten beschickt und dadurch ebenfalls in einen seltsamen Zustand
versetzt wird, was dann z. B. dazu führen könnte, dass der X-Server stirbt.
Bei "richtiger" Konfiguration der Umgebung (passender Daten- und
Kontrollfluss, nützliche Bugs, …) ist es also möglich, ein PNG-"Programm" zu
konstruieren, welches beim "Ausführen" den X-Server beendet.

Auch wenn dies nur ein hypothetisches Beispiel ist, existieren ähnliche reale
Beispiele. Eines davon ist der "Ping of Death", ein überlanger ICMP ECHO
Request, der per Pufferüberlauf viele verschiedene Systeme zum Absturz
bringen konnte. Neben Pufferüberläufen existieren aber noch viele andere
Wege, ein System negativ zu beeinflussen. Diese werden üblicherweise
auf Basis des verwendeten Mechanismus kategorisiert
(Stack-/Heap-Pufferüberlauf, SQL/…-Injection, Cross-Site-Scripting,
Return-Oriented Programming, …). Während z. B. SQL-Injection und
Cross-Site-Scripting als verwandte Mechanismen erkennbar sind, fällt es
schwer, einen Zusammenhang zwischen SQL-Injection und Return-Oriented
Programming oder auch einem Heap-Pufferüberlauf zu finden. Auch wenn diese
Auflistung gut genug für die Beschreibung von beobachteten Problemen und Bugs
funktioniert, kann sie deshalb nicht helfen, ein System robuster gegen neue
(noch unbekannte) Angriffswege zu machen.

Die zweite simple Erkenntnis, die den Kern der LANGSEC-Perspektive prägt,
ist, dass Eingaben in ein System bzw. Einflussnahme auf die Kommunikation
zwischen seinen Komponenten (also die Eingaben seiner Subsysteme) notwendiger
Bestandteil eines Angriffs sind. Kombiniert man diese und die andere
Kernerkenntnis ("Daten sind Code"), ergibt sich eine Sichtweise, die sowohl
zur systematischen Absicherung eines Systems als auch zur Suche nach
Schwachstellen und neuen Angriffswegen geeignet ist.

Zuallererst ist hiernach klar, dass der kritische Bereich eines Programms die
Verarbeitung von Eingaben ist. Damit ein Fehler in einem beliebigen Teil des
Programms tatsächlich eine ausnutzbare Schwachstelle darstellt, muss ein Pfad
(durch Daten oder Kontrollfluss) von Eingaben ausgehend zu diesem Punkt
existieren. Hieraus folgt, dass Eingaben so früh wie möglich so vollständig
wie möglich überprüft werden sollten und insbesondere auch ''alle'' möglichen
Eingaben behandelt werden sollten, um so die durch invalide Eingaben
erreichbaren Pfade zu beschränken.

Zur Suche von Schwachstellen ist die von der Eingabe ausgehend erreichbare
Funktionalität interessant. Ziel ist es, ein "Programm" zu schreiben,
welches mit der zur Verfügung gestellten Berechnungskapazität eine
unerwartete (die erwarteten oder zumindest erhofften Grenzen überschreitende)
Berechnung ausführt. Interessant hierfür sind z. B. Programmstellen, an denen
die Eingaben verzögert oder gar nicht geprüft werden und so interessante
Funktionalität erreichbar ist. Aber auch Mechanismen, die die Programmierung
vereinfachen, sind wertvolle Werkzeuge. (Erwähnt seien hier die Funde, dass
ELF-Metadaten<ref>
Rebecca Shapiro, Sergey Bratus, Sean W. Smith.
[https://www.usenix.org/system/files/conference/woot13/woot13-shapiro.pdf "Weird Machines" in ELF: A Spotlight on the Underappreciated Metadata]
''USENIX '''WOOT''' (Workshop on Offensive Technologies) '13''
</ref>, DWARF-Debug-Informationen<ref>
James Oakley, Sergey Bratus.
[https://www.usenix.org/legacy/event/woot11/tech/final_files/Oakley.pdf Exploiting the hard-working DWARF: Trojan and Exploit Techniques With No Native Executable Code]
''USENIX '''WOOT''' (Workshop on Offensive Technologies) '11''
</ref> und sogar die X86-MMU<ref>
Julian Bangert, Sergey Bratus, Rebecca Shapiro, Sean W. Smith.
[https://www.usenix.org/system/files/conference/woot13/woot13-bangert.pdf The Page-Fault Weird Machine: Lessons in Instruction-less Computation]
''USENIX '''WOOT''' (Workshop on Offensive Technologies) '13''
</ref> beliebige
Berechnungen ausführen können.)

Die logische Folge zur Defensive ist, dass sämtliche potentiell
unvertrauenswürdigen Eingaben zur Verfügung gestellte Berechnungskapazität
minimiert werden sollte. Empfehlenswert ist die Beschränkung auf reguläre
oder deterministisch kontextfreie Eingabeformate, da sich diese mit der
Berechnungskapazität eines endlichen- oder Kellerautomaten parsen und
validieren lassen. Für Sprachen höherer Komplexität ist die Frage, ob zwei
Grammatiken die selbe Sprache beschreiben, unentscheidbar. Das heißt, dass
nicht oder nur mit viel Aufwand für einen konkreten Fall sichergestellt werden
kann, dass zwei Implementierungen die selbe Eingabe gleich interpretieren.

Dies ist eine weitere häufige Ursache von sicherheitsrelevanten Fehlern. Als
vielseitiges Beispiel seien hier SSL-Zertifikate erwähnt. Im Zertifikat
bezeichnet auf ASN.1-Ebene die OID 2.5.4.3 den "common name", den Hostnamen
für den das Zertifikat ausgestellt wurde. Einige Programme interpretieren
aber z. B. 2.5.4.18446744073709551619 (also 2.5.4.(2^64+3)) ebenfalls als
diese OID (durch Verwendung von 64-bit Integern anstelle von Bignums). Auch
ist es möglich, als common name Zeichenketten wie <code>"bank.com\0.evil.com"</code> oder
mehrere common names zu verwenden. Certificate Authorities (CAs), Browser,
… verwenden unterschiedliche Parser und interpretieren das selbe Zertifikat
unterschiedlich. So kann also ein vom Besitzer von evil.com erzeugtes
Zertifikat von einer CA geprüft, von dieser als valide eingestuft und signiert
werden, dann aber von Browsern anders interpretiert und auch oder sogar nur
für bank.com akzeptiert werden.<ref>
Dan Kaminsky, Meredith L. Patterson, Len Sassaman.
[https://securewww.esat.kuleuven.be/cosic/publications/article-1432.pdf PKI Layer Cake: New Collision Attacks Against the Global X.509 Infrastructure]
''Financial Cryptography and Data Security '10''
</ref><ref>
Len Sassaman, Meredith L. Patterson, Sergey Bratus, Anna Shubina.
[http://langsec.org/papers/Sassaman.pdf The Halting Problems of Network Stack Insecurity]
''''';login:''' December 2011, Volume 36, Number 6''
</ref> (Hierbei sei angemerkt, dass die gleiche
Interpretation durch unterschiedliche Systeme wichtiger ist als die korrekte
Interpretation. Wenn z. B. alle Systeme Strings am ersten Null-Byte
abschneiden oder nur 64-bit-Zahlen verwenden, ist die tatsächlich
implementierte Sprache zwar eine andere als die im Standard beschriebene, es
ist aber genau eine Sprache und nicht eine Vielzahl verschiedener
semi-kompatibler Dialekte.)


==Polyglots==
==Polyglots==
[[File:Illusion.png|Kippbild "My wife and my mother in law"|thumb]]
Ein Polyglot ist eine Datei, die verschiedene Dateitypen hat. <ref name="Polyglots">http://openwall.info/wiki/_media/people/solar/pocorgtfo07.pdf</ref> Das heißt, ein Polyglot wird von zwei verschiedenen Interpretern
Ein Polyglot ist eine Datei, die verschiedene Dateitypen hat. <ref name="Polyglots">
Ange Albertini. [http://openwall.info/wiki/_media/people/solar/pocorgtfo07.pdf Funky Files, the Novella!] in: 7. Ausgabe des ''International Journal of '''PoC||GTFO''''', März 2015</ref> Das heißt, ein Polyglot wird von zwei verschiedenen Interpretern
akzeptiert und die Ausgabe ist u.U. unterschiedlich.
akzeptiert und die Ausgabe ist u.U. unterschiedlich.
Durch die Erzeugung von Polyglots lässt sich zeigen, dass eine Datei keinen eindeutigen Dateityp hat. Die Existenz einer solchen Datei genügt als Beweis. Dadurch lässt sich schließen, dass in diesem Bereich in der Praxis ein Kompromiss gemacht wird. Die potentielle Mehrdeutigkeit von Dateien wird in Kauf genommen, da Abwärtskompatibilität erwünscht ist.
Durch die Erzeugung von Polyglots lässt sich zeigen, dass eine Datei keinen eindeutigen Dateityp hat. Die Existenz einer solchen Datei genügt als Beweis. Dadurch lässt sich schließen, dass in diesem Bereich in der Praxis ein Kompromiss gemacht wird. Die potentielle Mehrdeutigkeit von Dateien wird in Kauf genommen, da Abwärtskompatibilität erwünscht ist.
Line 8: Line 136:
Ein Beispiel für ein striktes (Bild-)Dateiformat ist PNG.<ref name= "PNG"> https://www.w3.org/TR/PNG/ </ref>
Ein Beispiel für ein striktes (Bild-)Dateiformat ist PNG.<ref name= "PNG"> https://www.w3.org/TR/PNG/ </ref>
===Minimalbeispiel eines Polyglots===
===Minimalbeispiel eines Polyglots===
Eine einfache Möglichkeit ein Polyglot zu erstellen wird im Folgenden erläutert. Eine GIF-Datei benötigt, um als solche erkannt zu werden, am Anfang der Datei die Signatur "GIF". Das Ende der GIF-Datei wird mit "3B" markiert. Alle weiteren Bytes werden einfach ignoriert. <ref name= "corkami gif" https://github.com/corkami/pics/blob/master/GIF.png </ref> Dies ermöglicht das Anhängen einer weiteren Datei, zum Beispiel eine ZIP-Datei. Eine ZIP-Datei benötigt lediglich an einer Stelle in der Nähe vom Dateiende den Marker "PK56", der Hinweis darauf, dass sie eine Datei diesen Typs ist. Nach diesem Marker gibt es einen Verweis auf eine Central Directory, in dem alle Verweise auf Datenblöcke der Datei gelistet sind. Es muss allerdings nicht jedes Byte der Datei gelesen werden. <ref name= "corkami zip" https://github.com/corkami/pics/blob/master/ZIP.png </ref> Die Eigenschaften der GIF- und ZIP-Dateien ermöglichen das Konkatenieren zweier solcher Dateien miteinander, ohne dass die Funktionalität der ursprünglichen Dateien beeinträchtigt wird.
Eine einfache Möglichkeit ein Polyglot zu erstellen wird im Folgenden erläutert. Eine GIF-Datei benötigt, um als solche erkannt zu werden, am Anfang der Datei die Signatur "GIF". Das Ende der GIF-Datei wird mit "3B" markiert. Alle weiteren Bytes werden einfach ignoriert. <ref name= "corkami gif"> https://github.com/corkami/pics/blob/master/GIF.png</ref>


[[File:GIF.png|Der Aufbau einer GIF-Datei|thumb|center|500px]]
Sind also x.gif und y.zip eine GIF- bzw. eine ZIP-Datei, so lassen sich diese in der Linux-Kommandozeil mittels <code> cat x.gif y.zip > merge.new</code> zu einer neuen Datei merge.new konkatenieren. Diesen neue Datei kann mit "eog merge.new" als GIF-Datei ausgeführt und mit "unzip merge.new" wie eine ZIP-Datei entpackt werden.


Dies ermöglicht das Anhängen einer weiteren Datei, zum Beispiel eine ZIP-Datei. Eine ZIP-Datei benötigt lediglich an einer Stelle in der Nähe vom Dateiende den Marker "PK56", der Hinweis darauf, dass sie eine Datei diesen Typs ist. Nach diesem Marker gibt es einen Verweis auf eine Central Directory, in dem alle Verweise auf Datenblöcke der Datei gelistet sind. Es muss allerdings nicht jedes Byte der Datei gelesen werden. <ref name= "corkami zip">
Dasselbe Prinzip funktioniert auch mit einer JAR-Datei. Eine JAR-Datei ähnelt im Aufbau einer ZIP-Datei. Der Kernunterschied ist die Datei META-INF/MANIFEST.MF, die Informationen für die JAR-Datei enthält. Sie lässt sich jedoch einfach erstellen. Ist eine JAR-Datei und die zugehörige META-INF/MANIFEST.MF gegeben, so lässt sich analog wie im letzten Abschnitt ein Polyglot erstellen mit y.jar statt y.zip. Bei der Ausführung der JAR-Datei mit "java -jar merge.new" muss lediglich darauf geachtet werden, dass sich die Datei MÈTA-INF/MANIFEST.MF im selben Ordner befindet.
https://github.com/corkami/pics/blob/master/ZIP.png </ref>


[[File:ZIP.png|Der Aufbau einer ZIP-Datei|thumb|center|500px]]
==Fazit und Ausblick==

Die Eigenschaften der GIF- und ZIP-Dateien ermöglichen das Konkatenieren zweier solcher Dateien miteinander, ohne dass die Funktionalität der ursprünglichen Dateien beeinträchtigt wird.

Sind also x.gif und y.zip eine GIF- bzw. eine ZIP-Datei, so lassen sich diese in der Linux-Kommandozeil mittels <code> cat x.gif y.zip > merge.new</code> zu einer neuen Datei merge.new konkatenieren. Diesen neue Datei kann mit <code> eog merge.new </code> als GIF-Datei ausgeführt und mit <code> unzip merge.new </code> wie eine ZIP-Datei entpackt werden.

Dasselbe Prinzip funktioniert auch mit einer JAR-Datei. Eine JAR-Datei ähnelt im Aufbau einer ZIP-Datei. Der Kernunterschied ist die Datei META-INF/MANIFEST.MF, die Informationen für die JAR-Datei enthält. Sie lässt sich jedoch einfach erstellen. Ist eine JAR-Datei und die zugehörige META-INF/MANIFEST.MF gegeben, so lässt sich analog wie im letzten Abschnitt ein Polyglot erstellen mit y.jar statt y.zip. Bei der Ausführung der JAR-Datei mit <code> java -jar merge.new </code> muss lediglich darauf geachtet werden, dass sich die Datei MÈTA-INF/MANIFEST.MF im selben Ordner befindet.

===resultierende Probleme===
Wie gesehen können Dateien teilweise Interpretation unter mehr als einem existenten Dateiformat zulassen. So könnten potentiell gefährliche Daten durch ein System durchgeleitet werden, ohne dass dieses der Vorgang sicher verhindern oder auch nur bemerken kann. Es ist unmöglich, die Eindeutigkeit der Interpretation am Zielsystem zu garantieren. (Zum einen gibt es zu viele Programme und mögliche Dateiformate, zum anderen führen Bugs in der Eingabeverarbeitung dieser Programme oft dazu, dass auch invalide Daten akzeptiert oder valide Daten anders interpretiert werden.) Trotzdem versuchen viele Programme dies zu erreichen, oft durch Suche nach magic numbers von Dateiformaten. Da in hinreichend großen Datenmengen rein zufällig verschiedene Bytefolgen vorkommen werden, werden gelegentlich auch valide Daten abgelehnt.

Wir haben nun eine große Sammlung von validen PNGs nach magic numbers verschiedener Dateiformate durchsucht und viele Kollisionen bemerkt. Das unten zu betrachtene Bild einer Approximation der Mathematikerin Grete Hermann mit ~100 Dreiecken ist eines von etwa 10000 im Verlauf der Approximation entstandenen. Ungefähr ein Dutzend von diesen enthält im Bytestream zufällig die magic number von ZIP (<code>PK\05\06</code>) und kann dadurch in einem Mediawiki nicht hochgeladen werden. (Deswegen ist hier ein Screenshot zu sehen). Mediawiki glaubt, dass die Datei ein ZIP-Archiv sein ''könnte'', kann aber die (nicht vorhandenen) Daten nicht lesen, und verbietet deshalb "sicherheitshalber" den Upload. Demgegenüber gestellt kann das Vortrags-PDF, welches gleichzeitig eine tatsächliche ZIP-Datei ist, welche neben JARs und anderen Dateien ebenjenes Bild enthält, ohne Probleme hochgeladen werden (sofern nicht PDF-Upload generell verboten wurde).
[[File:grete.png|Hundertste Dreiecksiteration der Mathematikerin Grete Hermann|thumb|center|500px]]
[[File:Grete_Hermann_dump.png|Im Byte-Dump der Datei ist die ZIP-Signatur|thumb|center|500px]]

==Vortragsfolien==
Die Vortragsfolien können mit einem PDF-Viewer betrachtet und ebenso mit unzip entpackt werden.
[https://www.mathematik.hu-berlin.de/~bartelar/ Link zum Vortrag]


==Literatur- und Quellenverzeichnis==
==Literatur- und Quellenverzeichnis==
<references/>
<references/>

==Weiterführende Literatur==

* Halvar Flake. [https://drive.google.com/open?id=0B5hBKwgSgYFad1YybERxTmpURms Understanding the fundamentals of attacks: What is happening when someone writes an exploit?] (Slides, November 2016) - Eine detaillierte Einführung am Beispiel eines kleinen key-value-Stores, mit Fokus auf die Definition von Exploitbarkeit, über die ursprünglichen Ideen von LANGSEC hinausgehend.
* [http://langsec.org/ langsec.org] - Sammlung von Essays, Papers und Talks
* [https://www.alchemistowl.org/pocorgtfo/ alchemistowl.org/pocorgtfo/] - Alle Ausgaben von PoC||GTFO - Fast alle sind Polyglots, zusätzliche Informationen sind als ZIP-Archiv eingebettet. (Oft haben die PDFs aber noch mehr Interpretationen, sind z. B. bootbar, ein Dateisystem, als Android-Paket installierbar, oder sogar gleichzeitig PDF, ZIP, Audio, und Bild.)

Latest revision as of 02:22, 14 November 2016

LANGSEC

LANGSEC – language-theoretic security – ist ein relativ neuer Ansatz zur Betrachtung von Sicherheitsproblemen und ihren Ursachen. Im Kern steht die Erkenntnis, dass Eingaben (Dateien, Pakete, …) als Code aufgefasst werden können, der auf den durch das verarbeitende System zur Verfügung gestellten Berechnungsprimitiven ausgeführt wird.<ref> Sergey Bratus, Michael E. Locasto, Meredith L. Patterson, Len Sassaman, Anna Shubina. Exploit Programming: From Buffer Overflows to "Weird Machines" and Theory of Computation ;login: December 2011, Volume 36, Number 6 </ref> Die Struktur der Eingabedaten bestimmt, welche Codepfade des interpretierenden Programms durchlaufen und welche Aktionen dadurch ausgeführt werden.

Als sehr vereinfachtes Beispiel lässt sich eine PNG-Datei als ein "Programm" betrachten, welches, "ausgeführt" von einem Bildbetrachter, ein Bild auf den Bildschirm malt. Enthalten im Bildbetrachter wiederum ist üblicherweise libpng, auf welcher eine PNG-Datei als ein Programm zur Befüllung eines Speicherbereichs mit einer bestimmten Folge von Bytes verstanden werden kann – oberflächlich betrachtet relativ langweilig, jedoch hängt die Größe des Speicherbereichs dabei von Informationen in bestimmten Bereichen der Datei ab und Teile des Datenstroms sind "Unterprogramme" die von libz interpretiert werden.
Existiert nun z. B. in libz ein Bug (z. B. ein Heap Buffer Overflow), so können durch diesen andere Programmzustände und -pfade erreicht werden. Verwendet der Bildbetrachter die GPU (z. B. ein Browser), so kann es u. U. dazu kommen, dass diese aus einem seltsamen Programmzustand heraus mit invaliden Daten beschickt und dadurch ebenfalls in einen seltsamen Zustand versetzt wird, was dann z. B. dazu führen könnte, dass der X-Server stirbt. Bei "richtiger" Konfiguration der Umgebung (passender Daten- und Kontrollfluss, nützliche Bugs, …) ist es also möglich, ein PNG-"Programm" zu konstruieren, welches beim "Ausführen" den X-Server beendet.

Auch wenn dies nur ein hypothetisches Beispiel ist, existieren ähnliche reale Beispiele. Eines davon ist der "Ping of Death", ein überlanger ICMP ECHO Request, der per Pufferüberlauf viele verschiedene Systeme zum Absturz bringen konnte. Neben Pufferüberläufen existieren aber noch viele andere Wege, ein System negativ zu beeinflussen. Diese werden üblicherweise auf Basis des verwendeten Mechanismus kategorisiert (Stack-/Heap-Pufferüberlauf, SQL/…-Injection, Cross-Site-Scripting, Return-Oriented Programming, …). Während z. B. SQL-Injection und Cross-Site-Scripting als verwandte Mechanismen erkennbar sind, fällt es schwer, einen Zusammenhang zwischen SQL-Injection und Return-Oriented Programming oder auch einem Heap-Pufferüberlauf zu finden. Auch wenn diese Auflistung gut genug für die Beschreibung von beobachteten Problemen und Bugs funktioniert, kann sie deshalb nicht helfen, ein System robuster gegen neue (noch unbekannte) Angriffswege zu machen.

Die zweite simple Erkenntnis, die den Kern der LANGSEC-Perspektive prägt, ist, dass Eingaben in ein System bzw. Einflussnahme auf die Kommunikation zwischen seinen Komponenten (also die Eingaben seiner Subsysteme) notwendiger Bestandteil eines Angriffs sind. Kombiniert man diese und die andere Kernerkenntnis ("Daten sind Code"), ergibt sich eine Sichtweise, die sowohl zur systematischen Absicherung eines Systems als auch zur Suche nach Schwachstellen und neuen Angriffswegen geeignet ist.

Zuallererst ist hiernach klar, dass der kritische Bereich eines Programms die Verarbeitung von Eingaben ist. Damit ein Fehler in einem beliebigen Teil des Programms tatsächlich eine ausnutzbare Schwachstelle darstellt, muss ein Pfad (durch Daten oder Kontrollfluss) von Eingaben ausgehend zu diesem Punkt existieren. Hieraus folgt, dass Eingaben so früh wie möglich so vollständig wie möglich überprüft werden sollten und insbesondere auch alle möglichen Eingaben behandelt werden sollten, um so die durch invalide Eingaben erreichbaren Pfade zu beschränken.

Zur Suche von Schwachstellen ist die von der Eingabe ausgehend erreichbare Funktionalität interessant. Ziel ist es, ein "Programm" zu schreiben, welches mit der zur Verfügung gestellten Berechnungskapazität eine unerwartete (die erwarteten oder zumindest erhofften Grenzen überschreitende) Berechnung ausführt. Interessant hierfür sind z. B. Programmstellen, an denen die Eingaben verzögert oder gar nicht geprüft werden und so interessante Funktionalität erreichbar ist. Aber auch Mechanismen, die die Programmierung vereinfachen, sind wertvolle Werkzeuge. (Erwähnt seien hier die Funde, dass ELF-Metadaten<ref> Rebecca Shapiro, Sergey Bratus, Sean W. Smith. "Weird Machines" in ELF: A Spotlight on the Underappreciated Metadata USENIX WOOT (Workshop on Offensive Technologies) '13 </ref>, DWARF-Debug-Informationen<ref> James Oakley, Sergey Bratus. Exploiting the hard-working DWARF: Trojan and Exploit Techniques With No Native Executable Code USENIX WOOT (Workshop on Offensive Technologies) '11 </ref> und sogar die X86-MMU<ref> Julian Bangert, Sergey Bratus, Rebecca Shapiro, Sean W. Smith. The Page-Fault Weird Machine: Lessons in Instruction-less Computation USENIX WOOT (Workshop on Offensive Technologies) '13 </ref> beliebige Berechnungen ausführen können.)

Die logische Folge zur Defensive ist, dass sämtliche potentiell unvertrauenswürdigen Eingaben zur Verfügung gestellte Berechnungskapazität minimiert werden sollte. Empfehlenswert ist die Beschränkung auf reguläre oder deterministisch kontextfreie Eingabeformate, da sich diese mit der Berechnungskapazität eines endlichen- oder Kellerautomaten parsen und validieren lassen. Für Sprachen höherer Komplexität ist die Frage, ob zwei Grammatiken die selbe Sprache beschreiben, unentscheidbar. Das heißt, dass nicht oder nur mit viel Aufwand für einen konkreten Fall sichergestellt werden kann, dass zwei Implementierungen die selbe Eingabe gleich interpretieren.

Dies ist eine weitere häufige Ursache von sicherheitsrelevanten Fehlern. Als vielseitiges Beispiel seien hier SSL-Zertifikate erwähnt. Im Zertifikat bezeichnet auf ASN.1-Ebene die OID 2.5.4.3 den "common name", den Hostnamen für den das Zertifikat ausgestellt wurde. Einige Programme interpretieren aber z. B. 2.5.4.18446744073709551619 (also 2.5.4.(2^64+3)) ebenfalls als diese OID (durch Verwendung von 64-bit Integern anstelle von Bignums). Auch ist es möglich, als common name Zeichenketten wie "bank.com\0.evil.com" oder mehrere common names zu verwenden. Certificate Authorities (CAs), Browser, … verwenden unterschiedliche Parser und interpretieren das selbe Zertifikat unterschiedlich. So kann also ein vom Besitzer von evil.com erzeugtes Zertifikat von einer CA geprüft, von dieser als valide eingestuft und signiert werden, dann aber von Browsern anders interpretiert und auch oder sogar nur für bank.com akzeptiert werden.<ref> Dan Kaminsky, Meredith L. Patterson, Len Sassaman. PKI Layer Cake: New Collision Attacks Against the Global X.509 Infrastructure Financial Cryptography and Data Security '10 </ref><ref> Len Sassaman, Meredith L. Patterson, Sergey Bratus, Anna Shubina. The Halting Problems of Network Stack Insecurity ;login: December 2011, Volume 36, Number 6 </ref> (Hierbei sei angemerkt, dass die gleiche Interpretation durch unterschiedliche Systeme wichtiger ist als die korrekte Interpretation. Wenn z. B. alle Systeme Strings am ersten Null-Byte abschneiden oder nur 64-bit-Zahlen verwenden, ist die tatsächlich implementierte Sprache zwar eine andere als die im Standard beschriebene, es ist aber genau eine Sprache und nicht eine Vielzahl verschiedener semi-kompatibler Dialekte.)


Polyglots

Kippbild "My wife and my mother in law"

Ein Polyglot ist eine Datei, die verschiedene Dateitypen hat. <ref name="Polyglots"> Ange Albertini. Funky Files, the Novella! in: 7. Ausgabe des International Journal of PoC||GTFO, März 2015</ref> Das heißt, ein Polyglot wird von zwei verschiedenen Interpretern akzeptiert und die Ausgabe ist u.U. unterschiedlich. Durch die Erzeugung von Polyglots lässt sich zeigen, dass eine Datei keinen eindeutigen Dateityp hat. Die Existenz einer solchen Datei genügt als Beweis. Dadurch lässt sich schließen, dass in diesem Bereich in der Praxis ein Kompromiss gemacht wird. Die potentielle Mehrdeutigkeit von Dateien wird in Kauf genommen, da Abwärtskompatibilität erwünscht ist.

Warum gibt es Polyglots?

Polyglots sind aus der Informatik nicht wegzudenken. Die "historischen Fehler", die beim Design von Dateitypen gemacht wurden, machen das Verhindern von polyglotten Effekten de-facto unmöglich. Theoretisch kann ein Interpreter so realisiert werden, dass dieser nur strikte Dateiformate annimmt. Ein Dateiformat ist strikt, wenn es am offset zero (Dateianfang) eine eindeutige magic number hat. Dieser strikte Interpreter dürfte dann allerdings keine Formate wie z.B. PDF oder ZIP akzeptieren und wäre somit in seinem Nutzen stark eingeschränkt. Ein Beispiel für ein striktes (Bild-)Dateiformat ist PNG.<ref name= "PNG"> https://www.w3.org/TR/PNG/ </ref>

Minimalbeispiel eines Polyglots

Eine einfache Möglichkeit ein Polyglot zu erstellen wird im Folgenden erläutert. Eine GIF-Datei benötigt, um als solche erkannt zu werden, am Anfang der Datei die Signatur "GIF". Das Ende der GIF-Datei wird mit "3B" markiert. Alle weiteren Bytes werden einfach ignoriert. <ref name= "corkami gif"> https://github.com/corkami/pics/blob/master/GIF.png</ref>

Der Aufbau einer GIF-Datei

Dies ermöglicht das Anhängen einer weiteren Datei, zum Beispiel eine ZIP-Datei. Eine ZIP-Datei benötigt lediglich an einer Stelle in der Nähe vom Dateiende den Marker "PK56", der Hinweis darauf, dass sie eine Datei diesen Typs ist. Nach diesem Marker gibt es einen Verweis auf eine Central Directory, in dem alle Verweise auf Datenblöcke der Datei gelistet sind. Es muss allerdings nicht jedes Byte der Datei gelesen werden. <ref name= "corkami zip"> https://github.com/corkami/pics/blob/master/ZIP.png </ref>

Der Aufbau einer ZIP-Datei

Die Eigenschaften der GIF- und ZIP-Dateien ermöglichen das Konkatenieren zweier solcher Dateien miteinander, ohne dass die Funktionalität der ursprünglichen Dateien beeinträchtigt wird.

Sind also x.gif und y.zip eine GIF- bzw. eine ZIP-Datei, so lassen sich diese in der Linux-Kommandozeil mittels cat x.gif y.zip > merge.new zu einer neuen Datei merge.new konkatenieren. Diesen neue Datei kann mit eog merge.new als GIF-Datei ausgeführt und mit unzip merge.new wie eine ZIP-Datei entpackt werden.

Dasselbe Prinzip funktioniert auch mit einer JAR-Datei. Eine JAR-Datei ähnelt im Aufbau einer ZIP-Datei. Der Kernunterschied ist die Datei META-INF/MANIFEST.MF, die Informationen für die JAR-Datei enthält. Sie lässt sich jedoch einfach erstellen. Ist eine JAR-Datei und die zugehörige META-INF/MANIFEST.MF gegeben, so lässt sich analog wie im letzten Abschnitt ein Polyglot erstellen mit y.jar statt y.zip. Bei der Ausführung der JAR-Datei mit java -jar merge.new muss lediglich darauf geachtet werden, dass sich die Datei MÈTA-INF/MANIFEST.MF im selben Ordner befindet.

resultierende Probleme

Wie gesehen können Dateien teilweise Interpretation unter mehr als einem existenten Dateiformat zulassen. So könnten potentiell gefährliche Daten durch ein System durchgeleitet werden, ohne dass dieses der Vorgang sicher verhindern oder auch nur bemerken kann. Es ist unmöglich, die Eindeutigkeit der Interpretation am Zielsystem zu garantieren. (Zum einen gibt es zu viele Programme und mögliche Dateiformate, zum anderen führen Bugs in der Eingabeverarbeitung dieser Programme oft dazu, dass auch invalide Daten akzeptiert oder valide Daten anders interpretiert werden.) Trotzdem versuchen viele Programme dies zu erreichen, oft durch Suche nach magic numbers von Dateiformaten. Da in hinreichend großen Datenmengen rein zufällig verschiedene Bytefolgen vorkommen werden, werden gelegentlich auch valide Daten abgelehnt.

Wir haben nun eine große Sammlung von validen PNGs nach magic numbers verschiedener Dateiformate durchsucht und viele Kollisionen bemerkt. Das unten zu betrachtene Bild einer Approximation der Mathematikerin Grete Hermann mit ~100 Dreiecken ist eines von etwa 10000 im Verlauf der Approximation entstandenen. Ungefähr ein Dutzend von diesen enthält im Bytestream zufällig die magic number von ZIP (PK\05\06) und kann dadurch in einem Mediawiki nicht hochgeladen werden. (Deswegen ist hier ein Screenshot zu sehen). Mediawiki glaubt, dass die Datei ein ZIP-Archiv sein könnte, kann aber die (nicht vorhandenen) Daten nicht lesen, und verbietet deshalb "sicherheitshalber" den Upload. Demgegenüber gestellt kann das Vortrags-PDF, welches gleichzeitig eine tatsächliche ZIP-Datei ist, welche neben JARs und anderen Dateien ebenjenes Bild enthält, ohne Probleme hochgeladen werden (sofern nicht PDF-Upload generell verboten wurde).

Hundertste Dreiecksiteration der Mathematikerin Grete Hermann
Im Byte-Dump der Datei ist die ZIP-Signatur

Vortragsfolien

Die Vortragsfolien können mit einem PDF-Viewer betrachtet und ebenso mit unzip entpackt werden. Link zum Vortrag

Literatur- und Quellenverzeichnis

<references/>

Weiterführende Literatur

  • Halvar Flake. Understanding the fundamentals of attacks: What is happening when someone writes an exploit? (Slides, November 2016) - Eine detaillierte Einführung am Beispiel eines kleinen key-value-Stores, mit Fokus auf die Definition von Exploitbarkeit, über die ursprünglichen Ideen von LANGSEC hinausgehend.
  • langsec.org - Sammlung von Essays, Papers und Talks
  • alchemistowl.org/pocorgtfo/ - Alle Ausgaben von PoC||GTFO - Fast alle sind Polyglots, zusätzliche Informationen sind als ZIP-Archiv eingebettet. (Oft haben die PDFs aber noch mehr Interpretationen, sind z. B. bootbar, ein Dateisystem, als Android-Paket installierbar, oder sogar gleichzeitig PDF, ZIP, Audio, und Bild.)