Heap Overflow
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Przepełnienie sterty (heap overflow) jest jak przepełnienie stosu, 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 przepełnień stosu wiemy, że niektóre rejestry, takie jak wskaźnik instrukcji lub ramka stosu, będą przywracane ze stosu i może być możliwe ich nadużycie. W przypadku przepełnień sterty, 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 napastnik mógłby to wykorzystać.
Aby znaleźć przesunięcia przepełnienia, możesz użyć tych samych wzorców, co w przepełnieniach stosu.
W przypadku przepełnień stosu 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 przepełnienia sterty używana pamięć nie jest liniowa, ale przydzielone kawałki są zazwyczaj w oddzielnych pozycjach pamięci (nie jeden obok drugiego) z powodu koszyków i stref oddzielających przydziały według rozmiaru oraz dlatego, że wcześniej zwolniona pamięć jest używana przed przydzieleniem nowych kawałków. Trudno jest wiedzieć, który obiekt będzie kolidował z tym, który jest podatny na przepełnienie sterty. Dlatego, gdy znajdzie się przepełnienie sterty, 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 przepełnienie sterty, aby wymusić kolizję przepełnionego obiektu z obiektem ofiary, kilka kalloc
jest wymuszanych przez kilka wątków, aby spróbować zapewnić, że wszystkie wolne kawałki są wypełnione i że tworzona jest nowa strona.
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żliwe jest dokładne określenie rozmiaru alokacji kalloc
, a gdy odpowiedni port mach zostanie zniszczony, odpowiednia alokacja zostanie natychmiast zwolniona z powrotem do kfree
.
Następnie niektóre z tych miejsc rezerwowych mogą być zwolnione. Lista wolnych kalloc.4096
zwalnia elementy w kolejności ostatni wchodzi, pierwszy wychodzi, co zasadniczo oznacza, że jeśli niektóre miejsca rezerwowe 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.
Na tej stronie można znaleźć podstawową emulację przepełnienia sterty, 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 przepełnienie sterty może być wykorzystane do wywołania funkcji zwycięzcy, aby zdobyć flagę.
W przykładzie protostar heap 1 można zobaczyć, jak nadużycie przepełnienia bufora pozwala na nadpisanie w pobliskim kawałku adresu, gdzie dane użytkownika będą zapisywane.
Na stronie https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/ można znaleźć przykład przepełnienia sterty, 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 poprzez nadpisanie go prostym exploitem, takim jak:
Używamy podatności 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.
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)