Heap Overflow

Nauka hakowania AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Podstawowe informacje

Przepełnienie sterty jest podobne do przepełnienia stosu, ale występuje w stercie. Oznacza to, że pewna przestrzeń została zarezerwowana w stercie do przechowywania danych i przechowywane dane były większe niż zarezerwowana przestrzeń.

W przypadku przepełnień stosu wiemy, że niektóre rejestry, takie jak wskaźnik instrukcji lub ramka stosu, zostaną przywrócone ze stosu i możliwe jest ich nadużycie. W przypadku przepełnień sterty domyślnie nie ma przechowywanych żadnych wrażliwych informacji w kawałku sterty, który może zostać przepełniony. Jednak mogą to być wrażliwe informacje lub wskaźniki, więc krytyczność tej podatności zależy od tego, które dane mogą zostać nadpisane i jak atakujący mógłby to wykorzystać.

Aby znaleźć przesunięcia przepełnień, można użyć tych samych wzorców co przy przepełnieniach stosu.

Przepełnienia stosu vs przepełnienia sterty

W przypadku przepełnień stosu układ i dane, które będą obecne na stosie w momencie wystąpienia podatności, są dość niezawodne. Wynika to z faktu, że stos jest liniowy, zawsze zwiększający się w kolizyjnej pamięci, w konkretnych miejscach działania programu pamięć stosu zazwyczaj przechowuje podobny rodzaj danych i ma określoną strukturę z pewnymi wskaźnikami na końcu części stosu używanej przez każdą funkcję.

Jednak w przypadku przepełnienia sterty, ponieważ używana pamięć nie jest liniowa, ale zarezerwowane kawałki są zazwyczaj w oddzielonych pozycjach pamięci (nie obok siebie) z powodu kubłów i stref, które separują alokacje według rozmiaru i ponieważ poprzednio zwolniona pamięć jest używana przed alokacją nowych kawałków. Jest trudno określić obiekt, który będzie kolidować z obiektem podatnym na przepełnienie sterty. Dlatego, gdy znajdowane jest przepełnienie sterty, konieczne jest znalezienie niezawodnego sposobu, aby pożądany obiekt był następny w pamięci od tego, który może zostać przepełniony.

Jedną z technik używanych do tego jest Grooming sterty, która jest używana na przykład w tym poście. W poście wyjaśniono, że gdy w jądrze iOS strefa wyczerpie pamięć do przechowywania kawałków pamięci, rozszerza ją o stronę jądra, a ta strona jest dzielona na kawałki o oczekiwanych rozmiarach, które będą używane w kolejności (do wersji iOS 9.2, następnie te kawałki są używane w losowy sposób, aby utrudnić eksploatację tych ataków).

Dlatego w poprzednim poście, gdzie występuje przepełnienie sterty, aby wymusić, aby obiekt podatny na przepełnienie kolidował z obiektem ofiary, kilka kallocs jest wymuszanych przez kilka wątków, aby upewnić się, że wszystkie wolne kawałki są wypełnione i że zostaje utworzona nowa strona.

Aby wymusić to wypełnienie obiektami o określonym rozmiarze, alokacja poza linią związaną z portem mach iOS jest idealnym kandydatem. Poprzez dostosowanie rozmiaru wiadomości możliwe jest dokładne określenie rozmiaru alokacji kalloc, a gdy odpowiadający port mach zostanie zniszczony, odpowiadająca alokacja zostanie natychmiast zwolniona z powrotem do kfree.

Następnie niektóre z tych miejsc mogą być zwolnione. Lista zwolnionych elementów kalloc.4096 zwalnia elementy w kolejności od ostatniego do pierwszego, co oznacza, że jeśli niektóre miejsca są zwalniane i exploit próbuje alokować kilka obiektów ofiary, podczas gdy próbuje alokować obiekt podatny na przepełnienie, jest prawdopodobne, że ten obiekt będzie następowany przez obiekt ofiary.

Przykładowa biblioteka libc

Na tej stronie można znaleźć podstawową emulację przepełnienia sterty, która pokazuje, jak nadpisanie poprzedniego bitu w użyciu następnego kawałka i pozycja poprzedniego rozmiaru umożliwia skonsolidowanie użytego kawałka (poprzez sprawienie, że myśli, że jest nieużywany) i następnie ponowne go alokowanie, co pozwala na nadpisanie danych używanych w innym wskaźniku.

Inny przykład z protostar heap 0 pokazuje bardzo podstawowy przykład CTF, w którym przepełnienie sterty może być wykorzystane do wywołania funkcji zwycięzcy i uzyskania flagi.

W przykładzie protostar heap 1 można zobaczyć, jak nadużycie przepełnienia bufora umożliwia nadpisanie w sąsiednim kawałku adresu, gdzie dowolne dane od użytkownika zostaną zapisane.

Przykład ARM64

Na stronie https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/ znajdziesz przykład przepełnienia sterty, gdzie polecenie, które ma zostać wykonane, jest przechowywane w następnym kawałku po przepełnionym kawałku. Dlatego możliwe jest zmodyfikowanie wykonywanego polecenia poprzez nadpisanie go prostym exploitem.

python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
Nauka hakowania AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Last updated