Die Hacker-Bibel

Buffer-Overflow – So funktioniert ein Pufferüberlauf

Samstag den 28.04.2012 um 07:41 Uhr

von Thorsten Eggeling

Die Ausnutzung von Buffer-Overflows gehört zu den häufigsten Angriffsmethoden, mit denen Kriminelle versuchen, Schadsoftware auf PCs unterzubringen. Buffer-Overflows sind die allgemeine Form einer größeren Gruppe von Schwachstellen, die je nach konkreter Verwundbarkeit als Heap-Overflow, Stack-Overflow, Integer-Overflow oder String-Overflow bezeichnet werden.
Wenn ein Programm abstürzt, ist dafür häufig ein
Buffer-Overflow (Pufferüberlauf) verantwortlich. Der Fehler lässt
sich auch für Hacker-Angriffe ausnutzen.
Vergrößern Wenn ein Programm abstürzt, ist dafür häufig ein Buffer-Overflow (Pufferüberlauf) verantwortlich. Der Fehler lässt sich auch für Hacker-Angriffe ausnutzen.

Vereinfacht ausgedrückt geht es bei diesen Fehlern immer darum, ein Programm mit mehr Daten zu füttern, als es erwartet oder verarbeiten kann. Der eigentlich vorgesehene Speicherbereich reicht nicht für die Daten aus und daher wird der nachfolgende Speicherbereich überschrieben. Das führt in vielen Fällen zum Absturz des Programms und das Betriebssystem zeigt eine Fehlermeldung. Unter Windows 7 sehen Sie beispielsweise „Programm.exe funktioniert nicht mehr“, Linux zeigt „Segmentation fault“ oder Ähnliches. Für den Buffer-Overflow ist in jedem Fall der Programmierer verantwortlich, der die Dateneingabe beziehungsweise die Länge der Daten nicht ausreichend geprüft hat.

Was passiert beim Buffer-Overflow

Der Programmabsturz ist zwar ärgerlich, aber an sich nicht gefährlich. Die Gefahr für den PC entsteht erst, wenn über manipulierte Daten, etwa in einem Word-Dokument, einer PDF- oder SWF-Datei, zusätzlicher Programmcode gestartet wird.

Der Stack lässt sich durch lokale Variablen überschreiben.
Dabei kann auch die Rücksprungadresse geändert werden.
Vergrößern Der Stack lässt sich durch lokale Variablen überschreiben. Dabei kann auch die Rücksprungadresse geändert werden.

Um zu verstehen, wie das genau funktioniert, muss man sich die Speicherverwaltung etwas genauer ansehen. Wenn ein Programm gestartet wird, weist ihm das Betriebssystem einen bestimmten Speicherbereich zu. In einem Teil davon liegt der eigentliche Programmcode. Dieser ist geschützt und kann nicht geändert werden. Darüber liegt der Heap , in dem das System globale Variablen und Konstanten ablegt. Dann folgt der Stack , der lokale Variablen und den Inhalt von Prozessorregistern aufnehmen kann. Im Stack liegen auch die Rücksprung-Adressen von Unterprogrammen, also von Verzweigungen im Hauptprogramm. Beim Buffer-Overflow wird eine lokale Variable mit mehr Inhalt gefüllt, als für Sie reserviert ist. Dadurch kann der Stack und damit die Rücksprungadresse überschrieben werden. Wenn die Rücksprungadresse ungültig ist, kommt es zum Programmabsturz. Der Trick der Hacker besteht jetzt darin, die Rücksprungadresse auf Programmsegmente zu lenken, die den eigentlichen Schadcode enthalten.

Praktisches Beispiel für einen Buffer-Overflow

Wer selbst ausprobieren möchte, wie ein Pufferüberlauf funktioniert, benötigt dazu einen C++-Compiler und Perl. Für erste Ausflüge in die Programmierung empfiehlt sich das kostenlose Visual C++ 2010 Express von Microsoft. Zusätzlich ist noch das ebenfalls kostenlose Perl erforderlich. Alternativ können Sie sich die Open-Source-Entwicklungsumgebung MinGW . Im Komplettpaket ist Perl bereits enthalten.

Sie können das kostenlose Visual C++ 2010 Express
verwenden, um das Beispielprogramm zu erstellen.
Vergrößern Sie können das kostenlose Visual C++ 2010 Express verwenden, um das Beispielprogramm zu erstellen.

Wenn Sie sich die Entwicklungsumgebungen nicht installieren möchten, können Sie die fertigen Programme auch herunterladen . Diese enthalten natürlich keinen Schadcode, sondern demonstrieren nur - in einer stark vereinfachten Variante - wie ein Pufferüberlauf funktioniert. Den kompletten Quellcode können Sie als Visual C++ 2010-Projekt herunterladen .

Der Quellcode des Beispielprogramms sieht so aus (Auszüge):

int copy(char* input) {

char var[20];

strcpy (var, input);

return 0; }

int hacked(void) {

printf("Hier koennte der Schadcode gestartet werden!\n");

exit(0); }

int main(int argc, char* argv[]) {

printf("Adresse der Funktion: 0x%08x\n", hacked);

copy(argv[1]);

return 0; }

Beim Start gibt das Programm die Rücksprung-Adresse der Funktion „hacked“ aus (im Beispiel „0x00411181“). Dann wird eine auf der Kommandozeile übergebene Zeichenkette über die Funktion „copy“ in die Variable „var“ kopiert. Wenn die Anzahl der Zeichen großer ist als der reservierte Puffer („char var[20]), stürzt das Programm ab. Die Funktion „hacked“ wird im Programm selbst nie aufgerufen. Um den Code zu aktivieren, sind drei Zeilen Perl-Code nötig:

$arg = "AAAAABBBBBCCCCCDDDDDEEEE"."\x81\x11\x41";

$cmd = "./Buf_Test.exe ".$arg;

system($cmd);

Das Beispielprogramm liefert die Einsprungadresse einer
Programmfunktion. Mit einem Perl-Script lässt sich das
Unterprogramm gezielt starten.
Vergrößern Das Beispielprogramm liefert die Einsprungadresse einer Programmfunktion. Mit einem Perl-Script lässt sich das Unterprogramm gezielt starten.

Das Script übergibt eine Anzahl Zeichen und dahinter eine neue Rücksprung-Adresse. Dieser verweist genau auf die Funktion „hacked“. Das Programm gibt daher „Hier koennte der Schadcode gestartet werden!“ aus.

In der Praxis lässt sich ein Buffer-Overflow so einfach natürlich nicht ausnutzen. Da dem Hacker der Quellcode in der Regel nicht vorliegt, kann es nur selten passende Funktionen im Programm selbst verwenden. Stattdessen kommen Funktionen aus Windows-Programmbibliotheken zum Einsatz. Diese können allerdings bei jeder Variante eines Betriebssystems unterschiedlich sein und müssen daher immer speziell angepasst werden. Der Aufruf der Funktionen erfolgt über Shellcodes. Das sind Assembler-Befehle, die beim Pufferüberlauf im Speicher abgelegt werden. Beispiele für Shellcodes finden Sie beispielweise auf Shell-Storm.org .

Mittel gegen Pufferüberläufen

Wenn Sie den Beispiel-Quellcode in ein frisches Visual C++ 2010-Projekt kopieren und eine neue EXE-Datei erstellen, funktioniert der Hack nicht ohne weiteres. Das liegt daran, dass moderne Compiler den Programmierer automatisch vor groben Programmierfehlern schützen. Schon beim compilieren erhalten Sie die Warnmeldung, dass „strcpy“ unsicher ist und stattdessen „strcpy_s“ verwendet werden sollte. Aber selbst wenn Sie diese Warnung ignorieren, ist das erzeugte Programm nicht angreifbar. Visual C++ 2010 erzeugt standardmäßig Programme, bei denen "Address space layout randomization" (ASLR), "Data Execution Prevention" (DEP), Puffersicherheitsüberprüfung (Schalter /GS) und die vollständige Laufzeitüberprüfung (Schalter /RTC1) aktiviert ist. Mit ASLR beispielsweise ändert sich die Adresse der Funktion „hacked“ im Beispielprogramm bei jedem Start. Damit ist es nicht mehr ohne weiteres möglich, die Funktion über das Perl-Script aufzurufen. Außerdem verhindert der Compiler-Schalter /GS, dass ein Buffer-Overflow auftritt und dank /RTC1 wird die Ausführung des Programms abgebrochen, wenn ein Fehler entsteht.

Die „Puffersicherheitsüberprüfung“ (/GS) verhindert in
standardmäßig Buffer-Overflows bei mit Visual C++ 2010 erstellten
Programmen.
Vergrößern Die „Puffersicherheitsüberprüfung“ (/GS) verhindert in standardmäßig Buffer-Overflows bei mit Visual C++ 2010 erstellten Programmen.

Bei dieser Menge an Sicherungen ist es eigentlich verwunderlich, dass Buffer-Overflows immer noch zu den häufigsten Software-Fehlern gehören. Aber nicht alle Programme werden mit modernen Compilern erstellt, denn für die Programmierer ist es oft mit einem großen Aufwand verbunden, ihre Projekte an neue Entwicklungsumgebungen anzupassen. Außerdem schützen auch ASLR & Co nicht vollständig vor Programmierfehlern. Hacker haben aber bereits einige Methoden gefunden, mit denen sich auch diese Schutzmechanismen umgehen lassen.

So können Sie sich schützen

Vor Buffer-Overflows kann Sie nur der Hersteller der Software wirkungsvoll schützen. Sie müssen darauf hoffen, dass die Hersteller die Fehler schneller finden als die Hacker. Den besten Schutz für den PC gewährleisten auf jeden Fall regelmäßige Updates.

Ebenfalls sinnvoll: Verwenden Sie wann immer möglich alternative Software, etwa Foxit Reader statt Adobe Reader oder Google Chrome   statt Firefox. Diese Programme haben zwar nicht weniger Fehler und sind auch nicht sicherer, aber es gibt aufgrund der zurzeit geringeren Verbreitung kaum ein Interesse der Hacker, Schadsoftware dafür zu entwickeln.

Wenn es für Programme keine Updates mehr gibt und Sie Sicherheitslücken darin vermuten, gibt es noch eine weitere Möglichkeit. Mit dem kostenlosen Microsoft Tool Emet (Enhanced Mitigation Experience Toolkit ) lassen sich Programme auch nachträglich absichern. Weitere Infos zu EMET finden Sie im Artikel „ So wehren Sie Hacker-Angriffe besser ab “.

Samstag den 28.04.2012 um 07:41 Uhr

von Thorsten Eggeling

Kommentieren Kommentare zu diesem Artikel (0)
1352602