Stack Canaries
Reading time: 5 minutes
tip
Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Wsparcie HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegram lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów github.
StackGuard i StackShield
StackGuard wstawia specjalną wartość znaną jako canary przed EIP (Extended Instruction Pointer), konkretnie 0x000aff0d
(reprezentujący null, newline, EOF, carriage return), aby chronić przed przepełnieniem bufora. Jednak funkcje takie jak recv()
, memcpy()
, read()
, i bcopy()
pozostają podatne, a ochrona nie obejmuje EBP (Base Pointer).
StackShield przyjmuje bardziej zaawansowane podejście niż StackGuard, utrzymując Global Return Stack, który przechowuje wszystkie adresy powrotu (EIPs). Ta konfiguracja zapewnia, że każde przepełnienie nie powoduje szkód, ponieważ pozwala na porównanie przechowywanych i rzeczywistych adresów powrotu w celu wykrycia wystąpień przepełnienia. Dodatkowo, StackShield może sprawdzić adres powrotu w stosunku do wartości granicznej, aby wykryć, czy EIP wskazuje poza oczekiwaną przestrzeń danych. Jednak ta ochrona może być obejściem za pomocą technik takich jak Return-to-libc, ROP (Return-Oriented Programming) lub ret2ret, co wskazuje, że StackShield również nie chroni zmiennych lokalnych.
Stack Smash Protector (ProPolice) -fstack-protector
:
Ten mechanizm umieszcza canary przed EBP i reorganizuje zmienne lokalne, aby umieścić bufory na wyższych adresach pamięci, zapobiegając ich nadpisywaniu innych zmiennych. Bezpiecznie kopiuje również argumenty przekazywane na stosie powyżej zmiennych lokalnych i używa tych kopii jako argumentów. Jednak nie chroni tablic z mniej niż 8 elementami ani buforów w strukturze użytkownika.
Canary to losowa liczba pochodząca z /dev/urandom
lub domyślna wartość 0xff0a0000
. Jest przechowywana w TLS (Thread Local Storage), co pozwala na współdzielenie przestrzeni pamięci między wątkami, aby miały one specyficzne dla wątku zmienne globalne lub statyczne. Te zmienne są początkowo kopiowane z procesu nadrzędnego, a procesy potomne mogą zmieniać swoje dane bez wpływu na proces nadrzędny lub rodzeństwo. Niemniej jednak, jeśli fork()
jest używane bez tworzenia nowego canary, wszystkie procesy (nadrzędne i potomne) dzielą ten sam canary, co czyni je podatnymi. W architekturze i386 canary jest przechowywane w gs:0x14
, a w x86_64 w fs:0x28
.
Ta lokalna ochrona identyfikuje funkcje z buforami podatnymi na ataki i wstrzykuje kod na początku tych funkcji, aby umieścić canary, a na końcu, aby zweryfikować jego integralność.
Gdy serwer WWW używa fork()
, umożliwia to atak brute-force w celu odgadnięcia bajtu canary po bajcie. Jednak użycie execve()
po fork()
nadpisuje przestrzeń pamięci, niwecząc atak. vfork()
pozwala procesowi potomnemu na wykonanie bez duplikacji, aż spróbuje zapisać, w którym momencie tworzony jest duplikat, oferując inne podejście do tworzenia procesów i zarządzania pamięcią.
Długości
W binariach x64
cookie canary to 0x8
bajtowy qword. Pierwsze siedem bajtów jest losowych, a ostatni bajt to null byte.
W binariach x86
cookie canary to 0x4
bajtowy dword. Pierwsze trzy bajty są losowe, a ostatni bajt to null byte.
caution
Najmniej znaczący bajt obu canary to null byte, ponieważ będzie pierwszym na stosie pochodzącym z niższych adresów i dlatego funkcje, które odczytują ciągi, zatrzymają się przed jego odczytaniem.
Obejścia
Wyciekanie canary i następnie nadpisywanie go (np. przepełnienie bufora) własną wartością.
- Jeśli canary jest forkowane w procesach potomnych, może być możliwe brute-force go bajt po bajcie:
{{#ref}} bf-forked-stack-canaries.md {{#endref}}
- Jeśli w binarnym kodzie występuje interesujące wyciekanie lub podatność na odczyt dowolny, może być możliwe jego wyciekanie:
{{#ref}} print-stack-canary.md {{#endref}}
- Nadpisywanie wskaźników przechowywanych na stosie
Stos podatny na przepełnienie stosu może zawierać adresy do ciągów lub funkcji, które mogą być nadpisane, aby wykorzystać podatność bez potrzeby dotarcia do canary. Sprawdź:
{{#ref}} ../../stack-overflow/pointer-redirecting.md {{#endref}}
- Modyfikacja zarówno master, jak i thread canary
Przepełnienie bufora w funkcji wątkowej chronionej canary może być użyte do modyfikacji master canary w wątku. W rezultacie, łagodzenie jest bezużyteczne, ponieważ sprawdzenie jest używane z dwoma canary, które są takie same (choć zmodyfikowane).
Ponadto, przepełnienie bufora w funkcji wątkowej chronionej canary mogłoby być użyte do modyfikacji master canary przechowywanego w TLS. To dlatego, że może być możliwe dotarcie do pozycji pamięci, w której przechowywane jest TLS (a zatem, canary) za pomocą bof na stosie wątku.
W rezultacie, łagodzenie jest bezużyteczne, ponieważ sprawdzenie jest używane z dwoma canary, które są takie same (choć zmodyfikowane).
Ten atak jest opisany w artykule: http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads
Sprawdź również prezentację https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015, która wspomina, że zazwyczaj TLS jest przechowywane przez mmap
, a gdy stos wątku jest tworzony, jest również generowany przez mmap
, co może umożliwić przepełnienie, jak pokazano w poprzednim artykule.
- Modyfikacja wpisu GOT
__stack_chk_fail
Jeśli binarny kod ma Partial RELRO, można użyć dowolnego zapisu, aby zmodyfikować GOT entry __stack_chk_fail
na funkcję zastępczą, która nie blokuje programu, jeśli canary zostanie zmodyfikowane.
Ten atak jest opisany w artykule: https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/
Odniesienia
- https://guyinatuxedo.github.io/7.1-mitigation_canary/index.html
- http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads
- https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/
tip
Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Wsparcie HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegram lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów github.