Sonntag, 18. April 2010


Topthema

Donnerstag, 19. März 2009 | Topthema

About Security #196: Schwachstellen-Suche: Pufferüberläufe finden

(Link zum Artikel: http://www.entwickler.de/entwicklerde/kolumnen/047892)

Thema dieser Folge ist die Suche nach Pufferüberlauf-Schwachstellen in Webanwendungen. Pufferüberläufe (Bufferoverflows) kommen nur in kompilierten Programmen vor, während Webanwendungen meist in interpretierten Skriptsprachen geschrieben werden. Aber auch dabei können kompilierte Programme zum Einsatz kommen, z.B. wenn eine vorhandene Anwendung um eine Weboberfläche erweitert wurde oder die Webanwendung auf externe Komponenten zugreift. Auch die webbasierten Administrationsoberflächen von Geräten wie z.B. Druckern, Routern oder Switches greifen oft auf kompilierte Anwendungen zurück. Außerdem gibt es, wenn auch selten, auch vollständige kompilierte Webanwendungen.

Sofern man damit rechnen kann bzw. es beim Test der eigenen Webanwendung mit Sicherheit weiss, dass kompilierte Bestandteile vorhanden sind, lohnen sich einige Tests. Verdächtig sind natürlich vor allen Ressourcen, deren Name z.B. .dll oder .exe enthält, oder Funktionen, die auf vorhandene externe Komponenten zurückgreifen.

Zuerst aber noch eine Warnung: Bei der Suche nach Pufferüberlauf-Schwachstellen ebenso wie bei der Suche nach Integerüberläufen und Formatstring-Schwachstellen, die in den kommenden Folgen beschrieben werden, besteht die Gefahr, einen Denial-of-Service auszulösen. Die entsprechenden Schwachstellen machen sich evtl. durch eine nicht behandelte Exception bemerkbar, mit anderen Worten: Die betroffene Komponente stürzt ab. Wird ein Produktivsystem getestet (wovon in diesem Fall dringend abzuraten ist), muss der Betreiber sich des Risikos bewusst und auf das Beheben des Denial-of-Service vorbereitet sein.

Pufferüberlauf-Schwachstellen im Überblick

Was ein Pufferüberlauf überhaupt ist und wie man ihn allgemein finden und verhindern kann, wurde bereits in About Security #5 ff am Beispiel des Stacküberlaufs beschrieben. Außer einen Überlauf im Stack gibt es weitere Pufferüberlauf-Schwachstellen:

Ein Heapüberlauf entspricht im wesentlichen einem Stacküberlauf, nur dass der Puffer im Heap, dem allgemein für Programme zur Verfügung stehenden Speicher, liegt. Beim Heapüberlauf werden keine Rücksprungadressen überschrieben, sondern andere Bereiche des Heaps. Der Heap ist eine doppelt verkettete Liste: Vor jedem Block befindet sich ein Kontrollbereich mit der Blockgröße, einem Pointer zum vorhergehenden Block und einem Pointer zum folgenden Block. Beim Überlauf wird dieser Kontrollbereich mit vom Angreifer kontrollierten Daten überschrieben. Das kann z.B. ausgenutzt werden, um Informationen einzuschleusen, die bei der späteren Freigabe des manipulierten Blocks durch den Verweis auf falsche Blöcke den Programmablauf manipulieren und eingeschleusten Code ausführen.

About Security: Die komplette Serie

Off-by-One-Schwachstellen sind ein spezieller Fall der Pufferüberlauf-Schwachstellen: Dabei wird nur ein einzelnes Byte (manchmal auch eine geringe Anzahl von Bytes) hinter das Ende des reservierten Puffers geschrieben. Derartige Schwachstellen kommen häufig vor, wenn beim Kopieren von Strings vergessen wird, das am Ende ein Nullbyte als Kennung für das Stringende angefügt wird. Auch mit diesem einen Byte, meist sogar "nur" einem Nullbyte, kann der Programmablauf manipuliert werden. Eine weitere mögliche Folge einer Off-by-One-Schwachstelle: In C wird das Stringende anhand eines Nullbytes erkannt. Geht das verloren, wird beim Lesen der gesamte Speicher bis zum nächsten Nullbyte als der gespeicherte String aufgefasst und dabei evtl. auf vertrauliche Daten zugegriffen und diese dann ausgegeben.

Sowohl Heapüberläufe als auch Off-by-One-Schwachstellen werden im Anschluss an die Suche nach Schwachstellen in Webanwendungen noch genauer beschrieben.

Pufferüberlauf-Schwachstellen finden

Eigentlich ist die Suche ganz einfach: Man muss nur für jeden verdächtigen Parameter einen überlangen Wert eingeben, der den vorhandenen Puffer zum Überlauf bringt, wenn er ungeprüft hineinkopiert wird. Meist werden für Puffergrößen runde Dezimal- oder Hexadezimalwerte verwendet, die für ausreichend gross für einen normalen Eingabewert plus evtl. einer Reserve gehalten werden. Typische Werte sind z.B. 32, 100, 256, 1024, 4096, ... Zeichen bzw. Bytes. Als erster Schritt werden daher Werte eingegeben, die etwas größer/länger als diese Werte sind. Um sich gar nicht erst mit den kleinen Werten aufzuhalten kann man gleich mit z.B. 1100 Zeichen beginnen, dann 4200 und 33000. Dabei wird ein Parameter nach dem anderen getestet, wobei ggf. andere Parameter auf gültige Werte gesetzt werden müssen, um den manipulierten Parameter möglichst lange bearbeiten zu lassen. Schließlich muss der evtl. mehrere Schritte durchlaufen, bis er an einen kompilierten Teil der Anwendung übergeben wird.

Nach jeder präparierten Eingabe wird die Ausgabe der Webanwendung auf auffällige Zeichen hin überprüft. Da der Pufferüberlauf meist erst gegen Ende der Verarbeitungskette erfolgt, wird eine Fehlermeldung des betroffenen Programms sehr wahrscheinlich von der Webanwendung intern ausgewertet und nicht unbedingt direkt ausgegeben.

Worauf Sie bei der Auswertung der Ausgaben achten müssen, erfahren Sie in der nächsten Folge, in der auch mögliche Gegenmaßnahmen gegen Angriffe über Pufferüberlauf-Schwachstellen beschrieben werden.

Wenn Sie Fragen oder Themenvorschläge haben, können Sie diese gerne an die angegebene E-Mail-Adresse senden oder im Security-Forum einbringen!

Carsten Eilers

Kommentare

Folgende Links könnten Sie auch interessieren