House of Roman
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Основна інформація
Це була дуже цікава техніка, яка дозволяла RCE без leaks через fake fastbins, unsorted_bin attack та relative overwrites. Однак вона була patched.
Застосовність у 2026
- glibc window: Працює надійно на 2.23–2.27 (how2heap PoC тестував 2.23–2.25). Починаючи з 2.28, патч “additional checks for unsorted bin integrity” робить unsorted‑bin запис ненадійним, тож шанс успіху різко падає. З 2.34 і далі
__malloc_hook/__free_hookбули видалені, через що первісна ціль недоступна. Використовуйте це лише на старих libc (або custom build’ах, що зберігають hooks) або для CTF задач, що постачають стару libc. - Tcache era (≥2.26): Tcache “з’їсть” ваші 0x70 алокації і зупинить fastbin/unsorted примітиви. Вимкніть його (
setenv("GLIBC_TUNABLES","glibc.malloc.tcache_count=0",1);) перед будь‑якою алокацією або заповніть кожен 0x70 tcache bin 7 frees, щоб його спорожнити. - Safe-linking: Застосовується до tcache/fastbin у ≥2.32, але House of Roman потребує лише partial pointer overwrite існуючої libc адреси вже присутньої в fd/bk, тож safe-linking тут не допомагає захиснику (атакувальник ніколи не фальсифікує новий вказівник). Справжніми перешкодами є видалення hook’ів і перевірки unsorted‑bin.
Код
- Ви можете знайти приклад у https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
Мета
- RCE шляхом зловживання relative pointers
Вимоги
- Змінювати вказівники fastbin та unsorted bin
- Потрібно брутфорсити 12 біт випадковості (ймовірність успіху 0.02%)
Кроки атаки
Part 1: Fastbin Chunk points to __malloc_hook
Створіть кілька chunks:
fastbin_victim(0x60, offset 0): UAF chunk пізніше буде відредаговано, щоб вказувати на значення LibC.chunk2(0x80, offset 0x70): Для гарного вирівнюванняmain_arena_use(0x80, offset 0x100)relative_offset_heap(0x60, offset 0x190): відносний офсет на chunk ‘main_arena_use’
Потім free(main_arena_use), що помістить цей chunk в unsorted list і запише в fd та bk вказівники на main_arena + 0x68.
Тепер алокується новий chunk fake_libc_chunk(0x60), бо він міститиме в fd та bk вказівники на main_arena + 0x68.
Потім звільняються relative_offset_heap та 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маєfd, що вказує наrelative_offset_heaprelative_offset_heap— це зсув відfake_libc_chunk, який містить вказівник наmain_arena + 0x68- Зміна останнього байта
fastbin_victim.fdзмушуєfastbin_victimвказувати наmain_arena + 0x68.
Для попередніх дій атакуючий повинен мати можливість змінювати вказівник fd у fastbin_victim.
Далі main_arena + 0x68 не надто цікавий, тож модифікуємо його, щоб вказівник вказував на __malloc_hook.
Зауважте, що __memalign_hook зазвичай починається з 0x7f і має нулі перед ним, тому його можна підробити як значення в 0x70 fast bin. Оскільки останні 4 біти адреси є random, існує 2^4=16 можливостей, щоб значення в кінці вказувало туди, що нас цікавить. Тому тут виконується BF attack, тож чанк виглядає так: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23).
(Для отримання додаткової інформації про решту байтів перегляньте пояснення в the how2heap example). Якщо brute force зазнає невдачі, програма просто падає (перезапускайте, поки не спрацює).
Потім виконуються 2 mallocs, щоб видалити 2 початкові fast bin chunks, і виділяється третій, щоб отримати чанк в __malloc_hook.
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
Part 2: Unsorted_bin attack
Для детальнішої інформації дивіться:
Але по суті це дозволяє записати main_arena + 0x68 у будь-яке місце, вказане в chunk->bk. Для атаки ми обираємо __malloc_hook. Потім, після його overwrite, ми використаємо relative overwrite, щоб вказати на one_gadget.
Для цього ми спочатку отримуємо chunk і поміщаємо його в 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);
Використайте UAF у цьому чанку, щоб вказати unsorted_bin_ptr->bk на адресу __malloc_hook (we brute forced this previously).
Caution
Note that this attack corrupts the unsorted bin (hence small and large too). So we can only use allocations from the fast bin now (a more complex program might do other allocations and crash), and to trigger this we must alloc the same size or the program will crash.
Отже, щоб викликати запис main_arena + 0x68 у __malloc_hook після встановлення __malloc_hook у unsorted_bin_ptr->bk нам достатньо виконати: malloc(0x80)
Step 3: Set __malloc_hook to system
На кроці першому ми контролювали чанк, що містив __malloc_hook (в змінній malloc_hook_chunk), а на другому кроці нам вдалося записати туди main_arena + 0x68.
Тепер ми зловживаємо частковим перезаписом в malloc_hook_chunk, щоб використати адресу libc, яку записали туди (main_arena + 0x68), щоб вказати на адресу one_gadget.
Саме тут потрібно bruteforce 12 bits of randomness (more info in the how2heap example).
Нарешті, як тільки правильну адресу буде перезаписано, викличте malloc і запустіть one_gadget.
Modern tips & variants
- Unsorted-bin hardening (2.28+): Додаткові перевірки цілісності для unsorted chunks (size sanity + list linkage) роблять класичний unsorted‑bin write крихким. Щоб пережити
_int_malloc, потрібно зберегти консистентніfd/bkпосилання та правдоподібні розміри, що зазвичай вимагає потужніших примітивів, ніж простий partial overwrite. - Hook removal (2.34+): Якщо
__malloc_hookвідсутній, адаптуйте примітив, щоб потрапити на будь-яку записувану GOT/global змінну, яку пізніше можна повторно використати (наприклад, перезаписатиexit@GOTу non-PIE бінарниках), або зробіть pivot до стилю House of Pie top‑chunk hijack, щоб контролюватиtopзамість хуку. - Any‑address fastbin alloc (romanking98 writeup): Друга частина показує, як відновити 0x71 freelist і використати unsorted‑bin write, щоб отримати fastbin allocation над
__free_hook, потім поміститиsystem("/bin/sh")і викликати його черезfree()на libc‑2.24 (pre-hook removal).
References
- 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
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.


