Unsorted Bin Attack
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
For more information about what is an unsorted bin check this page:
Bins & Memory AllocationsUnsorted liste mogu da upisu adresu u unsorted_chunks (av)
u bk
adresu chunk-a. Stoga, ako napadač može da modifikuje adresu bk
pokazivača u chunk-u unutar unsorted bin-a, mogao bi da upisuje tu adresu u proizvoljnu adresu što bi moglo biti korisno za leak Glibc adresa ili zaobići neku od odbrana.
Dakle, u suštini, ovaj napad omogućava da postavite veliku brojku na proizvoljnu adresu. Ova velika brojka je adresa, koja može biti adresa heap-a ili Glibc adresa. Tipičan cilj je global_max_fast
kako bi se omogućilo kreiranje fast bin binova sa većim veličinama (i prelazak iz unsorted bin napada u fast bin napad).
Taking a look to the example provided in https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle and using 0x4000 and 0x5000 instead of 0x400 and 0x500 as chunk sizes (to avoid Tcache) it's possible to see that nowadays the error malloc(): unsorted double linked list corrupted
is triggered.
Stoga, ovaj unsorted bin napad sada (pored drugih provera) takođe zahteva da bude moguće popraviti dvostruko povezanu listu tako da se zaobiđe victim->bk->fd == victim
ili ne victim->fd == av (arena)
, što znači da adresa na koju želimo da pišemo mora imati adresu lažnog chunk-a u svom fd
položaju i da lažni chunk fd
pokazuje na arenu.
Note that this attack corrupts the unsorted bin (hence small and large too). So we can only use allocations from the fast bin now (a more complex program might do other allocations and crash), and to trigger this we must allocate the same size or the program will crash.
Napomena da prepisivanje global_max_fast
može pomoći u ovom slučaju verujući da će fast bin moći da se brine o svim ostalim alokacijama dok se eksploatacija ne završi.
The code from guyinatuxedo explains it very well, although if you modify the mallocs to allocate memory big enough so don't end in a Tcache you can see that the previously mentioned error appears preventing this technique: malloc(): unsorted double linked list corrupted
Ovo je zapravo vrlo osnovni koncept. Chunk-ovi u unsorted bin-u će imati pokazivače. Prvi chunk u unsorted bin-u će zapravo imati fd
i bk
linkove koji upućuju na deo glavne arene (Glibc).
Stoga, ako možete staviti chunk unutar unsorted bin-a i pročitati ga (use after free) ili ponovo ga alocirati bez prepisivanja barem 1 od pokazivača da biste zatim pročitali ga, možete imati Glibc info leak.
Sličan napad korišćen u ovom izveštaju, bio je zloupotreba strukture od 4 chunk-a (A, B, C i D - D je samo da spreči konsolidaciju sa top chunk-om) tako da je korišćen null byte overflow u B da bi C ukazivao da je B neiskorišćen. Takođe, u B su podaci prev_size
modifikovani tako da je veličina umesto veličine B bila A+B.
Zatim je C dealokiran, i konsolidovan sa A+B (ali je B još uvek bio u upotrebi). Novi chunk veličine A je alociran i zatim su adrese libc leak-ovane napisane u B odakle su leak-ovane.
Cilj je prepisati globalnu promenljivu sa vrednošću većom od 4869 kako bi bilo moguće dobiti zastavicu i PIE nije omogućen.
Moguće je generisati chunk-ove proizvoljnih veličina i postoji heap overflow sa željenom veličinom.
Napad počinje kreiranjem 3 chunk-a: chunk0 za zloupotrebu overflow-a, chunk1 da bude overflow-ovan i chunk2 da top chunk ne konsoliduje prethodne.
Zatim, chunk1 se oslobađa i chunk0 se overflow-uje tako da bk
pokazivač chunk-a1 pokazuje na: bk = magic - 0x10
Zatim, chunk3 se alocira sa istom veličinom kao chunk1, što će pokrenuti unsorted bin napad i izmeniti vrednost globalne promenljive, omogućavajući dobijanje zastavice.
Funkcija merge je ranjiva jer ako su oba prosleđena indeksa ista, ona će realloc-ovati na njemu i zatim ga osloboditi, ali vraćajući pokazivač na tu oslobođenu oblast koja se može koristiti.
Stoga, 2 chunk-a su kreirana: chunk0 koji će se spojiti sa samim sobom i chunk1 da spreči konsolidaciju sa top chunk-om. Zatim, merge funkcija se poziva sa chunk0 dva puta što će izazvati use after free.
Zatim, view
funkcija se poziva sa indeksom 2 (što je indeks chunk-a koji je use after free), što će leak-ovati libc adresu.
Kako binarni fajl ima zaštite da samo malloc veličine veće od global_max_fast
pa se nijedan fastbin ne koristi, koristiće se unsorted bin napad da prepiše globalnu promenljivu global_max_fast
.
Zatim, moguće je pozvati edit funkciju sa indeksom 2 (pokazivač use after free) i prepisati bk
pokazivač da pokazuje na p64(global_max_fast-0x10)
. Zatim, kreiranje novog chunk-a koristi prethodno kompromitovanu oslobođenu adresu (0x20) će pokrenuti unsorted bin napad prepisujući global_max_fast
koja je veoma velika vrednost, omogućavajući sada kreiranje chunk-ova u fast bin-ovima.
Sada se izvodi fast bin napad:
Prvo je otkriveno da je moguće raditi sa fast chunk-ovima veličine 200 na __free_hook
lokaciji:
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook> gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200
0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
Ako uspemo da dobijemo fast chunk veličine 0x200 na ovoj lokaciji, biće moguće prepisati pokazivač funkcije koja će biti izvršena
Za to, kreira se novi chunk veličine 0xfc
i merge funkcija se poziva sa tim pokazivačem dva puta, na ovaj način dobijamo pokazivač na oslobođeni chunk veličine 0xfc*2 = 0x1f8
u fast bin-u.
Zatim, edit funkcija se poziva na ovom chunk-u da izmeni fd
adresu ovog fast bin-a da pokazuje na prethodnu __free_hook
funkciju.
Zatim, kreira se chunk veličine 0x1f8
da se povuče iz fast bin-a prethodni beskorisni chunk tako da se kreira još jedan chunk veličine 0x1f8
da se dobije fast bin chunk u __free_hook
koji se prepisuje sa adresom funkcije system
.
I konačno, chunk koji sadrži string /bin/sh\x00
se oslobađa pozivajući delete funkciju, pokrećući __free_hook
funkciju koja pokazuje na system sa /bin/sh\x00
kao parametrom.
Još jedan primer zloupotrebe 1B overflow-a da se konsoliduju chunk-ovi u unsorted bin-u i dobiju libc infoleak i zatim izvrši fast bin napad da prepiše malloc hook sa adresom jednog gadget-a
Možemo alocirati samo chunk-ove veličine veće od 0x100
.
Prepisivanje global_max_fast
korišćenjem Unsorted Bin napada (radi 1/16 puta zbog ASLR, jer treba da modifikujemo 12 bita, ali moramo modifikovati 16 bita).
Fast Bin napad za modifikaciju globalnog niza chunk-ova. Ovo daje proizvoljnu read/write primitivu, koja omogućava modifikaciju GOT-a i postavljanje neke funkcije da pokazuje na system
.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)