어제부로 종강했는데, 그 동안 CTF 관련 내용들을 너무 복습하지 않아 까먹은 부분이 있어서 다시 복습할 겸 글을 적습니다.
Double Free Bug
말 그대로, Free를 두 번 시켜서 발생되는 취약점입니다.
// gcc -o tcache_dup tcache_dup.c -no-pie
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
char *ptr[10];
void alarm_handler() {
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(60);
}
int create(int cnt) {
int size;
if (cnt > 10) {
return -1;
}
printf("Size: ");
scanf("%d", &size);
ptr[cnt] = malloc(size);
if (!ptr[cnt]) {
return -1;
}
printf("Data: ");
read(0, ptr[cnt], size);
}
int delete() {
int idx;
printf("idx: ");
scanf("%d", &idx);
if (idx > 10) {
return -1;
}
free(ptr[idx]);
}
void get_shell() {
system("/bin/sh");
}
int main() {
int idx;
int cnt = 0;
initialize();
while (1) {
printf("1. Create\n");
printf("2. Delete\n");
printf("> ");
scanf("%d", &idx);
switch (idx) {
case 1:
create(cnt);
cnt++;
break;
case 2:
delete();
break;
default:
break;
}
}
return 0;
}
이 코드는 Double Free Bug 취약점이 있는 코드다. 만약 여기서 할당받은 메모리를 두 번 Free시킬 수 있다면, Double Free Bug가 발생해서 메모리가 연속적으로 이어지게 됩니다. 그런데, Dockerfile을 보면 버전이 ubuntu 18.04 버전입니다.
이 glibc 버전에서는 Double Free Bug Detection이 존재하지 않으므로, 단순하게 free를 두 번해서 Double Free Bug를 일으킬 수 있습니다.
Double Free Bug로 같은 메모리를 두 번 해제하면, 두 메모리는 서로 연결된 채로 유지됩니다. 즉, 이 메모리는 free가 되어 있는 상태이면서 할당이 될 수 있는 상태인 것입니다.
따라서, 만약 계속해서 할당을 하게 되면, 앞에서 할당한 값을 뒤에서 할당한 값으로 덮어씌울 수 있습니다.
-> 그러므로, 만약 puts_got을 앞에 넣어줬다면, 그 주소에 쓸 값을 뒤에 넣어주면 그 값으로 덮어 씌울 수 있는 것입니다.
그러나, 버전이 올라가면서 Double Free Bug Detection 부분이 추가가 된다면, 단순히 Double Free를 시켰을 때 오류가 발생합니다. Free된 메모리에 특정 키를 저장해서, 그 키가 그대로 유지되어 있을 때 Free를 하게 되면 Double Free가 되었음을 인지하고, 오류를 발생시키기 때문입니다.

따라서, 만약 해제된 메모리에 접근해서 내용을 수정할 수 있다면, 검사 키를 수정할 수 있게 되고, 그러면 다시 한 번 Double Free Bug를 일으킬 수 있게 됩니다.
Fastbin Duplication
그러나, Double Free Bug는 glibc 버전이 상승되면서 점차 우회하기 어려워졌습니다. 이에 대한 대응 방안으로 Fastbin Duplication이 등장하였습니다.
핵심 아이디어는 같은 chunk를 두 번 이상 Fastbin에 넣지 않고도 Fastbin 리스트 안에 같은 주소, 또는 조작한 주소를 의도적으로 두 번 삽입해서, 나중에 malloc()할 때 원하는 주소를 중복으로 리턴받게 하는 기법입니다.
먼저 tcachebins를 꽉 채워주어야 하는데, tcachebins는 총 7개입니다. 이들을 malloc과 free를 반복해서 꽉 채워줍니다.

이렇게 하면 fastbin까지 사용이 됩니다. 이제 여기서 fastbin 두 개를 연결되게 할 수 있다면 Double Free Bug를 일으킬 수 있게 됩니다.
추후에 Fastbin Dup같은 경우는 더 자세하게 공부해서 올리도록 하겠습니다.
'시스템해킹 > 개념' 카테고리의 다른 글
| puts 함수 분석을 통한 FSOP 공격 기법 분석 (2) | 2025.07.23 |
|---|---|
| Unsorted bin 공격 정리 (1) | 2025.07.13 |
| [Dreamhack-system] Background : _IO_FILE (1) | 2024.12.20 |
| [Dreamhack-system] SigReturn-Oriented Programming (3) | 2024.12.18 |
| [Dreamhack-system] Background : _rtld_global (3) | 2024.12.17 |