Off by one overflow
Last updated
Last updated
Dowiedz się i ćwicz hakowanie AWS:HackTricks Training AWS Red Team Expert (ARTE) Dowiedz się i ćwicz hakowanie GCP: HackTricks Training GCP Red Team Expert (GRTE)
Mając dostęp tylko do przepełnienia o jeden bajt, atakujący może modyfikować pole size
z następnego fragmentu. Pozwala to manipulować, które fragmenty są faktycznie zwalniane, potencjalnie generując fragment zawierający inny prawidłowy fragment. Wykorzystanie jest podobne do podwójnego zwalniania pamięci lub nakładających się fragmentów.
Istnieją 2 rodzaje podatności na przepełnienie o jeden:
Dowolny bajt: Ten rodzaj pozwala nadpisać ten bajt dowolną wartością
Bajt zerowy (off-by-null): Ten rodzaj pozwala nadpisać ten bajt tylko wartością 0x00
Powszechnym przykładem tej podatności jest poniższy kod, w którym zachowanie strlen
i strcpy
jest niekonsekwentne, co pozwala ustawić bajt 0x00 na początku następnego fragmentu.
Można to wykorzystać za pomocą House of Einherjar.
Jeśli używany jest Tcache, można to wykorzystać do sytuacji podwójnego zwalniania pamięci.
Wśród innych sprawdzeń, teraz za każdym razem, gdy kawałek jest zwalniany, rozmiar poprzedni jest porównywany z rozmiarem skonfigurowanym w metadanych kawałka, co sprawia, że ten atak jest dość skomplikowany od wersji 2.28.
Ten atak już nie działa ze względu na użycie Tcaches.
Ponadto, jeśli spróbujesz go wykorzystać, używając większych kawałków (aby tcaches nie były zaangażowane), otrzymasz błąd: malloc(): invalid next size (unsorted)
Umieść kawałek wewnątrz innego kawałka, dzięki czemu dostęp do zapisu na ten drugi kawałek pozwala nadpisać zawarty w nim kawałek
Przepełnienie o jeden, aby zmodyfikować informacje o metadanych rozmiaru
Zaalokuj trzy kawałki A
, B
i C
(powiedzmy rozmiary 0x20), oraz kolejny, aby zapobiec konsolidacji z kawałkiem górnym.
Zwolnij C
(wstawiony do listy wolnych Tcache 0x20).
Użyj kawałka A
, aby przepełnić B
. Wykorzystaj off-by-one, aby zmodyfikować pole size
B
z 0x21 na 0x41.
Teraz mamy B
zawierający wolny kawałek C
Zwolnij B
i zaalokuj kawałek 0x40 (zostanie tu ponownie umieszczony)
Możemy zmodyfikować wskaźnik fd
z C
, który nadal jest wolny (zatrucie Tcache)
Rezerwuje się 3 kawałki pamięci (a, b, c) jeden po drugim. Następnie środkowy jest zwalniany. Pierwszy zawiera podatność na przepełnienie o jeden, a atakujący ją z 0x00 (jeśli poprzedni bajt był 0x10, sprawi, że środkowy kawałek wskaże, że jest o 0x10 mniejszy, niż naprawdę jest).
Następnie, w środku zwolnionego kawałka (b) są przydzielane 2 mniejsze kawałki, jednakże, ponieważ b + b->size
nigdy nie aktualizuje kawałka c, ponieważ adres wskazywany jest mniejszy, niż powinien.
Następnie, b1 i c są zwalniane. Ponieważ c - c->prev_size
wciąż wskazuje na b (teraz b1), oba są konsolidowane w jeden kawałek. Jednakże, b2 nadal znajduje się wewnątrz pomiędzy b1 i c.
W końcu, wykonywane jest nowe przydział pamięci malloc, odzyskując ten obszar pamięci, który faktycznie będzie zawierał b2, pozwalając właścicielowi nowego malloc kontrolować zawartość b2.
To zdjęcie doskonale wyjaśnia atak:
Off-by-one z powodu strlen
uwzględniający pole size
następnego kawałka.
Używany jest Tcache, więc ogólne ataki off-by-one działają, aby uzyskać arbitralne pisanie zatruciem Tcache.
Możliwe jest wykorzystanie off-by-one do wycieku adresu z heap, ponieważ bajt 0x00 na końcu łańcucha znaków jest nadpisywany przez następne pole.
Pisanie arbitralne jest uzyskiwane poprzez wykorzystanie off-by-one write, aby wskaźnik wskazywał na inne miejsce, gdzie zostanie zbudowana fałszywa struktura z fałszywymi wskaźnikami. Następnie możliwe jest śledzenie wskaźnika tej struktury, aby uzyskać arbitralne pisanie.
Adres libc jest wyciekany, ponieważ jeśli sterta jest rozszerzana za pomocą mmap, pamięć przydzielona przez mmap ma stały przesunięcie od libc.
W końcu, arbitralne pisanie jest wykorzystywane do zapisania w adresie __free_hook z jednym gadżetem.
Istnieje podatność NULL off-by-one w funkcji getline
, która czyta linie wejściowe użytkownika. Ta funkcja służy do odczytywania "klucza" zawartości, a nie samej zawartości.
Udostępniaj sztuczki hakowania, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na GitHubie.