题目:Hawkeye: Towards a Desired Directed Grey-box Fuzzer
作者:Hongxu Chen ; Yinxing Xue∗ ; Yuekang Li ; Bihuan Chen
单位:Nanyang Technological University Singapore, Singapore Fudan University Shanghai, China
出版:CCS’18, October 15-19, 2018, Toronto, ON, Canada
目标:设计高效的定向灰盒模糊器
现有工作:
现有基于距离的DGF(代表是AFLGO)主要有以下几个方面的不足:
1)target函数可以在PUT的任意位置,很多不同的trace都可以到达target;
2)因为call graph很大程度地影响了trace距离的计算(与target sites的差异),所以它需要很准确地构建;特别地,函数间的间接调用不应该被忽略。
如果上述两个问题没有解决好,基于距离的方法就会是一种阻碍,难以找到隐藏在深的函数调用序列中的漏洞。
理想的定向灰盒模糊的四种所需属性:
P1 DGF应该具有强大的基于距离的机制,来引导定向模糊测试。需要考虑能到达目标的所有trace,避免偏向某些trace。
P2 DGF应在静态分析中达到耗费(overheads)和效用(utilities)之间的平衡。
P3 DGF应优先考虑并调度可以快速到达目标的种子。
P4当种子覆盖不同的程序状态时,DGF应采用自适应的变异策略。
需要解决的两个问题:
如何进行适当的静态分析,收集DGF的必要信息?
如何对DGF中使用的动态策略进行适当调整?
方案:
对于P1,应用静态分析结果计算相邻函数距离;并且在计算函数级距离和基本块级距离时加入相邻函数距离,以模拟函数之间的关系强度。同时,在模糊测试期间,通过将静态分析结果与运行时执行信息相结合,来计算基本块跟踪距离和执行trace与目标函数覆盖相似性。
对于P2,应用基于调用图(CG)和控制流图(CFG)的分析,即函数级可达性分析,函数指针的point-to分析(间接调用)和基本块度量。
对于P3,结合基本块trace距离和覆盖函数相似性来解决功率调度问题和种子优先级排序问题。
对于P4,根据可达性分析和覆盖函数相似性应用自适应变异策略。(自适应变异策略包含种子排优先级;根据是否达到目标决定是粗粒度、细粒度变异的分配;根据是否是xml等有规则的输入确定选择何种粗粒度变异器)
方法设计:
Hawkeye的workflow主要包括两个组件:静态分析和fuzzing loop.
Static Analysis
输入: 程序源码、目标位置
输出:带有基本块距离的插桩程序
步骤:生成CG和CFG,以及基于闭包的函数指针分析。通过计算整个程序内的函数point-to集合,构建包括所有直接和间接调用的相对精确的调用图。---P2(比LLVM内置的API更精确,又不像上下文/流敏感的分析成本高)。
1-Function level distance
1)Adjacent-Function Distance Augmentation
1.1Call site occurrences CN of a certain callee for a given caller(caller中调用多少次特定callee)
1.2The number of basic blocks CB in the caller that contains at least one call site of the callee.(caller 中有几个基本块包含对callee的调用)
那么,augmented adjacent-function distance(相邻函数距离)就是
note:AFLGO中的相邻函数距离是1.
2)函数目标距离
其中R(n,Tf ) ={tf|reachable(n,tf)}.
df(n,tf)是基于从n到CG中给定目标函数tf的增广函数距离的dijkstra最短路径。
2-Basic block level distance
3-Target function trace closure
收集所有target函数tf的前驱,直到main函数。
Fuzzing Loop
输入:插桩后的二进制,初始种子,目标位置,函数级距离、目标函数trace闭包等
输出:导致程序异常行为(crash、timeout)的种子
步骤:从优先级队列选择种子;对种子应用功率调度,赋予种子能量;对种子进行自适应突变;对新生成的种子计算覆盖函数相似度以及基本块trace距离,放进对应的优先级队列。
1-Power Scheduling
基于基本块trace距离和目标函数trace相似性两个度量,决定种子的功率。
Basic Block Trace Distance.
与AFLGO的公式相同,计算执行trace的基本块目标距离累加,然后进行min-max归一化。
Covered Function Similarity.
度量执行trace在函数级别上与目标之间的相似性:依据直觉:覆盖更多函数的种子更可能变异达到目标。比较当前种子trace的函数级与目标函数trace闭包的相似性。
main-》a->c-》d
SVF:
对种子trace覆盖的函数与目标函数trace闭包之间的交集,计算其函数距离的调和平均。
然后进行归一化。
Scheduling.
为了避免像aflgo的那种对短路径的偏向,本文同时考虑了trace distance和trace similarity,计算得到种子能量.
2-Adaptive Mutation
输入:种子能量
目的:在总能量已知的情况下,分配每种类型突变的数量。
两种类型突变:
粗粒度:
(1) Mixed havoc.(混合破坏)这包括几个批量突变,即删除一大块字节,用缓冲区中的其他字节覆盖给定的块,删除某些行,多次复制某些行等等。实际的突变涉及它们的组合。
(2) Semantic mutation.当已知目标程序处理语义相关的输入文件(如javascript,xml,css等)时使用。详细说明,这遵循Skyfire,其中包括三个元突变,将另一个子树插入随机AST位置, 删除给定的AST,并用另一个AST替换给定的位置。
(3) Splice.这包括队列中两个种子之间的交叉以及随后的混合破坏。
细粒度:
只涉及几个字节级的修改,插入或删除(比如位/字节翻转,某些字节上的算术)
自适应调度:
根据种子是否到达目标,调整进行粗粒度和细粒度变异的时间分配。
粗粒度变异:
根据是否需要语义上的变异,决定是否需要semMutates,以及coarseHavoc、splice突变的时间分配。
Seed Prioritization
提供了一个三层队列,根据分数将新生成的种子附加到不同的类别中。首先挑选顶层队列(第1层)中的种子,然后是第二层(第2层),最后是较低层(第3层)。 这模仿了具有恒定时间复杂度的简化优先级队列。
优先级排序策略:
第一层队列:新生成的种子中,满足1)覆盖新的trace;或者2)与目标种子具有更大的相似性值(即功率函数值);或者3)覆盖目标函数。
第二层队列:其他新生成的种子。
第三层队列:已经变异过的种子。
评估:
Hawkeye可以到达目标站点,并且比现有的最先进的灰盒模糊器更快地重现崩溃。可以用于进行补丁测试,crash暴露和其他情况
未来工作
扩展Hawkeye以支持二进制模糊测试;结合基于覆盖的灰盒模糊,如CollAFL、Skyfire等。
与AFLGO的对比:
考虑了相邻函数的增强距离(AFLGO将相邻函数距离视为1);
加入了种子优先级排序;(AFLGO没有修改AFL的种子选择,应该是按照放入顺序选取)
功率调度不仅考虑基本块trace距离,还是考虑了函数覆盖情况;(AFLGO只考虑距离可能更倾向短的路径)
自适应的功率调度,设计选择变异类型的策略。(AFLGO使用afl的变异策略)
lava-m、cgc