首页
论坛
课程
招聘
[原创]手动编译测试musl1.2.2 meta dequeue特性
2022-10-4 00:06 13319

[原创]手动编译测试musl1.2.2 meta dequeue特性

2022-10-4 00:06
13319

基础知识

看雪上0xRGz 师傅写的 [原创]musl 1.2.2 总结+源码分析 One-Pwn-看雪论坛-安全社区|安全招聘|bbs.pediy.com 很好,研究一下午就大致能了解透彻musl 1.2.2的内存管理结构和机制。美中不足的是没讲讲怎么编译一个用musl libc的程序。本文就简单介绍介绍如何编译一个musl libc下的程序,并通过它简单调试调试musl libc 的一些特性。

安装musl环境&&符号表

这里直接用0xRGz师傅的做法

 

下载.deb安装包(0xRGz师傅的链接在笔者的电脑上貌似失效了):http://ftp.de.debian.org/debian/pool/main/m/musl/musl_1.2.2-1_amd64.deb

 

安装:

1
sudo dpkg -i musl_1.2.2-1_amd64.deb

安装调试符号:

 

下载安装包musl-dbgsym_1.2.2-1_amd64.ddeb

 

安装:

1
sudo dpkg -i musl-dbgsym_1.2.2-1_amd64.ddeb

安装gdb小插件(from xf1les 师傅):

1
2
git clone https://github.com/xf1les/muslheap.git
echo "source /path/to/muslheap.py" >> ~/.gdbinit

(这里的/path/to是需要修改的,也就是你git的muslheap的路径。安装了这个就能使用mheap和mchunk等一些非常好用的辅助调试的命令)

手动编译第一个musl程序

下载&&安装

1
2
3
4
5
curl -LO http://musl.libc.org/releases/musl-1.2.2.tar.gz
tar vxf musl-1.2.2.tar.gz
cd musl-1.2.2
./configure --prefix=/usr/local/musl CFLAGS='-O2 -v'
make && sudo make install

源码&&编译

(在musl-1.2.2目录下的操作)

 

main.c

1
2
3
4
5
6
#include <stdio.h>
 
int main() {
    printf("Hello musl libc\n");
    return 0;
}

编译

1
./obj/musl-gcc main.c -o test

链接:

1
patchelf --set-interpreter ./libc.so ./test

运行

测试

demo1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<stdio.h>
#include <unistd.h>
 
void init()
{
        setbuf(stdin, 0);
        setbuf(stdout, 0);
        setbuf(stderr, 0);
}
 
int main() {
 
        init();
        size_t *p1,*p2,*p3;
        p1=(size_t *)malloc(0x20);
        p2=(size_t *)malloc(0x30);
        p3=(size_t *)malloc(0x40);
        read(0,p1,0x10);
        read(0,p2,0x20);
        read(0,p3,0x30);
        free(p1);
        free(p2);
        free(p3);
        return 0;
}

通过read我们就能定位到分配的chunk的地址,从而通过mchunk看出对应的group和meta。然后通过mheap中的active看出对应的meta有没有被dequeue

初始状态

malloc p1后

 

发现多了一个meta(其实是先多一个chunk,然后多一个group再多一个meta)

malloc p3后

 

多了两个meta

mchunk p1

到read看见p1的addr:

 

 

mchunk它:

 

 

可以看见它的group的首地址是它的地址减0x10,和文章里写的一样,并且group的首地址存了meta的地址

 

p (struct meta ) 这个地址看看:

 

 

发现这个meta此时是指向自己的,并且mem存的是group的地址(发现meta有东西指向group,group也有东西指向meta)

 

avail_mask为1022是因为它的二进制表示为:

1
01111111110

 

freed_mask记录group中已经被free释放的堆块,当前没有任何被释放的堆块,所以它为0

 

last_idx为9表示group中最多10个同大小的堆块(0~9)

 

free_able为1表示当前有一个堆块能free

 

sizeclass为2 表示由0x2这个group进行管理这一类的大小的chunk

 

maplen为0说明这个group不是通过mmap分配的

看看group中的chunk

 

0x70本来是chunk头,结果被last_idx和meta_addr占位了,从0x80开始是我们读入的数据“nameless”

free chunk过后看看:

 

发现active[2]不见了。这其实触发了meta dequeue的第一个条件——在free的时候,group中只有一个堆块处于使用状态中即free它过后,group中的所有堆块都处于未使用状态。这个时候还留它干嘛呢,直接将该meta dequeue了

demo2

通过demo1简单了解了gdb下musl 的chunk、group和meta怎么调试,以及meta dequeue的第一种触发方式。接下来我们调试调试meta dequeue第二种触发方式——malloc的时候

 

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<stdio.h>
#include <unistd.h>
 
void init()
{
        setbuf(stdin, 0);
        setbuf(stdout, 0);
        setbuf(stderr, 0);
}
 
int main() {
 
        init();
        size_t *p1;
        p1=(size_t *)malloc(0x20); //1
        p1=(size_t *)malloc(0x20); //2
        p1=(size_t *)malloc(0x20); //3
        p1=(size_t *)malloc(0x20); //4
        p1=(size_t *)malloc(0x20); //5
        p1=(size_t *)malloc(0x20); //6
        p1=(size_t *)malloc(0x20); //7
        p1=(size_t *)malloc(0x20); //8
        p1=(size_t *)malloc(0x20); //9
        p1=(size_t *)malloc(0x20); //10
        p1=(size_t *)malloc(0x20); //11
        p1=(size_t *)malloc(0x20); //12
        p1=(size_t *)malloc(0x20); //13
        p1=(size_t *)malloc(0x20); //14 
        return 0;
}

测试

发现当malloc第10个堆块过后,active[2]就从0x298变成0x2c0即发生了meta dequeue

 

 

而且group的位置也从0xc70变成了0xc50。这说明在这种dequeue的时候,会产生一个新grep,以及对应的meta

学meta dequeue有啥用呢?

做题!(即答)

 

别别别,ctf to learn,not learn to ctf

 

我们从p (struct meta ) 能看出来meta是一个双链表结构,dequeue的过程就牵扯到一个类似UB或者large bin chunk 的unlink的操作。就有可能通过这里的dequeue实现unlink 任意地址写,但具体怎么操作就留给读者思考或者看其它大师傅博客复现赛题了QAQ(笔者写这篇的时候还没做任何一道musl 1.2.2的题,虽然确实是奔着做题去学的,不过搞嵌入式的话不会arm,不会musl怎么行呢?)

一些话

纸上得来终觉浅,绝知此事要躬行,觉得在正式做题之前还是要自己写个demo简单调调,检验检验自己是否学懂了musl 1.2.2的特性。不能总想着做题.......

参考文章

[原创]musl 1.2.2 总结+源码分析 One-Pwn-看雪论坛-安全社区|安全招聘|bbs.pediy.com


[2022冬季班]《安卓高级研修班(网课)》月薪三万班招生中~

最后于 2022-10-8 11:19 被Nameless_a编辑 ,原因:
收藏
点赞0
打赏
分享
打赏 + 50.00雪花
打赏次数 1 雪花 + 50.00
 
赞赏  Editor   +50.00 2022/10/13 恭喜您获得“雪花”奖励,安全圈有你而精彩!
最新回复 (2)
雪    币: 4658
活跃值: 活跃值 (11898)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 2022-10-8 11:12
2
0
图片需要重新上传一下
雪    币: 2321
活跃值: 活跃值 (5382)
能力值: ( LV9,RANK:220 )
在线值:
发帖
回帖
粉丝
Nameless_a 活跃值 2 2022-10-8 11:20
3
0
kanxue 图片需要重新上传一下
抱歉,已修复
游客
登录 | 注册 方可回帖
返回