hacktricks/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/README.md

8.6 KiB

Stack Canaries

{% hint style="success" %} Naučite i vežbajte hakovanje AWS-a:HackTricks Training AWS Red Team Expert (ARTE)
Naučite i vežbajte hakovanje GCP-a: HackTricks Training GCP Red Team Expert (GRTE)

Pomozite HackTricks
{% endhint %}

StackGuard i StackShield

StackGuard ubacuje posebnu vrednost poznatu kao canary pre EIP (Extended Instruction Pointer), specifično 0x000aff0d (predstavlja null, novi red, EOF, povratak karijete) kako bi se zaštitio od preplavljivanja bafera. Međutim, funkcije poput recv(), memcpy(), read() i bcopy() ostaju ranjive, i ne štiti EBP (Base Pointer).

StackShield koristi sofisticiraniji pristup od StackGuard-a održavajući Global Return Stack, koji čuva sve povratne adrese (EIPs). Ova postavka osigurava da bilo koje preplavljivanje ne uzrokuje štetu, jer omogućava upoređivanje sačuvanih i stvarnih povratnih adresa radi otkrivanja preplavljivanja. Dodatno, StackShield može proveriti povratnu adresu u odnosu na granicnu vrednost kako bi otkrio da li EIP pokazuje van očekivanog prostora podataka. Međutim, ova zaštita može biti zaobiđena tehnikama poput Return-to-libc, ROP (Return-Oriented Programming) ili ret2ret, što ukazuje da ni StackShield ne štiti lokalne promenljive.

Stack Smash Protector (ProPolice) -fstack-protector:

Ovaj mehanizam postavlja canary pre EBP, i reorganizuje lokalne promenljive tako da postavlja baufere na višim memorijskim adresama, sprečavajući ih da prepisuju druge promenljive. Takođe, bezbedno kopira argumente prosleđene na stek iznad lokalnih promenljivih i koristi ove kopije kao argumente. Međutim, ne štiti nizove sa manje od 8 elemenata ili baufere unutar strukture korisnika.

Canary je slučajan broj izveden iz /dev/urandom ili podrazumevana vrednost 0xff0a0000. Čuva se u TLS (Thread Local Storage), omogućavajući deljenje memorijskih prostora između niti da imaju niti-specifične globalne ili statičke promenljive. Ove promenljive su početno kopirane iz roditeljskog procesa, a deca procesa mogu menjati svoje podatke bez uticaja na roditelja ili srodne procese. Ipak, ako se koristi fork() bez kreiranja novog canary-ja, svi procesi (roditelji i deca) dele isti canary, čineći ga ranjivim. Na arhitekturi i386, 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 ubacuje kod na početak ovih funkcija kako bi postavila canary, i na kraju kako bi proverila njegovu celovitost.

Kada veb server koristi fork(), omogućava napad brute-force da pogodi canary bajt po bajt. Međutim, korišćenje execve() nakon fork() prepisuje memorijski prostor, poništavajući napad. vfork() omogućava detetu procesa da izvršava bez dupliranja dok ne pokuša da piše, u tom trenutku se kreira duplikat, nudeći drugačiji pristup kreiranju procesa i upravljanju memorijom.

Dužine

U x64 binarnim fajlovima, canary kolačić je 0x8 bajt qword. Prva sedam bajtova su slučajna i poslednji bajt je nula bajt.

U x86 binarnim fajlovima, canary kolačić je 0x4 bajt dword. Prva tri bajta su slučajna i poslednji bajt je nula bajt.

{% hint style="danger" %} Najmanje značajan bajt oba canary-ja je nula bajt jer će biti prvi na steku dolazeći sa nižih adresa i stoga funkcije koje čitaju stringove će prestati pre nego što ga pročitaju. {% endhint %}

Bypasses

Procurenje canary-ja a zatim prepisivanje njega (npr. preplavljivanje bafera) sa sopstvenom vrednošću.

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

{% content-ref url="bf-forked-stack-canaries.md" %} bf-forked-stack-canaries.md {% endcontent-ref %}

  • Ako postoji neka zanimljiva procena ili proizvoljno čitanje ranjivosti u binarnom fajlu možda je moguće procuriti ga:

{% content-ref url="print-stack-canary.md" %} print-stack-canary.md {% endcontent-ref %}

  • Prepisivanje pokazivača smeštenih na steku

Stek ranjiv na preplavljivanje steka može sadržati adrese ka stringovima ili funkcijama koje mogu biti prepisane kako bi se iskoristila ranjivost bez potrebe da se dosegne canary steka. Proverite:

{% content-ref url="../../stack-overflow/pointer-redirecting.md" %} pointer-redirecting.md {% endcontent-ref %}

  • Modifikacija i master i thread canary-ja

Preplavljivanje bafera u niti zaštićenoj canary-jem može se koristiti za modifikaciju master canary-ja niti. Kao rezultat, mitigacija je beskorisna jer se provera vrši sa dva canary-ja koji su isti (iako modifikovani).

Osim toga, preplavljivanje bafera u niti zaštićenoj canary-jem može se koristiti za modifikaciju master canary-ja smeštenog u TLS-u. To je zato što je moguće dostići memorijsku poziciju gde je TLS smešten (i stoga, canary) putem bof-a na steku niti.
Kao rezultat, mitigacija je beskorisna jer se provera vrši sa dva canary-ja koji su isti (iako modifikovani).
Ovaj napad je izvršen u writeup-u: http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads

Pogledajte 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 pomoću mmap i kada se kreira stek niti takođe se generiše pomoću mmap prema tome, što može omogućiti preplavljivanje kao što je prikazano u prethodnom writeup-u.

  • Modifikacija GOT unosa __stack_chk_fail

Ako binarni fajl ima Partial RELRO, tada možete koristiti proizvoljni zapis da modifikujete GOT unos __stack_chk_fail da bude lažna funkcija koja ne blokira program ako se canary modifikuje.

Ovaj napad je izvršen u writeup-u: https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/

Reference

{% hint style="success" %} Učite i vežbajte hakovanje AWS-a:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte hakovanje GCP-a: HackTricks Training GCP Red Team Expert (GRTE)

Podržite HackTricks
{% endhint %}