The malloc maleficarum之The House of Force漏洞

一、The malloc maleficarum的历史由来

  • 从2004年末开始,glibc malloc变得更可靠了。之后,类似unlink的技巧已经废弃,攻击者没有线索。但是在2005年末,Phantasmal Phatasmagoria带来了一些其他技巧,用于成功利用堆溢出

二、The malloc maleficarum的内容

  • 虽然The malloc maleficarum技术最初包含5个内容,但是由于glib 2.23源码的发布,下面有些技术已经废弃了,不能够再使用了
    • The House of Prime(废弃)。
    • The House of Mind(废弃)。
    • The House of Force。
    • The House of Lore(废弃)。
    • The House of Spirit。

三、漏洞原理

  • 攻击者通过堆溢出或者其他方式,控制到topchunk的size成员,这样我们就可以使topchunk的地址超出正常的堆段的地址,这样我们就可以控制到超出堆段之外的内存。

四、漏洞实现

  • ①通过堆溢出或其他方式,控制到topchunk的size成员。
  • ②将topchunk的size成员变为一个非常大的数,这样topchunk就会超出内存中的堆段,从而访问到其他段的内存地址(got表的地址)。
  • ③此时通过malloc申请内存的时候,申请的就是got的内存地址,就可以更改got内存的内容。

五、虚拟机逃逸技术

  • 原理:我们在Windows主机中安装VMTools等软件,然后在软件中开启一个虚拟机。在虚拟机中书写一个程序,程序中包含The House of Force漏洞,因为VMTools原本就是在Windows主机的内存中开辟的一块内存空间,所以我们就可以利用虚拟机中程序的The House of Force漏洞,越界访问到VMTools之外的Windows主机的内存,从而可以控制内存的内容(例如开启一个计算器程序或者开启一个shell)。

六、演示案例

#include<stdio.h>
#include<malloc.h>
#include<unistd.h>
#include<string.h>
int main(){
    long *p = malloc(0x10); //第一步
    sleep(0);  //只为了程序打断点使用
	
    *(p+0x3) = -1; //第二步
    sleep(0);
	
    malloc(-4120); //第三步
    sleep(0);

    void *q = malloc(0x10); //第四步
    sleep(0);

    strcpy(q,"aaaaaaaa");  //第五步
    sleep(0);

    malloc(0); //第六步
    sleep(0);
	
    return 0;
}

第一步

  • 申请一个堆块,用p指针接收,p指向此堆块的fd成员。此时堆中只有p这个chunk和topchunk两个chunk。

第二步

  • 将p+0x3位置处的地址赋值-1,也就是将topchunk的size成员赋值为-1(因为p为long类型,在64位系统下为8字节,且chunk的成员也为8字节,又因为p不是largechunk,所以chunk的fd_nextsize和bk_nextsize成员没有被使用。因此p+0x3就是topchunk的size成员的地址)。
  • 为什么要设置为-1:malloc的参数在进入_lib_malloc函数的时候会被转换为无符号整数,那么topchunk的size成员就会变为整数中的最大值(0xffffffffffffffff),此时topchunk能够操控的地址范围就会非常大,并且已经超出了原本堆段的地址。

  • 当我们再去用heap查看topchunk的时候就看不到了,但是我们可以使用x命令查看内存,查看topchunk的结构(可以看到topchunk的size成员的值此时为0xffffffffffffffff)。

第三步

  • 此时我们通过malloc函数申请一个-4120的堆空间,同理,-4120也会被_lib_malloc函数转换为一个很大的正数,因此此处是向topchunk申请一个很大的堆空间。
  • 此时通过heap查看,可以看到一个很大的堆空间(0x601010),这个就是我们malloc出来的。并且fd指针此时指向于glibc中got表的_lib_malloc函数的位置,bk指针此时指向于got表中sleep函数的位置。

  • 通过vmmap查看可以看到,此时我们malloc的堆块是处于数据段的(造成堆溢出了)。

第四步

  • 此时我们再去malloc的时候,就是在got的内存地址处申请内存了,下图中可以看到0x601010这就是我们malloc的堆块。
  • 可以看到fd指向于_lib_malloc函数地址,bk成员指向于got中一个sleep函数地址。

第五步

  • 从第四步中可以看到,我们已经在got中申请到一个堆块,并且fd和bk成员都指向于got表的相关函数,那么此时我们就可以修改fd和bk成员,使其指向于另一个system的got函数,或者指向于one_gadget地址来起一个shell。
  • 但是此案例中我们只是向q中写入一个字符串,由于q指向于fd成员,且fd成员为glibc中_lib_malloc函数的地址,所以此处就是将got表中原本存放_lib_malloc函数地址的内容给改了,改为一串字符串了。
  • 通过heap的时候可以看到fd和bk都被修改了。

  • 查看这个堆块的内存。

第六步

  • 由于上面我们将got表中原本存放_lib_malloc函数地址的内容被改为一串字符串了,所以当我们再去malloc的时候,跳转到got表中的地址发现地址内容被修改了,于是就不能进行malloc,报错止终止。


  • 我是小董,V公众点击"笔记白嫖"解锁更多【堆漏洞挖掘】资料内容。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董哥的黑板报

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值