网络安全渗透测试之musl堆利用技巧

 更新时间:2022年6月1日 13:41  点击:358 作者:kali_Ma

前言

最近比赛出的musl题型的越来越多,不得不学习一波musl的堆利用来应对今后的比赛。这里要讲的是musl1.22版本的利用,因为网上可以找到很多审计源码的文章,所以这篇文章是通过一道题目来debug去学习堆的利用技巧,这里用到的是2021第五空间线上赛的notegame题目。

题目分析

1、首先是add函数,使用了calloc,申请的最大size是0x90

image.png

2、接着是delete函数,free之后将指针清空了

image.png

3、然后是edit函数,漏洞就出现在这里,这里存在溢出空字节的漏洞,可以对index清零指向 fake_meta

image.png

4、最后来看这个update函数,这个realloc函数会将原来chunk的内容复制到新的chunk里面,我们可以用这个来进行泄露libc地址

image.png

调试分析

musl的chunk跟glibc的区别就是,chunk头的结构存放了比较少的堆块信息,没有像glibc那样存放了一些指针地址信息,所以我们如果要泄露libc地址的话也是要特定的条件,就是要chunk里面保存着另外一个chunk的指针地址或者其他指针地址的信息,而且也再不能直接改指针去达到任意分配的效果,而是要改chunk头仅有的信息去伪造meta进行任意分配。

malloc_context

add(0x20,'a'*0x20)

image.png

1、secret是用来校验meta域的一个key

2、free_meta_head存放着释放掉的meta,是个单链表结构,这里还没有释放,所以为空

3、active是根据size大小分出来的不同的meta

4、usage_by_class是对应meta的数量

meta

add(0x20,'a'*0x20)
add(0x20,'a'*0x20)
add(0x20,'a'*0x20)
add(0x20,'a'*0x20)
free(3)

image.png

1、prev和next分别是上一个和下一个meta页,这里都指向本身,表示只有一个meta页

2、 mem表示group的地址,它是由多个chunk组成

3、avail_mask表示可以分配的chunk情况,0x3f0=0b01111110000,因为我们已经分配了4个堆块,所以这里表示前四个不可分配。

4、freed_mask表示已经释放的chunk情况,因为我们释放掉了第一个chunk,所以这里的0x1表示的是free掉的第一个chunk

5、last_idx表示最后一个chunk的下标,这里是0x9,总数是0xa个

6、freeable表示已经释放的堆块个数

7、sizeclass表示管理的group的大小

8、maplen如果不为零表示mmap分配的内存页数

chunk

add(0x20,'a'*0x20)
add(0x20,'a'*0x20)
add(0x20,'a'*0x20)
add(0x20,'a'*0x20)
free(3)

image.png

1、表示距离group首地址的偏移分别为0x0、0x30、0x60,系统是根据这个偏移来找到对应的meta地址,所以我们如果能改这个偏移比如把chunk1的偏移置零的话,就能在chunk1-0x10的地方伪造一个meta的指针,而这个地方又是我们可以控制的chunk0的data域,于是我们就可以在任意地方伪造一个meta,不过这个地址必须是跟0x1000对齐的。

2、表示当前chunk的下标,当chunk被free之后会变成0xff

3、表示剩下用户空间的大小,chunk头后面的4个字节跟glibc的prev_size那样可以被上一个chunk复用, 所以我们就可知道我们分配的大小跟chunk大小的关系

0x10:0-0xc
0x20:0xd-0x1c
0x30:0x1d-0x2c
0x40:0x2d-0x3c
...

chunk的分配释放

add(0x50,'a'*0x50)
add(0x50,'a'*0x50)
add(0x50,'a'*0x50)
free(0)
add(0x50,'a'*0x50)

image.png

avail_mask = 0x10=0b10000

freed_mask = 0x1 =0b00001

musl的chunk释放了之后并不会马上分配,这里group里面有5个chunk,先是申请了3个chunk,然后free掉第一个,再次申请的时候并不会把第一个chunk分配出来,而是把group的第四个chunk申请出来,然后对应的avail_mask置零

add(0x50,'a'*0x50)
add(0x50,'a'*0x50)
add(0x50,'a'*0x50)
add(0x50,'a'*0x50)
free(0)
free(1)
free(2)
add(0x50,'a'*0x50)
add(0x50,'a'*0x50)

image.png

avail_mask = 0x6 =0b0110

freed_mask = 0x0 =0b0000

耗尽group的chunk的时候,musl会把释放掉的申请出来,并把其他chunk对应的avail_mask置1

meta的释放

add(0x50,'a'*0x50)
free(0)

image.png

当只有一个chunk是被分配出去的,而freed_mask=0,我们把这个chunk给free掉之后,系统会回收整块meta空间

add(0x50,'a'*0x50)
add(0x50,'a'*0x50)
add(0x50,'a'*0x50)
add(0x50,'a'*0x50)
add(0x50,'a'*0x50)
free(0)
free(1)
free(2)
free(3)
free(4)

image.png

总结起来,就是说avail_mask |freed_mask的结果是满状态的时候,就会释放这个meta。

总结

本篇先通过debug的方法来简单阐述musl堆块的结构,后续再讲如何对它进行利用。

更多关于网络安全渗透测试musl堆的资料请关注猪先飞其它相关文章!

原文出处:https://blog.csdn.net/kali_Ma/article/details/122970885

[!--infotagslink--]

相关文章

  • 解决jmap命令打印JVM堆信息异常的问题

    这篇文章主要介绍了解决jmap命令打印JVM堆信息异常的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-04
  • C语言之栈和堆(Stack && Heap)的优缺点及其使用区别

    本篇文章主要介绍了什么是栈(Stack) 、什么是堆( Heap),以及栈和堆的优缺点,同时介绍了应该什么时候使用堆和栈,有需要的朋友可以参考下...2020-04-25
  • C#托管堆对象实例包含内容分析

    这篇文章主要介绍了C#托管堆对象实例包含内容,实例展示了托管对象的结构及运行原理,需要的朋友可以参考下...2020-06-25
  • 浅谈C#中堆和栈的区别(附上图解)

    C#中栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小...2020-06-25
  • C++ 在堆上开辟与释放二维、三维指针详细解析

    一维指针其实就相当于一维数组,不用去看书上所说的数组在内存中的首地址这些晦涩的话,以此类推 二维指针就相当于二维数组,新手对一维数组的开辟与释放比较容易熟悉...2020-04-25
  • C语言堆栈入门指南

    我身边的一些编程的朋友以及在网上看帖遇到的朋友中有好多也说不清堆栈,所以我想有必要给大家分享一下我对堆栈的看法,有说的不对的地方请朋友们不吝赐教,这对于大家学习会有很大帮助...2020-04-25
  • Python网络安全格式字符串漏洞任意地址覆盖大数字详解

    这篇文章主要介绍了Python网络安全格式字符串漏洞任意地址覆盖大数字的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步...2021-10-14
  • C++堆和栈的区别与联系讲解

    今天小编就为大家分享一篇关于C++堆和栈的区别与联系讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧...2020-04-25
  • c语言stack(栈)和heap(堆)的使用详解

    这篇文章主要介绍了c语言stack(栈)和heap(堆)的使用详解,需要的朋友可以参考下...2020-04-25
  • C++中静态存储区与栈以及堆的区别详解

    本篇文章是对C++中静态存储区与栈以及堆的区别进行了详细的分析介绍,需要的朋友参考下...2020-04-25
  • Java中PriorityQueue实现最小堆和最大堆的用法

    很多时候都会遇到PriorityQueue,本文主要介绍了Java中PriorityQueue实现最小堆和最大堆的用法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-06-27
  • C#栈和堆的区别浅谈

    理解堆与栈对于理解.NET中的内存管理、垃圾回收、错误和异常、调试与日志有很大的帮助...2020-06-25
  • 详解Java如何实现小顶堆和大顶堆

    今天给大家带来的是关于Java的相关知识,文章围绕着Java如何实现小顶堆和大顶堆展开,文中有非常详细的解释及代码示例,需要的朋友可以参考下...2021-06-21
  • C#数据结构之最小堆的实现方法

    这篇文章主要给大家介绍了关于C#数据结构之最小堆的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-09
  • 使用C#实现数据结构堆的代码

    这篇文章主要介绍了使用C#实现数据结构堆,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-06
  • C++实现二叉树及堆的示例代码

    这篇文章主要介绍了C++实现二叉树及堆的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-20
  • 数据结构之堆详解

    这篇文章主要介绍了数据结构之堆详解,本文讲解了堆的基本常识堆的基本操作、堆的应用等内容,需要的朋友可以参考下...2020-04-25
  • 突破神奇的Cloudflare防火墙的网络安全学习

    这篇文章主要为大家介绍了突破神奇的Cloudflare防火墙的网络安全学习,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...2022-07-23
  • 一看就懂:图解C#中的值类型、引用类型、栈、堆、ref、out

    这篇文章主要介绍了一看就懂:图解C#中的值类型、引用类型、栈、堆、ref、out,本文用浅显易懂的语言组织介绍了这些容易混淆的概念,需要的朋友可以参考下...2020-06-25
  • 堆基本操作实现最大堆

    这篇文章主要介绍了堆基本操作实现最大堆,需要的朋友可以参考下...2020-04-25