House of Roman
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
Información básica
This was a very interesting technique that allowed for RCE without leaks via fake fastbins, the unsorted_bin attack and relative overwrites. However it has been patched.
Aplicabilidad en 2026
- glibc window: Works reliably on 2.23–2.27 (the how2heap PoC tested 2.23–2.25). Starting 2.28, the “additional checks for unsorted bin integrity” patch makes the unsorted‑bin write unreliable, so success drops sharply. From 2.34 onward
__malloc_hook/__free_hookwere removed, making the original target unavailable. Use it only on old libc’s (or custom builds that keep the hooks) or for CTF challenges that ship an old libc. - Tcache era (≥2.26): Tcache will eat your 0x70 allocations and stop the fastbin/unsorted primitives. Disable it (
setenv("GLIBC_TUNABLES","glibc.malloc.tcache_count=0",1);) before any allocation or fill each 0x70 tcache bin with 7 frees to drain it. - Safe-linking: It applies to tcache/fastbin in ≥2.32, but House of Roman only needs partial pointer overwrite of a libc address already present in fd/bk, so safe-linking does not help the defender here (the attacker never forges a fresh pointer). The real stopper is the hook removal and the unsorted-bin checks.
Code
- You can find an example in https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
Objetivo
- RCE abusando de punteros relativos
Requisitos
- Edit fastbin and unsorted bin pointers
- 12 bits de aleatoriedad deben ser forzados por fuerza bruta (0.02% de probabilidad de éxito)
Pasos del ataque
Part 1: Fastbin Chunk apunta a __malloc_hook
Crear varios chunks:
fastbin_victim(0x60, offset 0): UAF chunk later to edit the heap pointer later to point to the LibC value.chunk2(0x80, offset 0x70): For good alignmentmain_arena_use(0x80, offset 0x100)relative_offset_heap(0x60, offset 0x190): relative offset on the ‘main_arena_use’ chunk
Then free(main_arena_use) which will place this chunk in the unsorted list and will get a pointer to main_arena + 0x68 in both the fd and bk pointers.
Now it’s allocated a new chunk fake_libc_chunk(0x60) because it’ll contain the pointers to main_arena + 0x68 in fd and bk.
Then relative_offset_heap and fastbin_victim are freed.
/*
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_victimtiene unfdque apunta arelative_offset_heaprelative_offset_heapes un offset de distancia desdefake_libc_chunk, el cual contiene un puntero amain_arena + 0x68- Cambiar el último byte de
fastbin_victim.fdhace quefastbin_victimapunte amain_arena + 0x68.
Para las acciones anteriores, el atacante necesita ser capaz de modificar el puntero fd de fastbin_victim.
Luego, main_arena + 0x68 no es tan interesante, así que modifiquémoslo para que el puntero apunte a __malloc_hook.
Tenga en cuenta que __memalign_hook suele comenzar con 0x7f y ceros antes, entonces es posible falsearlo como un valor en el fast bin de 0x70. Debido a que los últimos 4 bits de la dirección son aleatorios hay 2^4=16 posibilidades para que el valor termine apuntando donde nos interesa. Así que se realiza un BF attack aquí de modo que el chunk queda así: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23).
(Para más info sobre el resto de los bytes consulta la explicación en el how2heap example). If the brute force fails the program just crashes (restart until it works).
Luego, se realizan 2 mallocs para eliminar los 2 chunks iniciales del fast bin y se asigna un tercero para obtener un chunk en __malloc_hook.
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
Parte 2: Unsorted_bin attack
For more info you can check:
Pero básicamente permite escribir main_arena + 0x68 en cualquier ubicación especificada en chunk->bk. Para el ataque elegimos __malloc_hook. Luego, después de sobrescribirlo, usaremos una sobrescritura relativa para apuntar a un one_gadget.
Para esto empezamos obteniendo un chunk y colocándolo en el 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);
Usa un UAF en este chunk para apuntar unsorted_bin_ptr->bk a la dirección de __malloc_hook (esto lo forzamos por fuerza bruta previamente).
Caution
Ten en cuenta que este ataque corrompe el unsorted bin (hence small and large too). Así que solo podemos usar allocations del fast bin ahora (un programa más complejo podría hacer otras allocations y crash), y para desencadenarlo debemos alloc del mismo tamaño o el programa crashará.
Así que, para desencadenar la escritura de main_arena + 0x68 en __malloc_hook después de establecer __malloc_hook en unsorted_bin_ptr->bk solo necesitamos hacer: malloc(0x80)
Paso 3: Establecer __malloc_hook a system
En el paso uno controlamos un chunk que contenía __malloc_hook (en la variable malloc_hook_chunk) y en el segundo paso logramos escribir main_arena + 0x68 allí.
Ahora, abusamos de una sobreescritura parcial en malloc_hook_chunk para usar la dirección libc que escribimos ahí (main_arena + 0x68) para apuntar a una dirección one_gadget.
Aquí es donde es necesario bruteforcear 12 bits de aleatoriedad (más info en el ejemplo de how2heap).
Finalmente, una vez que la dirección correcta está sobreescrita, llama a malloc y dispara el one_gadget.
Modern tips & variants
- Unsorted-bin hardening (2.28+): Las comprobaciones de integridad extra en unsorted chunks (sanidad de tamaños + enlaces de lista) hacen que la clásica escritura en unsorted‑bin sea frágil. Para sobrevivir a
_int_malloc, debes mantener los enlacesfd/bkconsistentes y los tamaños plausibles, lo que normalmente requiere primitivas más potentes que una simple sobreescritura parcial. - Hook removal (2.34+): Con
__malloc_hookeliminado, adapta la primitiva para aterrizar en cualquier GOT/global escribible que luego puedas reutilizar (p. ej., sobreescribirexit@GOTen binarios non-PIE) o pivota a un secuestro del top‑chunk al estilo House of Pie para controlartopen lugar de un hook. - Any‑address fastbin alloc (romanking98 writeup): La segunda parte muestra cómo reparar la freelist 0x71 y usar la escritura en unsorted‑bin para colocar una allocation de fastbin sobre
__free_hook, luego ponersystem("/bin/sh")y desencadenarlo víafree()en libc‑2.24 (pre-hook removal).
Referencias
- 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
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.


