Heap Overflow

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

Podstawowe informacje

Heap overflow jest jak stack overflow, ale w stercie. Zasadniczo oznacza to, że pewna przestrzeń została zarezerwowana w stercie do przechowywania danych, a przechowywane dane były większe niż zarezerwowana przestrzeń.

W przypadku stack overflow wiemy, że niektóre rejestry, takie jak wskaźnik instrukcji czy ramka stosu, będą przywracane ze stosu i można to wykorzystać. W przypadku heap overflow nie ma żadnych wrażliwych informacji przechowywanych domyślnie w kawałku sterty, który może być przepełniony. Jednak mogą to być wrażliwe informacje lub wskaźniki, więc krytyczność tej podatności zależy od tego, jakie dane mogą być nadpisane i jak atakujący może to wykorzystać.

tip

Aby znaleźć przesunięcia przepełnienia, możesz użyć tych samych wzorców, co w przypadku stack overflow.

Stack Overflows vs Heap Overflows

W przypadku stack overflow układ i dane, które będą obecne na stosie w momencie, gdy podatność może zostać wyzwolona, są dość wiarygodne. Dzieje się tak, ponieważ stos jest liniowy, zawsze rośnie w kolidującej pamięci, w konkretnych miejscach działania programu pamięć stosu zazwyczaj przechowuje podobny rodzaj danych i ma pewną specyficzną strukturę z pewnymi wskaźnikami na końcu części stosu używanej przez każdą funkcję.

Jednak w przypadku heap overflow używana pamięć nie jest liniowa, ale alokowane kawałki są zazwyczaj w oddzielnych pozycjach pamięci (nie jeden obok drugiego) z powodu koszyków i stref oddzielających alokacje według rozmiaru oraz dlatego, że wcześniej zwolniona pamięć jest używana przed alokowaniem nowych kawałków. Trudno jest wiedzieć, który obiekt będzie kolidował z tym, który jest podatny na heap overflow. Dlatego, gdy znajdzie się heap overflow, konieczne jest znalezienie wiarygodnego sposobu, aby pożądany obiekt był następny w pamięci od tego, który może być przepełniony.

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

Dlatego w poprzednim poście, w którym występuje heap overflow, aby wymusić kolizję przepełnionego obiektu z obiektem ofiary, kilka kallocs jest wymuszanych przez kilka wątków, aby spróbować zapewnić, że wszystkie wolne kawałki są wypełnione i że nowa strona jest tworzona.

Aby wymusić to wypełnienie obiektami o określonym rozmiarze, alokacja poza linią związana z portem mach iOS jest idealnym kandydatem. Poprzez skonstruowanie rozmiaru wiadomości, można dokładnie określić rozmiar alokacji kalloc, a gdy odpowiedni port mach zostanie zniszczony, odpowiednia alokacja zostanie natychmiast zwolniona do kfree.

Następnie niektóre z tych miejsc mogą być zwolnione. Lista wolnych elementów kalloc.4096 zwalnia elementy w kolejności ostatni wchodzi, pierwszy wychodzi, co zasadniczo oznacza, że jeśli niektóre miejsca są zwolnione, a exploit próbuje alokować kilka obiektów ofiar, podczas gdy próbuje alokować obiekt podatny na przepełnienie, prawdopodobne jest, że ten obiekt będzie następował po obiekcie ofiary.

Przykład libc

Na tej stronie można znaleźć podstawową emulację heap overflow, która pokazuje, jak nadpisanie bitu prev in use następnego kawałka i pozycji prev size pozwala na konsolidację używanego kawałka (sprawiając, że myśli, że jest nieużywany) i następnie ponowne przydzielenie go, będąc w stanie nadpisać dane, które są używane w innym wskaźniku.

Inny przykład z protostar heap 0 pokazuje bardzo podstawowy przykład CTF, w którym heap overflow może być wykorzystany do wywołania funkcji zwycięzcy, aby zdobyć flagę.

W przykładzie protostar heap 1 można zobaczyć, jak wykorzystując przepełnienie bufora, można nadpisać w pobliskim kawałku adres, gdzie dane użytkownika będą zapisywane.

Przykład ARM64

Na stronie https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/ można znaleźć przykład heap overflow, w którym polecenie, które ma być wykonane, jest przechowywane w następnym kawałku z przepełnionego kawałka. Tak więc, możliwe jest modyfikowanie wykonywanego polecenia, nadpisując je prostym exploitem, takim jak:

bash
python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt

Inne przykłady

  • Auth-or-out. Hack The Box
  • Wykorzystujemy podatność na przepełnienie całkowite, aby uzyskać przepełnienie sterty.
  • Korumpujemy wskaźniki do funkcji wewnątrz struct przepełnionego kawałka, aby ustawić funkcję taką jak system i uzyskać wykonanie kodu.

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