JSRC安全小课堂CTF实战系列,将不定期为大家放出CTF赛事的题目解析以供CTF爱好者参考学习。
今天为大家带来的是2018年的看雪·京东CTF大赛里的一道加了逆向难度的PWN题。
C++ 编写,利用C++特性 增加一定的逆向难度
除此之外 对堆分配做了特殊处理 使得选手难以获得堆地址
题目的利用点在于 在编辑 AudioClip 的editor的功能下存在悬挂指针
C++写的堆溢出考题,保护全开。
载入IDA分析,在程序开头0x12B0处,做了随机化的堆操作:
如图,先256次随机大小的分配,然后随机释放掉其中的一部分。这时候堆会显得比较乱,如下:
注意到随机分配的大小v0是8bit的,也就是0~255,那么只要分配一个比较大的,就可以consolidate,清空fastbin,并且把unsortbin放到smallbin里去。
尝试分配一个video,之后堆就干净了一些:
回头看程序,看video相关操作。0x203C70处是它的vtable,里面4个函数分别是增改删查功能。
动态调试标出结构体。然后看添加video的逻辑,如下:
其中frames最大1024,并且会更新为实际读入的内容长度。
但是在play功能部分,可以看到循环上界有问题:
这里多输出了一个字节,那么可以走这里逐字节泄漏libc。
最后看编辑功能,如下:
可以看到这里有明显的UAF。
那么,总体来说就是非常直接的一道题了,简单总结一下看到的两个明显漏洞:
1.edit时的UAF
2.play的时候多输出一个byte
(不知道还有没有其他漏洞)
于是先搞出0x410的unsortbin,然后反复edit即可逐byte泄漏出unsortbin的bk指针,也就拿到了libc偏移。
然后就随便玩了,fastbin重定向或者house of orange都可以,或者再泄漏堆,修改堆上的vtable也行,总之八仙过海各显神通,大家各凭本事就好。我这里是用fastbin把malloc_hook改成one_gadget,完整利用如下:
当然因为程序开头的一些随机操作,这个利用概率性成功。提高利用成功率留作习题。