Samstag, 1. Mai 2010


Topthema

Donnerstag, 9. April 2009 | Topthema

About Security #199: Schwachstellen-Suche: Formatstrings

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

Eine Formatstring-Schwachstelle entsteht, wenn Benutzereingaben ungeprüft und ungefiltert an bestimmte C-Funktionen wie z.B. printf() übergeben werden, die formatierten Text ausgeben können. Diese Funktionen akzeptieren eine unterschiedliche Anzahl von Parametern, die aus verschiedenen Datentypen wie Zahlen oder Strings bestehen können. Der gleichzeitig übergebene Formatstring spezifiziert, welche Daten in den Variablen enthalten sind und in welchem Format sie dargestellt werden sollen.

Ein Beispiel

Die folgende Codezeile gibt eine Meldung aus, die den als Dezimalzahl dargestellten Wert der Variable irgendwas enthält:

printf("Der Wert von irgendwas ist %d.\n", irgendwas);

Der gefährlichste Formatierungsbefehl ist %n: Er bewirkt keine Ausgabe der übergebenen Parameter, sondern führt dazu, das die Anzahl der bisher geschriebenen Bytes an die Adresse geschrieben wird, auf die der als Parameter übergebene Wert zeigt:

int irgendwas = 123;
int geschrieben = 0;

printf("Der Wert von irgendwas ist %d%n.\n", irgendwas, &geschrieben);
printf("%d Bytes wurden geschrieben.\n", geschrieben);

erzeugt folgende Ausgabe:

Der Wert von irgendwas ist 123.
30 Bytes wurden geschrieben.

Die betreffenden Funktionen können nicht erkennen, ob der Formatstring mehr Steuerbefehle enthält, als Parameter übergeben wurden. Es werden solange Parameter vom Stack geholt, bis der Formatstring abgearbeitet ist.

Kann ein Angreifer den Formatstring ganz oder teilweise manipulieren, kann er darüber Teile des Speichers überschreiben und eigenen Code einschleusen und ausführen: Er kann sowohl die Anzahl der von der Funktion ausgegebenen Bytes als auch den Pointer auf dem Stack, der mit dieser Anzahl überschrieben wird, frei wählen und dadurch z.B. eine Rücksprungadresse oder den Pointer zu einem Exception-Handler überschreiben. Der Effekt ist vergleichbar mit einem stackbasierten Pufferüberlauf, siehe About Security #5 ff.

Formatstring-Schwachstellen finden

Bei der Suche nach Formatstring-Schwachstellen wird für alle in Frage kommenden Parameter, d.h. die, die evtl. an ein externes Programm weitergeleitet werden, eine Reihe von Testwerten mit Formatstrings übergeben und danach die Webanwendung auf unnormales Verhalten überwacht. Wie im Fall von Pufferüberlauf-Schwachstellen wird sich auch hier eine Schwachstelle meist durch einen Absturz des betroffenen Programms zu erkennen geben.

Testwerte

Für jeden Parameter wird eine große Anzahl der Formatierungsbefehle %n und %s eingegeben:

%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n%n
%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s

Da die Windows-Funktion FormatMessage die Steuerbefehle anders als die printf-Funktionen verwendet, müssen dafür auch die Testwerte angepasst werden:

%1!n!%2!n!%3!n!%4!n!%5!n!%6!n!%7!n!%8!n!%9!n!%10!n!  usw.
%1!s!%2!s!%3!s!%4!s!%5!s!%6!s!%7!s!%8!s!%9!s!%10!s!  usw.

Ggf. muss das %-Zeichen URL-kodiert als %25 übertragen werden.

%s wird als zusätzlicher Testwert verwendet, da in manchen Fällen %n aus Sicherheitsgründen ignoriert wird. %s führt dazu, das die betroffene Funktion jeden Parameter vom Stack dereferenziert. Enthält das Programm eine Formatstring-Schwachstelle, führt das sehr wahrscheinlich zu einem Zugriffsfehler.

Nach jeder Eingabe wird die Ausgabe der Webanwendung wie bei der Suche nach Pufferüberlauf-Schwachstellen auf ungewöhnliche Reaktionen überprüft, siehe About Security #197.

Formatstring-Schwachstellen verhindern
About Security: Alle Folgen

Formatstring-Schwachstellen können vermieden werden, indem Formatierungsbefehle aus den Eingaben ausgefiltert und die betroffenen Funktionen mit gesetzten Formatierungsbefehlen aufgerufen werden. Ein Aufruf von z.B. printf(puffer) führt dazu, das die Variable puffer als String mit Formatierungsbefehlen interpretiert wird. Ein Aufruf von z.B. printf("%s", puffer) hingegen führt zur Ausgabe des Puffers, da der Formatierungsbefehl bereits angegeben wurde.

Allgemeine Bemerkungen

Zum Abschluss noch einige allgemeine Bemerkungen zu Pufferüberlauf-, Integer- und Formatstring-Schwachstellen in Webanwendungen. Diese Schwachstellen treten in den in interpretierten Sprachen wie z.B. PHP geschriebenen Webanwendungen nicht auf. Wenn bekannt ist, das keine externen Programme aufgerufen werden, kann man daher auf die Suche nach ihnen verzichten.

Da es bei der Suche nach diesen Schwachstellen sehr wahrscheinlich zu Abstürzen und damit einem Denial-of-Service kommt, wird man entsprechende Tests i.d.R. auf einem Testsystem durchführen. Wenn man weiß, wie die möglicherweise betroffenen externen Programme aufgerufen werden, kann man diese auch separat testen und dabei z.B. auf die in About Security #10 beschriebenen Hilfsmittel zur Suche nach Pufferüberlauf-Schwachstellen zurückgreifen.

Hiermit ist die Suche nach Schwachstellen in kompilierten Programmen abgeschlossen. In der nächsten Woche erscheint die 200. nummerierte Folge von About Security mit einer Zusammenfassung der Entwicklungen in den vergangenen 4 Jahren. Mit der Schwachstellensuche in Webanwendungen geht es in About Security #201 weiter, dann geht es um Angriffe auf die Anwendungsarchitektur.

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

About Security - Übersicht zum aktuellen Thema:

(rl)

Kommentare

Folgende Links könnten Sie auch interessieren