House of Roman
Tip
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)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Podstawowe informacje
To była bardzo interesująca technika, która pozwalała na RCE bez leaks przy użyciu fake fastbins, unsorted_bin attack i relative overwrites. Jednak została patched.
Zastosowanie w 2026
- glibc window: Działa niezawodnie na 2.23–2.27 (the how2heap PoC testował 2.23–2.25). Począwszy od 2.28, poprawka “additional checks for unsorted bin integrity” powoduje, że zapis do unsorted‑bin staje się zawodny, więc szansa powodzenia gwałtownie spada. Od 2.34
__malloc_hook/__free_hookzostały usunięte, co czyni oryginalny cel niedostępnym. Używaj tego tylko na starych libc (lub niestandardowych buildach, które zachowują hooki) lub do zadań CTF dostarczających starą libc. - Tcache era (≥2.26): Tcache pochłonie twoje alokacje 0x70 i zatrzyma fastbin/unsorted prymitywy. Wyłącz go (
setenv("GLIBC_TUNABLES","glibc.malloc.tcache_count=0",1);) przed jakąkolwiek alokacją lub napełnij każdy 0x70 tcache bin 7 free, aby go opróżnić. - Safe-linking: Dotyczy tcache/fastbin w ≥2.32, ale House of Roman wymaga tylko partial pointer overwrite of a libc address already present in fd/bk, więc safe-linking nie pomaga obrońcy tutaj (atakujący nigdy nie fałszuje nowego wskaźnika). Prawdziwym ograniczeniem są usunięcie hooków i sprawdzenia unsorted‑bin.
Code
- You can find an example in https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
Cel
- RCE przez nadużycie relative pointers
Wymagania
- Modyfikacja wskaźników fastbin i unsorted bin
- Konieczne brute-force’owanie 12 bitów losowości (0.02% szans na powodzenie)
Kroki ataku
Część 1: Fastbin Chunk wskazuje na __malloc_hook
Utwórz kilka chunków:
fastbin_victim(0x60, offset 0): UAF chunk, który później posłuży do edycji wskaźnika heap, aby wskazywał na wartość z LibC.chunk2(0x80, offset 0x70): Dla poprawnego wyrównaniamain_arena_use(0x80, offset 0x100)relative_offset_heap(0x60, offset 0x190): względny offset na chunku ‘main_arena_use’
Następnie free(main_arena_use), co umieści ten chunk na liście unsorted i spowoduje wpisanie wskaźnika do main_arena + 0x68 zarówno w fd, jak i w bk.
Teraz alokowany jest nowy chunk fake_libc_chunk(0x60), ponieważ będzie on zawierał wskaźniki do main_arena + 0x68 w fd i bk.
Następnie zwalniane są 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_victimmafdwskazujący narelative_offset_heaprelative_offset_heapto offset odległości odfake_libc_chunk, który zawiera wskaźnik domain_arena + 0x68- Zmiana ostatniego bajtu
fastbin_victim.fdpowoduje, żefastbin_victimwskazuje namain_arena + 0x68.
Do wykonania powyższych działań atakujący musi umieć zmodyfikować wskaźnik fd fastbin_victim.
Następnie main_arena + 0x68 nie jest zbyt interesujący, więc zmodyfikujmy go tak, by wskaźnik wskazywał na __malloc_hook.
Zauważ, że __memalign_hook zazwyczaj zaczyna się od 0x7f i poprzedzają go zera, dlatego można go sfałszować jako wartość w 0x70 fast bin. Ponieważ ostatnie 4 bity adresu są random, istnieje 2^4=16 możliwości, że wartość w końcu będzie wskazywać tam, gdzie nas interesuje. Dlatego wykonywany jest tutaj BF attack, tak że chunk kończy się jak: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23).
(For more info about the rest of the bytes check the explanation in the how2heap example). Jeśli brute force zawiedzie, program po prostu ulega awarii (restartuj, aż zadziała).
Następnie wykonuje się 2 mallocs, aby usunąć 2 początkowe fast bin chunks, a trzeci jest alokowany, aby uzyskać chunk w __malloc_hook.
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
Część 2: Unsorted_bin attack
Więcej informacji znajdziesz:
Ale w zasadzie pozwala zapisać main_arena + 0x68 w dowolnej lokalizacji wskazanej przez chunk->bk. Do ataku wybieramy __malloc_hook. Następnie, po jego nadpisaniu (overwrite), użyjemy relative overwrite, aby wskazać na one_gadget.
W tym celu pobieramy chunk i wkładamy go do 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);
Use an UAF in this chunk to point unsorted_bin_ptr->bk to the address of __malloc_hook (we brute forced this previously).
Caution
Zwróć uwagę, że ten atak uszkadza unsorted bin (a więc też small i large). Dlatego możemy teraz use allocations from the fast bin (bardziej złożony program może wykonać inne alokacje i się zawiesić), a aby to wywołać musimy alloc the same size or the program will crash.
So, to trigger the write of main_arena + 0x68 in __malloc_hook we perform after setting __malloc_hook in unsorted_bin_ptr->bk we just need to do: malloc(0x80)
Krok 3: Ustaw __malloc_hook na system
W kroku pierwszym kontrolowaliśmy chunk zawierający __malloc_hook (w zmiennej malloc_hook_chunk), a w drugim kroku udało nam się zapisać tam main_arena + 0x68.
Teraz wykorzystujemy partial overwrite w malloc_hook_chunk, aby użyć zapisanego tam adresu libc (main_arena + 0x68) do wskazania na adres one_gadget.
Tutaj trzeba bruteforce 12 bits of randomness (więcej informacji w przykładzie how2heap).
W końcu, gdy poprawny adres zostanie nadpisany, wywołaj malloc i uruchom one_gadget.
Modern tips & variants
- Unsorted-bin hardening (2.28+): Dodatkowe kontrole integralności dla unsorted chunks (sprawdzenie rozmiaru + powiązania listy) czynią klasyczny unsorted‑bin write kruchym. Aby przetrwać
_int_malloc, musisz utrzymać spójne linkifd/bki wiarygodne rozmiary, co zwykle wymaga silniejszych prymitywów niż prosty partial overwrite. - Hook removal (2.34+): With
__malloc_hookgone, adapt the primitive to land on any writable GOT/global you can later reuse (e.g., overwriteexit@GOTin non-PIE binaries) or pivot to a House of Pie style top‑chunk hijack to controltopinstead of a hook. - Any‑address fastbin alloc (romanking98 writeup): Druga część pokazuje naprawę freelist 0x71 i użycie zapisu do unsorted‑bin, by umieścić alokację fastbin nad
__free_hook, następnie wstawićsystem("/bin/sh")i wywołać to przezfree()na libc‑2.24 (pre-hook removal).
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/
- https://halloween.synacktiv.com/publications/heap-tricks-never-get-old-insomnihack-teaser-2022.html
- https://gist.github.com/romanking98/9aab2804832c0fb46615f025e8ffb0bc
- https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=NEWS;hb=glibc-2.34
- https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c
Tip
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)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


