honggfuzz漏洞挖掘技术深究系列(2)—— Persistent Fuzzing
上篇《honggfuzz漏洞挖掘技术深究系列(1)——反馈驱动(Feedback-Driven)》讲到基于软件的代码覆盖率驱动fuzzing的方式,除了软件还有硬件方式,即基于Intel BTS (Branch Trace Store) 或Intel PT (Processor Tracing) 去计算代码覆盖率,同时要求Linux内核>=4.2,这种方式的最大好处是完全由硬件支配,无所谓软件是闭源还是开源。由于硬件环境受限,我也一直未使用过,有此条件的同学可以试下。
本篇主要讲下持久型fuzzing(Persistent Fuzzing),即fuzzing API,这种方式会更精准和高效的。
先看使用方法:
1 | $ cat test.c |
这里用到几个编译选项:
- 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为例,测试代码如下:
用trace_pc编译:
可以看到自定义的函数被执行,输出执行过的不同pc地址,其它编译选项的用法同上。
下面是honggfuzz对各个回调函数的定义情况:
然后就是记录代码覆盖率情况并进行统计,跟驱动反馈的方式一样了。
再回头看使用示例中的LLVMFuzzerTestOneInput
函数,honggfuzz是如何处理它的呢?
通过for无限循环调用目标函数进行Fuzzing,其中参数buf,即样本文件内容,len是数据长度。
最后根据发现的新路径,将相应的样本作为新样本继续fuzzing。