House of Force
개요
Glibc의 top chunk(wilderness)의 size 필드를 조작하여 malloc()이 임의의 주소에 메모리를 할당하도록 유도하는 공격 기법입니다.
전제 조건
- Top chunk의 size 필드를 덮어쓸 수 있는 힙 오버플로우가 존재
- malloc의 size를 공격자가 제어 가능
- malloc을 최소 2번 호출 가능 (glibc 2.29 이전)
공격 원리
malloc은 요청 크기를 top chunk에서 잘라냄. top chunk size를 0xffffffffffffffff로 덮으면, 이후 어떤 크기로 malloc을 해도 “top chunk 안에 공간이 있다”고 판단함.
[heap] ... [top chunk header | size: 0xffffffffffffffff | ...]
목표 주소로 이동하는 계산식:
malloc_size = target_addr - top_chunk_addr - 0x10(header) - 0x10(prev)
이 크기로 malloc을 1번 호출하면 top chunk 포인터가 target 근처로 이동하고, 그 다음 malloc 호출 시 target 주소에 청크가 할당됨.
공격 시나리오 예시
1. heap overflow → top chunk size = 0xffffffffffffffff
2. malloc(offset) → top chunk를 원하는 위치(예: __malloc_hook, GOT)로 이동
3. malloc(size) → 해당 위치에 청크 반환
4. 해당 위치에 원하는 값 write (예: system 주소)
주요 타겟
| 타겟 | 목적 |
|---|---|
__malloc_hook | 다음 malloc 시 쉘코드/system 실행 |
__free_hook | free 시 실행 |
| GOT 영역 | 함수 포인터 덮어쓰기 |
패치 이후 (glibc 2.29+)
_int_malloc 내부에 top chunk size 유효성 검사가 추가되어 현재는 기본적으로 막혀 있음.
// 추가된 검사
assert ((old_top == initial_top (av) && old_size == 0) ||
((unsigned long) (old_size) >= MINSIZE &&
prev_inuse (old_top) &&
((unsigned long) old_end & (pagesize - 1)) == 0));요약
Top chunk size를 무한대로 덮은 뒤, malloc size를 조절해서 top chunk 포인터를 원하는 주소로 끌어당기는 기법. 단순하고 강력하지만 최신 glibc에서는 패치됨.