Exploits entmystifiziert, Teil 2 Einen Stack-basierten Pufferüberlauf provozieren

Autor / Redakteur: Thorsten Henning* / Stephan Augsten

Das Ausnutzen von Speicherfehlern ist ein gängiger Weg für einen Schwachstellen-Exploit. Doch wie werden Speicherbereiche überschrieben und Speicherabfragen auf genau diese Bereiche umgebogen? Dies wollen wir uns am Beispiel stapelbasierter Pufferüberlauf-Schwachstellen genauer ansehen.

Anbieter zum Thema

Der stapelbasierte Pufferüberlauf ist einer der Klassiker, wenn es um Schwachstellen-Exploits geht.
Der stapelbasierte Pufferüberlauf ist einer der Klassiker, wenn es um Schwachstellen-Exploits geht.
(Bild: Archiv)

Im ersten Teil dieser Serie haben wir die Grundlagen der Ausnutzung von Speicherfehlern behandelt. Der Exploitation-Prozess setzt sich somit aus den folgenden Teilen zusammen:

  • Überschreiben einer Adresse im Prozess-Speicherraum
  • Umleiten der Ausführungsabfolge zur Shellcode-Adresse
  • Ausführen des Shellcodes

Im Folgenden geht es um die eigentliche Umsetzung des Überschreibens und Umleitens. In seiner einfachsten Form wird der Speicherplatz in den Bereich des ausführbaren (Executable) Codes und den Datenbereich unterteilt.

Der Executable-Bereich enthält sowohl einzigartigen Code des Programms als auch DLLs (Dynamic Link Libraries; Dynamische Programmbibliotheken), die das Betriebssystem für alle Prozesse bereitstellt. Der Datenbereich enthält, wie der Name schon sagt, die Daten, auf dem der Code arbeitet.

Der Datenbereich besteht aus dem Stack (Stapel) und dem Heap (Haufen), was im Folgenden noch näher beschrieben werden soll. Der Angreifer interessiert sich für eben diesen Datenbereich, da der Shellcode in das eingebettet ist, was hier hinein geladen werden soll. Das heißt, sobald die Datei mit dem Shellcode ausgeführt wird, befindet sich der Shellcode entweder in einem Stack oder in einem Heap.

Herausforderung und Lösung aus Angreifer-Perspektive

Aus der Sicht des Angreifers ist es erforderlich, den Shellcode in den Datenbereich zu injizieren. Die Rolle des Shellcodes ist es, ausgeführt zu werden und eine Verbindung zwischen dem Angreifer und dem Zielcomputer zu öffnen. Dies ist die grundlegende Herausforderung bei einem Exploit:

  • 1. Der Shellcode wird standardmäßig in den Datenbereich geladen.
  • 2. Der Shellcode muss ausgeführt werden.
  • 3. Dadurch dass er im Datenbereich residiert, können die „besetzten“ Speicheradressen nie zur Ausführung von der CPU abgerufen werden.

Hauptziel des Angreifers ist es, die CPU so zu manipulieren, dass Inhalte von Speicheradressen ausgeführt werden, die unter normalen Umständen nicht ausgeführt würden. An dieser Stelle kommen Schwachstellen ins Spiel.

Was es genau bedeutet, wenn man davon spricht, dass eine Anwendung eine Sicherheitslücke oder Schwachstelle enthält? Damit ist gemeint, dass eine in Handarbeit erstellte Eingabedatei den Ausführungsfluss von seinem vorbezeichneten Kurs ablenkt. In anderen Worten, die CPU wird abgeholt zu einer Adresse, die sie nicht empfangen sollte.

Das alles gilt es nun, zu verbinden: Der Angreifer hat es geschafft, einen Shellcode im Datenbereich des Prozessspeichers einzufügen. Jetzt sucht er nach einer Möglichkeit, den Shellcode ausgeführt zu bekommen. Um das zu erreichen, wird der Angreifer die Datei so anpassen, dass die abgelenkte Adresse eine Anleitung enthält, in die Shellcode-Adresse zu springen. Nun empfängt die CPU eine Adresse, die ausführbaren Code enthält, und wird den Anweisungen folgen, zur Shellcode-Adresse springen und diese ausführen.

(ID:43793086)