Frage von xAnonym, 17

Was sind BufferOverflows?

was sind Buffer Overflows? Habe ich es richtig verstanden, dass das große Mengen an Daten sind, die in einem dafür kleineren Speicherbereich gespeichert werden und dadurch die Gefahr besteht, dass sie überschrieben werden können? Aber was hat das ganze damit zutun, dass es dadurch für Angreifer leichter ist? (Von-Neumann-Architektur)

Antwort
von TeeTier, 2

Also ich habe mir gerade mal folgendes kleine Beispiel aus den Fingern gesaugt, welches einen Pufferüberlauf auf dem Stack demonstriert (das findet man so ähnlich auch in vielen Lehrbüchern):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
int pass = 0;
char buf[8];

printf("Passwort: ");
fflush(stdout);

scanf("%s", buf);

if (strcmp(buf, "geheim") == 0) {
pass = 1;
}

printf("Zugang %s!\n", pass ? "OK" : "verweigert");

return EXIT_SUCCESS;
}

Hierbei wird ein Puffer mit einer Größe von nur 8 Byte angelegt, und anschließend nach dem Passwort gefragt, welches in eben diesen Puffer geschrieben wird. Danach wird der Pufferinhalt mit dem erwarteten Passwort verglichen, und bei einem Treffer eine Variable gesetzt. Später dann wird anhand dieser Variable entschieden, ob ein fiktiver Zugang gewährt wird, oder nicht.

Soweit die Theorie. In der Praxis ist der obige Code grauenhaft naiv, und vermutlich werden nur die wenigsten so einen Mist fabrizieren. :)

a) Der Passwort-Puffer ist viel zu klein, und wenn ich z. B. "123456789AB" eingebe, gibt es einen Pufferüberlauf (= Buffer-Overflow) und die dahinter liegende Integer-Variable, welche eigentlich gar nicht angefasst werden soll, enthält einen Wert, der nicht mehr 0 entspricht.

b) Beim Einlesen mit scanf wird keine Puffergröße angegeben, was unseren Überlauf erst so richtig möglich macht. Da die größe des Puffers unbekannt ist, nimmt die stupide scanf-Funktion einfach "unendlich" an, und schreibt die Benutzereingaben munter auch noch NACH dem eigentlichen Puffer direkt in den Speicher.

c) Die strcmp-Funktion vergleicht die Eingabe mit unserem hartkodierten Passwort und setzt die Integer-Variable auf einen Wert ungleich 0. Da wir den Puffer aber zum überlaufen gebracht haben, ist besagte Variable aber sowieso schon mit einem Nicht-Null-Wert gefüllt, also kann es uns egal sein, ob wir das richtige Passwort eingegeben haben, oder nicht.

Zum Schluss wird der Systemzugang nur durch printf demonstriert, und folgende Ein- bzw. Ausgaben sind möglich:

A) Ein falsches Passwort:

Passwort: abc123
Zugang verweigert!

B) Das richtige Passwort:

Passwort: geheim
Zugang OK!

C) Und schließlich ein Pufferüberlauf:

Passwort: 123456789abcd
Zugang OK!

Wie du siehst, erhalten wir dank des Pufferüberlaufes Zugriff, da der Puffer nur 8 Zeichen fasst, wir aber deutlich mehr eingeben, um darauf folgende Variablen zu überschreiben.

Aber Achtung: Diese Anfängerfehler bei Überläufen werden bei modernen Compilern durch sog. Stack-Canaries und andere Schutzmaßnahmen verhindert. Wie das genau funktioniert würde den Rahmen dieser Antwort hier sprengen, aber ich glaube das ist sogar in der Wikipedia ganz gut erklärt. Fakt ist, wenn du obiges Beispielprogramm erfolgreich kompilieren und testen willst, musst du dem Compiler sagen, dass er doch bitte schön etwaige Schutzmaßnahmen deaktivieren soll. Damit simulieren wir soz. einen älteren Compiler. Beim GCC macht man das so:

gcc -fno-stack-protector bo.c

Ohne die "no-stack-protector" Option, wird das Programm umgehend terminiert und man erhält folgende Fehlerausgabe (oder so ähnlich):

*** stack smashing detected ***: ./a.out terminated

Es gibt noch seeeehr viel mehr Typen von Pufferüberläufen, und anderen Möglichkeiten Bugs auszunutzen und entsprechende Gegenmaßnahmen. Aber alle kann man irgendwie umgehen, und es ist manchmal nur eine Frage der Zeit, bis man Fehler findet, die sich günstig ausnutzen lassen.

Wenn man jetzt z. B. dem Flashplayer auf einer Website eine manipulierte SWF-Datei unterschiebt, die beim Endbenutzer geladen und im Browser ausgeführt wird, kann man darüber (und eine Reihe benötigter weiterer Bugs) beliebigen Code auf dem System ausführen, um z. B. Trojaner nachzuladen und zu installieren.

Von daher sind Pufferüberläufe schon eine gemeine Sache.

Naja, ich hoffe als Einleitung reicht mein Beispiel aus. Wie gesagt, das ganze Thema ist so umfangreich, dass hier jede weitere Erklärung den Rahmen sprengen würde. :)

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten