Format Strings
Grundlegende Informationen
In C ist printf
eine Funktion, die verwendet werden kann, um einen String auszugeben. Der erste Parameter, den diese Funktion erwartet, ist der rohe Text mit den Formatierern. Die folgenden erwarteten Parameter sind die Werte, die die Formatierer des Rohtexts ersetzen sollen.
Andere anfällige Funktionen sind sprintf()
und fprintf()
.
Die Verwundbarkeit tritt auf, wenn ein Angreifertext als erster Argument an diese Funktion übergeben wird. Der Angreifer kann einen speziellen Eingabe missbrauchen, um die Fähigkeiten der printf-Formatzeichenfolge zu nutzen und beliebige Daten an beliebiger Adresse zu lesen und zu schreiben (lesbar/schreibbar). Auf diese Weise kann er beliebigen Code ausführen.
Formatierer:
Beispiele:
Verwundbares Beispiel:
Normale Verwendung:
Mit fehlenden Argumenten:
fprintf anfällig:
Zugriff auf Zeiger
Das Format %<n>$x
, wobei n
eine Zahl ist, ermöglicht es printf anzuweisen, den n-ten Parameter (vom Stack) auszuwählen. Wenn Sie also den vierten Parameter vom Stack mit printf lesen möchten, könnten Sie Folgendes tun:
und Sie würden vom ersten bis zum vierten Parameter lesen.
Oder Sie könnten Folgendes tun:
und lesen Sie direkt den vierten.
Beachten Sie, dass der Angreifer den pr
intf
-Parameter kontrolliert, was im Grunde bedeutet, dass seine Eingabe im Stapel liegt, wenn printf
aufgerufen wird, was bedeutet, dass er spezifische Speicheradressen im Stapel schreiben könnte.
Ein Angreifer, der diese Eingabe kontrolliert, kann beliebige Adressen im Stapel hinzufügen und printf
dazu bringen, darauf zuzugreifen. Im nächsten Abschnitt wird erläutert, wie dieses Verhalten genutzt werden kann.
Beliebiges Lesen
Es ist möglich, den Formatter %n$s
zu verwenden, um printf
die Adresse zu erhalten, die sich an der n-Position befindet, und sie dann zu drucken, als ob es ein String wäre (drucken, bis eine 0x00 gefunden wird). Wenn die Basisadresse der Binärdatei 0x8048000
ist und wir wissen, dass die Benutzereingabe an der 4. Position im Stapel beginnt, ist es möglich, den Anfang der Binärdatei mit zu drucken:
Beachten Sie, dass Sie die Adresse 0x8048000 nicht am Anfang der Eingabe platzieren können, da die Zeichenfolge am Ende dieser Adresse mit 0x00 abgeschnitten wird.
Offset finden
Um den Offset für Ihre Eingabe zu finden, könnten Sie 4 oder 8 Bytes (0x41414141
) senden, gefolgt von %1$x
und den Wert erhöhen, bis die A's
zurückgegeben werden.
Last updated