# House of Force {{#include ../../banners/hacktricks-training.md}} ## 基本信息 ### 代码 - 该技术已被修补([**在这里**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=30a17d8c95fbfb15c52d1115803b63aaa73a285c)),并产生此错误:`malloc(): corrupted top size` - 如果需要,您可以尝试[**这里的代码**](https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html)进行测试。 ### 目标 - 此攻击的目标是能够在特定地址分配一个块。 ### 要求 - 一个允许覆盖顶部块头部大小的溢出(例如 -1)。 - 能够控制堆分配的大小。 ### 攻击 如果攻击者想要在地址 P 中分配一个块以覆盖此处的值。他首先通过`-1`(可能通过溢出)覆盖顶部块的大小。这确保了 malloc 不会使用 mmap 进行任何分配,因为顶部块将始终有足够的空间。 然后,计算顶部块地址与要分配的目标空间之间的距离。这是因为将执行一个具有该大小的 malloc,以便将顶部块移动到该位置。这就是如何轻松计算差异/大小的方法: ```c // From https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c#L59C2-L67C5 /* * The evil_size is calulcated as (nb is the number of bytes requested + space for metadata): * new_top = old_top + nb * nb = new_top - old_top * req + 2sizeof(long) = new_top - old_top * req = new_top - old_top - 2sizeof(long) * req = target - 2sizeof(long) - old_top - 2sizeof(long) * req = target - old_top - 4*sizeof(long) */ ``` 因此,分配大小为 `target - old_top - 4*sizeof(long)`(4个long是因为顶部块和新分配块的元数据)将把顶部块移动到我们想要覆盖的地址。\ 然后,再次进行malloc以在目标地址获取一个块。 ### 参考文献与其他示例 - [https://github.com/shellphish/how2heap/tree/master](https://github.com/shellphish/how2heap/tree/master?tab=readme-ov-file) - [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/) - [https://heap-exploitation.dhavalkapil.com/attacks/house_of_force](https://heap-exploitation.dhavalkapil.com/attacks/house_of_force) - [https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c) - [https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html](https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html) - [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#hitcon-training-lab-11](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#hitcon-training-lab-11) - 这个场景的目标是ret2win,我们需要修改一个函数的地址,该函数将由ret2win函数的地址调用 - 二进制文件存在一个溢出,可以被利用来修改顶部块的大小,该大小被修改为-1或p64(0xffffffffffffffff) - 然后,计算指针存在的地方的地址,以及从当前顶部块位置到该处的差值,并使用`malloc`进行分配 - 最后,分配一个新块,其中将包含这个期望的目标,该目标将被ret2win函数覆盖 - [https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?\_x_tr_sl=es&\_x_tr_tl=en&\_x_tr_hl=en&\_x_tr_pto=wapp](https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp) - 在`Input your name:`中存在一个初始漏洞,允许从堆中泄漏一个地址 - 然后在`Org:`和`Host:`功能中,当询问**org name**时,可以填充`s`指针的64B,在栈中紧随其后的是v2的地址,然后是指示的**host name**。由于strcpy将复制s的内容到一个大小为64B的块中,因此可以用**host name**中放入的数据**覆盖顶部块的大小**。 - 现在任意写入成为可能,`atoi`的GOT被覆盖为printf的地址。然后可以使用`%24$p`泄漏`IO_2_1_stderr`的地址。通过这个libc泄漏,可以再次用`system`的地址覆盖`atoi`的GOT,并传递`/bin/sh`作为参数调用它 - 在这个其他写作中提出的替代方法[proposed in this other writeup](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#2016-bctf-bcloud),是用`puts`覆盖`free`,然后在稍后将被释放的指针中添加`atoi@got`的地址,以便泄漏,并通过这个泄漏再次用`system`覆盖`atoi@got`并调用它,参数为`/bin/sh`。 - [https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) - 存在一个UAF,允许重用一个未清除指针的已释放块。由于存在一些读取方法,可以通过在GOT中写入指向free函数的指针来泄漏libc地址,然后调用读取函数。 - 然后,使用House of force(利用UAF)来用-1覆盖剩余空间的大小,分配一个足够大的块以到达free hook,然后分配另一个块,该块将包含free hook。然后,在hook中写入`system`的地址,在一个块中写入`"/bin/sh"`,最后释放包含该字符串内容的块。 {{#include ../../banners/hacktricks-training.md}}