Libc Protections

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Egzekwowanie Wyrównania Kawałków

Malloc alokuje pamięć w grupach 8 bajtów (32-bitowych) lub 16 bajtów (64-bitowych). Oznacza to, że koniec kawałków w systemach 32-bitowych powinien być wyrównany z 0x8, a w systemach 64-bitowych z 0x0. Funkcja zabezpieczeń sprawdza, czy każdy kawałek jest poprawnie wyrównany na tych konkretnych lokalizacjach przed użyciem wskaźnika z pojemnika.

Korzyści dla Bezpieczeństwa

Egzekwowanie wyrównania kawałków w systemach 64-bitowych znacząco zwiększa bezpieczeństwo Malloc poprzez ograniczenie umieszczania fałszywych kawałków tylko na 1 z każdych 16 adresów. Sprawia to, że wysiłki eksploatacyjne są bardziej skomplikowane, zwłaszcza w scenariuszach, gdzie użytkownik ma ograniczoną kontrolę nad wartościami wejściowymi, co sprawia, że ataki są bardziej złożone i trudniejsze do wykonania z sukcesem.

  • Atak Fastbin na __malloc_hook

Nowe zasady wyrównania w Malloc również udaremniają klasyczny atak polegający na __malloc_hook. Wcześniej atakujący mogli manipulować rozmiarami kawałków, aby nadpisać ten wskaźnik funkcji i uzyskać wykonanie kodu. Teraz surowe wymagania wyrównania zapewniają, że takie manipulacje nie są już możliwe, zamykając powszechną drogę eksploatacji i zwiększając ogólne bezpieczeństwo.

Mieszanie Wskaźników na fastbinach i tcache

Mieszanie Wskaźników to zabezpieczenie używane do ochrony szybkich pojemników i wskaźników Fd tcache w operacjach zarządzania pamięcią. Ta technika pomaga zapobiegać pewnym rodzajom taktyk eksploatacji pamięci, zwłaszcza tym, które nie wymagają wycieku informacji o pamięci ani manipulowania lokalizacjami pamięci bezpośrednio względem znanych pozycji (nadpisywanie względne).

Rdzeniem tej techniki jest wzór obfuskacji:

Nowy_Wskaźnik = (L >> 12) XOR P

  • L to Lokalizacja Przechowywania wskaźnika.

  • P to rzeczywisty Wskaźnik Fd szybkiego pojemnika/tcache.

Powód przesunięcia bitowego lokalizacji przechowywania (L) o 12 bitów w prawo przed operacją XOR jest kluczowy. Ta manipulacja adresuje podatność wynikającą z deterministycznej natury najmniej znaczących 12 bitów adresów pamięci, które zazwyczaj są przewidywalne ze względu na ograniczenia architektury systemu. Przesunięcie bitów przenosi przewidywalną część z równania, zwiększając losowość nowego, zmieszanego wskaźnika i tym samym zabezpieczając przed atakami polegającymi na przewidywalności tych bitów.

Ten zmieszany wskaźnik wykorzystuje istniejącą losowość zapewnianą przez Losową Układankę Przestrzeni Adresowej (ASLR), która losuje adresy używane przez programy, aby utrudnić atakującym przewidywanie układu pamięci procesu.

Demiksowanie wskaźnika w celu odzyskania oryginalnego adresu polega na użyciu tej samej operacji XOR. Tutaj zmieszany wskaźnik jest traktowany jako P w formule, a gdy jest XORowany z niezmienioną lokalizacją przechowywania (L), odsłania oryginalny wskaźnik. Ta symetria w mieszaniu i demiksowaniu zapewnia, że system może efektywnie kodować i dekodować wskaźniki bez znaczącego narzutu, jednocześnie znacznie zwiększając bezpieczeństwo przed atakami manipulującymi wskaźnikami pamięci.

Korzyści dla Bezpieczeństwa

Mieszanie wskaźników ma na celu zapobieganie nadpisywaniu częściowego i pełnego wskaźnika w stercie, co stanowi znaczące wzmocnienie bezpieczeństwa. Ta funkcja wpływa na techniki eksploatacji w kilku aspektach:

  1. Zapobieganie Nadpisywaniu Wskaźników Względnych Bye Byte: Wcześniej atakujący mogli zmienić część wskaźnika, aby przekierować kawałki sterty na inne lokalizacje bez znajomości dokładnych adresów, technika widoczna w eksploacie House of Roman bez wycieku pamięci. Dzięki mieszaniu wskaźników, takie nadpisywanie względne bez wycieku sterty teraz wymaga brutalnej siły, drastycznie zmniejszając szanse na sukces.

  2. Zwiększenie Trudności Ataków na Pojemniki Tcache/Fastbin: Powszechne ataki, które nadpisują wskaźniki funkcji (jak __malloc_hook) poprzez manipulowanie wpisami szybkich pojemników lub tcache, są utrudnione. Na przykład atak może polegać na wycieku adresu LibC, zwolnieniu kawałka do pojemnika tcache, a następnie nadpisaniu wskaźnika Fd, aby przekierować go do __malloc_hook w celu wykonania arbitralnego kodu. Dzięki mieszaniu wskaźników, te wskaźniki muszą być poprawnie zmieszane, wymagając wycieku sterty dla dokładnej manipulacji, podnosząc tym samym barierę eksploatacji.

  3. Wymaganie Wycieku Sterty w Lokacjach Poza Stertą: Utworzenie fałszywego kawałka w obszarach poza stertą (jak stos, sekcja .bss lub PLT/GOT) teraz również wymaga wycieku sterty ze względu na konieczność mieszania wskaźników. To zwiększa złożoność eksploatowania tych obszarów, podobnie jak wymaganie manipulowania adresami LibC.

  4. Wyciek Adresów Sterty Staje Się Trudniejszy: Mieszanie wskaźników ogranicza przydatność wskaźników Fd w szybkich pojemnikach i pojemnikach tcache jako źródeł wycieków adresów sterty. Jednak wskaźniki w nieuporządkowanych, małych i dużych pojemnikach pozostają niezmieszane, nadal więc nadają się do wycieków adresów. Ten przesunięty nacisk zmusza atakujących do eksplorowania tych pojemników w poszukiwaniu informacji podatnych na eksploatację, chociaż niektóre techniki mogą nadal pozwalać na demiksowanie wskaźników przed wyciekiem, choć z ograniczeniami.

Demiksowanie Wskaźników z Wyciekiem Sterty

Dla lepszego wyjaśnienia procesu sprawdź oryginalny post tutaj.

Przegląd Algorytmu

Wzór używany do mieszania i demiksowania wskaźników to:

Nowy_Wskaźnik = (L >> 12) XOR P

Gdzie L to lokalizacja przechowywania, a P to wskaźnik Fd. Gdy L jest przesuwane w prawo o 12 bitów, odsłania najbardziej znaczące bity P, ze względu na naturę XOR, która zwraca 0, gdy bity są XORowane ze sobą.

Kluczowe Kroki w Algorytmie:

  1. Początkowe Wycieki Najbardziej Znaczących Bitów: Poprzez XORowanie przesuniętego L z P, efektywnie otrzymujesz 12 najbardziej znaczących bitów P, ponieważ przesunięta część L będzie zerem, pozostawiając niezmienione bity odpowiadające P.

  2. Odzyskiwanie Bitów Wskaźnika: Ponieważ XOR jest odwracalny, znając wynik i jeden z operandów, możesz obliczyć drugi operand. Ta właściwość jest wykorzystywana do wydedukowania całego zestawu bitów dla P, poprzez sukcesywne XORowanie znanych zestawów bitów z częściami zmieszanego wskaźnika.

  3. Iteracyjne Demiksowanie: Proces jest powtarzany, za każdym razem używając nowo odkrytych bitów P z poprzedniego kroku do dekodowania kolejnego segmentu zmieszanego wskaźnika, aż wszystkie bity zostaną odzyskane.

  4. Obsługa Deterministycznych Bitów: Ostatnie 12 bitów L jest tracone z powodu przesunięcia, ale są one deterministyczne i mogą być odtworzone po procesie.

Możesz znaleźć implementację tego algorytmu tutaj: https://github.com/mdulin2/mangle

Ochrona wskaźnika

Ochrona wskaźnika to technika zabezpieczeń wykorzystywana w bibliotece glibc do ochrony przechowywanych wskaźników funkcji, zwłaszcza tych zarejestrowanych przez wywołania biblioteczne, takie jak atexit(). Ochrona ta polega na przemieszaniu wskaźników poprzez XORowanie ich z sekretem przechowywanym w danych wątku (fs:0x30) i zastosowaniu bitowej rotacji. Mechanizm ten ma na celu zapobieganie atakom polegającym na przejęciu kontroli poprzez nadpisanie wskaźników funkcji.

Ominięcie ochrony wskaźnika za pomocą wycieku

  1. Zrozumienie operacji ochrony wskaźnika: Przemieszanie wskaźników jest wykonywane za pomocą makra PTR_MANGLE, które XORuje wskaźnik z 64-bitowym tajnym kluczem, a następnie wykonuje lewą rotację o 0x11 bitów. Operacja odwrotna, czyli odzyskanie pierwotnego wskaźnika, jest obsługiwana przez PTR_DEMANGLE.

  2. Strategia ataku: Atak opiera się na podejściu znanych tekstów jawnie, gdzie atakujący musi znać zarówno oryginalną, jak i przemieszaną wersję wskaźnika, aby wydedukować użyty do przemieszania sekret.

  3. Wykorzystanie znanych tekstów jawnie:

  • Identyfikacja stałych wskaźników funkcji: Poprzez analizę kodu źródłowego glibc lub zainicjowanych tabel wskaźników funkcji (np. __libc_pthread_functions), atakujący może znaleźć przewidywalne wskaźniki funkcji.

  • Obliczanie sekretu: Korzystając z znanego wskaźnika funkcji, takiego jak __pthread_attr_destroy i jego przemieszanej wersji z tabeli wskaźników funkcji, sekret można obliczyć poprzez odwrócenie rotacji (rotacja w prawo) przemieszanego wskaźnika, a następnie XORowanie go z adresem funkcji.

  1. Alternatywne teksty jawnie: Atakujący może również eksperymentować z przemieszaniem wskaźników znanymi wartościami, takimi jak 0 lub -1, aby sprawdzić, czy powodują one rozpoznawalne wzorce w pamięci, potencjalnie ujawniając sekret, gdy te wzorce zostaną znalezione w zrzutach pamięci.

  2. Zastosowanie praktyczne: Po obliczeniu sekretu atakujący może manipulować wskaźnikami w kontrolowany sposób, w zasadzie omijając ochronę wskaźnika w aplikacji wielowątkowej z wiedzą o adresie bazowym libc i możliwością odczytu dowolnych lokalizacji pamięci.

Odnośniki

Last updated