学习总结,一个理解起来比较简单的堆的漏洞利用,是Fastbin Attack之一。
环境:Ubuntu16.04 64bit
0x00 House of Spirit原理
这个需要先了解glibc的fastbin机制,大致上fastbin里的堆块大小都在2*SIZE_SZ ~ av->system_mem的范围之内,在x64的机器上,就是大于16字节,小于128字节(32位系统默认是8字节到64字节)。由于fastbin采取LIFO策略,最近释放的chunk会被更早地分配。这样的话,我们能组织House of Spirit攻击。
1 | +--------------+ |
在这种情形中,我们可以构造可控区域1和可控区域2,然后覆盖一个堆指针,使之指向可控区域1,然后free该块区域,使之进入到fastbin中,然后重新申请该区域,那么不可控区域就变得可操作了。
利用思路
1,我们需要通过可控区域1和可控区域2,把这个区域伪造成一个fast chunk
2,覆盖一个堆指针,让这个指针指向fast chunk
3,free这个fast chunk
4,申请刚刚释放的区域,这样不可控区域就变得可控了
free时,相关代码如下:
1 | __libc_free (void *mem) |
要将堆块释放到fastbin,需要满足一些限制:
fake chunk的ISMMAP位不能为1,当free时,如果时mmap的chunk,会做单独处理
fake chunk地址需要对齐,MALOC_ALIGN_MASK
1
2
3
4
5
6
7
8
9
/* The corresponding word size. */
/* The corresponding bit mask value. */fake chunk的size大小需要满足对应的fastbin的需求,同时也得对齐
fake chunk的next chunk的大小不能小于2 * SIZE_SZ,同时也不能大于av->system_mem
fake chunk对应的fastbin链表头部不能是该fake chunk,既不能构成double free的情况
0x01 栗子
借用how2heap的例子,源网页在此。
1 |
|
通过将fake_chunk[1]作为fast chunk的size,fake_chunk[9]作为fast chunk下一个chunk的size,然后把指针a指向fake_chunk[2],完成构造,然后free,再次申请,就能把对应区域申请回来。
House of Spirit的技术关键在于合理构造目标区域前后的数据,然后绕过相关的检测。
0x02 pwn200(LCTF2016)
刚开始的函数是这样的
1 | int sub_400A8E() |
可以看到v2可以刚好填满而没有0结尾,所以可以泄露出rbp。
啊自己尝试写了一下,惨不忍睹2333,还是搬运BruceFan的利用exp吧。。。
1 | #!/usr/bin/python |
0x03 总结
这个利用起来真的要计算清楚位置和大小,而且要熟练掌握chunk的结构。然后就是各种小地方的问题,要多调试。。。
fastbin attack 存在的原因在于 fastbin 是使用单链表来维护释放的堆块的,并且由 fastbin 管理的 chunk 即使被释放,其 next_chunk 的 prev_inuse 位也不会被清空。
构造好目标区域前后的数据。在House of Spirit中重要的好像就是两个地方的size以及size的标记位,其他的可以不管,比如pre size这样的就不需要,总的来说还是比unlink需要构造的地方少一点,好像(萌新之言。。。