Unsorted Bin Attack
Last updated
Last updated
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Für weitere Informationen darüber, was ein unsortierter Bin ist, siehe diese Seite:
Bins & Memory AllocationsUnsortierte Listen können die Adresse von unsorted_chunks (av)
in der bk
-Adresse des Chunks schreiben. Daher, wenn ein Angreifer die Adresse des bk
-Zeigers in einem Chunk innerhalb des unsortierten Bins modifizieren kann, könnte er in der Lage sein, diese Adresse an einer beliebigen Adresse zu schreiben, was hilfreich sein könnte, um Glibc-Adressen zu leaken oder einige Abwehrmaßnahmen zu umgehen.
Im Grunde ermöglicht dieser Angriff, eine große Zahl an einer beliebigen Adresse zu setzen. Diese große Zahl ist eine Adresse, die eine Heap-Adresse oder eine Glibc-Adresse sein könnte. Ein typisches Ziel ist global_max_fast
, um die Erstellung von Fast-Bin-Bins mit größeren Größen zu ermöglichen (und von einem unsortierten Bin-Angriff zu einem Fast-Bin-Angriff überzugehen).
Ein Blick auf das Beispiel, das in https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle bereitgestellt wird, und die Verwendung von 0x4000 und 0x5000 anstelle von 0x400 und 0x500 als Chunk-Größen (um Tcache zu vermeiden), zeigt, dass heutzutage der Fehler malloc(): unsorted double linked list corrupted
ausgelöst wird.
Daher erfordert dieser unsortierte Bin-Angriff jetzt (neben anderen Überprüfungen) auch die Fähigkeit, die doppelt verkettete Liste zu reparieren, sodass dies victim->bk->fd == victim
oder nicht victim->fd == av (arena)
umgangen wird, was bedeutet, dass die Adresse, an die wir schreiben möchten, die Adresse des gefälschten Chunks in seiner fd
-Position haben muss und dass der gefälschte Chunk fd
auf die Arena zeigt.
Beachte, dass dieser Angriff den unsortierten Bin (und damit auch kleine und große) beschädigt. Daher können wir jetzt nur Allokationen aus dem Fast Bin verwenden (ein komplexeres Programm könnte andere Allokationen durchführen und abstürzen), und um dies auszulösen, müssen wir die gleiche Größe allokieren, oder das Programm wird abstürzen.
Beachte, dass das Überschreiben von global_max_fast
in diesem Fall helfen könnte, in der Annahme, dass der Fast Bin in der Lage sein wird, sich um alle anderen Allokationen zu kümmern, bis der Exploit abgeschlossen ist.
Der Code von guyinatuxedo erklärt es sehr gut, obwohl du, wenn du die Mallocs änderst, um genügend Speicher zu allokieren, sodass du nicht in einem Tcache landest, sehen kannst, dass der zuvor erwähnte Fehler erscheint, der diese Technik verhindert: malloc(): unsorted double linked list corrupted
Dies ist tatsächlich ein sehr grundlegendes Konzept. Die Chunks im unsortierten Bin werden Zeiger haben. Der erste Chunk im unsortierten Bin wird tatsächlich die fd
- und bk
-Links auf einen Teil der Hauptarena (Glibc) zeigen.
Daher, wenn du einen Chunk in einen unsortierten Bin legen und ihn lesen (use after free) oder ihn erneut allokieren kannst, ohne mindestens 1 der Zeiger zu überschreiben, um ihn dann zu lesen, kannst du einen Glibc-Infoleak erhalten.
Ein ähnlicher Angriff, der in diesem Bericht verwendet wurde, bestand darin, eine Struktur mit 4 Chunks (A, B, C und D - D dient nur dazu, die Konsolidierung mit dem Top-Chunk zu verhindern) auszunutzen, sodass ein Null-Byte-Overflow in B verwendet wurde, um C anzuzeigen, dass B ungenutzt war. Außerdem wurde in B die prev_size
-Daten geändert, sodass die Größe anstelle der Größe von B A+B war.
Dann wurde C freigegeben und mit A+B konsolidiert (aber B war weiterhin in Gebrauch). Ein neuer Chunk der Größe A wurde allokiert und dann wurden die geleakten Adressen der libc in B geschrieben, von wo sie geleakt wurden.
Das Ziel ist es, eine globale Variable mit einem Wert größer als 4869 zu überschreiben, sodass es möglich ist, die Flagge zu erhalten und PIE nicht aktiviert ist.
Es ist möglich, Chunks beliebiger Größen zu generieren, und es gibt einen Heap-Overflow mit der gewünschten Größe.
Der Angriff beginnt mit der Erstellung von 3 Chunks: chunk0, um den Overflow auszunutzen, chunk1, um überflutet zu werden, und chunk2, damit der Top-Chunk die vorherigen nicht konsolidiert.
Dann wird chunk1 freigegeben und chunk0 wird überflutet, sodass der bk
-Zeiger von chunk1 auf zeigt: bk = magic - 0x10
Dann wird chunk3 mit der gleichen Größe wie chunk1 allokiert, was den unsortierten Bin-Angriff auslöst und den Wert der globalen Variable ändert, wodurch es möglich wird, die Flagge zu erhalten.
Die Merge-Funktion ist anfällig, weil, wenn beide übergebenen Indizes gleich sind, sie darauf realloc und dann freigeben wird, aber einen Zeiger auf diesen freigegebenen Bereich zurückgibt, der verwendet werden kann.
Daher werden 2 Chunks erstellt: chunk0, das mit sich selbst zusammengeführt wird, und chunk1, um die Konsolidierung mit dem Top-Chunk zu verhindern. Dann wird die Merge-Funktion mit chunk0 zweimal aufgerufen, was zu einem Use-After-Free führt.
Dann wird die view
-Funktion mit Index 2 (der Index des Use-After-Free-Chunks) aufgerufen, was einen libc-Adresse leak auslösen wird.
Da die Binärdatei Schutzmaßnahmen hat, um nur Malloc-Größen größer als global_max_fast
zuzulassen, wird ein unsortierter Bin-Angriff verwendet, um die globale Variable global_max_fast
zu überschreiben.
Dann ist es möglich, die Edit-Funktion mit Index 2 (dem Use-After-Free-Zeiger) aufzurufen und den bk
-Zeiger so zu überschreiben, dass er auf p64(global_max_fast-0x10)
zeigt. Dann wird ein neuer Chunk erstellt, der die zuvor kompromittierte freigegebene Adresse (0x20) verwendet, was den unsortierten Bin-Angriff auslöst, der global_max_fast
überschreibt, was einen sehr großen Wert hat, sodass jetzt Chunks in Fast-Bins erstellt werden können.
Jetzt wird ein Fast Bin-Angriff durchgeführt:
Zunächst wird entdeckt, dass es möglich ist, mit schnellen Chunks der Größe 200 im __free_hook
-Bereich zu arbeiten:
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook> gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200
0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
Wenn es uns gelingt, einen schnellen Chunk der Größe 0x200 an dieser Stelle zu erhalten, wird es möglich sein, einen Funktionszeiger zu überschreiben, der ausgeführt wird.
Dazu wird ein neuer Chunk der Größe 0xfc
erstellt und die Merge-Funktion wird mit diesem Zeiger zweimal aufgerufen, sodass wir einen Zeiger auf einen freigegebenen Chunk der Größe 0xfc*2 = 0x1f8
im Fast Bin erhalten.
Dann wird die Edit-Funktion in diesem Chunk aufgerufen, um die fd
-Adresse dieses Fast Bins so zu ändern, dass sie auf die vorherige __free_hook
-Funktion zeigt.
Dann wird ein Chunk der Größe 0x1f8
erstellt, um den vorherigen nutzlosen Chunk aus dem Fast Bin abzurufen, sodass ein weiterer Chunk der Größe 0x1f8
erstellt wird, um einen Fast Bin-Chunk im __free_hook
zu erhalten, der mit der Adresse der system
-Funktion überschrieben wird.
Und schließlich wird ein Chunk, der den String /bin/sh\x00
enthält, freigegeben, indem die Delete-Funktion aufgerufen wird, was die __free_hook
-Funktion auslöst, die auf system mit /bin/sh\x00
als Parameter zeigt.
Ein weiteres Beispiel für den Missbrauch eines 1B-Overflows, um Chunks im unsortierten Bin zu konsolidieren und einen libc-Infoleak zu erhalten und dann einen Fast Bin-Angriff durchzuführen, um den Malloc-Hook mit einer One-Gadget-Adresse zu überschreiben.
Wir können nur Chunks mit einer Größe größer als 0x100
allokieren.
Überschreibe global_max_fast
mit einem Unsorted Bin-Angriff (funktioniert 1/16 Mal aufgrund von ASLR, da wir 12 Bits ändern müssen, aber 16 Bits ändern müssen).
Fast Bin-Angriff, um ein globales Array von Chunks zu ändern. Dies gibt eine beliebige Lese-/Schreibprimitive, die es ermöglicht, die GOT zu ändern und einige Funktionen auf system
zu zeigen.
Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)