House of Roman
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Informação Básica
Esta foi uma técnica muito interessante que permitia RCE sem leaks via fake fastbins, o ataque unsorted_bin e relative overwrites. No entanto ela foi patched.
Aplicabilidade em 2026
- glibc window: Funciona de forma confiável em 2.23–2.27 (o how2heap PoC testou 2.23–2.25). A partir de 2.28, o patch “additional checks for unsorted bin integrity” torna a escrita no unsorted‑bin pouco confiável, então o sucesso cai acentuadamente. A partir de 2.34
__malloc_hook/__free_hookforam removidos, tornando o alvo original indisponível. Use apenas em libc antigas (ou builds custom que mantenham os hooks) ou em CTFs que incluam uma libc antiga. - Tcache era (≥2.26): Tcache vai absorver suas alocações 0x70 e impedir os primitivos fastbin/unsorted. Desative-o (
setenv("GLIBC_TUNABLES","glibc.malloc.tcache_count=0",1);) antes de qualquer alocação ou preencha cada bin tcache 0x70 com 7 frees para esvaziá-lo. - Safe-linking: Aplica-se a tcache/fastbin em ≥2.32, mas House of Roman só precisa de sobrescrita parcial de ponteiro de um endereço libc já presente em fd/bk, então safe-linking não ajuda aqui (o atacante nunca forja um ponteiro novo). O verdadeiro bloqueador é a remoção dos hooks e as checagens do unsorted-bin.
Código
- Você pode encontrar um exemplo em https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c
Objetivo
- RCE abusando de relative pointers
Requisitos
- Editar ponteiros de fastbin e unsorted bin
- 12 bits de aleatoriedade precisam ser brute forced (0.02% de chance) para funcionar
Etapas do Ataque
Parte 1: Fastbin Chunk aponta para __malloc_hook
Crie vários chunks:
fastbin_victim(0x60, offset 0): chunk UAF que mais tarde será editado para apontar o ponteiro do heap para o valor da LibC.chunk2(0x80, offset 0x70): Para bom alinhamentomain_arena_use(0x80, offset 0x100)relative_offset_heap(0x60, offset 0x190): offset relativo no chunk ‘main_arena_use’
Então free(main_arena_use) o que colocará este chunk na lista unsorted e colocará um ponteiro para main_arena + 0x68 tanto em fd quanto em bk.
Agora é alocado um novo chunk fake_libc_chunk(0x60) porque ele conterá os ponteiros para main_arena + 0x68 em fd e bk.
Então relative_offset_heap e fastbin_victim são 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_victimtem umfdapontando pararelative_offset_heaprelative_offset_heapé um offset de distância desdefake_libc_chunk, que contém um ponteiro paramain_arena + 0x68- Alterar o último byte de
fastbin_victim.fdfaz com quefastbin_victimaponte paramain_arena + 0x68.
Para as ações anteriores, o atacante precisa ser capaz de modificar o ponteiro fd de fastbin_victim.
Então, main_arena + 0x68 não é tão interessante, então vamos modificá-lo para que o ponteiro aponte para __malloc_hook.
Note que __memalign_hook normalmente começa com 0x7f e zeros antes disso; então é possível falsificá-lo como um valor no fast bin 0x70. Como os últimos 4 bits do endereço são aleatórios existem 2^4=16 possibilidades para que o valor acabe apontando para onde nos interessa. Então um BF attack é realizado aqui de modo que o chunk termina assim: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23).
(Para mais info sobre o resto dos bytes verifique a explicação em how2heap example). Se o brute force falhar o programa simplesmente trava (reinicie até que funcione).
Então, são executados 2 mallocs para remover os 2 chunks iniciais do fast bin e um terceiro é alocado para obter um chunk em __malloc_hook.
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
Part 2: Unsorted_bin attack
Para mais informações, você pode consultar:
Mas basicamente ele permite escrever main_arena + 0x68 para qualquer local especificado em chunk->bk. Para o ataque escolhemos __malloc_hook. Então, após sobrescrevê-lo, usaremos uma sobrescrita relativa para apontar para um one_gadget.
Para isso, começamos obtendo um chunk e colocando-o no 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 um UAF in this chunk para apontar unsorted_bin_ptr->bk para o endereço de __malloc_hook (we brute forced this previously).
Caution
Observe que este ataque corrompe o unsorted bin (portanto small e large também). Então só podemos usar alocações do fast bin agora (um programa mais complexo pode fazer outras alocações e travar), e para provocar isso devemos alocar do mesmo tamanho ou o programa vai travar.
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)
Etapa 3: Definir __malloc_hook para system
No passo um controlamos um chunk contendo __malloc_hook (na variável malloc_hook_chunk) e no segundo passo conseguimos escrever main_arena + 0x68 lá.
Agora, abusamos de uma sobregravação parcial em malloc_hook_chunk para usar o endereço libc que escrevemos ali (main_arena + 0x68) para apontar para um endereço one_gadget.
É aqui que é necessário fazer brute-force em 12 bits de aleatoriedade (mais info no how2heap exemplo).
Finalmente, uma vez que o endereço correto seja sobrescrito, chame malloc e dispare o one_gadget.
Dicas modernas & variantes
- Unsorted-bin hardening (2.28+): As verificações extras de integridade em chunks unsorted (checagem de tamanho + vinculação da lista) tornam a escrita clássica no unsorted‑bin frágil. Para sobreviver ao
_int_malloc, você deve manter os linksfd/bkconsistentes e os tamanhos plausíveis, o que normalmente requer primitivas mais fortes do que uma simples sobregravação parcial. - Hook removal (2.34+): Com
__malloc_hookremovido, adapte a primitiva para aterrissar em qualquer GOT/global gravável que você possa reutilizar depois (por exemplo, sobrescreverexit@GOTem binários non-PIE) ou pivote para um sequestro do top-chunk ao estilo House of Pie para controlartopem vez de um hook. - Any‑address fastbin alloc (romanking98 writeup): A segunda parte mostra como reparar a freelist 0x71 e usar a escrita no unsorted‑bin para posicionar uma alocação fastbin sobre
__free_hook, então colocarsystem("/bin/sh")e acioná-lo viafree()no libc‑2.24 (pré-removal do hook).
Referências
- 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
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.


