首页
社区
课程
招聘
[原创] honggfuzz漏洞挖掘技术深究系列
发表于: 2018-11-24 13:24 31666

[原创] honggfuzz漏洞挖掘技术深究系列

2018-11-24 13:24
31666

“反馈驱动:通过监控样本触发的代码覆盖率,进而改进输入样本以提高代码覆盖率,增加发现漏洞的概率。”

目前业界中基于代码覆盖率的最著名的三大Fuzzer,当属Google开发的AFL、libfuzzer和honggfuzz,且他们都是开源的,在github上都可以搜索到。

相信很多搞fuzzing的同学都听过或用过这三款工具,本系列主要讲honggfuzz的原理与应用,之前把honggfuzz源码都阅读过一遍,并且二次开发过,该工具的挖洞效果还是不错的。

计算代码覆盖率情况就需要有个计量单位,通常有3种:

函数(Fuction-Level)

基本块(BasicBlock-Level)

边界(Edge-Level)

1. 函数(Fuction-Level)

先说下函数,这个很容易理解,就是代码执行时调用到哪些函数,但是函数里面的具体代码行却不作统计,相对比较粗糙但高效的统计方式。

所以,通常的统计方式是用基本块,简称BB。

2.基本块(BasicBlock-Level)

什么是基本块,直接看下图就很容易理解了。

IDA中每一块代码就代表着一个基本块,就是以指令跳转为作划分界限的。

3.边界(Edge-Level)

edge本身就涵盖了基本块部分,唯一的差别是edge多记录了一些执行边界的信息。比如示例代码:

在IDA中可以看到A、B、C这3个基本块,但当a为假时,程序就会从A执行到C。

前面基本块的方式就无法确切地知道是否曾从A执行到C,尤其是该段代码被多次执行的情况,就更无法知道,这时edge覆盖方式就出现了。

edge会在A跟C之间建立虚拟块D,通过判断D是否执行过,来确认是否曾从A执行到C,这种方式也会比较消耗性能就是:

统计代码覆盖率又分两种情况:

1.【有源码】:直接使用SanitizerCoverage即可,在编译选项中添加相应的覆盖率统计方式,比如基本块统计方式可以添加:

CFLAG=“-fsanitize=address -fsanitize-coverage=bb”

2.【无源码】:使用Pin、DynamoRIO等二进制插桩工具去hook统计,或者pediy改指令的方式去监控也是可以的,本系列的后续文章可能会细说。

本文我们默认以基本块作为代码覆盖率的统计方式,比如采用如下编译选项:

ASAN_OPTIONS=coverage=1:coverage_direct=1 -fsanitize=address -fsanitize-coverage=bb

执行后它会生成两个文件:.sancov.map和.sancov.raw,这是honggfuzz处理过的scancov文件。

其中.sancov.map文件记录是模块信息,.sancov.raw文件则记录着执行过的基本块地址信息:

1、首先,honggfuzz会先去分析.sancov.raw文件,保存命中的基本块地址,记录BB数,以及总共的BB数:

2、计算代码覆盖率 = 命中BB数 / (命中BB数 + 未命中的BB数)

以下是旧版honggfuzz关于coverage的显示内容格式:

新版的变成只记录BB/edge数:

3、发现新路径或者新插桩链接库加载,则添加此变异样本为新的输入样本,供后面作进一步变异,以触发更多新路径

honggfuzz最早创建于2015年,跟AFL的发布时间差不多,AFL的出现可以说在安全界是项里程碑标志,给漏洞挖掘技术带来新的技术革命,网上对其源码分析的文章也到处可见,但对honggfuzz的详细分析还没有,因此才作此系列记录下。

个人也曾给honggfuzz贡献过代码,但由于某次pull request未被采用,于是就自己二次开发不再提交合并。因为我是在macOS下开发,而原作者主要是用Linux,那次提交的功能对我很有用,所以只好自己维护一份二次开发版本。

后来自己也在Windows和macOS平台上扩展了许多新功能,在本系列文章中,后面可能会单篇聊一聊,也感谢作者robertswiecki开发出这么好用的fuzzer,让我借此刷了不少CVE。


上篇《honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)》讲到基于软件的代码覆盖率驱动fuzzing的方式,除了软件还有硬件方式,即基于Intel BTS (Branch Trace Store) 或Intel PT (Processor Tracing) 去计算代码覆盖率,同时要求Linux内核>=4.2,这种方式的最大好处是完全由硬件支配,无所谓软件是闭源还是开源。由于硬件环境受限,我也一直未使用过,有此条件的同学可以试下。

本篇主要讲下持久型fuzzing(Persistent Fuzzing),即fuzzing API,这种方式会更精准和高效的。

先看使用方法:

这里用到几个编译选项:

trace-pc:追踪执行过的基本块BB,在每个edge中插入__saitizer_cov_trace_pc()函数,可定义该函数作为相应的回调处理

indirect-calls:在每个间接调用中添加PC追踪,与前面的trace-pc或trace-pc-guard联合使用,回调函数:__sanitizer_cov_trace_pc_indir

trace-cmp:追踪每个比较指令和swith语句

以trace-pc为例,测试代码如下:

可以看到自定义的函数被执行,输出执行过的不同pc地址,其它编译选项的用法同上。
下面是honggfuzz对各个回调函数的定义情况:

然后就是记录代码覆盖率情况并进行统计,跟驱动反馈的方式一样了。

再回头看使用示例中的LLVMFuzzerTestOneInput函数,honggfuzz是如何处理它的呢?

通过for无限循环调用目标函数进行Fuzzing,其中参数buf,即样本文件内容,len是数据长度。

最后根据发现的新路径,将相应的样本作为新样本继续fuzzing。


honggfuzz在对输入文件进行变异前,会先创建个临时文件名(honggfuzz+pid+time),然后将输入数据变异后写入临时文件。

fuzz策略的实现主要集中在mangle.c中,在循环的fuzzloop函数中,会根据用户的选择的fuzz方式来调用动态fuzz或者静态fuzz的方法,但最后都是调用mangle_mangleContent来变异文件数据:

跟进mangle_mangleContent函数:

重点就在于后半部分,它会随机选择变异函数进行处理,更改的字节数也是随机的,根据用户指定的mutation变异率来定,即允许变异文件大小的百分比,变异函数列表如下:

这些函数都是在mangle_init中初始化,各函数之间也会相互调用:

把这些函数过一遍就是honggfuzz中所有的文件变异规则了,如果想实现自己的fuzzer,这些规则来扣出来用Python实现一遍,顺便把afl的规则也扣过来就更完美了,下面是我之前写office fuzzer时的半成品代码,最后偷懒直接用radamas去实现变异了:

再回到刚才的变异函数列表,我们一个个走读源码。

1、mangle_Resize函数:

用空格填充随机位置

2、mangle_Byte函数:

向随机位置写随机的uint8类型的数据

3、mangle_Bit函数:

取随机位置的数值做位翻转

4、mangle_Bytes函数:

在随机位置覆盖写2~4字节数据

5、mangle_Magic函数:

取各种边界值进行覆写,这些边界值部分跟AFL还不一样,我在自己的fuzzer里面把它们作了整合。由于边幅所限,我省略了不少边界值:

6、mangle_IncByte函数:

取随机位置的数据加1

7、mangle_DecByte函数:

取随机位置的数据减1

8、mangle_NegByte函数:

取随机位置的数据取反

9、mangle_AddSub函数:

取随机位置的1、2、4或8字节的数据长度作加减操作,操作数取 rand(0~8192)-4096


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2018-11-28 10:04 被riusksk编辑 ,原因:
收藏
免费 19
支持
分享
最新回复 (25)
雪    币: 1646
活跃值: (2666)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
2
PT这东西算intel黑科技了,overhead巨低
2018-11-24 15:09
2
雪    币: 2063
活跃值: (1752)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
有afl的文章吗
2018-11-24 16:09
2
雪    币: 47147
活跃值: (20440)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
4
感谢泉哥的分享!
2018-11-24 16:34
2
雪    币: 23
活跃值: (57)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
学习!!
2018-11-24 17:45
2
雪    币: 26339
活跃值: (63282)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
6
感谢分享!!
2018-11-24 18:54
1
雪    币: 2754
活跃值: (346)
能力值: ( LV15,RANK:828 )
在线值:
发帖
回帖
粉丝
7
膜泉哥
2018-11-24 18:55
1
雪    币: 416
活跃值: (162)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
8
在知乎上面就看泉哥的这个系列文章了,很详细,适合新人
2018-11-24 19:34
0
雪    币: 53
活跃值: (106)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
好久没在看雪上看到这么精彩的文章了
2018-11-25 10:36
1
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
10
davidangle 有afl的文章吗
论坛已经有afl的分析了,可以搜索下
2018-11-25 11:10
0
雪    币: 292
活跃值: (810)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
11
终于来了,感谢泉哥分享,看到intel pt就开心,期待后续的内容!
2018-11-26 09:11
1
雪    币: 292
活跃值: (810)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
12
另外想请教一下泉哥关于intel pt是否可以在vm环境下使用,我曾经尝试过,但是失败了..还是说intel pt目前只能在host中使用?
2018-11-26 09:32
0
雪    币: 1646
活跃值: (2666)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
13
Keoyo 另外想请教一下泉哥关于intel pt是否可以在vm环境下使用,我曾经尝试过,但是失败了..还是说intel pt目前只能在host中使用?
vm环境下的话,在hyper-v的root partition是可以用的,但是特么hyper-v好像没有虚拟性能计数器。VMware的话,你逆过它的hypervisor就发现压根没实际处理PT相关的指令(至少14.0是这比样)。所以目前来讲,你不想花大力气去搞虚拟化的话,只能跑在host上。
2018-11-26 10:10
1
雪    币: 1392
活跃值: (5167)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
14
2018-11-26 11:36
1
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
15
Keoyo 另外想请教一下泉哥关于intel pt是否可以在vm环境下使用,我曾经尝试过,但是失败了..还是说intel pt目前只能在host中使用?
国外有人在最新版vmware 下,通过改配置开启过,不过我也没成功过。
所以我装了win/ubuntu双系统
最后于 2018-11-26 12:26 被riusksk编辑 ,原因:
2018-11-26 12:25
1
雪    币: 292
活跃值: (810)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
16
ifyou vm环境下的话,在hyper-v的root partition是可以用的,但是特么hyper-v好像没有虚拟性能计数器。VMware的话,你逆过它的hypervisor就发现压根没实际处理PT相关的指 ...
感谢指点
2018-11-26 16:47
0
雪    币: 292
活跃值: (810)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
17
riusksk Keoyo 另外想请教一下泉哥关于intel pt是否可以在vm环境下使用,我曾经尝试过,但是失败了..还是说intel pt目前只能在host中使用? ...
多谢泉哥指点
2018-11-26 16:47
0
雪    币: 1491
活跃值: (985)
能力值: (RANK:860 )
在线值:
发帖
回帖
粉丝
18
Keoyo 另外想请教一下泉哥关于intel pt是否可以在vm环境下使用,我曾经尝试过,但是失败了..还是说intel pt目前只能在host中使用?
可以使用 VT技术,可以在VM下使用
2018-11-26 16:57
0
雪    币: 292
活跃值: (810)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
19
仙果 可以使用 VT技术,可以在VM下使用
嗯嗯,谢谢果牛,VT-x我一直都是在用的,因为之前有段时间在看kafl,kafl就是在intel pt下做的,因为vm下没法用intel pt所以就耽搁下来了,所以有此一问
2018-11-27 09:22
0
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
20
IamHuskar https://github.com/hunter-ht-2018/ptfuzzer基于PT的AFL  
win下有个支持pt的winafl-intelpt: https://github.com/intelpt/winafl-intelpt
但没有相应的使用说明,也没搞懂怎么用,大家有兴趣的可以看看
最后于 2018-11-28 10:02 被riusksk编辑 ,原因:
2018-11-27 15:14
0
雪    币: 1491
活跃值: (985)
能力值: (RANK:860 )
在线值:
发帖
回帖
粉丝
21
贴子置顶一个月,欢迎大家讨论学习
泉哥棒棒哒!
2018-11-27 23:40
0
雪    币: 206
活跃值: (108)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
22
好详细的过程,记录下
2018-11-28 09:32
0
雪    币: 861
活跃值: (683)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
23
感谢泉哥
2018-11-28 10:05
0
雪    币: 27
活跃值: (622)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
24
感谢分享
2018-12-5 14:08
0
雪    币: 336
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25
感谢分享
2019-1-20 21:34
0
游客
登录 | 注册 方可回帖
返回
//