首页
社区
课程
招聘
[原创]看雪6月 京东 2018CTF 第九题——羞耻player pwn
发表于: 2018-7-3 15:14 3212

[原创]看雪6月 京东 2018CTF 第九题——羞耻player pwn

2018-7-3 15:14
3212

第一次做C++的pwn,然后做的时候走了点弯路,做完之后发现此题其实并不难。。。所以打算把心路历程记录一下,总结经验以免以后掉进同样的坑。。。

这次C++的struct没弄好,浪费了好多时间,IDA一直不支持C++的类,所以特别蛋疼。。。这次是拿union搞的,把所有类放在一个共用体,弄完之后发现可读性极差。。。其实感觉最好还是把父类作为一个成员放在最前面(这里的话只有虚表),然后后面放其他子类的成员。。。

漏洞点在subtitle_init 0x26D0函数中

可见,当a1->length + buf <= 400,但是buf是一个很大的无符号数0xffffffff时,存在整形溢出,能过前面<=400的检查,也能分配一个正常大小的堆。但是在read(0, (char *)dest + a1->length, buf)时,相当于执行了read(0, (char *)dest + a1->length, 0xffffffff),存在堆溢出!

打开程序,发现bins里面并不是空的,有很多chunks,可能是因为C++的原因吧。这很不方便我们的利用,所以先通过不停地分配clips来把这些bins清空

这个/bin/sh没用的。。。不管他。。。

一开始没看到read之后把size字段重置了,以为那样直接就能leak。。(盲人CTF,bestCTF

首先是要泄露libc的基址,也许要通过虚表地址泄露程序的基址,然后leak需要存在一个UAF,或者overlap chunk,所以要把溢出转换成这种东西。

然后这个我想了一段时间,最后觉得还是用null byte poisoning的思路比较合适。

这个利用方法不详细说了,不知道可以看看上面shellphish的how2heap。

然后这里要注意,null byte poisoning要让3个非fastbin的chunk互相连接,而这道题会先new一个类的对象,然后在初始化函数里面再new其data,所以直接从top chunk取的话没法保证data互相连接,所以要预先对堆做一点处理。还有就是,这题有内存泄露,delete掉类的时候只delete了data没有delete这个类。

怎么预先处理,就是让类的new从fastbin里面拿就好了,很简单,所以预先先放几个0x60的chunks在fastbin即可。(Video类大小为0x50)

这个时候,再create_video只要data字段不会被分到0x60的chunk,类就会从fastbin里拿,而data就会从topchunk里面拿,这样就能有null byte poison的利用条件了。

接下来便是null byte poison利用,基本上跟how2heap上面差不多。首先新建一个subtitle,然后这个的类和data都会从topchunk里面取,其data的chunk作为chunk a,然后chunk b2先是用来作为一个video的data,再分配一个video的chunk在相同的位置,同时后面也有一个unsorted bin,所以一下子可以把程序基址和libc都leak出来。注意最后一个chunk很重要,不然就不是unsorted bin而是topchunk了,这样libc就leak不出来

然后对堆做一些清理,进行下一阶段的利用

本来想溢出盖指针实现任意写这样直接利用的,就不用攻击堆管理器了比较简单,然后能直接改data字段的数据结构也就只有subtitle,所以就想通过subtitle那个整形溢出直接溢出他自己的类对象,改写指针到__free_hook,然后发现不行,因为subtitle_init 0x26D0在后面会把data字段delete掉,这个时候会delete掉__free_hook的地址,直接出错。。。

然后试着构造一个unsorted bin overlap chunk,就是覆盖unsorted bin的头延伸chunk大小,同时在相应新大小的尾部也要有正确的prev_sizesize,这能使得unsorted bin的chunk跟subtitle的类重合,再次new就可以重写subtitle的类,然后就快成功了,我在subtitle_edit 295A突然发现了这行代码。。。

小于等于4。。小于等于4。。。也就是说这个执行了一定会退出。。。看到这里有种想打死出题人的冲动。。。

所以还是攻击堆管理器吧(为什么早不这么做呢),可以fastbin attack写__malloc_hookone_gadget。。这个具体原理说一下,就是在__malloc_hook前有一个0x7fxxxxxxxxxx的地址,后面紧随一个0,然后我们可以利用这个0x7f做一个伪造的0x70 fastbin chunk(思考在小端情况下这两个数在内存中的布局),可以把在0x70的fastbin的fd指针写成libc_addr + e.symbols["__malloc_hook"] - 3 - 0x10,这样malloc两次0x70就能覆盖__malloc_hook了。这个利用的是libc在分配fastbin中的free chunk时只会检查size,而且不会检查低4位,什么prev size,align和next chunk都不会检查,所以可以这么利用。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2018-7-4 13:54 被holing编辑 ,原因:
上传的附件:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//