musl 堆利用技巧,你知道多少
前言
最近比赛出的 musl 题型的越来越多,不得不学习一波 musl 的堆利用来应对今后的比赛。这里要讲的是 musl1.22 版本的利用,因为网上可以找到很多审计源码的文章,所以这篇文章是通过一道题目来 debug 去学习堆的利用技巧,这里用到的是 2021 第五空间线上赛的 notegame 题目。
题目分析
1、首先是 add 函数,使用了 calloc,申请的最大 size 是 0x90
2、接着是 delete 函数,free 之后将指针清空了
3、然后是 edit 函数,漏洞就出现在这里,这里存在溢出空字节的漏洞,可以对 index 清零指向 fake_meta
4、最后来看这个 update 函数,这个 realloc 函数会将原来 chunk 的内容复制到新的 chunk 里面,我们可以用这个来进行泄露 libc 地址
【一>所有资源获取<一】1、网络安全学习路线 2、电子书籍(白帽子)3、安全大厂内部视频 4、100 份 src 文档 5、常见安全面试题 6、ctf 大赛经典题目解析 7、全套工具包 8、应急响应笔记
调试分析
musl 的 chunk 跟 glibc 的区别就是,chunk 头的结构存放了比较少的堆块信息,没有像 glibc 那样存放了一些指针地址信息,所以我们如果要泄露 libc 地址的话也是要特定的条件,就是要 chunk 里面保存着另外一个 chunk 的指针地址或者其他指针地址的信息,而且也再不能直接改指针去达到任意分配的效果,而是要改 chunk 头仅有的信息去伪造 meta 进行任意分配。
malloc_context
add(0x20,'a'*0x20)
1、secret 是用来校验 meta 域的一个 key
2、free_meta_head 存放着释放掉的 meta,是个单链表结构,这里还没有释放,所以为空
3、active 是根据 size 大小分出来的不同的 meta
4、usage_by_class 是对应 meta 的数量
meta
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
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 大小的关系
chunk 的分配释放
avail_mask = 0x10=0b10000
freed_mask = 0x1 =0b00001
musl 的 chunk 释放了之后并不会马上分配,这里 group 里面有 5 个 chunk,先是申请了 3 个 chunk,然后 free 掉第一个,再次申请的时候并不会把第一个 chunk 分配出来,而是把 group 的第四个 chunk 申请出来,然后对应的 avail_mask 置零
avail_mask = 0x6 =0b0110
freed_mask = 0x0 =0b0000
耗尽 group 的 chunk 的时候,musl 会把释放掉的申请出来,并把其他 chunk 对应的 avail_mask 置 1
meta 的释放
当只有一个 chunk 是被分配出去的,而 freed_mask=0,我们把这个 chunk 给 free 掉之后,系统会回收整块 meta 空间
总结起来,就是说avail_mask |freed_mask
的结果是满状态的时候,就会释放这个 meta。
总结
本篇先通过 debug 的方法来简单阐述 musl 堆块的结构,后续再讲如何对它进行利用。
评论