Off by one overflow
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Der Zugriff auf einen 1B Overflow ermöglicht es einem Angreifer, das size
-Feld des nächsten Chunks zu ändern. Dies ermöglicht es, zu manipulieren, welche Chunks tatsächlich freigegeben werden, was potenziell einen Chunk erzeugt, der einen anderen legitimen Chunk enthält. Die Ausnutzung ist ähnlich wie bei double free oder überlappenden Chunks.
Es gibt 2 Arten von Off-by-One-Sicherheitsanfälligkeiten:
Arbitrary byte: Diese Art erlaubt es, dieses Byte mit einem beliebigen Wert zu überschreiben.
Null byte (off-by-null): Diese Art erlaubt es, dieses Byte nur mit 0x00 zu überschreiben.
Ein häufiges Beispiel für diese Sicherheitsanfälligkeit kann im folgenden Code gesehen werden, wo das Verhalten von strlen
und strcpy
inkonsistent ist, was es ermöglicht, ein 0x00-Byte am Anfang des nächsten Chunks zu setzen.
Dies kann mit dem House of Einherjar ausgenutzt werden.
Wenn Tcache verwendet wird, kann dies zu einer double free Situation ausgenutzt werden.
Unter anderen Überprüfungen wird jetzt, wann immer ein Chunk freigegeben wird, die vorherige Größe mit der in den Metadaten des Chunks konfigurierten Größe verglichen, was diesen Angriff ab Version 2.28 recht komplex macht.
Dieser Angriff funktioniert nicht mehr aufgrund der Verwendung von Tcaches.
Darüber hinaus, wenn Sie versuchen, es mit größeren Chunks auszunutzen (so dass Tcaches nicht beteiligt sind), erhalten Sie den Fehler: malloc(): invalid next size (unsorted)
Einen Chunk in einen anderen Chunk einzufügen, sodass der Schreibzugriff auf diesen zweiten Chunk es ermöglicht, den enthaltenen zu überschreiben.
Off-by-one-Overflow, um die Größenmetadateninformationen zu ändern.
Drei Chunks A
, B
und C
(sagen wir Größen 0x20) zuweisen und einen weiteren, um die Konsolidierung mit dem Top-Chunk zu verhindern.
C
freigeben (in die 0x20 Tcache-Freiliste eingefügt).
Chunk A
verwenden, um auf B
zu überlaufen. Off-by-one ausnutzen, um das size
-Feld von B
von 0x21 auf 0x41 zu ändern.
Jetzt haben wir B
, das den freien Chunk C
enthält.
B
freigeben und einen 0x40 Chunk zuweisen (er wird hier wieder platziert).
Wir können den fd
-Zeiger von C
ändern, der immer noch frei ist (Tcache-Poisoning).
3 Chunks Speicher (a, b, c) werden nacheinander reserviert. Dann wird der mittlere freigegeben. Der erste enthält eine Off-by-One-Overflow-Schwachstelle, und der Angreifer nutzt dies mit einem 0x00 aus (wenn das vorherige Byte 0x10 war, würde es den mittleren Chunk anzeigen, dass er 0x10 kleiner ist, als er tatsächlich ist).
Dann werden 2 weitere kleinere Chunks im freigegebenen Chunk (b) zugewiesen, jedoch wird b + b->size
den Chunk c nie aktualisieren, da die angegebene Adresse kleiner ist, als sie sein sollte.
Dann werden b1 und c freigegeben. Da c - c->prev_size
immer noch auf b (jetzt b1) zeigt, werden beide in einem Chunk konsolidiert. b2 befindet sich jedoch immer noch zwischen b1 und c.
Schließlich wird ein neues malloc durchgeführt, das diesen Speicherbereich zurückgewinnt, der tatsächlich b2 enthalten wird, wodurch der Besitzer des neuen malloc den Inhalt von b2 kontrollieren kann.
Dieses Bild erklärt den Angriff perfekt:
Off-by-one aufgrund von strlen
, das das size
-Feld des nächsten Chunks berücksichtigt.
Tcache wird verwendet, sodass ein allgemeiner Off-by-One-Angriff funktioniert, um eine willkürliche Schreibprimitive mit Tcache-Poisoning zu erhalten.
Es ist möglich, einen Off-by-One auszunutzen, um eine Adresse aus dem Heap zu leaken, da das Byte 0x00 am Ende eines Strings vom nächsten Feld überschrieben wird.
Willkürliches Schreiben wird durch den Missbrauch des Off-by-One-Schreibens erreicht, um den Zeiger auf einen anderen Ort zu lenken, an dem eine gefälschte Struktur mit gefälschten Zeigern erstellt wird. Dann ist es möglich, dem Zeiger dieser Struktur zu folgen, um willkürlich zu schreiben.
Die libc-Adresse wird geleakt, weil, wenn der Heap mit mmap erweitert wird, der von mmap zugewiesene Speicher einen festen Offset von libc hat.
Schließlich wird das willkürliche Schreiben ausgenutzt, um in die Adresse von __free_hook mit einem One-Gadget zu schreiben.
Es gibt eine NULL Off-by-One-Schwachstelle in der Funktion getline
, die Benutzereingabezeilen liest. Diese Funktion wird verwendet, um den "Schlüssel" des Inhalts und nicht den Inhalt selbst zu lesen.
Im Writeup werden 5 anfängliche Chunks erstellt:
chunk1 (0x200)
chunk2 (0x50)
chunk5 (0x68)
chunk3 (0x1f8)
chunk4 (0xf0)
chunk defense (0x400), um die Konsolidierung mit dem Top-Chunk zu vermeiden.
Dann werden Chunk 1, 5 und 3 freigegeben, sodass:
[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]
[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]