题目:MOPT: Optimize Mutation Scheduling for Fuzzers
作者:Chenyang Lv†, Shouling Ji†, Chao Zhang¶, Yuwei Li†, Wei-Han Lee§, Yu Song†, and Raheem Beyah‡
单位:Zhejiang University; Tsinghua University; IBM Research;Georgia Institute of Technology
出版:USENIX Security 2019
问题
如何变异生成有效的测试用例
背景
Mutation-based Fuzzing
Mutation Operators
AFL的变异操作包括:
bitflip; byteflip; arithmetic inc/dec;interesting values;
user extras; auto extras;
random bytes; delete bytes; insert bytes; overwrite bytes
cross over
Mutation Scheduling Schemes
AFL在三个阶段使用的三种不同的调度策略:
- Deterministic stage scheduler
在种子被第一次选择的时候进行确定性变异(确定且慢)
- Havoc stage scheduler
更加通用,且被广泛应用到fuzzer中。是本文的关注点。
AFL按照统一的概率分布,选择R0个变异操作,应用到种子上,生成n个种子
使用固定的变异调度器从预定义的变异操作集合中选择操作。突变调度器不是直接生成一个突变操作,而是生成预定义操作的概率分布,fuzzer将遵循该分布选择操作符。
- Splicing stage scheduler
如果上面两个阶段没能找到crash或者新的路径,AFL会进入特殊的splicing stage,只执行cross over操作生成新种子。将新的种子传递给havoc stage scheduler (很少用到该阶段)
这种固定的变异调度的不足:
-
没考虑不同变异操作在一个目标程序上的有效性不同。
-
没考虑变异操作在不同目标程序上的有效性不同。
-
AFL花费大量时间在确定性变异阶段,而havoc阶段往往对于生成有趣种子更有效。
-
AFL花费大量时间在无效的变异操作上。
现有工作
当前提升fuzzing性能的工作往往关注种子能量调度以及种子选择策略,很少关注变异操作的调度。而现有的变异操作调度的工作[1,2],未能提高性能,因为没考虑如下问题:
- 不同变异操作的有效性不同
- 同一变异操作在不同目标程序上的有效性不同
变异操作的性能是依赖被测程序的,而这种依赖关系难以静态确定
- 同一变异操作的有效性随时间而变。
- 调度会引入性能负载。
好的变异调度应该有较少的计算避免降低fuzzing的速度。 - 机器学习的数据不平衡
在fuzz的过程中,真假样本的数量是不平衡的,变异操作生成有趣种子的概率较小,这可能会影响梯度下降或者其他机器学习算法的有效性。
[1]Deep reinforcement fuzzing;
[2]Fuzzergym: A competitive framework for fuzzing and learning
方案
受粒子群算法(PSO)的启发,可以动态评估变异操作的有效性,调整变异操作选择的概率。
为了选择好的变异操作以提高fuzzing的性能,通过聚合粒子发现的概率,找到变异算子的最优选择概率分布,使聚合产生更多高质量的测试用例。
MOPT根据本地的最优概率以及全局的最优概率更新每个粒子的概率;然后将所有粒子更新过的概率集成,以获取新的概率分布。
设计
目的:变异调度器可以选择下一个优化的变异操作,在给定运行上下文时,找到更多的有趣测试用例。
问题:如何找到变异操作的最优概率分布,调度器在测试目标程序时将按照该分布选择下一个操作。
let each operator explore its own optimal probability
based on those optimal probabilities, we could obtain a global optimal probability distribution of mutation operators
Particle Swarm Optimization (PSO)
Design Details
MOPT使用多个群swarms,在每个群(swarm)上应用调整后的PSO算法。其中每个粒子是一个变异操作,位置就是概率,一个swarm代表一些变异操作的概率分布。
T1: 定位每个群中每个粒子的最佳位置。
T2: 定位所有粒子的跨群最佳位置。
T3: 选择最优的群来引导fuzzing。
调整后的PSO算法
先探索每个操作的最优概率,再构建最优的概率分布。
Particles
每个变异算子都是一个粒子
本地最优位置 Lbest
通过某变异操作生成有趣种子的数目/调用这个变异操作的次数
全局最优位置 Gbest
在所有swan(群)中,该粒子(变异操作)得到的有趣测试用例数目。
Multiple Swarms
MOPT选取最有效的群的概率分布来调度fuzzing过程。
swarm’s efficiency =
当前swarm贡献的有趣测试用例div整个迭代过程的所有新的测试用例数
实现
MOPT Main Framework
PSO Initialization Module
只在fuzz开始的时候执行一次
设置每个swam每个粒子的当前位置为随机值,并将一个swam中所有粒子的当前位置之和正规化为1
设置每个swam每个粒子的位移为0.1
初始每个swam每个例子的efficiency effnow为0
初始化每个群的每个粒子的本地最佳位置 Lbest为 0.5
初始化每个粒子的跨群全局最佳位置Gbest为 0.5
Pilot Fuzzing Module
该模块要执行多个swam(群),每个swam探索不同的概率分布。
按顺序对每个swam进行fuzz,直到该swam生成足够数量的测试用例(预设的periodpilot)为止。
通过插桩,记录每个swam的三个度量
- 该swam生成的有趣测试用例数目
- 每个粒子贡献的有趣测试用例数目
- 调用特定例子的次数
这样可以得到粒子的本地最佳位置Lbest。
Core Fuzzing Module
- 采用pilot fuzzing module选出的最好swam的概率分布进行fuzzing,停止条件:生成预设的periodcore个新种子
- fuzzing停止后,计算每个粒子贡献的有趣种子数目(从PSO初始化到现在,不管哪个swam),计算粒子的全局最佳位置Gbest
PSO Updating Module
根据polit和core fuzzing阶段的信息,使用公式3,4更新每个swam的粒子
进入下一次迭代
Pacemaker Fuzzing Mode
AFL系列fuzzer花费大部分时间在确定性变异上,而用在havoc和splicing这些可以发现更多unique cash和路径的阶段时间少。MOPT提供给AFL系列fuzzer一个优化,称为pacemaker fuzzing mode,可以选择性地避免耗时的确定性变异阶段。
如果对一个种子进行变异,超过用户指定的T时间,还没有新的unique crash和path,那么将选择性地关闭后续测试用例的确定性变异。
这种模式有以下优点:
- 确定性变异耗时。MOPT是调整havoc阶段的变异,减少确定性变异会加快havoc阶段的收敛。
- 避免对单一测试用例花费太多时间,可以更多地选择队列中的其他种子,提高快速发现漏洞的机会。
- 确定性变异通常在开始阶段性能好,在一段时间之后变性能变差。这种模式可以在性能变差后选择性地关闭确定性变异,所以可以从该阶段受益,同时避免浪费太多时间。
根据确定性变异是否会被重启,MOPT为AFL提供两种模式:
- MOPT-AFL-tmp:在生成一定数量的有趣种子后重启
- MOPT-AFL-ever:在后续的fuzz过程中不会被重启