BUU上的
n1ctf2018_null
很好的说明了这个问题。题目链接:
BUUCTF在线评测
看一下保护:
除了pie保护剩下的保护全开了,
64位ida
载入看一下:
我们进去看看:
是一个死循环,可以看见对输入的chunk大小以及数量都是非常大的,而且程序还有一个溢出我们看一下sub_400bca:
我们再看一下它下面的函数:
如果我们能修改此处的地址为system,而参数是/bin/sh那么我们就可以得到shell。
如果我们溢出的字节足够大可以覆盖线程arena,那么我们可将fake_chunk链接到fastbin,进而分配我们想要的地址,但是arena是先mmap出来的,heap是过后才分配出来,所以我们覆盖不了线程arena,但是如果,我们把这块内存耗完会发生什么,那么系统会重新分配mmap一段内存,但是由于它后面是libc的地址,所以它会往前面找一块地址,那么我们输入的内容就可能在线程arena的前面,我们先申请这么大看看:
看一下vmmap:
我们看一下此处内容,从链表特征上来看,这是一个线程arena结构,它位于地址较低的地方:
现在计算偏移进行覆盖:
填充0x50个垃圾数据覆盖到线程arena,这里注意这里有个大小我们不要随意去改变,可以适当改最前面的一个字节,不然会出现一系列的问题。
后面我们在把我们的fake_chunk接上去:
程序会把rbp-8处的位置给rdi,而且这个位置就是我们申请chunk输入的数据,随后call rax(0x602038)进而得到shell,记得补齐到0x60哦✅: