7.7 KiB
Przepełnienie sterty
Nauka hakowania AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLANY SUBSKRYPCYJNE!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do HackTricks i HackTricks Cloud na GitHubie.
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że 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ć.
{% hint style="success" %} Aby znaleźć przesunięcia przepełnień, można użyć tych samych wzorców co w przepełnieniach stosu. {% endhint %}
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 wywołania 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 podobne rodzaje 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 koszykó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 obiektu, 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 ostatni wchodzi, pierwszy wychodzi, co w zasadzie oznacza, że jeśli niektóre miejsca są zwalniane i exploit próbuje alokować kilka obiektów ofiary podczas próby alokacji obiektu podatnego na przepełnienie, jest prawdopodobne, że ten obiekt będzie następowany przez obiekt ofiary.
Przykład libc
W tym miejscu 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 jego 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żywając przepełnienia bufora, możliwe jest 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 jego nadpisanie 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:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF sprawdź PLANY SUBSKRYPCYJNE!
- Kup oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się swoimi sztuczkami hakowania, przesyłając PR-y do HackTricks i HackTricks Cloud na GitHubie.