house_of_force
适用版本
glibc2.23 - 2.29
利用条件
- 能控制top chunk的size域
- 能获取heap_base,进而计算出top_chunk的地址
- 能自由控制堆分配尺寸大小
利用思路
将top chunk的size改得很大,使后续能够分配很大的堆块,从而使topchunk指向目标地址。
精准计算top chunk的地址与target addr-0x10之间偏移,再进行细微的调整,使申请完一个chunk后,top chunk的data域直接位于target addr处。
再申请一个chunk,往目标地址处写入值。
实现目的
任意地址写
利用原理
2.27glibc top chunk分配源代码如下
1 | victim = av->top; |
其中nb定义在checked_request2size (bytes, nb);
,这个宏内部定义了nb的值(也就是sz)。_int_malloc (mstate av, size_t bytes)
,bytes是该函数的参数,也就是我们调用malloc函数时传进去的数字。nb
实质上是用来存储经过调整后的内存请求大小的变量。
1 |
|
这里我们如果申请一个大小为负数的chunk,实际上nb经request2size处理后是一个非常大的正数,但加上一定值后溢出,也就实现了正常的正数与负数的运算。我们的topchunk实际上会向低地址处偏移。需要注意的是,申请一个大小为负数的chunk时,这个负数会被unsigned
int转换成一个非常大的数。这时如果我们这个转换后的数的大小大于我们修改的top
chunk的size,malloc
将尝试扩展堆空间,这时候就会调用
sysmalloc
,其中就会报错退出。所我们一般直接把top
chunk的size改成-1,也就是0xffffffffffffffff。基本就可以通过所有检测。

由于我们要精准控制申请后的大小来使top chunk落在想要的位置,也就是要控制request2size(req)的值
1 |
|
由于(req) + SIZE_SZ + MALLOC_ALIGN_MASK
一般都会大于MINSIZE,所以我们就要使我们输入req为target_offset - SIZE_SZ - MALLOC_ALIGN_MASK
,这样我们只要target_add是关于16字节对齐的,那么最后申请出chunk就会使top_chunk偏移到我们想要的地址处。
题目分析
hitcontraning_lab11


我们可以发现有对v4中函数指针的调用,而v4是一个指向堆的指针,那么我们就可以想办法改掉其中的函数指针实现任意地址的跳转,而程序中又有magic后门函数,所以思路就是改位于v4+8位置处的函数指针为magic,最后再传入5来调用magic。




可以发现change_item方法中我们可以任意控制输入大小,从而造成堆溢出,这里其实也可以用overlapping来构造double free,不过显然house_of_force更快更方便。
先把板子套上:
1 | def add(size,content): |
具体打法:
首先溢出改top chunk的size域
1 | magic = 0x0000000000400D49 |

然后算出偏移后申请一个目标大小的chunk
1 | off = -0x60 - 0x8 - 0xf |

此时我们发现top chunk已经到了目标位置处,再申请一个chunk就可以改写目标位置函数指针了。
1 | add(0x10,p64(magic)*2) |
- 标题: house_of_force
- 作者: collectcrop
- 创建于 : 2024-10-03 00:32:38
- 更新于 : 2024-11-23 19:44:34
- 链接: https://collectcrop.github.io/2024/10/03/house-of-force/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。