Unsorted Bin Attack
Last updated
Last updated
Naučite i vežbajte hakovanje AWS-a:HackTricks Obuka AWS Crveni Tim Stručnjak (ARTE) Naučite i vežbajte hakovanje GCP-a: HackTricks Obuka GCP Crveni Tim Stručnjak (GRTE)
Za više informacija o tome šta je nesortirana binarna provera, pogledajte ovu stranicu:
Bins & Memory AllocationsNesortirane liste mogu da upišu adresu u unsorted_chunks (av)
u adresu bk
dela isečka. Dakle, ako napadač može da izmeni adresu pokazivača bk
u isečku unutar nesortirane binarne hrpe, mogao bi da upiše tu adresu na proizvoljnu adresu što bi moglo biti korisno za otkrivanje adresa Glibc-a ili zaobići neku odbranu.
Dakle, u osnovi, ovaj napad omogućava da se postavi veliki broj na proizvoljnu adresu. Taj veliki broj je adresa, koja može biti adresa hrpe ili adresa Glibc-a. Tipična meta je global_max_fast
kako bi se omogućilo kreiranje brzih bin binova većih veličina (i preći sa napada na nesortiranu binarnu hrpu na napad na brzi bin).
Pogledajte primer koji je dat na https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle i koristeći 0x4000 i 0x5000 umesto 0x400 i 0x500 kao veličine isečaka (kako bi se izbegao Tcache), moguće je videti da se danas sada pokreće greška malloc(): unsorted double linked list corrupted
.
Stoga, ovaj napad na nesortiranu binarnu hrpu sada (pored ostalih provera) takođe zahteva mogućnost popravljanja dupliranog povezanog spiska tako da se ovo 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 isečka na svojoj poziciji fd
i da lažni isečak fd
pokazuje na arenu.
Imajte na umu da ovaj napad narušava nesortiranu binarnu hrpu (takođe i male i velike). Zato sada možemo koristiti alokacije iz brzih binova (neki složeniji program može obaviti druge alokacije i srušiti se), i da bismo pokrenuli ovo moramo dodeliti istu veličinu ili će program pasti.
Imajte na umu da prebrisavanje global_max_fast
može pomoći u ovom slučaju verujući da će brzi bin biti u mogućnosti da se brine o svim ostalim alokacijama dok se eksploatacija ne završi.
Kod sa guyinatuxedo objašnjava to veoma dobro, iako ako izmenite alokacije da alociraju memoriju dovoljno veliku da ne završe u Tcache, možete videti da se pomenuta greška pojavljuje sprečavajući ovu tehniku: malloc(): unsorted double linked list corrupted
Ovo je zapravo veoma osnovan koncept. Isečci u nesortiranoj binarnoj hrpi će imati pokazivače. Prvi isečak u nesortiranoj binarnoj hrpi zapravo će imati fd
i bk
veze koje pokazuju na deo glavne arene (Glibc).
Dakle, ako možete ubaciti isečak unutar nesortirane binarne hrpe i pročitati ga (korišćenje nakon oslobađanja) ili ponovo ga alocirati bez prepisivanja bar 1 od pokazivača da biste ga zatim pročitali, možete imati otkrivanje informacija o Glibc-u.
Sličan napad korišćen u ovom opisu, bio je da se zloupotrebi struktura od 4 isečka (A, B, C i D - D je samo da spreči konsolidaciju sa vršnim isečkom) tako da je prelivanje nula bajta u B korišćeno da C pokaže da B nije korišćen. Takođe, u B je modifikovan podatak prev_size
tako da veličina umesto veličine B bude A+B.
Zatim je C oslobođen, i konsolidovan sa A+B (ali B je i dalje bio u upotrebi). Alociran je novi isečak veličine A, a zatim su adrese Glibc-a koje su procurile upisane u B odakle su procurile.
Cilj je prepisati globalnu promenljivu sa vrednošću većom od 4869 kako bi se mogla dobiti zastava i PIE nije omogućen.
Moguće je generisati isečke proizvoljnih veličina i postoji prelivanje hrpe sa željenom veličinom.
Napad počinje kreiranjem 3 isečka: isečak0 za zloupotrebu preliva, isečak1 za prelivanje i isečak2 kako vršni isečak ne bi konsolidovao prethodne.
Zatim, isečak1 je oslobođen i isečak0 je preliven tako da pokazivač bk
isečka1 pokazuje na: bk = magic - 0x10
Zatim je alociran isečak3 iste veličine kao isečak1, što će pokrenuti napad na nesortiranu binarnu hrpu i izmeniti vrednost globalne promenljive, omogućavajući dobijanje zastave.
Funkcija spajanja je ranjiva jer ako su oba prosleđena indeksa isti, ponovo će alocirati na njemu, a zatim ga osloboditi ali će vratiti pokazivač na tu oslobođenu oblast koja može biti korišćena.
Stoga, kreirana su 2 isečka: isečak0 koji će biti spojen sa samim sobom i isečak1 da spreči konsolidaciju sa vršnim isečkom. Zatim je pozvana funkcija spajanja sa isečkom0 dva puta što će izazvati korišćenje nakon oslobađivanja.
Zatim je pozvana view
funkcija sa indeksom 2 (koji je indeks isečka korišćenog nakon oslobađivanja), što će procureti adresu Glibc-a.
Kako binarni fajl ima zaštitu da samo alocira veličine veće od global_max_fast
tako da nema korišćenja brzih binova, biće korišćen napad na nesortiranu binarnu hrpu da se prepiše globalna promenljiva global_max_fast
.
Zatim je moguće pozvati funkciju edit sa indeksom 2 (pokazivač korišćen nakon oslobađivanja) i prepisati pokazivač bk
da pokazuje na p64(global_max_fast-0x10)
. Zatim, kreiranje novog isečka će koristiti prethodno kompromitovanu adresu oslobođenog (0x20) i pokrenuti napad na nesortiranu binarnu hrpu prepisivanjem global_max_fast
sa veoma velikom vrednošću, omogućavajući sada kreiranje isečaka u brzim binovima.
Sada se vrši napad na brze binove:
Prvo je otkriveno da je moguće raditi sa brzim isečcima veličine 200 na lokaciji __free_hook
:
$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 brzi blok veličine 0x200 na ovoj lokaciji, biće moguće prepisati pokazivač funkcije koji će biti izvršen
Za to, kreira se novi blok veličine 0xfc
i poziva se spojena funkcija sa tim pokazivačem dva puta, na taj način dobijamo pokazivač na oslobođeni blok veličine 0xfc*2 = 0x1f8
u brzom bloku.
Zatim se poziva funkcija za uređivanje u ovom bloku kako bi se izmenila adresa fd
ovog brzog bloka da pokazuje na prethodnu funkciju __free_hook
.
Zatim se kreira blok veličine 0x1f8
kako bi se iz brzog bloka povukao prethodni beskorisni blok, tako da se kreira još jedan blok veličine 0x1f8
kako bi se dobio brzi blok u __free_hook
koji je prepisan adresom funkcije system
.
Na kraju se oslobođuje blok koji sadrži string /bin/sh\x00
pozivom funkcije brisanja, pokreće se funkcija __free_hook
koja pokazuje na sistem sa /bin/sh\x00
kao parametrom.
Još jedan primer zloupotrebe prelivanja od 1B kako bi se konsolidovali blokovi u nesortiranom bloku i dobio libc infoleak, a zatim izvršio brzi napad na bin da se prepise kuka za alociranje sa adresom jednog gedžeta
Možemo alocirati samo blokove veće od 0x100
.
Prepisati global_max_fast
korišćenjem napada na nesortirani bin (radi 1/16 puta zbog ASLR-a, jer moramo izmeniti 12 bitova, ali moramo izmeniti 16 bitova).
Brzi napad na bin kako bi se izmenio globalni niz blokova. Ovo daje proizvoljni čitanje/pisanje, što omogućava izmenu GOT i postavljanje neke funkcije da pokazuje na system
.
Naučite i vežbajte hakovanje AWS:HackTricks Training AWS Red Team Expert (ARTE) Naučite i vežbajte hakovanje GCP: HackTricks Training GCP Red Team Expert (GRTE)