Full-speed Fuzzing: Reducing Fuzzing Overhead through Coverage-guided Tracing

Full-speed Fuzzing: Reducing Fuzzing Overhead through Coverage-guided Tracing

文章来自SP2019(SP的文章内容是真的饱满)

作者来自弗吉尼亚理工大学

一、论文阅读

Abstract

引入了覆盖引导追踪(Coverage-guided tracing)的概念。只有一小部分增加覆盖的测试用例需要追踪;随着时间的增加,产生新覆盖的测试用例越来越少。

1. Introduction

AFL追踪测试用例的花销太大。产生新覆盖的测试用例占比不足1/10000。

通过插桩目标二进制文件实现增加覆盖时自动报告,作者称插桩后的目标文件为:interest oracles

产生新的覆盖,则移除相应部分的插桩代码,以反映覆盖范围。这样做会使追踪测试用例的时间变为2倍。

贡献:

  • 引入了覆盖引导追踪的概念,只追踪增加覆盖的测试用例。

  • 根据八个程序,量化了增加覆盖的测试用例的频率。

  • 表明AFL和Driller大部分时间用在追踪测试用例上

  • 基于Dyninst实现了UnTracer并与AFL-QEMU,AFL-Clang,AFL-Dyninst进行比较

  • 基于QSYM实现了QSYM-UnTracer,效果蛮好

  • 开源了benchmarksexperimental infrastructureUnTracer

2. Background

没啥好说的,一些简单介绍和相关工作

2.1 An overview of fuzzing

基于语法生成、基于变异的模糊测试,目前工作主要集中在后者。黑白灰盒测试

2.2 Coverage-guided fuzzing

覆盖引导模糊测试流程。三种覆盖粒度,目前还没有研究路径覆盖的工作。

2.3 Coverage tracing performance

有无源码插桩,动静态插桩

2.4 Focus of this paper

只追踪增加覆盖的测试用例。实现了用于覆盖引导模糊测试的覆盖引导追踪框架UnTracer


3. Impact of discarded test cases

调查AFL和Driller中不增加覆盖的测试用例对性能的影响

每小时中执行用例+覆盖追踪的时间占比

AFL-Clang:91.8%

AFL-QEMU:97.3%

Driller-AFL:95.9%

增加覆盖的测试用例占比

AFL-Clang:0.0062%

AFL-QEMU:0.0257%

Driller-AFL:0.00653%


4. Coverage-guided tracing

4.1 Overview

覆盖引导追踪在测试用例生成和代码覆盖追踪之间增加了一个步骤:interest oracle

interest oracle是目标二进制的一个修改版本,在每个未覆盖的基本块头部插入断点。

触发断点则为增加覆盖,追踪并记录后移除对应的断点,这样以来,只有执行新的基本块会触发断点,即增加覆盖。

在这里插入图片描述

  • Determine Interesting:用interest oracle 执行测试用例,根据是否触发断点判断是否为有趣的,即覆盖增加的测试用例
  • Full Tracing:追踪覆盖增加的测试用例的完整执行路径。因为上一步触发断点后就退出了。
  • Unmodify Oracle:对每个新覆盖的基本块,移除interest oracle中相应的断点。
  • 返回第一步重复执行
4.2 The interest oracle

interest oracle 要求识别每个基本块的地址,angr和Dyninst都可以实现。

需要注意的问题:断点的中断信号不能和用于fuzz的信号冲突;插入的断点指令大小不能超过基本块的大小。

4.3 Tracing

interest oracle是在基本块级别插桩的,所以代码追踪也是在基本块级别操作(可以是基本块级别的追踪,也可以是边级别的追踪)。

4.4 Unmodifying

根据target binary 将插入的桩代码覆盖

4.5 Theoretical performance impact

随着时间推移,越来越多的基本块中的桩代码被移除,oracle和target binary也就越来越接近。到后期,绝大部分测试用例都执行和target binary一样的代码,也就没有额外的追踪开销。


### 5. Implementation:UnTracer
5.1 UnTracer overview

插桩两个版本的目标文件 interest oracle,tracer,一个识别增加覆盖的测试用例,一个追踪完整覆盖路径。二者都采用fork server执行。

在这里插入图片描述

  • AFL初始化
  • 插桩oracle和tracer
  • 静态分析识别所有基本块
  • 在oracle每个基本块开头插入断点
  • 分别启动fork server
  • 进入循环
    • 生成测试用例
    • 在oracle中执行,如果触发断点
      • 标记为增加覆盖的测试用例
      • 在tracer中收集完整执行路径
      • 暂停fork server
      • 移除oracle中对应基本块的桩代码
      • 重启fork server
      • AFL处理新的种子
      • 下一次迭代

流程图如下

在这里插入图片描述

5.2 Fork server instrumentation

oracle执行所有的测试用例,tracer执行覆盖增加的测试用例,两者都需要执行许多测试用例,所以都采用了fork server模式加快速度,

首先在 .text 段插入forkserver函数,然后在main函数的第一个基本块链接函数的回调。

在tracer中用Dyninst的二进制重写功能插桩,包括插入forkserver。

在oracle中,用AFL的汇编时插桩将forkserver插入到目标程序中。因为oracle要执行所有的测试用例,二Dyninst还是有一些性能影响。

5.3 Interest oracle binary

利用Dyninst静态分析得到基本块列表,遍历该列表插入桩代码,为了防止在fork server 初始化之前触发中断,忽略掉main函数中fork server回调之前的函数_start, _libc_start_main, _init, frame_dummy

使用SIGTRAP作为中断信号,因为经常用于细粒度执行控制以及分析,二进制0xCC表示为一个字节,可以覆盖所有大小的基本块。

5.4 Tracer Binary

在每个基本块插入用于追踪覆盖的回调,但执行完一个基本块后,回调会将基本块地址存入文件中

有一个问题是循环代码导致执行重复的基本块,进而重复记录相同的基本块,oracle也会重复处理这些基本块。文章的处理方式如下:

在fork server 中初始化一个全局的哈希表,之后每个fork出的子进程都会继承这个空哈希表,一旦执行完一个基本块,回调会查找这个基本块是否已经存在于哈希表中,如果没有,则更新哈希表和覆盖日志。

(这里虽说是全局的,但是其实每次执行开始时都是空哈希表。fork是写时复制的,对子进程中的哈希表更新并不会对fork server中的哈希表产生影响,所以这里消除重复处理的基本块也只是针对一次执行中的,并没有消除所有执行之间的重复。举个例子:第一次执行路径A->B->C->D,第二次执行路径A->B->C->B->C->D,第一次和第二次执行中的A、B、C三个基本块的重复处理没有消除,第二次执行中的B和C两个基本块会消除重复处理。论文读起来是这样的,还需要看看源码印证一下!)

5.5 Unmodifying the Oracle

设置了一个类似tracer中的哈希表,消除同一个基本块中的重复移除操作


6. Tracing-only evaluation

6.1 Evaluation overview

在8个程序上与AFL-Clang、AFL-QEMU,AFL-Dyninst对比。

6.2 Experiment infrasttucture

每个程序有五个输入数据集,输入数据来自AFL-QEMU运行生成

6.3 Benchmarks

baseline:afl-as的修改版本(去掉了追踪部分)作为基准开销

6.4 Timeouts

500ms

6.5 Untracer versus Covera-agnostic tracing

与AFL-QEMU和AFL-Dyninst进行黑盒比较,

与AFLClang进行白盒比较

6.6 Dissecting UnTracer’s overhead

启用fork server 和追踪(80%)是开销占比最大的两个部分

6.7 Overhead versus rate of Coverage-increasing test cases

在开始阶段,UntTracer相较于普通Fuzzer是慢一些的,因为开始时有很多覆盖增加的测试用例,因为跟踪读写以及文件输入输出操作。

作者的想法是设置一个阈值(增加覆盖的测试用例占比),大于阈值用普通Fuzzer,小于阈值用UnTracer


### 7. Hybrid fuzzing evaluation

QSYM-Tracer与QSYM比较


### 8.Discuss
8.1 UnTracer and Intel processor trace

硬件辅助覆盖跟踪

8.2 Incorporating edge coverage tracking

UnTracer使用块覆盖,作者讲到适用性(可能因为实现起来更容易吧)。

UnTracer目前不支持纯黑盒,需要两个版本的目标二进制文件:tracer(白盒插桩)和oracle(黑盒插桩)

二、源码分析

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值