8.2 KiB
Dom rzymski
{% hint style="success" %}
Naucz się i praktykuj Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Naucz się i praktykuj Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Wesprzyj HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Udostępnij sztuczki hakerskie, przesyłając PR-y do HackTricks i HackTricks Cloud na githubie.
Podstawowe informacje
Była to bardzo interesująca technika, która umożliwiała RCE bez wycieków poprzez fałszywe fastbiny, atak na unsorted_bin i względne nadpisywanie. Jednak została załatana.
Kod
- Możesz znaleźć przykład w https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
Cel
- RCE poprzez nadużycie względnych wskaźników
Wymagania
- Edytuj wskaźniki fastbin i unsorted bin
- Należy brutalnie przełamać 12 bitów losowości (0,02% szansy), aby zadziałało
Kroki ataku
Część 1: Fastbin Chunk wskazuje na __malloc_hook
Utwórz kilka chunków:
fastbin_victim
(0x60, przesunięcie 0): Chunk UAF później do edycji wskaźnika sterty, aby wskazywał na wartość LibC.chunk2
(0x80, przesunięcie 0x70): Dla dobrego wyrównaniamain_arena_use
(0x80, przesunięcie 0x100)relative_offset_heap
(0x60, przesunięcie 0x190): względne przesunięcie na chunku 'main_arena_use'
Następnie zwolnij(main_arena_use)
, co umieści ten chunk na liście unsorted i otrzymasz wskaźnik do main_arena + 0x68
zarówno w wskaźnikach fd
, jak i bk
.
Teraz alokowany jest nowy chunk fake_libc_chunk(0x60)
, ponieważ będzie zawierał wskaźniki do main_arena + 0x68
w fd
i bk
.
Następnie zwolnij relative_offset_heap
i fastbin_victim
.
/*
Current heap layout:
0x0: fastbin_victim - size 0x70
0x70: alignment_filler - size 0x90
0x100: fake_libc_chunk - size 0x70 (contains a fd ptr to main_arena + 0x68)
0x170: leftover_main - size 0x20
0x190: relative_offset_heap - size 0x70
bin layout:
fastbin: fastbin_victim -> relative_offset_heap
unsorted: leftover_main
*/
-
fastbin_victim
mafd
wskazujący narelative_offset_heap
-
relative_offset_heap
to przesunięcie odległości odfake_libc_chunk
, który zawiera wskaźnik domain_arena + 0x68
- Zmieniając ostatni bajt
fastbin_victim.fd
, można sprawić, żefastbin_victim wskazuje
namain_arena + 0x68
Dla powyższych działań atakujący musi być w stanie modyfikować wskaźnik fd fastbin_victim
.
Następnie, main_arena + 0x68
nie jest tak interesujące, więc zmodyfikujmy go tak, aby wskaźnik wskazywał na __malloc_hook
.
Zauważ, że __memalign_hook
zazwyczaj zaczyna się od 0x7f
i zer przed nim, więc można to sfałszować jako wartość w fast binie 0x70
. Ponieważ ostatnie 4 bity adresu są losowe, istnieje 2^4=16
możliwości, aby wartość wskazywała tam, gdzie jesteśmy zainteresowani. Dlatego tutaj wykonywany jest atak BF, aby kawałek kończył się tak: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)
.
(Dla więcej informacji na temat pozostałych bajtów sprawdź wyjaśnienie w how2heap przykładzie). Jeśli atak BF nie zadziała, program po prostu się zawiesi (więc zacznij ponownie, aż zadziała).
Następnie wykonywane są 2 alokacje pamięci, aby usunąć 2 początkowe kawałki fast binów, a trzecia jest alokowana, aby uzyskać kawałek w __malloc_hook:
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
Część 2: Atak na unsorted_bin
Więcej informacji można znaleźć tutaj:
{% content-ref url="unsorted-bin-attack.md" %} unsorted-bin-attack.md {% endcontent-ref %}
Ale w skrócie pozwala to na zapisanie main_arena + 0x68
w dowolnym miejscu określonym przez chunk->bk
. A dla ataku wybieramy __malloc_hook
. Następnie, po nadpisaniu go, użyjemy względnego nadpisania, aby wskazać na one_gadget
.
Aby to osiągnąć, zaczynamy od uzyskania fragmentu i umieszczenia go w unsorted bin:
uint8_t* unsorted_bin_ptr = malloc(0x80);
malloc(0x30); // Don't want to consolidate
puts("Put chunk into unsorted_bin\n");
// Free the chunk to create the UAF
free(unsorted_bin_ptr);
Wykorzystaj UAF w tym fragmencie, aby wskazać unsorted_bin_ptr->bk
na adres __malloc_hook
(wcześniej już to brutalnie obliczyliśmy).
{% hint style="danger" %} Zauważ, że ten atak narusza nieuporządkowany blok (stąd też mały i duży). Dlatego teraz możemy korzystać tylko z alokacji z szybkiego bloku (bardziej złożony program może wykonywać inne alokacje i się zawiesić), aby wywołać to musimy zaalokować taką samą wielkość, inaczej program się zawiesi. {% endhint %}
Więc, aby wywołać zapis main_arena + 0x68
w __malloc_hook
, po ustawieniu __malloc_hook
w unsorted_bin_ptr->bk
, musimy po prostu wykonać: malloc(0x80)
Krok 3: Ustawienie __malloc_hook na system
W kroku pierwszym kontrolowaliśmy kawałek zawierający __malloc_hook
(w zmiennej malloc_hook_chunk
) i w drugim kroku udało nam się zapisać main_arena + 0x68
tutaj.
Teraz wykorzystujemy częściowe nadpisanie w malloc_hook_chunk
, aby użyć adresu libc, który tam zapisaliśmy (main_arena + 0x68
) do wskazania adresu one_gadget
.
Tutaj konieczne jest bruteforce'owanie 12 bitów losowości (więcej informacji w how2heap przykładzie).
Wreszcie, gdy poprawny adres zostanie nadpisany, wywołaj malloc
i wywołaj one_gadget
.
Referencje
- https://github.com/shellphish/how2heap
- https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
- https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_roman/
{% hint style="success" %}
Dowiedz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Dowiedz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud na githubie.