Unsorted Bin Attack

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)

Podržite HackTricks

Osnovne informacije

Za više informacija o tome šta je nesortirana binarna provera, pogledajte ovu stranicu:

Bins & Memory Allocations

Nesortirane 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

Napad na nesortiranu binarnu hrpu za otkrivanje informacija

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.

Reference i drugi primeri

  • 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:

  • gef➤  p &__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)

Podržite HackTricks

Last updated