3.9 KiB
Atak na duży kubełek
Zacznij od zera i opanuj hakowanie AWS dzięki 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 hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud github repos.
Podstawowe informacje
Aby uzyskać więcej informacji na temat tego, co oznacza duży kubełek, sprawdź tę stronę:
{% content-ref url="bins-and-memory-allocations.md" %} bins-and-memory-allocations.md {% endcontent-ref %}
Można znaleźć świetny przykład w how2heap - atak na duży kubełek.
W zasadzie można zobaczyć, jak w najnowszej "obecnej" wersji glibc (2.35) nie jest sprawdzane: P->bk_nextsize
, co pozwala zmodyfikować dowolny adres wartością dużego kawałka kubełka, jeśli spełnione są pewne warunki.
W tym przykładzie można znaleźć następujące warunki:
- Zaalokowany jest duży kawałek
- Zaalokowany jest duży kawałek mniejszy od pierwszego, ale w tym samym indeksie
- Musi być mniejszy, więc musi iść pierwszy w kubełku
- (Tworzony jest kawałek, aby zapobiec scaleniu z kawałkiem górnym)
- Następnie pierwszy duży kawałek jest zwalniany, a zaalokowany jest nowy kawałek większy od niego -> Kawałek1 trafia do dużego kubełka
- Następnie drugi duży kawałek jest zwalniany
- Teraz podatność: Atakujący może zmodyfikować
chunk1->bk_nextsize
na[target-0x20]
- Następnie zaalokowany jest większy kawałek niż kawałek 2, więc kawałek2 jest wstawiany do dużego kubełka, nadpisując adres
chunk1->bk_nextsize->fd_nextsize
adresem kawałka2
{% hint style="success" %}
Istnieją inne potencjalne scenariusze, chodzi o dodanie do dużego kubełka kawałka, który jest mniejszy niż aktualny kawałek X w kubełku, więc musi zostać wstawiony tuż przed nim w kubełku, i musimy móc zmodyfikować bk_nextsize
X, ponieważ właśnie tam zostanie zapisany adres mniejszego kawałka.
{% endhint %}
Oto istotny kod z funkcji malloc. Dodano komentarze, aby lepiej zrozumieć, jak został nadpisany adres:
{% code overflow="wrap" %}
/* if smaller than smallest, bypass loop below */
assert (chunk_main_arena (bck->bk));
if ((unsigned long) (size) < (unsigned long) chunksize_nomask (bck->bk))
{
fwd = bck; // fwd = p1
bck = bck->bk; // bck = p1->bk
victim->fd_nextsize = fwd->fd; // p2->fd_nextsize = p1->fd (Note that p1->fd is p1 as it's the only chunk)
victim->bk_nextsize = fwd->fd->bk_nextsize; // p2->bk_nextsize = p1->fd->bk_nextsize
fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim; // p1->fd->bk_nextsize->fd_nextsize = p2
}
{% endcode %}
To może być użyte do nadpisania zmiennej globalnej global_max_fast
w libc, aby następnie wykorzystać atak na szybkie kubełki z większymi fragmentami.
Możesz znaleźć inną świetną wyjaśnienie tego ataku na stronie guyinatuxedo.