honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)

  • A+
所属分类:安全文章

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


honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)


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


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



01

关于代码覆盖率的那些事


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

  • 函数(Fuction-Level)

  • 基本块(BasicBlock-Level)

  • 边界(Edge-Level)


honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)

1. 函数(Fuction-Level)


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


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


2.基本块(BasicBlock-Level)


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


honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)

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


3.边界(Edge-Level)


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

honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)


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


honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)


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


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

honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)


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

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

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

    honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)

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



02


Honggfuzz反馈驱动原理


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


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


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


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


honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)


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


honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)


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

honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)

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

honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)

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

honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)


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

honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)


03


总结


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


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


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




honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)


本文始发于微信公众号(漏洞战争):honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: