Translated ['src/binary-exploitation/libc-heap/unsorted-bin-attack.md']

This commit is contained in:
Translator 2025-08-28 17:00:36 +00:00
parent 0729dc69c3
commit 5e7d1947f5

View File

@ -2,54 +2,112 @@
{{#include ../../banners/hacktricks-training.md}}
## Grundinformationen
## Grundlegende Informationen
Für mehr Informationen darüber, was ein unsorted bin ist, siehe diese Seite:
Für weitere Informationen darüber, was ein unsortierter Bin ist, siehe diese Seite:
{{#ref}}
bins-and-memory-allocations.md
{{#endref}}
Unsortierte Listen können die Adresse zu `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.
Unsorted-Listen können die Adresse von `unsorted_chunks (av)` in das `bk`-Feld des Chunks schreiben. Daher, wenn ein Angreifer die Adresse des `bk`-Pointers in einem Chunk im unsorted bin **ändern** kann, könnte er in der Lage sein, **diese Adresse an eine beliebige Adresse zu schreiben**, was nützlich sein kann, um Glibc-Adressen zu leaken oder Schutzmechanismen zu umgehen.
Im Grunde genommen 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).
Kurz gesagt erlaubt 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 kann. Ein traditionelles Ziel war **`global_max_fast`**, um fast bins mit größeren Größen zu ermöglichen (und vom unsorted bin attack zum fast bin attack zu wechseln).
- Moderne Anmerkung (glibc ≥ 2.39): `global_max_fast` wurde zu einem 8Bit Global. Blindes Schreiben eines Pointers dort via unsorted-bin write wird angrenzende libc-Daten überschreiben und erhöht die fastbin-Grenze nicht mehr zuverlässig. Bevorzuge andere Ziele oder Primitiven gegen glibc 2.39+. Siehe "Modern constraints" weiter unten und erwäge die Kombination mit anderen Techniken wie einem [large bin attack](large-bin-attack.md) oder einem [fast bin attack](fast-bin-attack.md), sobald du ein stabiles Primitive hast.
> [!TIP]
> Ein Blick auf das Beispiel in [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle) zeigt, dass die Verwendung von 0x4000 und 0x5000 anstelle von 0x400 und 0x500 als Chunk-Größen (um Tcache zu vermeiden) dazu führt, dass der Fehler **`malloc(): unsorted double linked list corrupted`** ausgelöst wird.
> Wenn man sich das Beispiel in [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle) anschaut und 0x4000 und 0x5000 statt 0x400 und 0x500 als Chunk-Größen verwendet (um Tcache zu vermeiden), sieht man, 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, dass die doppelt verkettete Liste repariert wird, sodass `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 ihrer `fd`-Position haben muss und dass der gefälschte Chunk `fd` auf die Arena zeigt.
> Daher erfordert dieser unsorted bin attack jetzt (neben anderen Checks) auch, die doppelt verkettete Liste so zu manipulieren, dass die Prüfung `victim->bk->fd == victim` oder `victim->fd == av (arena)` nicht fehlschlägt. Das bedeutet, dass die Adresse, an die wir schreiben wollen, in ihrer `fd`-Position die Adresse des gefälschten Chunks enthalten muss und das gefälschte Chunk `fd` auf die arena zeigt.
> [!CAUTION]
> Beachten Sie, 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, sonst wird das Programm abstürzen.**
> Beachte, dass dieser Angriff das unsorted bin (und damit auch small und large) korruptiert. Deshalb können wir jetzt nur **Allokationen aus den fast bins verwenden** (ein komplexeres Programm könnte andere Allokationen durchführen und abstürzen); um das auszulösen, müssen wir **genau dieselbe Größe allokieren, sonst stürzt das Programm ab.**
>
> Beachten Sie, dass das Überschreiben von **`global_max_fast`** in diesem Fall hilfreich sein könnte, in der Annahme, dass der Fast Bin in der Lage ist, sich um alle anderen Allokationen zu kümmern, bis der Exploit abgeschlossen ist.
> Das Überschreiben von **`global_max_fast`** kann in diesem Fall helfen, wenn man darauf vertraut, dass die fast bin die restlichen Allokationen übernimmt, bis der Exploit abgeschlossen ist.
Der Code von [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) erklärt dies sehr gut, obwohl Sie, wenn Sie die Mallocs ändern, um genügend Speicher zu allokieren, damit sie nicht in einem Tcache enden, sehen können, dass der zuvor erwähnte Fehler auftritt, der diese Technik verhindert: **`malloc(): unsorted double linked list corrupted`**
Der Code von [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) erklärt das sehr gut; wenn man die mallocs aber so ändert, dass sie groß genug sind, um nicht in Tcache zu landen, sieht man den oben genannten Fehler, der diese Technik verhindert: **`malloc(): unsorted double linked list corrupted`**
## Unsorted Bin Infoleak Angriff
### Wie der Schreibvorgang tatsächlich abläuft
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 Sie **einen Chunk in einen unsortierten Bin legen und ihn lesen** (use after free) oder **ihn erneut allokieren, ohne mindestens 1 der Zeiger zu überschreiben**, um ihn dann **zu lesen**, können Sie einen **Glibc-Infoleak** erhalten.
- Der unsorted-bin write wird beim `free` ausgelöst, wenn das freigegebene Chunk an den Kopf der unsorted-Liste eingefügt wird.
- Während der Einfügung führt der Allocator folgende Schritte aus: `bck = unsorted_chunks(av); fwd = bck->fd; victim->bk = bck; victim->fd = fwd; fwd->bk = victim; bck->fd = victim;`
- Wenn du `victim->bk` vor dem Aufruf von `free(victim)` auf `(mchunkptr)(TARGET - 0x10)` setzen kannst, wird die letzte Anweisung den Schreibvorgang durchführen: `*(TARGET) = victim`.
- Später, wenn der Allocator das unsorted bin verarbeitet, prüfen die Integritätschecks (unter anderem), dass `bck->fd == victim` und `victim->fd == unsorted_chunks(av)`, bevor sie unlinken. Da die Einfügung bereits `victim` in `bck->fd` (unser TARGET) geschrieben hat, können diese Prüfungen erfüllt sein, wenn der Schreibvorgang erfolgreich war.
Ein ähnlicher [**Angriff, der in diesem Bericht verwendet wurde**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html), bestand darin, eine Struktur mit 4 Chunks (A, B, C und D - D dient nur dazu, die Konsolidierung mit dem Top-Chunk zu verhindern) zu missbrauchen, 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 so modifiziert, dass die Größe anstelle der Größe von B A+B war.\
Dann wurde C deallokiert 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.
## Moderne Einschränkungen (glibc ≥ 2.33)
## Referenzen & Weitere Beispiele
Um unsortedbin-Schreibvorgänge zuverlässig auf aktuellem glibc zu nutzen:
- Tcache interference: Für Größen, die in Tcache fallen, werden frees dorthin umgeleitet und berühren nicht das unsorted bin. Entweder
- mache Anfragen mit Größen > MAX_TCACHE_SIZE (≥ 0x410 auf 64Bit standardmäßig), oder
- fülle das entsprechende Tcache-Bin (7 Einträge), sodass zusätzliche frees die globalen Bins erreichen, oder
- wenn die Umgebung kontrollierbar ist, deaktiviere tcache (z. B. GLIBC_TUNABLES glibc.malloc.tcache_count=0).
- Integritätsprüfungen auf der unsorted-Liste: Auf dem nächsten Allokationspfad, der das unsorted bin prüft, testet glibc (vereinfacht):
- `bck->fd == victim` und `victim->fd == unsorted_chunks(av)`; andernfalls bricht es mit `malloc(): unsorted double linked list corrupted` ab.
- Das bedeutet, dass die Adresse, die du anvisierst, zwei Schreiboperationen tolerieren muss: zuerst `*(TARGET) = victim` zur freeZeit; später, wenn das Chunk entfernt wird, `*(TARGET) = unsorted_chunks(av)` (der Allocator schreibt `bck->fd` zurück auf den Bin-Kopf). Wähle Ziele, bei denen allein das Erzwingen eines großen NichtNullWerts nützlich ist.
- Typische stabile Ziele in modernen Exploits
- Anwendungs- oder globaler Zustand, der "große" Werte als Flags/Grenzen behandelt.
- Indirekte Primitives (z. B. Vorbereitung für einen nachfolgenden [fast bin attack]({{#ref}}fast-bin-attack.md{{#endref}}) oder um später einen writewhatwhere zu pivotieren).
- Vermeide `__malloc_hook`/`__free_hook` in neueren glibc: diese wurden in 2.34 entfernt. Vermeide `global_max_fast` auf ≥ 2.39 (siehe vorherige Anmerkung).
- Über `global_max_fast` in aktuellem glibc
- In glibc 2.39+ ist `global_max_fast` ein 8Bit Global. Der klassische Trick, dort einen HeapPointer hineinzuschreiben (um fastbins zu vergrößern), funktioniert nicht mehr sauber und wird wahrscheinlich angrenzenden AllocatorZustand korruptieren. Bevorzuge andere Strategien.
## Minimales ExploitRezept (modernes glibc)
Ziel: Mit der unsortedbin insertion primitive eine einzelne willkürliche Schreiboperation eines HeapPointers an eine beliebige Adresse erreichen, ohne einen Absturz zu verursachen.
- Layout/Grooming
- Allokiere A, B, C mit Größen, die groß genug sind, um tcache zu umgehen (z. B. 0x5000). C verhindert die Konsolidierung mit dem top chunk.
- Korruption
- Overflow von A in B's ChunkHeader, um `B->bk = (mchunkptr)(TARGET - 0x10)` zu setzen.
- Auslösen
- `free(B)`. Zur Einfügezeit führt der Allocator `bck->fd = B` aus, daher wird `*(TARGET) = B`.
- Fortsetzung
- Wenn du weiter allokieren willst und das Programm das unsorted bin verwendet, erwarte, dass der Allocator später `*(TARGET) = unsorted_chunks(av)` setzt. Beide Werte sind typischerweise groß und können ausreichen, um Größen-/LimitSemantik in Zielen zu ändern, die nur auf "groß" prüfen.
PseudocodeGerüst:
```c
// 64-bit glibc 2.352.38 style layout (tcache bypass via large sizes)
void *A = malloc(0x5000);
void *B = malloc(0x5000);
void *C = malloc(0x5000); // guard
// overflow from A into Bs metadata (prev_size/size/.../bk). You must control B->bk.
*(size_t *)((char*)B - 0x8) = (size_t)(TARGET - 0x10); // write fake bk
free(B); // triggers *(TARGET) = B (unsorted-bin insertion write)
```
> [!NOTE]
> • Wenn du tcache nicht über die Größe umgehen kannst, fülle das tcache bin für die gewählte Größe (7 frees), bevor du den korrumpierten chunk freigibst, damit der free in den unsorted geht.
> • Wenn das Programm bei der nächsten Allocation sofort wegen unsorted-bin-Checks abbricht, überprüfe nochmals, dass `victim->fd` weiterhin dem bin head entspricht und dass dein `TARGET` nach dem ersten write exakt den `victim`-Pointer hält.
## Unsorted Bin Infoleak Attack
Das ist eigentlich ein sehr grundlegendes Konzept. Die chunks im unsorted bin enthalten Pointer. Der erste Chunk im unsorted bin wird tatsächlich die **`fd`** und die **`bk`** Links haben, die **auf einen Teil der main arena (Glibc)** zeigen.\
Daher kannst du, wenn du **einen Chunk in den unsorted bin platzierst und ihn ausliest** (use after free) oder **ihn erneut allokierst, ohne mindestens einen der Pointer zu überschreiben**, um ihn anschließend **auszulesen**, ein **Glibc info leak** erhalten.
Ein ähnlicher [**attack used in this writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html) bestand darin, eine Struktur aus 4 Chunks (A, B, C und D — D dient nur dazu, eine Consolidation mit dem top chunk zu verhindern) auszunutzen: Ein Null-Byte-Overflow in B wurde verwendet, damit C anzeigt, dass B unused ist. Außerdem wurde in B das `prev_size` Feld so verändert, dass die Größe statt der Größe von B die von A+B war.\
Dann wurde C freigegeben und mit A+B konsolidiert (wobei B weiterhin in use war). Ein neuer Chunk der Größe A wurde allokiert und die aus libc geléakten Adressen wurden in B geschrieben, von wo sie ausgelesen wurden.
## References & Other examples
- [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap)
- Das Ziel ist es, eine globale Variable mit einem Wert größer als 4869 zu überschreiben, damit 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 überlaufen zu werden, und chunk2, damit der Top-Chunk die vorherigen nicht konsolidiert.
- Dann wird chunk1 freigegeben und chunk0 wird überlaufen, sodass der `bk`-Zeiger von chunk1 aufzeigt: `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.
- Ziel ist es, eine globale Variable mit einem Wert größer als 4869 zu überschreiben, sodass man das Flag erhält und PIE nicht aktiviert ist.
- Es ist möglich, Chunks beliebiger Größen zu erzeugen, und es existiert ein Heap-Overflow in der gewünschten Größe.
- Der Angriff beginnt mit der Erstellung von 3 Chunks: chunk0 zum Ausnutzen des Overflows, chunk1, das überlaufen wird, und chunk2, damit der top chunk die vorherigen nicht konsolidiert.
- Dann wird chunk1 freed und chunk0 so überlaufen, dass der `bk`-Pointer von chunk1 auf Folgendes zeigt: `bk = magic - 0x10`
- Danach wird chunk3 mit der gleichen Größe wie chunk1 alloziert, was den unsorted bin attack auslöst und den Wert der globalen Variable verändert, wodurch es möglich wird, das Flag zu erhalten.
- [**https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html**](https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html)
- Die Merge-Funktion ist anfällig, da sie, wenn beide übergebenen Indizes gleich sind, darauf realloc und dann freigibt, 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 **eine libc-Adresse leakt**.
- 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, wodurch 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:
- Die merge-Funktion ist verwundbar, weil sie, wenn beide übergebenen Indizes gleich sind, auf genau diesen Bereich reallocatet und ihn dann freed, aber einen Pointer auf diese freed-Region zurückgibt, der wiederverwendet werden kann.
- Daher werden **2 Chunks erzeugt**: **chunk0**, das mit sich selbst gemerged wird, und chunk1, um eine Konsolidation mit dem top chunk zu verhindern. Dann wird die **merge-Funktion mit chunk0** zweimal aufgerufen, was zu einem use after free führt.
- Danach wird die **`view`**-Funktion mit Index 2 (dem Index des use-after-free-Chunks) aufgerufen, wodurch eine libc-Adresse geleakt wird.
- Da das Binary Schutzmechanismen hat, die nur mallocs größer als **`global_max_fast`** zulassen (also keine fastbin benutzt werden), wird ein unsorted bin attack benutzt, um die globale Variable `global_max_fast` zu überschreiben.
- Danach ist es möglich, die edit-Funktion mit Index 2 (dem use-after-free-Pointer) aufzurufen und den `bk`-Pointer zu überschreiben, sodass er auf `p64(global_max_fast-0x10)` zeigt. Dann wird ein neuer Chunk erstellt, wodurch die zuvor kompromittierte free-Adresse (0x20) benutzt wird und **der unsorted bin attack** ausgelöst wird, der `global_max_fast` mit einem sehr großen Wert überschreibt und es so erlaubt, Chunks in den fastbins zu erzeugen.
- Nun wird ein **fast bin attack** durchgeführt:
- Zunächst wird festgestellt, dass es möglich ist, mit fast Chunks der Größe 200 an der Position von **`__free_hook`** zu arbeiten:
- <pre class="language-c"><code class="lang-c">gef➤ p &__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
@ -58,16 +116,20 @@ gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
</code></pre>
- Wenn es uns gelingt, einen schnellen Chunk der Größe 0x200 an diesem Ort 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 die Zeichenfolge `/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.
- Wenn es gelingt, einen fast chunk der Größe 0x200 an dieser Position zu platzieren, wird es möglich sein, einen Funktionspointer zu überschreiben, der dann ausgeführt wird.
- Dazu wird ein neuer Chunk der Größe `0xfc` erstellt und die merge-Funktion mit diesem Pointer zweimal aufgerufen; so erhält man einen Pointer auf einen freed Chunk der Größe `0xfc*2 = 0x1f8` im fastbin.
- Dann wird die edit-Funktion auf diesem Chunk aufgerufen, um die **`fd`**-Adresse dieses fastbins so zu verändern, dass sie auf das vorherige **`__free_hook`** zeigt.
- Danach wird ein Chunk mit Größe `0x1f8` erstellt, um aus dem fastbin den vorherigen nutzlosen Chunk zurückzuholen, und ein weiterer Chunk der Größe `0x1f8` erstellt, um einen fastbin-Chunk in **`__free_hook`** zu erhalten, welcher mit der Adresse der **`system`**-Funktion überschrieben wird.
- Schließlich wird ein Chunk, der den String `/bin/sh\x00` enthält, freigegeben (delete), wodurch die **`__free_hook`**-Funktion ausgelöst wird, die nun auf system zeigt und `/bin/sh\x00` als Parameter erhält.
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html)
- Ein weiteres Beispiel für den Missbrauch eines 1B-Overflows zur Konsolidierung von Chunks im unsortierten Bin und zum Erhalten eines libc-Infoleaks und dann zur Durchführung eines Fast Bin-Angriffs, um den Malloc-Hook mit einer One-Gadget-Adresse zu überschreiben.
- Ein weiteres Beispiel für das Ausnutzen eines 1-Byte-Overflows, um Chunks im unsorted bin zu konsolidieren und ein libc infoleak zu erhalten, gefolgt von einem fast bin attack, um malloc hook mit einer one-gadget-Adresse zu überschreiben
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
- Wir können nur Chunks mit einer Größe größer als `0x100` allokieren.
- Überschreiben von `global_max_fast` mit einem Unsorted Bin-Angriff (funktioniert 1/16 Mal aufgrund von ASLR, da wir 12 Bits modifizieren müssen, aber 16 Bits modifizieren müssen).
- Fast Bin-Angriff zur Modifikation eines globalen Arrays von Chunks. Dies gibt eine beliebige Lese-/Schreibprimitive, die es ermöglicht, die GOT zu modifizieren und einige Funktionen auf `system` zu zeigen.
- Es können nur Chunks mit Größe größer als `0x100` alloziert werden.
- Überschreiben von `global_max_fast` mittels Unsorted Bin attack (funktioniert 1/16 Mal wegen ASLR, weil 12 Bits modifiziert werden müssen, wir aber 16 Bits verändern).
- Fast Bin attack, um ein globales Array von Chunks zu modifizieren. Das ergibt ein arbiträres read/write-Primitive, mit dem GOT-Einträge geändert werden können, sodass eine Funktion auf `system` zeigt.
## Referenzen
- Glibc malloc unsorted-bin integrity checks (Beispiel im Source von 2.33): https://elixir.bootlin.com/glibc/glibc-2.33/source/malloc/malloc.c
- `global_max_fast` und verwandte Definitionen in modernem glibc (2.39): https://elixir.bootlin.com/glibc/glibc-2.39/source/malloc/malloc.c
{{#include ../../banners/hacktricks-training.md}}