概述
作用:在程序没有free
函数的情况下将一个chunk
放到unsorted bin中
要求:能够控制top chunk
的size域
利用原理
试想,当top chunk
被耗尽时,再次申请一个chunk
时,会发生什么?
malloc
会调用sysmalloc
来向系统申请内存,这其中又有两种方式,一种是通过sbrk
进行内存的拓展,另一种是通过mmap
函数独立映射一块内存
我们想要将剩下的top chunk
分配到unsorted bin
只有在sysmalloc
通过sbrk
拓展内存的时候才能实现
那么如何才能确保sysmalloc
是调用的sbrk
函数而不是mmap
函数呢?
1 | if (av == NULL |
这里检测要分配的大小是否大于mp_.mmap_threshold
,默认为128kb,且mmap
分配的内存块小于设定的最大值时,就会调用mmap
来映射内存
所以要保证调用的时sbrk
而不是mmap
首先要保证分配大小小于128kb
sysmalloc
中还存在以下检测
1 | /* |
这里验证了top chunk
的合法性,第五行是在检测top chunk
是否还未初始化,之后检测top chunk
的size是否大于MINISEIZE以及top chunk
的P位是否为1,最后检测top chunk
的结束地址是否是页对齐的(一般内存页的大小是4kb)
那么我们要满足的条件有如下几点:
- 堆块申请的大小要小于128kb
top chunk
的size必须大于MINISIZE(0x10)top chunk
的size必须小于申请的chunk size + MINISIZEtop chunk
的P位必须为1top chunk
的结束地址必须是页对齐
之后剩下的top chunk
就会通过_int_free
进入到unsorted bin中
总结
house of orange堆利用手法适合在程序没有free函数时使用,作用是获得一块释放的堆块,在进行利用的时候涉及到对top chunk
的控制,需要格外注意
题外话
可能有师傅和我一样心生疑惑:一定要更改top chunk
的size域吗?通过多次申请chunk将top chunk
耗尽再申请一个较大块的chunk来获得unsorted bin不行吗?
先说结论:经测试确实不行,原因不明,探究过程如下
先贴出我的测试程序
1 |
|
我是编译的2.23版本的,直接通过高版本编译然后patchelf
到低版本的libc不行,如果有ubuntu16的虚拟机或者docker可以通过虚拟机或docker来编译,如果没有可以将其移动到how2heap里,通过脚本一键编译,也可以自寻他法(gcc指定库编译类的)
前两个应该是作为缓冲区留下的,我们先直接申请一个大小为132900的堆块
ok现在我们得到了一个较小的堆块了,我们继续申请一个大小为200的堆块,然后进入malloc
函数看看发生了什么
成功进入sysmalloc
函数
可以看到程序在执行了2554行代码后就开始进行收尾了
堆块成功拓展了,但是剩余的top chunk
却没有进入unsorted bin,而是直接和新的top chunk
合并到了一起
1 | /* |
libc2.23malloc.c第2543行起↑
这里有三个条件判断,而我们需要的_int_free (av, old_top, 1);
位于最后一个else语句里,这里进入第二个分支导致无法进入第三个分支释放旧的top chunk
疑惑:在执行malloc_printerr (3, "break adjusted to free malloc space", brk,av);
时程序不应该终止吗,难道调试器欺骗了我?
通过修改top chunk
的size来达成利用条件时是成功了的
师傅们恕我能力不足只能列出现象,原因至少现在的我还无法解决,如果您看到了这里且有确切的答案,我将不胜感激如果你能通过本博客提供的联系方式联系到我,也欢迎与我一起讨论