Skip to content

Schutzmaßnahmen: Weitere Angriffe trotz ASLR

Eine der ersten beiden Schutzmaßnahmen gegen Angriffe auf Pufferüberlauf-Schwachstellen ist die Data Execution Prevention (DEP). Da sie sich umgehen lässt, reicht sie als alleiniger Schutz nicht aus. Zusätzlichen Schutz bietet die Adress Space Layout Randomization (ASLR), aber auch diese Schutzmaßnahme lässt sich natürlich umgehen. Bereits beschrieben wurden Angriffe über Heapspraying mit Java und der Missbrauch der DLLs des Flash Players.

Weitere Angriffe trotz ASLR

Alexander Sotirov und Mark Dowd haben auf der Sicherheitskonferenz Black Hat USA 2008 weitere Möglichkeiten zum Umgehen von ASLR beschrieben ("How To Impress Girls With Browser Memory Protection Bypasses"):

JavaScript gegen ASLR

Mit JavaScript konnten Alexander Sotirov und Mark Dowd ASLR unter dem damals aktuellen Windows Vista umgehen. Mittels Heap Spraying wurden 100 MB des Heap des Internet Explorers mit Shellcode gefüllt. Dazu wurde mit JavaScript-Code 1 MB große Strings im Speicher verteilt. Der Speicher wird in 64KB-Blöcken reserviert, der eingeschleuste Code beginnt mit einem Offset von 36 Byte. Indem der Shellcode sich alle 64 KB im String wiederholt, wird sicher gestellt, dass jede Heapadresse, die mit 0x0024 endet, sehr wahrscheinlich den Shellcode enthält.

Die Heap-Randomization von Vista verschiebt den Anfang des Heaps um bis zu 2 MB, danach wird der Speicher aber der Reihe nach reserviert. Trotz ASLR landet der meiste Shellcode also auf jedem System im gleichen Speicherbereich. Über eine Pufferüberlauf-Schwachstelle wurde dann die Rücksprungadresse mit einem Wert überschrieben, der wie oben angegeben auf 0x0024 endet und in der Mitte des Bereichs liegt, in dem der über Heap Spraying verteilte Shellcode liegt. Es ist sehr wahrscheinlich, dass sich an dieser Adresse Shellcode befindet, und der Exploit war in der Tat sehr zuverlässig.

Die DEP lässt sich so nicht umgehen, da bei aktivierter DEP der Heap-Speicher nicht als ausführbar markiert ist, der Shellcode also nicht ausgeführt würde.

Weitere Spraying-Angriffe

Heap Spraying wird, wie bereits beschrieben, dazu verwendet, Shellcode auf den Heap zu verteilen, der dann mit mehr oder weniger großer Wahrscheinlichkeit zuverlässig angesprungen werden kann. Spraying kann aber auch in anderen Situationen helfen, um Schutzfunktionen zu umgehen.

Der Angreifer kann zum Beispiel den Stack mit Adressen füllen, so dass er nicht eine bestimmte Stelle auf den Stack anspringen muss, sondern nur eine ungefähr bekannte. Dazu kann zum Beispiel eine Funktion ohne lokale Variablen und Parametern rekursiv aufgerufen werden, bei jedem Aufruf wird der Stack dann mit der zugehörigen Rücksprungadresse gefüllt. Zumindest in der Theorie erfolgt das in einem großen Block, in den dann beliebig gesprungen werden kann. In der Praxis werden im Allgemeinen weitere Daten auf dem Stack gespeichert, was beim Anspringen natürlich berücksichtigt werden muss.

Ebenso ist es möglich, Shellcode auf den Stack zu sprayen. Dazu wird dann zum Beispiel eine Funktion rekursiv aufgerufen, die den Shellcode als lokale Variable(n) auf dem Stack ablegt. Bei aktivierter DEP ist so ein Angriff ebenso wie Heap Spraying zwecklos, da der eingeschleuste Code nicht ausgeführt würde.

Interessanter ist es dann, den Stack mit Pointern zu füllen, die zum Beispiel auf den Shellcode verweisen. Erledigt wird das wieder über eine rekursive Funktion, die die entsprechenden Daten als lokale Variablen oder Parameter verwendet.

Alle Spraying-Techniken liegt die Annahme zu Grunde, dass die Wahrscheinlichkeit, das Ziel zu treffen, steigt, wenn es mehr mögliche Ziele gibt. Sinngemäß ist dann zum Beispiel der Heap nach einem Heap Spraying das sprichwörtliche Scheunentor, dass man kaum verfehlen kann. Wo genau das Scheunentor dann getroffen wird, ist egal. OK, im Fall eines Exploits sollte schon der Anfang des Shellcodes oder die meist davor abgelegten NOP-Befehle getroffen werden, aber das Prinzip ist das gleiche. Vielleicht sollte man es besser mit den Treffen eines Bretts des Scheunentores vergleichen: Ein ganz bestimmtes Brett im Scheunentor zu treffen ist schwieriger als überhaupt irgend ein Brett zu treffen. Entsprechend ist es einfacher, einen von vielen Shellcode-Blöcken im Heap zu treffen als den einzigen bei einem Angriff ohne Spraying.

Angriffe abwehren

Die vorgestellten Beispiele zeigen: Es gibt immer einen Weg, ASLR zu umgehen. Manche Angriffe lassen sich zur Änderungen an der ASLR abwehren, manche nur weiter erschweren. Aber das ist kein Grund, auf die Schutzmaßnahmen zu verzichten, denn die "Mitigations" sollen ja Angriffe gar nicht komplett verhindern, sondern nur so weit wie möglich erschweren. Für die Cyberkriminellen sind Exploits nur dann interessant, wenn sie zumindest halbwegs zuverlässig funktionieren. Unzuverlässige Exploits, die womöglich noch zu Abstürzen führen, könnten die Angriffe vorzeitig verraten. Und darauf legen die Cyberkriminellen natürlich keinen Wert.

In der nächsten Folge geht es um weitere Schutzmaßnahmen gegen Angriffe auf/über Pufferüberlauf-Schwachstellen.

Carsten Eilers


Übersicht über alle Artikel zum Thema

Schutzmaßnahmen: Content Security Policy gegen XSS, Teil 1
Schutzmaßnahmen: Content Security Policy gegen XSS, Teil 2
Schutzmaßnahmen: Content Security Policy gegen XSS, Teil 3
Schutzmaßnahmen: Content Security Policy gegen XSS, Teil 4
Schutzmaßnahmen: Der Pufferüberlauf im Überblick
Schutzmaßnahmen: Canary und DEP gegen Pufferüberlauf-Schwachstellen
Schutzmaßnahmen: ASLR gegen Pufferüberlauf-Schwachstellen
Schutzmaßnahmen: ASLR kann unterlaufen werden
Schutzmaßnahmen: Weitere Angriffe trotz ASLR

Trackbacks

Dipl.-Inform. Carsten Eilers am : Drucksache: Windows Developer 7.16 - Alles im Fluss?

Vorschau anzeigen
Im windows.developer 7.16 ist ein Artikel über Angriffe auf den Kontrollfluss von .NET-Anwendungen erschienen. Das alte Wettrennen zwischen Angreifern auf und Verteidigern von Windows-Rechnern geht in eine neue Runde: Auf der DEF CON 2