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

8.6 KiB

Stack Canaries

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

Drugi načini podrške HackTricks-u:

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 pristupa na sofisticiraniji način 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 naspram granice vrednosti 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 StackShield takođe 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 sigurno 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. Međutim, 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 da postavi canary, i na kraju da proveri njegovu celovitost.

Kada veb server koristi fork(), omogućava napad brute-force da pogodi bajt canary-ja po bajt. Međutim, korišćenje execve() nakon fork() prepisuje memorijski prostor, poništavajući napad. vfork() omogućava detetu procesu da izvrši bez dupliranja dok ne pokuša da piše, nakon čega 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="opasnost" %} 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 sa čitanjem pre njega. {% endhint %}

Bypasses

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

  • Ako je canary forkovan u dečijim procesima možda je moguće brute-force-ovati ga po bajtovima:

{% 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, možete koristiti proizvoljni zapis za modifikaciju GOT unosa __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

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

Drugi načini podrške HackTricks-u: