Die Rückkehr des Sprayers - Exploits trotz DEP und ASLR

Das Traumpaar aus Data Execution Prevention (DEP) und Adress Space Layout Randomisation (ASLR) galt lange Zeit als kaum überwindbar. Doch dann kam JIT-Spraying und wendete das Blatt wieder zu Gunsten der Angreifer.

In Pocket speichern vorlesen Druckansicht
Lesezeit: 5 Min.

Die Kombination der mit Windows Vista beziehungsweise XP SP2 eingeführten Schutztechniken setzte die Entwickler von Exploits eine Zeit lang tatsächlich Schach Matt. Selbst wenn sie eine Sicherheitslücke in einem Programm fanden, über die sie den Programmfluss verbiegen konnten, gelang es oft nicht, die Kontrolle über das System zu übernehmen. Sprangen sie wie in der "guten alten Zeit" den auf dem Stack oder Heap eingeschleusten Code an, setzte es wegen der Data Execution Prevention (DEP) einen Interrupt und das System beendete den gerade mühsam gepwnten Prozess, bevor schlimmeres passieren konnte.

Neuere Exploit-Techniken wie Return-to-Libc oder dessen Verfeinerung Return Oriented Programming kamen ebenfalls nicht zum Zug. Return-to-Libc beruht darauf, bereits vorhandene Systemfunktionen, etwa zum Verwalten von Speicher mit den passenden Parametern zu versorgen und dann damit zu verwenden. Wegen der quasi zufälligen Verwürfelung der Speicheradressen via Adress Space Layout Randomisation (ASLR) wusste man jedoch nicht, an welcher Adresse der benötigte Code im konkreten Fall zu erreichen wäre. Das Gegenmittel Heap Spraying scheiterte wiederum am DEP – ein Teufelskreis.. Erst mit dem so genannten JIT-Spraying wendete sich das Blatt und die Angreifer sind plötzlich wieder im Spiel.

JIT-Spraying macht sich zu Nutze, dass Just-in-Time (JIT) Compiler aus Script-Code wie ActionScript zur Laufzeit ausführbaren Code erzeugen. Damit kann man also mit einem Flash-Filmchen schon mal ausführbaren Code erstellen, gegen den DEP nichts einzuwenden hat. Allerdings erlaubt ActionScript längst nicht alles, was man für einen vollwertigen Exploit braucht. So würde der Exploit-Autor etwa gerne via VirtualProtect() den Speicherschutz DEP für ein paar Seiten abschalten, auf denen der gewünschte Code zur kompletten Übernahme des Systems bereits liegt. Derartige Low-Level-Funktionen sieht die zur Steuerung von Multimedia-Inhalten vorgesehene Skript-Sprache jedoch nicht vor.

Um das trotzdem zu erreichen, hat Dion Blazakis im Frühjahr 2010 einen genialen Trick aus dem Hut gezaubert. Er beruht darauf, dass es bei einer Folge von Bytes sehr wohl darauf ankommt, an welcher Stelle genau man beginnt, sie als Code zu interpretieren. Diese XOR-Befehle in ActionScript

var ret=(0x3C909090^0x3C909090^0x3C909090^0x3C909090^ …);

übersetzt der JIT-Compiler in folgende Maschinenbefehle:

0x1A1A0100: 359090903C XOR EAX, 3C909090
0x1A1A0105: 359090903C
XOR EAX, 3C909090
0x1A1A010A: 359090903C
XOR EAX, 3C909090

Springt man jedoch knapp daneben, auf eine der Speicheradressen mit dem Wert 0x90 sieht die CPU das Folgende:

0x1A1A0101: 90   NOP
0x1A1A0102: 90
   NOP
0x1A1A0103: 90
   NOP
0x1A1A0104: 3C35
CMP AL, 35
0x1A1A0106: 90
   NOP
...

Leser der Serie Tatort Internet erkennen das sofort als Tu-Nix-Rutsche (NOP-Slide) – einen wichtigen Bestandteil der Heap-Spraying-Technik. Im Wesentlichen passiert hier gar nichts, bis die CPU dann irgendwann beim eigentlichen Shellcode an kommt. Da auch 0x3C zur Rutsche führt, stehen die Chancen bei einem Sprung ins Ungewisse 5:1 für die Rutsche und gegen die XOR-Interpretation.

Und der Clou daran ist, dass sich durch geschickte Wahl der XOR-Werte auch anderer Code zusammenbauen lässt. Etwa solcher, der die Adresse von VirtualProtect() im virtuellen Speicher ermittelt, den Speicherschutz deaktiviert und dann den zweiten Teil des Shellcodes anspringt. Mittlerweile gibt es dafür sogar Tutorials wie Writing JIT-Spray Shellcode for fun and profit.

Sprüht der Angreifer also via ActionScript ausreichend XOR-Befehle mit einer Tu-Nix-Rutsche und dem Shellcode in den Speicher, kann er anschließend einen Sprung ins Blaue wagen – etwa, indem er einen Fehler im Flash-Plugin oder dem Browser auslöst. Alternativ hat Blazakis auch gleich noch einen Weg aufgezeigt, wie man sich trotz ASLR in ActionScript die Adresse des Shellcodes besorgen kann. Da der angesprungene JIT-Code als ausführbar markiert ist, führt die CPU die Befehle klaglos aus – der Exploit ist gelungen.

Das alles heißt keineswegs, dass ASLR und DEP nutzlos wären. Sie bieten in vielen Fällen weiterhin guten Schutz vor dem Ausnutzen eventueller Sicherheitslücken. Es ist also durchaus eine gute Idee, sie wie im Artikel Schadensbegrenzer beschrieben, auch nachträglich via EMET zu aktivieren. Doch nachdem für eine Zeit lang mit den bei Windows Vista eingeführten Schutzmechanismen die Verteidiger die Oberhand hatten, ist mit JIT-Spraying wieder Bewegung in das Geschehen gekommen und das Hase-und-Igel-Rennen ist jetzt wieder in vollem Gange. Erste Ansätze, wie man JIT-Spraying erkennen und verhindern kann, wurden im Herbst 2010 veröffentlicht.

Literatur:

Dion Blazakis, Interpreter Exploitation: Pointer Inference and JIT Spraying (PDF) (ju)