写在前面的话
其实我也是照葫芦画瓢(但学习本来就是这么一件事),首先基本的原理你的搞懂吧。具体参考CTF-WIKI,那个真的是说得非常清楚了!我也只是记录一下自己的学习笔记!
原理
首先House of Force
这种利用方法,主要强调一点就是堆溢出,溢出到能够覆盖top chunk
的大小,也即是size
域!,这就是最基本的利用条件。
因为当我们每一次malloc()
,其实都是在申请一块chunk
,在物理结构上,因为我们现在能够申请的chunk的位置是在ptmalloc给我们分配的分配区里面,就在这个这个分配区里,只要总的大小没有超过当前的分配区,那么我们每一个malloc
分配到的chunk
就是在物理上一个接着一个的。所以问题就来了!
当我们malloc
一个空间的时候,在申请到的这个chunk的后面就是top chunk
,然而当我们输入的数据大小超过我们申请的范围,就会溢出到top chunk
的位置。
对于top chunk
来说,ptmalloc对于我们的要求就是当前top chunk
的大小要满足分配给你申请的大小之后,剩下的大小还必须要达到最小chunk的要求,也就是MINSIZE + 你申请的大小 <= 当前top chunk的大小
。
这个只是说一下这个点,但是要做到就非常简单了,我们直接让size域非常大就解决问题了,通常我们会传入-1
,因为ptmalloc的源码中对于size使用unsigned long
进行强转抓换,-1
转过来就是最大的数了
上面其实就做了一件事,溢出覆盖top chunk的size域非常大
!
接下来我们就要开始malloc()申请内存了,这里通过Linux的内存布局我们明白heap区域所处在的位置,所以要利用的话,一种是让top chunk
向低地址延伸然后就跑到了我们用户程序的位置,另外一种是向高地址的话就跑到了libc区域了!
malloc(); // 改变top chunk的指针
mem = malloc(); // 实现任意地址写 向高地址或低地址都可以
*mem = "nice";
实例
向低地址移动
int main()
{
long *ptr, *ptr1;
ptr = malloc(0x10);
ptr = (long *)(((long)ptr) + 24);
*ptr = -1;
malloc(-4120); // 减少top chunk的指针
malloc(0x10);
}
向高地址移动
int main()
{
long *ptr, *ptr1;
ptr = malloc(0x10);
ptr = (long *)(((long)ptr) + 24);
*ptr = -1;
malloc(140737345551056); // 增大top chunk的指针
malloc(0x10);
}