LANGSEC (language-theoretic security): Difference between revisions
(→Weiterführende Literatur: mehr info zu PoC||GTFO) |
|||
(44 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
==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. |
|||
[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 zwei verschiedene Dateitypen hat. 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. |
||
(in Progress) |
|||
===Warum gibt es Polyglots?=== |
===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. |
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 Dateiformat ist PNG. |
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> |
|||
[[File:GIF.png|Der Aufbau einer GIF-Datei|thumb|center|500px]] |
|||
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> |
|||
[[File:ZIP.png|Der Aufbau einer ZIP-Datei|thumb|center|500px]] |
|||
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== |
|||
<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
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>
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.
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).
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.)