mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
77 lines
6.1 KiB
Markdown
77 lines
6.1 KiB
Markdown
# Stack Canaries
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|
|
|
|
## **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:
|
|
|
|
{{#ref}}
|
|
bf-forked-stack-canaries.md
|
|
{{#endref}}
|
|
|
|
- Ako postoji neka zanimljiva **curenje ili ranjivost u čitanju** u binarnoj datoteci može biti moguće da se curi:
|
|
|
|
{{#ref}}
|
|
print-stack-canary.md
|
|
{{#endref}}
|
|
|
|
- **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:
|
|
|
|
{{#ref}}
|
|
../../stack-overflow/pointer-redirecting.md
|
|
{{#endref}}
|
|
|
|
- **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](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](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/](https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/)
|
|
|
|
## Reference
|
|
|
|
- [https://guyinatuxedo.github.io/7.1-mitigation_canary/index.html](https://guyinatuxedo.github.io/7.1-mitigation_canary/index.html)
|
|
- [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads)
|
|
- [https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/](https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/)
|
|
|
|
{{#include ../../../banners/hacktricks-training.md}}
|