House Of Force
House Of Force
首先介绍一下什么是House Of Force
House Of Force 是一种堆利用方法,但是并不是说 House Of Force 必须得基于堆漏洞来进行利用。如果一个堆 (heap based) 漏洞想要通过 House Of Force 方法进行利用,需要以下条件:
- 能够以溢出等方式控制到 top chunk 的 size 域
- 能够自由地控制堆分配尺寸的大小
一句话来说,如果我们可以控制top chunk的指针,那么我们就可以达到任意地址写,但是glibc对申请chunk进行了验证
// 获取当前的top chunk,并计算其对应的大小
victim = av->top;
size = chunksize(victim);
// 如果在分割之后,其大小仍然满足 chunk 的最小大小,那么就可以直接进行分割。
if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE))
{
remainder_size = size - nb;
remainder = chunk_at_offset(victim, nb);
av->top = remainder;
set_head(victim, nb | PREV_INUSE |
(av != &main_arena ? NON_MAIN_ARENA : 0));
set_head(remainder, remainder_size | PREV_INUSE);
check_malloced_chunk(av, victim, nb);
void *p = chunk2mem(victim);
alloc_perturb(p, bytes);
return p;
}
但是当我们把size的值改成一个很大的值比如0xffffffffffffffff,那么就可以轻松绕过这个验证,一般的做法是把size改成-1,因为在进行比较时会把 size 转换成无符号数,因此 -1 也就是说 unsigned long 中最大的数,所以无论如何都可以通过验证。
remainder = chunk_at_offset(victim, nb);
av->top = remainder;
/* Treat space at ptr + offset as a chunk */
#define chunk_at_offset(p, s) ((mchunkptr)(((char *) (p)) + (s)))
之后会把top指针进行更新,然而size段也会更新更新方法如下
victim = av->top;
size = chunksize(victim);
remainder_size = size - nb;
set_head(remainder, remainder_size | PREV_INUSE);
所以,如果我们想要下次在指定位置分配大小为 x 的 chunk,我们需要确保 remainder_size 不小于 x+ MINSIZE。
题目链接:链接:https://pan.baidu.com/s/1lr2jAQwL9Ow5FVjzrSfbWA 提取码:tx88
查看保护,pie保护关闭
64位ida载入
首先发现了后门函数
add函数
edit函数
值得注意的是这个函数并没有对我们输入的新长度进行判断,那么我们就可以修改到top chunk的siez域,实现House Of Force
先贴一下wp我再详细解释
现在看看调试
-0x70怎么来的
前面我说了需要将top thunk指向我们想要的地方,那么0xf262a0-0xf26260=0x50,而0x10是因为chunk头部有0x10大小,因此我我们下次申请的chunk的起始地址是0xf26250 + 0x10 = 0xf26260,然后我们再修改地址为flag地址再进行调用就可以得到flag
以上均为本人理解,有任何错误烦请各位师傅即使指出
参考文章 https://tty-flag.github.io/2021/04/20/House-Of-Force.html