Stack Canaries

Reading time: 5 minutes

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks

StackGuard i StackShield

StackGuard umetne posebnu vrednost poznatu kao canary pre EIP (Extended Instruction Pointer), specifično 0x000aff0d (predstavlja null, newline, EOF, carriage return) kako bi se zaštitio od buffer overflow-a. Međutim, funkcije kao što su recv(), memcpy(), read(), i bcopy() ostaju ranjive, a ne štiti EBP (Base Pointer).

StackShield koristi sofisticiraniji pristup od StackGuard-a održavajući Global Return Stack, koji čuva sve adrese povratka (EIPs). Ova postavka osigurava da bilo kakvo prelivanje ne uzrokuje štetu, jer omogućava poređenje između sačuvanih i stvarnih adresa povratka kako bi se otkrile pojave prelivanja. Pored toga, StackShield može proveriti adresu povratka u odnosu na graničnu vrednost kako bi otkrio da li EIP pokazuje izvan očekivanog prostora podataka. Međutim, ova zaštita se može zaobići tehnikama kao što su Return-to-libc, ROP (Return-Oriented Programming), ili ret2ret, što ukazuje da StackShield takođe ne štiti lokalne promenljive.

Stack Smash Protector (ProPolice) -fstack-protector:

Ovaj mehanizam postavlja canary pre EBP, i reorganizuje lokalne promenljive kako bi pozicionirao bafer na višim adresama memorije, sprečavajući ih da prepisuju druge promenljive. Takođe sigurno kopira argumente prosleđene na steku iznad lokalnih promenljivih i koristi te kopije kao argumente. Međutim, ne štiti nizove sa manje od 8 elemenata ili baferima unutar korisničke strukture.

Canary je nasumičan broj dobijen iz /dev/urandom ili podrazumevana vrednost 0xff0a0000. Čuva se u TLS (Thread Local Storage), omogućavajući deljenje memorijskih prostora između niti sa globalnim ili statičkim promenljivim specifičnim za nit. Ove promenljive se inicijalno kopiraju iz roditeljskog procesa, a dečiji procesi mogu menjati svoje podatke bez uticaja na roditelja ili braću i sestre. Ipak, ako se fork() koristi bez kreiranja novog canary-a, svi procesi (roditelj i deca) dele isti canary, što ga čini ranjivim. Na i386 arhitekturi, canary se čuva na gs:0x14, a na x86_64, na fs:0x28.

Ova lokalna zaštita identifikuje funkcije sa baferima ranjivim na napade i injektuje kod na početku ovih funkcija kako bi postavio canary, i na kraju da proveri njegovu integritet.

Kada web server koristi fork(), omogućava napad silom da pogodi canary bajt po bajt. Međutim, korišćenje execve() nakon fork() prepisuje memorijski prostor, poništavajući napad. vfork() omogućava dečijem procesu da izvrši bez dupliciranja dok ne pokuša da piše, u tom trenutku se kreira duplikat, nudeći drugačiji pristup kreaciji procesa i upravljanju memorijom.

Dužine

U x64 binarnim datotekama, canary cookie je 0x8 bajt qword. Prvih sedam bajtova su nasumični i poslednji bajt je null bajt.

U x86 binarnim datotekama, canary cookie je 0x4 bajt dword. Prva tri bajta su nasumična i poslednji bajt je null bajt.

caution

Najmanji značajan bajt oba canary-a je null bajt jer će biti prvi na steku dolazeći iz nižih adresa i stoga funkcije koje čitaju stringove će stati pre nego što ga pročitaju.

Bypasses

Curiti canary i zatim ga prepisati (npr. buffer overflow) sa sopstvenom vrednošću.

  • Ako je canary fork-ovan u dečijim procesima može biti moguće da se brute-force jedan bajt po jedan:

BF Forked & Threaded Stack Canaries

  • Ako postoji neka zanimljiva curenje ili ranjivost u čitanju u binarnoj datoteci može biti moguće da se curi:

Print Stack Canary

  • Prepisivanje pokazivača sa steka

Stek ranjiv na stack overflow može sadržati adrese do stringova ili funkcija koje mogu biti prepisane kako bi se iskoristila ranjivost bez potrebe da se dođe do canary-a. Proverite:

Pointer Redirecting

  • Modifikovanje i master i thread canary

Buffer overflow u funkciji sa nitima zaštićenoj canary-em može se koristiti za modifikovanje master canary-a niti. Kao rezultat, mitigacija je beskorisna jer se provera koristi sa dva canary-a koja su ista (iako modifikovana).

Pored toga, buffer overflow u funkciji sa nitima zaštićenoj canary-em može se koristiti za modifikovanje master canary-a sačuvanog u TLS. To je zato što, može biti moguće doći do memorijske pozicije gde je TLS sačuvan (i stoga, canary) putem bof-a na steku niti.
Kao rezultat, mitigacija je beskorisna jer se provera koristi sa dva canary-a koja su ista (iako modifikovana).
Ovaj napad je izveden u pisanju: http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads

Proverite takođe prezentaciju https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015 koja pominje da se obično TLS čuva putem mmap i kada se steck niti kreira takođe se generiše putem mmap, što može omogućiti prelivanje kao što je prikazano u prethodnom pisanju.

  • Modifikujte GOT unos __stack_chk_fail

Ako binarna datoteka ima Partial RELRO, onda možete koristiti proizvoljno pisanje da modifikujete GOT unos __stack_chk_fail da bude dummy funkcija koja ne blokira program ako se canary modifikuje.

Ovaj napad je izveden u pisanju: https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/

Reference

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks