 Hallo und herzlich willkommen beim Talk-Emmet-Schutzschild oder Vorhang. Ich bin René Feinkrober, ich erzähle euch über Exploit-Entwicklung und vor allem, wie man verschiedene Mitigation-Techniken von Emmet umgeht. Lass uns kurz mal anschauen, was wir heute vor uns haben. Zuerst gebe ich euch eine kleine Einführung, meine Person. Dann geht es um die Grundlagen, es gibt Konzepte wie ASLA und DEP. Wir werden auch die Firefox-Verwundbarkeit sprechen, die wir in diesem Talk verwenden werden, um ein Exploit zu machen. Dann kommt das erste Kapitel, das Emmet zu tun hat und sah, wie wir die Emmet DLL im Speicher finden. Wir werden sehen, wie wichtig das ist. Danach etwas Code-Reuse, eine Technik, die nicht nur für Exploit-Entwickler interessant ist, aber wenn man darüber nachdenkt, wie Emmet umgangen werden kann, ist es nützlich, sich damit zu beschäftigen. Dann kommen Beschäftigungen zwischen verschiedenen Techniken, die Emmet benutzt, um Angriff abzuwehren, um Rücksprungerrichtigte Programmierung und Export-Adress-Filterungs-Rechnismen und dann geht es noch an eine kurze Demo und Zeit für ein paar Fragen. Wie gesagt, mein Name ist René Frank-Kuber. Ich arbeite seit zwei Jahren als Security Consultant bei SCC Consult. Ich bin außerdem gerade Student an der Technischen Universität Wien und mache laut meine Bachelor-Teases über Exploits und möchte hier meinem Professor, Dr. Christian, Platz danken, dass er mir die Möglichkeit gegeben hat, über so ein Thema zu schreiben. Ich habe auch noch eine Slide über meine Company, über meine Firma. Der interessante Teil für euch ist, dass wir natürlich gerade Leute suchen, also wenn ihr als Security Consultants arbeiten wollt in Deutschland, schickt mir einfach eine Mail oder geht auf unsere Webseite oder beschrecht mich nach dem Talk an. So, Basics. Exploits waren vor ein paar Jahren noch sehr einfach, fünf Jahren. Wenn man ein Stack-Overflow oder ein Buff-Overflow hätte, musste man einfach nur so lange schlitten bauen, bis man eine Adresse gefunden hat, die wo den Instruction-Pointer lag, seinen Exploit-Hot dahin packen und dann wird alles ausgeführt. Heute ist alles ein bisschen schwieriger. Wir haben nämlich viele, viele verschiedene Schutzmechanismen, die wir umgehen müssen. Auf der linken Seite seht ihr ein Bild von einigen der Namen dieser Schutzvorrichtungen. Das ist nicht vollständig, aber aus Perspektive der technischen Perspektive muss man sowieso alle davon umgehen. Die wichtigen hier sind DEP Date Excusion Prevention, Datenausführungsverhinderung und der SLA-Zufallsgestaltung und Adressraumaufbau, Address, Base Layout oder Analyse. Also, wir gehen da schnell drüber und machen dann weiter. Die Idee von ASL-R ist, dass alles in eine zufällige Adresse im Speicher geladen wird. Also, wenn ich Firefox oder eine andere Anwendung zweimal starte, dann werden alle Code und alle Daten-Sektionen in verschiedenen Adressen eine zufällige Adresse geladen. Und aus dem Perspektive des Angreifers weiß ich also nicht, wo die Daten im Speicher liegen. Date Excusion Protection auf der anderen Seite bedeutet, dass Daten, die im hier und im Stack gespeichert sind, nur lesen und schreibbar sind, aber nicht ausführbar. Das heißt, man kann einfach das Nichtexecutive-Befleck auf diese Speicherseiten setzen und wenn man dann versucht daran etwas ausführen möchte, dann geht es ein Segmentation Fault, weil diese Page nicht als ausführbar markiert ist. Normalerweise kommt man darunter, indem man Return-Oriented-Programming benutzt, also Rücksprung-Oriented-Programmierung. Das heißt, man springt an einen bestehenden Code-Tile im Programm, nutzt also die schon bestehenden Instruktionen und strickt dann an eine andere Stelle und verkettert das so, um neue Logik ins Programm einzubauen. Jetzt seht ihr, warum es schwierig ist, sowohl ASL als auch die EIP zu umgehen, denn mit ASL-A weiß man eben nicht, wo der bestehende Code ist. Also typischerweise müssen wir erst ASL-A umgehen. Ich kann also viele Verwundbarkeiten in eine Information-Disclosure-Verwundbarkeit umwandeln und dann die Basis-Adresse eines Modules benutzen und mit dem Wissen dann eine Rob-Chain starten. Wir sehen später noch, wie das genau aussieht, wenn ich euch die Firefox-Verwundbarkeit zeige. In diesem Fall habe ich Firefox Array Reduce Write, es ist ein bisschen älter als von 2011, weil ich euch dann den Exploit-Code zeigen kann und das Risiko, das irgendjemand es braucht. Der Exploit ist sehr zuverlässig gegen alle möglichen Betriebssysteme von Windows XP bis der 7.8.2038.012. Es umgeht ASL-A und die EIP. Wir machen keinen Heapspraying, weil Heapspraying eine Technik ist, die gegen ASL angewendet werden kann. Die Idee ist einfach, dass man die Daten überall hinschmeibt, wo sie sein könnten und dann können wir jede beliebige Adresse nutzen, weil die Daten überall sind. Das Problem dabei ist, dass der Browser für einige Sekunden einfrieren würde, weil wenn wir das Spraying machen und das heißt, das Opfer könnte bemerken, dass ein Angriff läuft. In diesem Fall, wenn das Opfer meine Webseite besucht, dann bemerkt er nicht, freht nicht ein, der Browser stürzt nicht ab. Es sieht aus wie eine normale Webseite, aber er wird dann halt mein Pailer infiziert. Leider habe ich nicht genug Zeit, um alle Details des Exploits zu besprechen, aber wenn ihr da mehr wissen wollt, schaut euch einfach den Talk Tale of Two Firefox Box von Fierenbar Davis an. Es ist auf YouTube oder schaut einfach in meine Bachelorarbeit, die in zwei bis drei Wochen veröffentlicht wird. Für alle, die nicht wissen, wie die ReduceRide Funktion funktioniert, die kann man benutzen, um eine Callback Funktion auf alle Elemente eines... Ein Moment, bitte. Entschuldigung. Also für jeder, der diese Reduce Funktion nicht kennt, das kann man benutzen, um eine Callback Funktion auf alle Elemente eines Areas anzuwenden. Also sagen wir, die Callback Funktion ist eine Ausdruckfunktion, dann wird also quasi das erste Element ausgedruckt und dann das zweite Element ausgedruckt und so weiter, bis alle Elemente ausgedruckt worden sind. Und die ReduceRide Funktion beginnt einfach auf der rechten Seite, beginnt also beim letzten Element und geht dann bis zum ersten nach vorne. Das bedeutet, dass wir also bei der Indexlänge des Areas minus 1 beginnen. Das heißt, wir können das Längefeld auf einen beliebigen Wert setzen, zum Beispiel auf einen sehr großen Wert, zum Beispiel 10,000. Dann ist das Problem, dass der Index ein vorzeichenbehaftet Wert ist. Das heißt, das kann auch zu einem negativen Wert werden, wenn Länge sehr groß wird. Das heißt, wir können Elemente außerhalb des Areas zugreifen. Und das sehen wir hier auf der nächsten Slide. Also wenn wir jetzt hier auf Index 0 was speichern, dann wird das hier im Speicher landen bei Index 1 hier und so weiter. Und wir sehen, dass dieser Array eben eine Länge von sechs Elementen enthalten kann. Und wenn wir ein Index der kleiner ist als sechs, dann ist es erlaubt. Und es ist auch erlaubt, wenn wir einen Zugreifen, was kleiner ist als das letzte Element. Aber wenn wir außerhalb dieses Areas zugreifen wollen, dann wird der Zugriff abgelehnt. Aber wenn ich einen negativen Index benutzen, dann wird das auch benutzt, weil nur der obere, die obere Grenze geprüft wird. Das heißt, wir können jetzt auf Daten, die vor dem Array im Speicher gespeichert werden zugreifen. Wenn ich einen Array in JavaScript alloziiere, dann erhalte ich so eine Datenstruktur. Ich habe verschiedene Felder, die diesen Array beschreiben. Und wie es schon gesagt wurde, wenn ich es als Index 0 speichere, dann hier Index 1, dann hier und so weiter. Und jeder Eintrag besteht aus acht Bytes. Die ersten vier Bytes werden für die Daten benutzt. Und wenn ich einen Integer Wert speichere, dann wird also der zum Beispiel hier gespeichert. Und die zweiten vier Bytes werden für den Typ benutzt, also ob es ein String ist oder ein Objekt oder eine Ganzzahl. Wer ist ein String, dann würde da nur stehen, das ist ein String. Und die ersten vier Bytes wären ein Pointer auf die String-Datenstruktur. Wir sehen hier auch, dass dieser Array eine feste Größe hat. Also hier kann man zum Beispiel nur zehn Elemente speichern. Und wenn wir einen größeren Array daraus machen, dann würde der also an eine neue Position im Speicher kopiert. Und dann haben wir einen Pointer, der dann auf den tatsächlich benutzten Array speichert. Und wenn der aber kopiert wird, dann wird er zum Beispiel auf diese neuen Ort im Speicher zeigen. Und jetzt kommen wir auf die ersten Angriff. Also ich habe einfach diesen Array umkopiert auf eine andere, auf einen anderen Ort mit einer festen Größe von 512 Einträgen. Und das bedeutet, ich habe jetzt volle Kontrolle über den Speicherbereich unmittelbar vor dem neuen Array. Und ich benutze jetzt also quasi dieses übergroße Längenfeld, was minus 1 bedeutet. Und das bedeutet, ich kann mit dem Speicher arbeiten, der unter meiner Kontrolle ist. Und die Daten in dem Fall werden hier einfach auf diesen Hexwert gesetzt mit ff005. Und 05 bedeutet, das ist ein String. Das heißt, der erste Word hier wird interpretiert als Zeiger auf einem String. Und den lasse ich dann hier vorne auf dieses Feld zeigen. Und da werden dann Attribute definiert wie die Länge oder die Adresse von dem String. Und damit bekomme ich dann ein String-Pointer und davon kann ich einfach lesen. Also hier sehen wir die Implementierung des Codes in JavaScript. Hier sehen Sie das Längenfeld, was quasi gesetzt wird. Und dann wird die ReduceRide-Funktion aufgerufen mit der League-Funktion als Callback-Funktion. Und das aktuelle Element, was als Argument übergeben wird, ist unter meiner Kontrolle. Und ich werde einfach nur prüfen, ob der Datentyp wirklich String ist. Dann setze ich einfach den String auf das CurrentElement und gebe den einfach nur zurück und kann den jetzt lesen, also den Speicherbereich, den ich lesen möchte und kann jetzt also in diesem Programm beliebige Speicherbereiche auslesen. Und der nächste Schritt ist dann Code auszuführen. Und das kann man machen, indem ich aus dem String-Datentyp ein Objekt-Datentyp mache. Denn jedes Objekt hat am Anfang ein Zeiger auf ein Virtual Table und darin werden virtuelle Funktionenpointer gespeichert. Das heißt, wenn wir hier nochmal zurückgeben, wenn also Current als Typ Objekt hat, dann wird also Type-Off ausgeführt und das folgt einfach dem Zeiger auf das Objekt und den virtuellen Objekt-Pointer in dem Objekt und die wird dann einfach ausgeführt. Und nachdem ich volle Kontrolle über diese Pointer habe, habe ich also auch offensichtlich volle Kontrolle über diesen virtuellen Table-Pointer und kann die Type-Off-Funktion einfach zeigen lassen auf den Shell-Code, den ich ausführen möchte. In dem Fall habe ich einfach die andere Funktion benutzt und das sorgt dafür, dass der Browser nicht abstürzt, nachdem ich den Code ausgeführt habe. Also ich setze hier einfach den Datentyp auf 7. Das heißt, es ist ein Objekt-Datentyp-Pointer und dann folge ich also dem Objekt-Pointer und den virtuellen Table-Pointer und lande dann hier vorne in dem anderen Speicherbereich und wenn ich davon aus jetzt diese Funktion aufrufe, dann kann mein Shell-Code ausgeführt werden und am Ende sehen wir, dass wir den Obcode C3 gespeichert haben hier am Ende und am Ende wird einfach ganz normal Return ausgeführt. Das heißt, der springt aus meiner Funktion zurück und wird ganz normal weiter funktionieren, als wäre nichts passiert. Das Problem ist, das funktioniert nur bei älteren Systemen wie Windows XP zum Beispiel, denn nur da ist der Shell-Code auf dem heap landet und wegen Data Execution Protection ist der bei neueren Systemen eben nicht ausführbar und was man also machen möchte, ist, man möchte so eine Rob Chain bauen und das Problem ist, die Adresse von dem Rob-Table wird von der Adresse des Stacks abgeleitet und das Problem ist, Stack-Pointer haben also die Adresse des Stacks, aber wir wissen nicht wo der ist. Wir können nur hier oben das rote Gebiet kontrollieren und das bedeutet, dass die erste Rob Gadget in irgendeiner Art und Weise hier auf diesen heap zeigen muss. Wir müssen also so ein Gadget finden und wir können das machen, indem wir an zwei FoxMool anschauen. Schauen wir uns hier an. Das ist ein Jump. Diese Sprung Instruktion hat zwei Bytes, also 72 ist der Sprung und C9 ist der relative Offset. Das Problem ist, dass mit Return-Oriented-Programming müssen wir nicht den Anfang dieser Instruktion anspringen, sondern wir können auch mitten reinspringen und reinterpretieren diesen Code dann als eine neue Instruktion. Wir können also neue Instruktionen bauen, die nicht vorher nicht da waren, indem wir in die Mitte von schon existierenden Konstrukten springen. Wenn wir also auf C9 springen, wenn wir also in den Mitte springen, dann wäre C9 eine Leaf Instruktion und die Leaf ist genau das, was ich möchte, denn das nimmt das Base-Pointer-Register und bewegt es in den Stack-Pointer und das ist dann ein Code, der unter meiner Kontrolle unterliegt. Kurze Ausschreifung über, wie man Rob Gadgets findet. Es gibt welche Arten von gibt es, könnt ihr nachher anschauen, aber grundsätzlich geht es um syntax-basierte Gadgets. Es gibt viele verschiedene Wege, um das gleiche Verhalten zu erlangen mit verschiedenen Instruktionen. Man muss einfach nur eines davon finden, dass ein Poch ab irgendwo vor kommt. Das dauert ziemlich lange, was ich also gemacht habe, ist, das einfach mit paar Emotes zu emulieren und dann das Verhalten analysieren. Also habe ich einfach dieses Gadget mehrmals emuliert mit verschiedenen Startregistern und dann geschaut, wie sich das Ganze verhält und am Ende fällt dann raus, ob es Verhaltensbasierte Suche machen oder wenn es rausfällt, welche Gadgets verwendet werden können, um zum Beispiel ECX auf 0 zu setzen. Das macht die Arbeit deutlich einfacher. Jetzt kommen wir zum ersten Emmet-Teil, wenn er entstattet, dass das User-Interface um kann man OS-Weit-Sachen wie DEP oder ASLA konfigurieren, sieht unten die laufenden Prozesse und welche davon geschützt werden. Und wenn man den Apps-Button anklickt, kann man pro Prozess konfigurieren. In diesem Fall habe ich einfach alle Mechanismen für Firefox angeschaltet. Wenn wir Firefox jetzt startet, sieht man, dass Firefox einfach nur abstürzt und unten rechts sieht man das Emmet eine Stack-Pivot-Attacke entdeckt und verhindert hat. Bevor wir über verschiedene Umgebungstechniken reden, müssen wir in ein paar generelle Sachen sprechen. Was wir machen wollen, ist, dass wir uns gegen echte Angriffe schützen. Das bedeutet, wir müssen denken, wie echte Angreifer in der Ende, und nicht gegen irgendwelche akademischen Angreifer verteidigen, die nur auf einem speziellen Betriebssystem und einen Konfigurationen laufen. Was sind also die Ziele von realen Angreifen? Sie wollen Umgebungstechniken, die zuverlässig sind, gegen verschiedene Betriebssysteme funktionieren. Wenn also 100 potenzielle Opfer meiner Webseite besuchen, möchte ich jetzt natürlich alle 100 App informiert werden. Das bedeutet, es muss mit allen Betriebssystemen funktionieren, mit allen Service-Pack-Levels funktionieren und gegen alle Emmet-Versionen. Die andere Sache ist, dass der Exploit leicht wiederverwendbar sein sollte, wenn ich also zum Beispiel einen Monat brauche, um eine meiner Bypass-Techniken zu entwickeln. Dann möchte ich es natürlich später einfach copy-pasten können, wenn ich eine andere Vorwirkbarkeit in Internet Explorer finden und nicht wieder einen ganzen Monat darauf zuwenden, alles wieder von Anfang an zu entwickeln. Und das bringt uns dann zu der Idee, dass wir alles auf die MEDL bauen können. Denn MEDL funktioniert, indem es an der eigene Bibliothek in alle geschützten Anwendungen initiiert und dann einfach Funktionen huckt und sagt hier, für bitte meinen Code aus, bevor du diese Funktion aufrufst und wenn der Code funktioniert, dann ist gut auch weiter. Und wenn nicht, dann wird die Anwendung einfach geschlossen, bevor irgendwas anderes passiert. Wir sehen hier, MEDL ist ein großartiges Ziel, um Bypasses darauf zu bauen, denn wenn man das schon mal bypassen muss, wissen wir, dass es immer da sein wird. Wenn man alles auf MEDL für Firefox basiert, dann wissen wir, ist es auch da, wenn ich zum Beispiel Adobe Reader antreifen möchte. Der erste Schritt ist also, dass wir MEDL im Speicher finden. Andere Forscher von Offensive Security zum Beispiel haben schon einen MEDL-Bypass gefunden, die darauf aufs bauen, die MEDL LCS zu finden. Also ich empfehle, dass ihr euch diese Blockpost anschaut. Die sind sehr gut von Offensive Security. Ich rede nachher kurz über ihre Technik. Aber was die Taten ist, dass sie einfach angenommen haben, dass getModuleHandle von einem Modul importiert wird und dann einfach einen RobChain schreiben, der diese Funktion aufruft und dem das Argument MEDL übergibt und dann gibt die Funktion eben die Basisadresse dieses Moduls zurück. Das Problem dabei ist, wenn die Anwendung diese Funktion nicht importiert, dann kann das nicht angewendet werden und deshalb hat man in einigen Fällen extra Abhängigkeiten. Also habe ich meine eigenen Methode gebaut. Ich nenne es die Hook Methode, die schon gesagt, MED hooked bestimmte kritische Funktionen, zum Beispiel VirtualAllow, VirtualProtect, WinExec, LoadLibrary, weil die benutzt werden könnten, um DEP auszuschalten und zum Beispiel mit StackPivote verhindern, wie wir schon im Bild gesehen haben. Zum Beispiel prüft ihr da einfach, ob der StackPointer momentan auf den Stack zeigt oder ob es weggeschiftet wurde und in den Heap zeigt, wie im Firefox Explore die Funktion ist. Und das ist das Problem, dass man die Funktionen von StackPivote und StackPivote verhindern kann. Das ist das Problem, dass man die Funktionen von StackPivote und StackPivote auf den Stack zeigt oder ob es weggeschiftet wurde und in den Heap zeigt, wie im Firefox Explore. Und das ist also, wie ihr mit das erkennt. Und deshalb sagt, hier geht gerade, hier findet gerade ein Angriff statt. Um die Hook Methode zu verstehen, müssen wir uns die Implementierung der VirtualProtect Funktion anschauen und auch sehen, wie MED sich da reinhängt. Das ist die 32 von VirtualProtect. Diese Implementierung ist Standardprolog, die ist immer da. Das POP-EVP macht den Prolog nur rückgängig, dann gibt es einen Jump zur eigentlichen Implementierung. Wenn man nun aber sieht, wenn man diese Applikation jetzt mit MED schützt, dann setzt MED einen Hook rein, ersetzt also einfach die erste Anweisung mit einem sprungenden eigenen Code, setzt dann eine zufällige Anzahl von Bites als Breakpoint und wenn man sich dann den Sprung anschaut, dann sieht man hier den Code, der von MED allokiert wurde. Wir sehen hier, es pusht einfach ein paar Argumente auf den Stack und ruft dann schließlich die MED DLL auf. Was der Hook Methode jetzt versucht ist, dass die diesem ersten Hook folgt, bis es an diese Stelle kommt und dann einfach weiter runter geht und diese Adresse extra hier, die als Sprungziel benutzt wird. Wir können einfach runtergehen, bis wir den Peader finden und dann runtergehen und die Image Base finden. Das Interessante ist hier, dieser Pushwert zeigt genau auf diese Location hier, weil MED also die alte, die alten Bytes, die alte Implementierung der Funktion wegkopiert hat und ihr setzt da mit dem Hook Code, muss MED irgendwo die alten Codes, die alten Instruktionen im Speicher behalten. Das ist die Stelle, wo diese Bytes hingestellt werden. Das wird nachher noch interessant, also haltet es euch im Kopf. Das hat die Samenfassung der Hook Methode. Wir schauen uns den Trust Table Eintrag einer kritischen Funktion anlesen. Die ersten fünf Bytes dieser Funktionen, wenn es eine Move Instruction ist, dann ist es nicht von MED geschützt, dann kann ich den Exploit einfach so ausführen, wenn es ein Sprung ist, dann folge ich einfach diesem Sprung, bis ich die Basisadresse vom MED finde. Seht ihr hier, das ist die Rob Chain, die das implementiert? Kurze Frage, wer von euch hat schon mal eine Rob Chain geschrieben? Hand hoch? Okay. Ich gehe nur ganz kurz über die ersten drei Zeilen, sodass jeder weiß, was hier passiert. Das ist die Adresse, die ich auf den Stack oder Hieb schreibe. Das ist die Return Adresse. Diese Adresse stehen diese Assembler Instruktionen. Also es würde einfach anfangen, hier zu auszuführen in POPIAX, weil der Stack-Pointer gerade auf dieser Adresse zeigt, würde diesen Wert nehmen und diesen Wert poppen in das ERX-Register und dann anfangen, die nächste Zeile auszuführen, was Move ERX-ERX bedeutet. Es hat den Pointer gerade auf Virtual Alloc gepoppt und mit dieser Zeile resolve ich den Eintrag. Der nächste Eintrag würde den Content dann aus dem ERX-Register wieder in das ED-Register bewegen, mit Push und Pop und so weiter. Es würde also einfach weitermachen mit diesen Sachen. Dann muss man hier unten, seht ihr, dass ich ein paar hart kodierte Werte genutzt habe auf Grundlage der MED-Version. Wenn es also MED 4.1 muss diesen Offset nehmen, für MED 5.0 muss diesen Offset nutzen. Und das Problem ist, dass ich momentan gerade nicht weiß, welche MED-Version da läuft. Das ist also keine gute Methode. Es würde gegen eine oder zwei spezielle MED-Versionen laufen. Das ist aber nicht, was wir wollen. Wenn ich versuche, eine lokale Anwendung anzugreifen, dann kann ich eine bessere Rockchain schreiben. Das ist sehr komplex, weil ich dann abhängige Sprünge ausführen muss. Und das macht den Code extrem viel größer. Wenn ich aber mit einer Browserverwundbarkeit zu tun habe, eine Browser-Schwachstelle zu tun habe, dann kann ich diese Technik nutzen. Und zwar ist die Idee, dass wir einfach schon Bestehenden oder anderen Code benutzen. Wenn wir jetzt einen Browser oder eine PDF-Lise benutzen, dann weiß ich, dass irgendwo Code sein muss, z.B. Datenstrukturen in JavaScript behandelt. Und die Idee ist, dass wir jetzt einfach eine Rockchain benutzen oder eine andere Schwachstelle um diese Datenstrukturen zu manipulieren. Wir können also sagen, dass dieser String jetzt auf eine andere Location im Speicher zeigt. Und dann können wir das ganze Ding in JavaScript implementieren. Ich habe nachher rausgefunden, dass diese Methode schon veröffentlicht wurde von Yang Yu. At Can't Set Quest dieses Jahr als Robs are 99%. Wir sind ein paar Beispiele. Das erste Beispiel ist, wir können einfach einen String manipulieren. Wir können sagen, dass dieses String jetzt auf unseren Hubcode zeigt. Dann können wir das gesamte Paar singen JavaScript implementieren. Ein anderes Beispiel ist das dritte. In diesem Beispiel können wir einfach sagen, dass der String in irgendeinem Code-Teil als langen Modul start. Dann können wir zu Funktionen wie Index of Innerhalb dieser Code-Sectionen herausfinden, wo die Rob-Gadgets liegen. Also die relativen Offsets dieser Rob-Gadgets in der dieser Strings. Also ich einfach sagen, zeig mir, wo eine Pop-Up-Return Instruktion liegt. Das bedeutet, ich kann einen Exploit für Amit 5.1 schreiben und wenn Microsoft dann später Amit 5.2 oder so veröffentlicht, würde der Exploit einfach weiter funktionieren, weil ich in Amit alles finden könnte. Mit dieser Technik kann ich also sehr zuverlässigen Code schreiben. Hier sehen wir die Implementierung in JavaScript. Also hier wird einfach nur diese Abitrary-Leak-Bytes- Funktionen aufgerufen, die diesen String zurück gibt von der VirtualElloc-Funktion. Und dann kann ich schlicht diese Bytes testen. Und wenn es eine Move-Instruktion ist, dann wird einfach der Exploit ausgeführt ohne Amit-Schutz. Und wenn es eine Jump-Instruktion ist, dann wird dem Jump gefolgt und wir suchen dann, bis wir die Call-Instruktion finden. E8 ist hier der Op-Code von der Call-Instruktion. Und wenn es dieser Op-Code ist, dann ist es eine Sub-Instruktion. Es gibt mich drei Bytes, weil das die Größe hat. Und bei einer Push-Instruktion fünf Bytes und so weiter, solange bis ich die Call-Instruktion finde. Und wenn ich die Call-Instruktion finde, dann kann ich den Header hinzufügen. In dem Fall wird einfach die Check-Summe und Timestamp ausgelesen. Und daraus kann ich herausfinden, welche Version von Amit eingesetzt wird. Und dann weiß ich, welche Version von Amit eingesetzt ist. Und jetzt kommen wir also zu den verschiedenen Schutzmechanismen. Also wie wir schon erwähnt haben, hat Amit fünf verschiedene ROP-Schutzmaßnahmen. Und wenn wir die umgehen wollen, dann haben wir drei mögliche Ansätze. Der erste Ansatz ist, dass wir jeden Schutz einzeln umgehen. Da gibt es also dieses Paper von Gerald de Motte mit einem großartigen Überblick zu dem Thema. Und die andere Idee wäre, dass wir einen Trick von Offensive Security benutzen. Und was die machen, ist, dass sie einfach MDLL rückgängig machen. Und es gibt also offensichtlich eine globale Fleck, die man setzen kann, die alle Schutzmaßnahmen gleichzeitig deaktiviert. Und man kann also einfach diese Fleck deaktivieren. Nach Hinweisen hat Microsoft also diese Fleck in einer Read-Only, also nur lesbare Speicherposition verschoben. Und jetzt hat Microsoft das Alteres gemacht. Sie haben das in eine Code eingebaut, den man jetzt aber mit ROP anspringen kann. Und Offensive Security haben da also quasi ROP benutzt, um diesen Fleck wieder zu setzen. Und Microsoft hat hier wieder einen Schutz eingebaut. Aber das Problem ist jetzt, dass es einen dritten Trick gibt, den wir benutzen können, um MDLL zu umgehen. Und Offensive Security macht jetzt folgendes. Die benutzen also nur diesen dritten Trick hier. Da wird einfach diese nur lesbare Sektion auf wieder schreibbar gesetzt und dann können sie dieses Fleck überschreiben. Und solange das nicht gefixt ist, werden die einfach diesen dritten Trick wieder benutzen. Aber falls sie das dann doch fixen, dann müssen wir tatsächlich jede einzelnen Schutz extra umgeben. Und den dritten Ansatz hier habe ich selbst entwickelt in meiner Forschung. Aber gleichzeitig hat Offensive Security auch diesen Trick herausgefunden. Und die Idee ist, dass man einfach direkte Systemaufrufe machen kann. Und wenn man also einen Aufruf direkt an den Kernel macht, dann hat EMET keine Möglichkeit, diesen abzufangen und einen Angriff zu detektieren. Und jetzt reden wir über die einzelnen Schutzmaßnahmen einzeln und wie wir die umgehen können. Load Library ist der erste Schutz. Und die Idee ist, dass EMET verhindert, dass ein Angreifer zusätzliche Module nachlädt. Und das musste ich nicht wirklich umgehen, weil ich gar keine zusätzlichen Module lade. Aber man kann sich den Talk, der hier erwähnt ist, angucken und da wird es erklärt. Es funktioniert nur bei EMET 3.5, aber es ist auch einfach für neue Versionen. Der andere Schutz ist Mem Protect. Also hier werden Funktionen wie Virtual Protect oder Virtual Alloc daran gehindert, den Stack ausführbar zu machen, denn der Stack sollte niemals Ausführbarencode enthalten. Und das kann man leicht umgehen, indem man einfach irgendeine andere, also eine andere Speicheradresse ausführbar macht, zum Beispiel den heap. Aber damit kann man dann die Rob Chain umgehen. Also wir benutzen zum Beispiel nur ein Tool, um so eine Rob Chain zu generieren, weil wir eben faul sind. Und das Wichtige hier dran ist, dass es also die PushAD Instruktion benutzt wird, um diese virtuelle Alloc Funktion aufzurufen. Und ich habe jetzt eben meine eigene Rob Chain entworfen und benutze die Push Instruktion, um die Funktion aufzurufen und kann also alle Argumente einzeln setzen. Und ich komme da aber später noch mal dazu zu dieser Rob Chain. Und die Stack Pivot Methode, die wurde ja vorhin schon erwähnt, da ist die Idee, dass EMET einfach nur prüft, ob der Stack Pointer zu dem Stack auf den Stack zeigt oder irgendwo anders hingeschoben wurde. Und um das zu umgehen, müssen wir einfach nur alles vom heap zurück auf den Stack kopieren, bevor wir die kritische Funktion aufrufen. Also man sieht den Code hier, mit dem wir das machen können. Das ist nicht sehr einfach, es ist nicht sehr schwierig, es ist einfach nur ein While Loop. Und dann benutzen wir Exchange, um vom heap zum Stack zu gehen. Und die Caller Mitigation Technik ist sehr spannend, weil wir wollen ja eine Funktion aufrufen, das ist erlaubt. Aber wir können auch an den Start der Funktion springen oder wir können einen Funktionsreturn simulieren und einfach die Adresse der Funktion pushen. Und das bedeutet, dass die Return Funktion dann einfach zu der Adresse der Funktion springt. Und bei Rob benutzen wir üblicherweise diesen dritten Ansatz und was EMET macht ist, wenn man diesen erlaubten, diesen ersten Ansatz benutzt, dann wird die Adresse der nächsten Instruktion auf den Stack gepusht und EMET kann dann die Return Adresse benutzen und prüft dann einfach, ob es dann tatsächlich einen Aufruf gibt für diese Funktion. Und wenn man also den zweiten und dritten Ansatz benutzt, dann gibt es also keine so eine Adresse und so kann EMET also diesen Angriff detektieren. Und was wir machen können ist, dass wir stattdessen direkt zu der Funktion zurückkehren, können wir zu einem Aufruf der Funktion zurückkehren. Und das wurde also von Jar Dimot erfunden und er benutzt also diesen Code hier. Und wir springen also zurück zu diesem Aufruf hier, statt direkt zu returnen. Und EMET prüft dann also, ob es hier diesen Call Aufruf gibt und stellt fest, ja, der ist tatsächlich da und der Schutz ist umgeben. Aber ich sehe ein Problem mit diesem Rob Gadget, weil wenn man sich die Adressen anschaut, das ist von der Windows Bibliothek. Das würde also nur funktionieren gegen ein spezielles Betriebssystem und nur gegen ein spezielles Service Pack Level, was natürlich schlecht ist, weil wir andere Betriebssysteme so nicht angreifen können. Und wir sehen also viele Referenzen auf den Speicher, was dazu führen kann, dass wir also einen Crash auslösen. Und das ist problematisch, weil wir hier diesen, weil diese Aufrufe weit voneinander entfernt sind. Und was wir hier also machen wollten ist, wir wollten jetzt quasi direkt in EMET benutzen. Es gibt also hier wieder einen Aufruf zu Virtual Protect und das ist also auch nur eine Speicheradresse. Das heißt, das wird also auch nicht abstürzen. Und der Jump geht dann zu dem Return und zum nächsten Gadget. Aber was machen wir, wenn wir so einen Gadget nicht finden können, der nah bei dem Return steht? Und die Idee ist, wir können einfach jeden Aufruf, also jeden Aufruf benutzen, der irgendwie einen Register enthält. Wenn wir uns also hier angucken, den Aufruf zu der Funktion, der ruft diesen Code hier auf. Also ich mache hier einen Call auf EDi und wir stellen einfach nur sicher, dass EDi auf die Funktion zeigt, die ich aufrufen möchte. Also hier wird einfach nur EAX gepoppt und der nächste Wert landet also in EAX. Das ist also die Adresse von dem Virtual Alloc-Adress-Table. Und ja, mit dem Exchange wird es dann einfach nur in EDi reingeschoben. Und das kann man hier auch noch mal sehen, dass EDi tatsächlich auf Virtual Alloc zeigt. Und danach gibt es einfach nur einen Jump, das heißt, hier kann es auch wieder keinen Absturz geben. Und der Jump geht dann einfach wieder nach vorne. Wir haben ja überhaupt keine Zeiger in den Speicher. Das kann also nicht abstürzen. Und den letzten Schutz, den wir umgehen müssen, ist SimExecFlow. Und da wird einfach nur diese Caller Limit-Militation-Technik für alle Adressen benutzt und wird also für alle Return-Adressen angewandt immer wieder. Und wenn wir diese anderen Schutz umgehen, dann ist auch dieser Schutz quasi automatisch mit umgangen. Und bei diesem Schutzmechanismus wird quasi auch ausgelöst, wenn man meinen Shellcode ausführt. Und die Lösung ist ganz einfach. Ich call einfach so eine Instruktion und dann wird die Return-Adresse gepoppt. Und das tut gar nichts natürlich, wird aber nur diese Simulation verwirrt. Und damit kann man also diesen Schutzmechanismus auch umgehen. Und der Trick, der jetzt also benutzt werden kann, um das alles auf einmal zu umgehen, ist eben, dass ich einfach nur direkte Systemaufrufe mache. Weil EMMAT komplett im User-Space passiert, kann ich also, wenn ich direkt in den Kernel aufrufe mache, kann EMMAT nichts dagegen tun. Und das Problem dabei aber ist, dass wenn ich hier die Betriebssysteme wechsle oder den Patch-Level wechsle, dann kann ich also mir den Syscall-Nummer nicht merken. Das heißt, ich brauche zuerst mal die Versionsnummer von dem Betriebssystem und dem Service-Pack-Level. Und dann könnte ich da also diese Tabelle benutzen, aber wir haben was Besseres. Wenn wir uns angucken, wie EMMAT eine Funktion abfängt, dann gucken wir uns also hier angucken, was passiert. Wenn wir Virtual Protect aufrufen, dann wird es also nur die, wird es einfach nur hier zu dieser DLL-Version weitergeleitet. Und die erste Zeile, die verschiebt dann einfach nur den System-Call-Nummer in den IRX-Register. Und die zwei weiteren Zeilen, die rufen dann einfach nur die Funktion im Kernel auf. Also in dem Fall sehen wir das 32-Bit-System. Und wenn man dem weiter folgt, dann sehen wir hier den Sys-Enter-Call. Und wenn wir das jetzt mit EMMAT schützen, dann macht er also wieder dasselbe wie vorhin, ersetzt also nur die erste Instruktion mit Jump. Und wir sehen hier, dass das dritte Argument von Push, also hier unten auf diesen Bereich zeigt. Und EMMAT hat also nur diesen Bereich wegkopiert. Und ich kann also diese Adresse finden, indem ich einfach nur einen relativen Offset nehme. Das kann ich also leicht finden. Und dann kann ich also dieses dritte Push-Argument mir angucken, was da unten zeigt. Und dann kann ich also direkt hier hinspringen. Also ich kann zu allen EMMAT, ich kann alle Funktionen von EMMAT direkt anspringen. Also wir sehen jetzt hier die Implementierung. Das ist eine ziemlich komplizierte Rob Chain. Damit will ich euch jetzt nicht... Also die ist nur deswegen so lang, weil sie zuerst sich selbst im Speicher sucht und dann sich selbst modifiziert. Und jetzt gucken wir uns die letzte Schutzmechanismus an. EAF Export Address Table Filtering, also Export Tabellen, Zugriffsfilterung. Und diese Address of Function Field muss also übergeben werden für Load Library oder GetProc Address und um diese Funktionen also zu finden. Und was EMMAT jetzt macht, ist, dass es einfach Hardware Breakpoints in diesem Feld einsetzt. Und wenn eine Funktion dieses Feld lesen will, dann wird der Breakpoint ausgesetzt und EMMAT Code wird ausgeführt und kann also zusätzliche Prüfungen machen. Und wenn also die Funktion zu dem Modul gehört, dann kann er das also ausführen und ansonsten kann die Ausführung abgebrochen werden. Und wir haben wieder ganz viele verschiedene Ideen, wie wir diesen Schutz umgehen können. Zuerst können wir einfach wieder eine Rob Chain benutzen, weil wir dann die Institution von einem geladen Modul kommt. Wir können andere Techniken benutzen. Aber das Problem mit den ersten drei ist, dass wir den Shell Code verändern müssen, wenn wir diese Techniken verwenden. Weil Exploit-Entwickler super faul sind, können wir diese letzte Methode nutzen und wollen fast sagen, hey, wir entfernen einfach alle Breakpoints, bevor wir unseren eigenen Shell Code ausführen. Und um diese Breakpoints zu entfernen, haben wir schon wieder viele verschiedene Möglichkeiten. Der Hauptansatz war von Piotre Barnier. Ihr könnt euch das Blog-Post anschauen. Das Problem daran ist, dass der HardCode System Calls verwendet. Was ich schon dessen tun wollte, ist, dass ich die API verwendet habe und eine steuerische Stelle innerhalb von EMMAT springe. Das Problem daran ist, dass seit EMMAT 5.0 die auch diese Funktionen hookt. Wir können das also nicht weiter anwenden, außer wir schalten diese Schutz, diesen Schutz erst ab. Aber ich denke, in den nächsten Versionen von EMMAT wird das nicht mehr funktionieren. Und deshalb denke ich, es ist nicht so interessant hier. Die erste Methode ist, also die System-Call-Zahlen zu verwenden. Das Problem daran ist, dass es nur gegen eine Betriebssystem- und Service-Pack-Version funktioniert. Dann gibt es zwei andere Techniken, aber für die neue System-Pack-Version sind sie nicht so interessant. Also ich springe einfach mal drüber. Es waren also nur ein paar Methoden, wie man das tun kann. Ich glaube, die interessanteste ist, dass wir einfach über die alle Hooks drüber springen können und direkt den System-Call einrufen, wie wir eben schon erwähnt haben. Diese Technik hat keine Nachteile. Es funktioniert gegen alle Versionen von Windows, alle Service-Packs und alle Versionen von EMMAT. Und jetzt hast du die stichende Gedanken. EMMAT hat viele Schutzmechanismen, aber ich denke, diese zwei, der Rob-Schutz und IRF, sind die interessantesten von der technischen Perspektive. Andere Mechanismen sind zum Beispiel Text-Service Reduction, wo die andere Oberfläche reduziert wird. Dass ich also Java zum Beispiel aus dem Internet lade, aber nicht aus dem Internet oder Certificat bei Vertrauen. SEHOP, Structured-Exception-Handler, Override-Protection, also die schütterierte Ausnahmehändler durch Überschreibenschutz. SEHOP ist auch leicht zu umgehen. Die Hiebspray Entschärfung, Hiebspray Vorbeugung und Alpage Preallocation ist es sehr leicht, die rauszunehmen, einfach eine Adresse zu nutzen, die nicht von EMMAT geschützt ist. Wenn ihr da mehr wissen wollt, schaut euch einfach meine Ruckscon 2014 Slides an. Ich denke, das ist nicht so interessant. Dann mandatory ASLR und bottom-up Randomization erhöhen nur die Funktionalität von ASLR, aber wenn man ASLR umgehen kann, dann wird das quasi mit umgangen. Und schließlich IRF Plus ist ein interessanter Schutz, weil es eigentlich gegen meinen aktuellen Exploit schützen sollte. Tut es aber nicht. Ich weiß nicht genau, warum. Wir diskutieren das gerade mit Microsoft, aber selbst wenn es gegen die aktuelle Version helfen würde, wäre es nicht schwierig, den Exploit so zu erweitern, um auch diesen Schutz zu umgehen. Abschließend, kurze Zusammenfassung. Wir springen jetzt kurz nach der Zusammenfassung, was ich gesagt habe und kommen wir zum abschletzten Gedanken. Wir würden wirklich gerne mit Microsoft zusammenarbeiten und spüren spätere Versionen von EMMAT Robuster machen. Wir haben schon ein paar Ideen, wie EMMAT verbessert werden kann, aber natürlich ist kein Schutz 100% kugelsicher als ein kleines Demo-Video. Hier seht ihr den Exploiten Action. Hier seht ihr alles, das ist grün. Alle Schutz, wenn ihr das aktiviert, Firefox ist geschützt von EMMAT. Hier seht ihr, alle sind aktiviert. Wenn man einmal ein sauberer Klick sieht man hier, die ERT-RF Plus ist aktiviert. Wenn ich Firefox jetzt mit dem alten Exploit starte, ohne die Bypasses, dann seht ihr, dass es abstürzt und EMMAT daraufhin, was als Angriff gefunden wurde. Wenn ich da einfach so nochmal starte, die Tast jetzt noch mal refresher, wir sehen, es ist immer noch geschützt. Wenn ich jetzt den neuen Exploit nutze mit den Bypasses, dann kann ich meinen eigenen Exploit ausführen und da kommt der Rechner. Ihr seht auch, dass Firefox nicht abstürzt. Ich kann den Exploit also einfach mehrmals ausführen und es auch vermerkt nicht, dass da was passiert ist. Noch in Zusammenfassung über die Arbeit, die da reingegangen ist. Der initiale Exploit ohne EMMAT-Bypass dauerte nur 3-5 Tage, war eher leicht. Ich denke, wenn man es wirklich schnell macht, kann man es in einem Tag hinkriegen. Aber ich habe es mir in der Freizeit gemacht. Also ich habe zwischendurch auch noch TV-Fernsehen geschaut und so. Also 3 Tage nebenbei. Dann die erste Umgehung für EMMAT 4.1. Das war wirklich viel auffahren. Ich kann euch gar nicht sagen, wie lange der Exploit-Code fährt, dann 5.000 Zeilen Code. Also es ist richtig riesig. Dann habe ich wirklich lange dafür gebraucht. Die Idee war aber, dass ich ganz viele verschiedene Ideen entwickle, um diese Schutzmechanismen zu gehen. Ich habe euch jetzt nur ein paar gezeigt. Es bedeutet, ich kann einfach konfigurieren, wenn EMMAT sich dann auf 0 aktualisiert hat, waren es nur 5 Minuten, 4 Code Zeilen, den Exploit zu verbessern. Ich musste nur zwei neue Methoden hinzufügen, zwei neue Instruktionen passen können. Also diese Instruktion sagt dann, wenn es ein Push ist, wenn es länger von 5 hat, dann füge ich einfach zwei Einsachtstunden hinzu. Das Gleiche war mit dem Upgrade auf EMMAT 5.1. Die aktuelle Version hat mir etwa 40 Minuten gekostet, weil sie versucht haben, meinen Scandown-Technik zu umgehen, also zu verhindern. Also ich liege an DLL, ich gehe dann soweit runter, bis ich den PI-Header finde und sehe das hier auf dem nächsten Slide. Ein EMMAT 4.1, das sind die Sections der Datei, das ist der PI-Header, das ist die Text-Section. Ich habe also einen Pointer in dieser Text-Section und dann gehe ich einfach nur runter, bis ich diesen PI-Header finde und ihr seht, da ist keine Lücke dazwischen. Also wenn ich einfach zu dieser Base-Adresse die Länge hinzuaddiere, dann landlich genau bei dieser Adresse, also der adresselle Text-Section. Dasselbe gilt bei EMMAT 5.0. Auch hier seht ihr, wenn ich da das 1 hinzufüge, dann komme ich bei der nächsten Adresse raus, das EMMAT 5.1 dann gemacht hat, dass ich jetzt hier diese Länge hinzufüge zu addiere. Dann komme ich nicht an die Text-Section, sondern es gibt ein Loch dazwischen, wo kein Speicher hingemappt ist. Wenn ich also da versuche, durchzuscannen, dann greife ich auf mich zu, wie sind Speicher zu, ich kriege Segmentation Fault. Das bedeutet, ich suche also jetzt erst den Start der Text-Section und kann da den relativen Offset subtrahieren, um den PI-Header zu finden. Das ist also relativ leicht darunter umzugehen. Ihr seht also, es geht oft auch gegen die aktuellste Version von EMMAT. Ich habe gerade vor zwei Tagen nochmal geschaut, das ist die aktuellste Version. Das sind noch meine Kontaktdaten für mich und meine Unternehmen. Wie gesagt, wir suchen gerade neue Angestellte. Wenn ihr interessiert seid, schreibt einfach eine Mail oder schreibt eine Mail ins Office oder schreibt mich nachher an. Danke für Ihre Aufmerksamkeit, gibt es Fragen. Thank you for this very nice talk, René. If you have any questions, please do line up at the six microphones we have here at the ground level. While you're doing this, quick announcement. Ja, jetzt kommt noch eine kurze Bekanntmachung. Heute um 17 Uhr bei der Fairy Dust Rakete gibt es eine Freiheit statt Angst Demonstration. Wenn ihr da hingehen wollt, dann seid einfach um fünf da. Wir haben eine Frage für den Mikrofon 2. Danke für den Talk. Was ich wissen wollte ist, du hast gesagt, nach der Rob Chain kannst du wieder zurück ins Javasdritt. Ja, das habe ich nie nicht drauf. Wir müssen also die Verwundbarkeit ausnutzen, ohne dass die Anwendung crasht. Also mit lokalen Erbindungen ist es schwieriger. Ja schon, aber was, wenn diese Rob Gadgets die einige Register ändern, was passiert? Könnte das möglicherweise den Rest des Codes nicht mehr ausführen. So ein Maß habe ich nicht verstanden. Also wenn einer dieser Rob Gadgets ein Register ändert, dann wird das nicht automatisch wieder hergestellt, wenn ich zurück springe. Und das kann die Ausführung verhindern. Was ich tue ist, dass ich einfach alles vorher von Hand überschreibe, bevor ich returning. Also ich fasse eigentlich nur, in diesem Fall nur die Datenstruktur an. Aber man muss da nicht wirklich ein Rob Gadget ausführen. Ich kann auch die Verwundbarkeit direkt ausnutzen, in diesem Fall. Also ich habe viele Sachen hier weg abstrahiert, dass diese Präsentation, um sie leichtverständlich zu machen, aber statt eine Rob Chain auszuführen, kann ich auch direkt in irgendwelchen Speicher schreiben. Also man muss gar keine Rob Chain nutzen, um diesen Speicher zu überschreiben. Also zum Beispiel, wenn ich hier zurückgehe. Hier seht ihr hier das zweite Beispiel, in diesem Fall. Hier das zweite Beispiel. Sagt euch, ihr könnt diese Technik benutzen, um Speicher zu schreiben. Am liebsten Stellen Speicher zu schreiben. Das ist ja so tun können, dass das hier ein Array im Speicher anlegt und dann die Schreibzugriffe dahin umleitet, sodass es die Datenstrukturen überschreibt. Wir müssen also nicht wirklich die Rob Chain ausführen. Okay, danke. Gibt es noch andere Fragen? Es gibt eine Frage vom Signal Angel aus dem ISC. Ja, wird Emmet in Firmen häufig benutzt? Ich habe es nicht oft gesehen bisher, weil das Problem ist die Kompatibilität. Wenn ich es zu Hause nutze, dann crasht mein Firefox alle drei bis vier Tage, weil Emmet sagt, dass es einen Angriff gefunden hat, aber in Wahrheit gibt es gar keinen Angriff. Also es hat eine hohe false positive Rate. Ich denke, das ist das Hauptproblem davon. Aber ja, ich glaube auch, dass das ein Problem ist, dass es nicht so leicht deployet werden kann in Domains. Ja, lieben Dank. Eine weitere Frage? Ja, Mikrofon 2. Hältest du Windows für sicher in einem Unternehmensumfeld? Würden Sie also empfehlen, Windows in Organisationen einzusetzen? Windows? Schwere zu sagen. In meiner Meinung nach, also in der Grundeinstellung ist Windows schwerer aus zu exploiten als Linux. Musst man das Compiler Flake hinzufügen, um Positionsunabhängige Ausführbare Dateien zu bekommen, damit der Schutz auch aktiver ist. Wenn man das einfach nur kompiliert, dann wird es nicht in eine andere Adresse gemärbt. Also die Code-Sektion wird immer in der gleichen Stelle sein. Das Problem daran ist, dass viele Standardanwendungen nicht aktiviert haben. Die Situation ist für Windows besser. Aber es kommt drauf an. Wenn mehr Leute Windows benutzen, dann werden mehr Angreifer versuchen, Windows auszugreifen. Noch zwei Fragen aus dem ISC? Hast du ausprobiert, ob diese Technik auch mit anderen Exploits funktioniert? Ich habe es mit einer Testanwendung ausprobiert. Es funktioniert auch für VLC. Mit anderen Exploits habe ich es nicht versucht, weil ich weiß, dass es funktioniert. Ich habe alles auf mtl aufgebaut. Aber in diesem Fall, diese besondere Schwachstelle erlaubt mir sehr viel zu tun. Ich kann Speicher schreiben und lesen, wie ich will. Ich stütze nichts ab. Ich kann es also immer wieder ausführen. In diesem Fall ist es sehr einfach zu machen. Wenn nur eine Lokale Anwendung wie VLC angreifen will, es wird alles ein bisschen schwieriger, weil man diese Code-Reusechnik nicht verwenden kann. Wir können nicht einfach JavaScript-Code in eine Lokale Anwendung ausführen. Das bedeutet, wir müssen alles in eine Rob-Chain implementieren. Das bedeutet, alles wird wirklich schwierig, weil wir bedingte Sprünge ausführen müssen und sicherstellen müssen, dass es mit allen Versionen vom Triebsystem läuft. Aber es ist schwierig. Hallo. Danke für die Präsentation. Gibt es Pläne, einige dieser Schutzmechanismen im Kernel zu aktivieren? Das sieht alles aus, als wäre das alles im User-Space implementiert und manche dieser Schutzmechanismen könnten vielleicht auch im Kernel implementiert werden. Warum wird das nicht gemacht? Also der Null-Paget-Schutz sollte da eigentlich gegen Schützen, aber ich weiß nicht genau, es gibt keine Null-Pages. Noch eine Frage vom Signalengel. Ist die Größe des Codes ein großes Problem wegen zusätzlicher Komplexität? Ja, ich denke, das ist die Idee hinter Emmett, was sie sagen ist, dass sie wissen, dass Emmett umgehend umgangen werden kann. Aber sie wollen einfach die Arbeit für den Antreifer schweren. Also wenn ich ein Antreifer wäre und 100 Leute suchen meine Webseite und nur eine hat Emmett aktiviert, dann würde ich mir den Aufwand nicht machen. Das würde keinen Sinn machen, da extra Emmett umgehen und einzubauen für diesen einen Besucher. Aber wenn mehr Leute Emmett benutzen würden, dann würde ich diese Arbeit machen. Aber in diesem 5000-Seinen-Code habe ich viele verschiedene Methoden implementiert, um jeden einzelnen Schutz zu umgehen. Deshalb ist es so viel Code. Ich glaube, wir haben keine weiteren Fragen aus dem Publikum. Danke René Feinkruber. Und ja, das ist das Ende der Emmett-Session. Vielen Dank für's