hacktricks/binary-exploitation/heap/unsorted-bin-attack.md

9.3 KiB

Napad na nesortiranu binarnu hrpu

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Osnovne informacije

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

{% content-ref url="bins-and-memory-allocations.md" %} bins-and-memory-allocations.md {% endcontent-ref %}

Nesortirane liste mogu upisati adresu u unsorted_chunks (av) u adresu bk dela bloka. Dakle, ako napadač može izmeniti adresu pokazivača bk u bloku unutar nesortirane hrpe, mogao bi upisati tu adresu na proizvoljnu adresu što bi moglo biti korisno za otkrivanje libc adresa ili zaobići neku odbranu.

Dakle, u osnovi, ovaj napad omogućava da se prepiše neka proizvoljna adresa velikim brojem (adresa koja može biti adresa hrpe ili libc adresa) poput neke adrese steka koja može biti otkrivena ili nekog ograničenja poput globalne promenljive global_max_fast kako bi se omogućilo kreiranje brzih binova sa većim veličinama (i preći sa napada na nesortiranu binu na napad na brzi bin).

{% hint style="success" %} 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 blokova (kako bi se izbegli tcache-ovi) moguće je videti da se danas aktivira greška malloc(): unsorted double linked list corrupted.

Stoga, ovaj napad na nesortiranu binu sada (pored ostalih provera) takođe zahteva mogućnost popravljanja duplirane liste tako da se zaobiđe victim->bck->fd == victim ili ne victim->fd == av (arena). Što znači da adresa na koju želimo da pišemo mora imati adresu lažnog bloka na svojoj poziciji fd i da lažni blok fd pokazuje na arenu. {% endhint %}

{% hint style="danger" %} Imajte na umu da ovaj napad korumpira nesortiranu binu (takođe male i velike). Tako da sada možemo koristiti alokacije iz brzih binova (neki složeniji program može vršiti druge alokacije i rušiti se), i da bismo aktivirali ovo moramo alocirati istu veličinu ili će program pasti.

Imajte na umu da bi pravljenje global_max_fast moglo 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. {% endhint %}

Kod sa guyinatuxedo objašnjava to veoma dobro, iako ako modifikujete alokacije da alociraju memoriju dovoljno veliku da ne završe u tcache-u, možete videti da se pomenuta greška pojavljuje sprečavajući ovu tehniku: malloc(): unsorted double linked list corrupted

Napad na nesortiranu binu za curenje informacija

Ovo je zapravo veoma osnovan koncept. Blokovi u nesortiranoj bini će imati pokazivače dvostruke pokazivače za kreiranje bine. Prvi blok u nesortiranoj bini će zapravo imati FD i BK linkove koji pokazuju na deo glavne arene (libc).
Stoga, ako možete ubaciti blok unutar nesortirane bine 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 curenje libc informacija.

Reference i drugi primeri

  • https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap
  • Cilj je prepisati globalnu promenljivu sa vrednošću većom od 4869 kako bi se mogla dobiti zastava, a PIE nije omogućen.
  • Moguće je generisati blokove proizvoljnih veličina i postoji prelivanje hrpe sa željenom veličinom.
  • Napad počinje kreiranjem 3 bloka: blok0 za zloupotrebu preliva, blok1 za prelivanje i blok2 kako vrh bloka ne bi konsolidovao prethodne.
  • Zatim, blok1 se oslobađa i blok0 se preliva tako da pokazivač bk bloka1 pokazuje na: bk = magic - 0x10
  • Zatim, blok3 se alocira iste veličine kao blok1, što će pokrenuti napad na nesortiranu binu i izmeniti vrednost globalne promenljive, omogućavajući dobijanje zastave.
  • https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html
  • 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 regiju koja može biti korišćena.
  • Stoga, kreiraju se 2 bloka: blok0 koji će biti spojen sa samim sobom i blok1 kako se ne bi konsolidovao sa vrhom bloka. Zatim se funkcija spajanja poziva sa blokom0 dva puta što će izazvati korišćenje nakon oslobađanja.
  • Zatim se view funkcija poziva sa indeksom 2 (koji je indeks bloka korišćenja nakon oslobađanja), što će procureti libc adresu.
  • Pošto binarni fajl ima zaštitu da alocira samo veličine veće od global_max_fast tako da nema korišćenja fastbin-a, napad na nesortiranu binu će biti korišćen za prepisivanje globalne promenljive global_max_fast.
  • Zatim je moguće pozvati funkciju edit sa indeksom 2 (pokazivač korišćenja nakon oslobađanja) i prepisati pokazivač bk da pokazuje na p64(global_max_fast-0x10). Zatim, kreiranje novog bloka će koristiti prethodno kompromitovanu adresu oslobođenog bloka (0x20) će pokrenuti napad na nesortiranu binu prepisivanjem global_max_fast sa veoma velikom vrednošću, omogućavajući sada kreiranje blokova u brzim binovima.
  • Sada se vrši napad na brze binove:
  • Prvo je otkriveno da je moguće raditi sa brzim blokovima 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 prebrisati pokazivač funkcije koji će biti izvršen
  • Za ovo, 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 binu.
  • Zatim se poziva funkcija za uređivanje u ovom bloku kako bi se izmenila adresa fd ovog brzog bina da pokazuje na prethodnu funkciju __free_hook.
  • Zatim se kreira blok veličine 0x1f8 kako bi se iz brzog bina 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 prebrisan adresom funkcije system.
  • Na kraju se oslobođava blok koji sadrži string /bin/sh\x00 pozivom funkcije za brisanje, pokrećući funkciju __free_hook koja pokazuje na sistem sa /bin/sh\x00 kao parametrom.
Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u: