Use-After-Free: 해방된 메모리를 다시 잡아라
UAF(Use-After-Free) 는 heap 메모리를 free() 한 이후에도 해당 포인터를 계속 사용할 때 발생하는 취약점이다. 현대 브라우저, 커널, 서버 소프트웨어에서 끊임없이 발견되며 CTF에서도 단골 주제다.
동작 원리
char *buf = malloc(64);
free(buf);
// buf는 이제 dangling pointer
strcpy(buf, "pwned"); // UAF 발생!
free() 이후 포인터를 NULL로 초기화하지 않으면 buf는 dangling pointer 가 된다. 이 상태에서 같은 크기의 chunk를 다시 할당하면 tcache/fastbin 재사용 메커니즘으로 인해 공격자가 그 영역을 장악할 수 있다.
공격 시나리오
- Heap Spray — 해제된 chunk 크기와 동일한 객체로 heap을 채워 원하는 데이터를 그 위치에 올린다.
- Type Confusion — 해제된 포인터가 다른 타입으로 재해석되도록 유도해 vtable 포인터를 덮는다.
- Tcache Poisoning — tcache의
fd포인터를 조작해 임의 주소를 다음 할당 위치로 만든다.
GDB로 UAF 관찰하기
gdb ./vuln
pwndbg> heap
pwndbg> bins # tcache/fastbin 상태 확인
pwndbg> vis_heap_chunks
pwndbg의 vis_heap_chunks 명령으로 해제된 chunk가 tcache에 어떻게 연결되는지 시각적으로 확인할 수 있다.
방어 기법
| 기법 | 설명 |
|---|
- 포인터 NULL화 —
free(p); p = NULL;습관화 - Heap Hardening — glibc 2.32+
safe-linking으로 tcache fd 암호화 - ASAN(AddressSanitizer) — 개발 단계에서 UAF 자동 탐지
- CFI(Control Flow Integrity) — vtable 포인터 변조 방지
CTF 접근법
UAF 문제를 만나면 다음 순서로 접근하자:
checksec으로 보호 기법 확인 (PIE, RELRO, Canary)- 할당/해제 흐름을 파악해 같은 크기 chunk 재사용 가능 여부 체크
- libc 버전 확인 → tcache 구조 파악
pwntools로 익스플로잇 자동화
UAF는 단순해 보이지만 heap 구조에 대한 깊은 이해가 필요하다. heap 마스터리의 시작점이다. 🔥