House of Force

概述:

house of force是一种针对top chunk的利用手法,它是通过修改top_chunk的size域从而完成一次几乎是任意地址的内存分配

原理:

根据前面的堆的基础知识可以知道,当程序需要分配一块内存,而tcache或者各个bin中都没有对应大小的堆块的话就会从top_chunk中分割一个对应大小的chunk出来给我们用,但是如果我们可以控制top_chunk的size域话,我们只需要在分配时用些小手段就可以将top_chunk分配到任意一个地址上去。

首先我们来看一下分割top_chunk时的操作和检查:

// 获取当前的top chunk,并计算其对应的大小
victim = av->top; //获取top_chunk地址
size   = chunksize(victim); //获取top_chunk大小
// 如果在分割之后,其大小仍然满足 chunk 的最小大小,那么就可以直接进行分割。
if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE)) 
{
    remainder_size = size - nb; //分配后的大小
    remainder      = chunk_at_offset(victim, nb); //分配后top_chunk的地址
    av->top        = remainder;
    //下面的两个set是跟完成分配后的top_chunk和分割出去的chunk设置chunk_header的流程,这里不用管
    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;
}

可以看见在流程中只有一个检查,就是这一句判断:

if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE)) 

判断top_chunk现在的size是否比需要分割出去的chunk的size大,这里加的 MINSIZE 是要保证即使top_chunk的大小比需要的大小大,但是分配完成后还要保证有一个MINSIZE大小的内存来存放top_chunk的chunk_header。

那么这个判断想要绕过也很简单,只需要让top_chunk的size很大就行了,这里可以发现在进入判断时会把size强行转换为无符号长整型,所以,这里我们如果能将其设置为-1,在转换后就会变成无符号整形里最大的数(0xffffffffffffffff)就可以绕过判断了

示例:

这里采用wiki上的第一个例子来看一下house of force的流程:

这个例子是要篡改malloc函数got表地址的内存

int main()
{
    long *ptr,*ptr2;
    ptr=malloc(0x10);
    ptr=(long *)(((long)ptr)+24);
    *ptr=-1;        // <=== 这里把top chunk的size域改为0xffffffffffffffff
    malloc(-4120);  // <=== 减小top chunk指针
    malloc(0x10);   // <=== 分配块实现任意地址写
}

程序流程比较简单就不赘述了,这里讲一下为什么要在修改top_chunk的size位后分配一个大小为-4120的chunk:

因为我们要控制malloc的got表处的内存,在gdb中可以查到他的got表所在的地址是:0x601020

在这里插入图片描述
然后top_chunk的地址是:0x602020
在这里插入图片描述
所以我们要让top_chunk的地址向上移 0x601010 - 0x602020= -4112,这里由于要经过内部的checked_request2size,所以我们是要满足对齐参数MALLOC_ALIGN(详细的解释可以看wiki,后面总结的时候会再提一下),所以最终是要减去一个-4120。

之后我们进入gdb看一下流程:

首先将断点下在第10行看一下top_chunk的size被修改后的情况:

在这里插入图片描述
已经修改成功了,之后步进下一步分配走那个0x4120大小的chunk让top_chunk来到malloc的got表地址位置上的内存:
在这里插入图片描述
可以看见已经被分配出来了,之后我们只要再次申请申请堆块就可以控制修改malloc的got表内容了。

总结:

house of force这个手法的原理和操作都比较简单,位移比较需要考虑的点就是修改top_chunk的size之后怎么将地址转移到目标地址处,首先要知道64位的操作系统下所有chunk都需要一个0x10的空间存放chun_header 所以我们可以有一下这个公式:

最终目标地址 = 需要控制的地址- 0x10

top_chunk需要移动的距离 = 最终目标地址 - top_chunk的地址

这里得到的top_chunk需要移动的距离由于要通过request2size,就需要满足对齐参数MALLOC_ALIGN 实际上,对齐参数(MALLOC_ALIGNMENT)大小的设定需要满足以下两点:

  1. 必须是2的幂
  2. 必须是void *的整数倍

所以top_chunk需要移动的距离如果不满足这两个条件的话就要简单的修改一下,就像前面的例子里一样。

然后就是这个利用手法需要的条件:

  1. 能够以溢出等方式控制到 top chunk 的 size 域
  2. 能够自由地控制堆分配尺寸的大小
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值