House of Roman
Tip
AWS 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
기본 정보
이는 fake fastbins, the unsorted_bin attack 및 relative overwrites를 통해 leaks 없이 RCE를 허용하는 매우 흥미로운 기법이었습니다. 그러나 patched.
2026년 적용성
- glibc 범위: 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(또는 훅을 유지하는 커스텀 빌드)나 오래된 libc를 포함한 CTF 문제에서만 사용하세요. - Tcache 시대 (≥2.26): Tcache는 0x70 할당을 흡수하여 fastbin/unsorted 원시(primitives)를 막습니다. 모든 할당 이전에 비활성화하세요 (
setenv("GLIBC_TUNABLES","glibc.malloc.tcache_count=0",1);) 또는 각 0x70 tcache bin을 7번의 free로 채워 비우세요. - Safe-linking: ≥2.32에서 tcache/fastbin에 적용되지만 House of Roman은 fd/bk에 이미 존재하는 libc 주소의 부분 포인터 덮어쓰기를 필요로 하므로 safe-linking은 방어자에게 도움이 되지 않습니다(공격자는 새 포인터를 위조하지 않습니다). 실제 제약은 훅 제거와 unsorted-bin 체크입니다.
코드
목표
- relative pointers 남용을 통한 RCE
요구사항
- fastbin 및 unsorted bin 포인터 편집
- 작동하려면 12비트의 무작위성을 브루트포스해야 함(성공 확률 0.02%)
공격 단계
파트 1: Fastbin Chunk가 __malloc_hook을 가리킴
여러 청크를 생성합니다:
fastbin_victim(0x60, offset 0): 나중에 heap 포인터를 LibC 값으로 편집하기 위한 UAF 청크.chunk2(0x80, offset 0x70): 정렬을 위해.main_arena_use(0x80, offset 0x100)relative_offset_heap(0x60, offset 0x190): ‘main_arena_use’ 청크에 대한 상대 오프셋.
그런 다음 free(main_arena_use)를 수행하면 이 청크가 unsorted 리스트에 들어가고 fd와 bk 포인터 둘 다에 main_arena + 0x68에 대한 포인터가 설정됩니다.
이제 fake_libc_chunk(0x60)라는 새 청크를 할당합니다. 이 청크는 fd와 bk에 main_arena + 0x68에 대한 포인터를 포함할 것이기 때문입니다.
그런 다음 relative_offset_heap과 fastbin_victim을 free합니다.
/*
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_heap를 가리킵니다relative_offset_heap는fake_libc_chunk로부터의 오프셋이며, 그 안에는main_arena + 0x68를 가리키는 포인터가 있습니다fastbin_victim.fd의 마지막 바이트를 변경하면fastbin_victim이main_arena + 0x68를 가리키게 됩니다
앞의 동작들을 위해, 공격자는 fastbin_victim의 fd 포인터를 수정할 수 있어야 합니다.
그런 다음, main_arena + 0x68는 별로 흥미롭지 않으므로 포인터가 **__malloc_hook**를 가리키도록 수정합시다.
참고로 __memalign_hook는 보통 0x7f로 시작하고 그 앞이 0으로 채워져 있으므로, 이를 0x70 fast bin의 값으로 위조하는 것이 가능합니다. 주소의 마지막 4비트가 무작위이기 때문에 결과적으로 2^4=16가지 경우가 존재하여 원하는 위치로 끝날 수 있습니다. 따라서 여기서 BF attack이 수행되어 청크는 다음과 같이 끝납니다: 0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23).
(나머지 바이트에 대한 자세한 정보는 how2heap example의 설명을 확인하세요). If the brute force fails the program just crashes (restart until it works).
그 다음, 초기 2개의 fast bin 청크를 제거하기 위해 2번의 malloc을 수행하고, 세 번째 할당으로 **__malloc_hook**에 해당하는 위치의 청크를 얻습니다.
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
Part 2: Unsorted_bin attack
For more info you can check:
기본적으로 이는 chunk->bk에 지정된 임의의 위치에 main_arena + 0x68을 쓸 수 있게 합니다. 공격에서는 __malloc_hook을 선택합니다. 덮어쓴 뒤에는 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);
Use an UAF in this chunk to point unsorted_bin_ptr->bk to the address of __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.
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)
3단계: __malloc_hook을 system으로 설정
In step one we controlled a chunk containing __malloc_hook (in the variable malloc_hook_chunk) and in the second step we managed to write main_arena + 0x68 there.
Now, we abuse a partial overwrite in malloc_hook_chunk to use the libc address we wrote there (main_arena + 0x68) to point to a one_gadget address.
Here is where it’s needed to bruteforce 12 bits of randomness (more info in the how2heap example).
Finally, once the correct address is overwritten, call malloc and trigger the one_gadget.
Modern tips & variants
- Unsorted-bin hardening (2.28+): unsorted 청크에 대한 추가 무결성 검사(크기 유효성 검사 + 리스트 연결)가 기존의 unsorted‑bin 쓰기를 취약하게 만듭니다.
_int_malloc을 통과하려면fd/bk링크를 일관되게 유지하고 크기를 그럴듯하게 보이게 해야 하며, 이는 보통 단순한 partial overwrite보다 더 강력한 프리미티브를 필요로 합니다. - Hook removal (2.34+):
__malloc_hook이 제거된 경우, 프리미티브를 조정해 나중에 재사용할 수 있는 쓰기 가능한 GOT/글로벌에 착지시키거나(예: non-PIE 바이너리에서exit@GOT덮어쓰기), 훅 대신top을 제어하기 위해 House of Pie 스타일의 top‑chunk 하이재킹으로 전환하세요. - Any‑address fastbin alloc (romanking98 writeup): 두 번째 부분은 0x71 freelist를 복구하고 unsorted‑bin write를 사용해 fastbin 할당을
__free_hook위로 배치한 다음,system("/bin/sh")를 넣고 libc‑2.24(훅 제거 이전)에서free()로 이를 트리거하는 방법을 보여줍니다.
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 해킹 배우기 및 연습하기:
HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기:HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.


