《Automated Whitebox Fuzz Testing》

题目:Automated Whitebox Fuzz Testing (NDSS’ 2008 CCF B类)
作者:Patrice Godefroid, Michael Y.Levin, David Molnar
单位:Microsoft(Research), Microsoft(CSE), UC Berkeley
问题

传统的模糊测试工具对符合语法规则(well-formed)的程序输入进行随机变异并测试结果值。

方案

提出一种白盒模糊测试方法,记录在符合语法规则的输入下一个实际的程序运行,符号化地计算被记录的trace,收集对输入的约束,捕获程序怎样使用它们。被收集的约束一个一个地反转并用约束求解器求解,产生新的输入执行程序的不同控制路径。这个过程在最大化覆盖率启发式算法的帮助下重复,尽可能快地找缺陷。
在工具SAGE(Scalable, Automated, Guided Execution)中实现,用x86指令级trace和模拟,白盒模糊测试x86 windows应用,目前关注于读文件的应用,也可用于面向网络的应用。SAGE能够发现黑盒模糊测试找不到的bug。
检测出了很多黑盒模糊测试和静态分析遗漏的MS07-017 ANI脆弱性。发现了30+个新bug。

贡献
1)为系统化的测试生成提出一种新的搜索算法,为了大型输入文件的大型应用提供优化,展示搜索不完全的长trace
2)讨论SAGE的实现:符号执行算法背后的工程选择,能够处理大型程序trace的关键优化技术
3)讨论SAGE的实验:给出发现的缺陷的例子并讨论多种实验结果

原理

1.模糊测试:快速、划算。是一种形式的黑盒随机测试,随机地变异符合语法规则的输入并在结果数据上测试程序。
语法:用于生成符合规则的输入,允许编码特定应用知识和测试heuristics。
模糊测试/黑盒测试/随机测试存在缺点:覆盖率低–>可能错过bug
2.白盒模糊测试:开始于一个fixed input,动态符号执行程序,收集输入的约束,然后将约束系统地反转,用约束求解器求解。然后重复该过程,利用了一个新的覆盖率最大化的搜索算法,尽快找到缺陷。
3.系统化动态测试生成的局限:
路径爆炸:执行所有可达程序路径不适用于大型真实程序,可通过独立测试函数、用输入前置条件和输出后置条件将测试结果编码成函数摘要再服用摘要等方式缓解该问题
有缺点的符号执行:由于复杂的程序语句(指针操作、算数运算等)、对操作系统和库函数的调用在合理的开销下很难或无法准确处理的问题,对大程序的符号执行受限于不准确的问题。
4.新的搜索算法,特点:
被设计用于系统化地(目前是部分地)探索有大型输入的(成千上万的符号化变量)和很深路径的大型应用的状态空间
最大化每次符号执行中新测试生成的数目,避免搜索的冗余
用启发式算法尽可能快地最大化代码覆盖率,目的是更快发现bug
对divergence有复原力,每当divergence发生时,搜索可以恢复和继续
当实际执行路径与符号执行预测的给定输入向量的程序路径不匹配时成为发生了divergence
搜索算法:
初始输入inputSeed,将其加入到workList中,运行该程序并检查是否有bug。从workList选取一个元素,并进行expand以生成新的输入,对每个产生的输入,用该输入执行被测程序,检查是否有错,并被赋予一个分值(依照执行这个输入新覆盖了多少基本块),在加入到workList之前,先按分值排序。
expand过程: 给定一个输入,用该输入符号化地执行被测程序,产生路径约束PC。然后尝试expand路径约束中的每个约束,判断PC[0…(j-1)] && not(PC[j])是否可满足。如果可满足就为新路径约束生成用例I。
也就是说给定一个输入,搜索算法会用深度优先或宽度优先搜索尝试expand PC中的所有约束
由于每个执行都会expand很多孩子,所以该搜索成为代搜索(generational search)
处理divergence:是本算法处理大型应用的重要特征
存在的问题:divergence可能会阻止搜索获得新进展。如深度优先搜索,一条路径p和之前探索的路径p’不同,可能会在p’和后来的不同的run p之间循环
代搜索可容忍该问题:每个run会产出很多孩子,而不是只有一个run产生孩子,如果一个子run p和之前的p’不同,那么p的得分会是0,被安排在workList的尾部,不会妨碍其他的non-divergent的孩子expand
代搜索可以很好地并行化,因为孩子可以独立地检查和评分,只有workList和总的块覆盖率需要被共享
SAGE系统
可以测试Windows上任何读文件的程序,把从文件中读的字节看做符号化的输入
在x86二进制的程序trace上进行符号执行
1)架构:SAGE通过重复四类任务执行代搜索
Tester任务实现函数Run和Check,通过在给定测试输入下执行程序并查看是否有不正常的事件,比如access violation exceptions和extreme memory consumption。只有Tester任务没有遇到错误时才会继续后续的任务,如果Tester检查到了错误,它会把测试用例保存起来,并执行自动分类。
Tracer任务用相同是输入文件执行目标程序,这次记录执行日志,用于后续任务offline重跑程序。这个任务用iDNA框架在机器指令级收集完整的执行trace
CoverageCollector任务重跑被记录的execution,计算这次run中哪些基本块被执行了。SAGE用这个信息实现Score函数
SymbolicExecutor任务实现函数ExpandExecution,通过再次重跑被记录的execution,这次为了收集输入相关的约束并用约束求解器Disolver生成新输入
其中CoverageCollector和SymbolicExecutor任务构建在replay框架TruScan之上,输入是iDNA产生的trace文件,虚拟地重执行被记录的运行。TruScan提供多种特性,简化符号执行,包括指令解码、提供程序符号化信息的接口、监控多种输入/输出系统调用、维护堆和栈帧分配的追踪以及追踪数据流
2)基于追踪的x86约束生成:SAGE的约束生成和之前的动态测试生成的实现的不同主要体现在两个方面:
SAGE是基于机器代码的方法而不是基于源代码插桩的方法,原因主要有三个:multitude of languages and build processes。基于源代码插桩的必须支持特定语言、编译器和被测程序构建的过程,每支持一种新的开销都很大。而基于机器代码的符号执行引擎虽然复杂,但只需要为每种架构插桩一次。
编译器和编译后转换。通过在二进制代码上执行符号执行,SAGE可以不仅在目标程序中捕获bug,还可以在编译和后处理工具中捕获,如代码模糊处理器和基本块转换器等可能引入源代码和最终产品语义上的不同
源不可用。可能很难获得第三方组件的源代码或者甚至同组织不同组的组件。基于源代码的插桩可能也很难处理自修改或JITed的代码。通过工作在机器代码级,SAGE避免了这个问题。虽然少了源代码中的类型和结构信息,单SAGE路径探索也不需要。

SAGE采用的是offline基于trace的约束生成。 在线约束生成需要被静态插桩的代码或在动态二进制插桩工具(如Nirvana或Valgrind)的帮助下。
SAGE用的是offline trace-based约束生成,两个原因:
单个程序中可能会调用大量二进制组件,其中一些可能被操作系统保护或被混淆,很难用被插桩的版本替换。
大型目标程序固有的不确定性使得在线debug约束生成很难。一旦约束生成引擎出现什么问题,无法重新生成导致该问题的环境 SAGE中采用的约束生成是确定的,因为执行trace捕获了被记录的run过程中遇到的所有不确定事件的结果
3)约束生成 SAGE维护具体和符号化状态,每个内存位置关联一个存储对,分别存储字节量的值和一个符号化标签(symbolic tag)。
符号化标签是个表达式,用于表示要么是个输入值,要么是某输入值的函数
SAGE支持多种tag:
input(m)表示输入的第m个字节
c表示常量
t1 op t2表示标签t1和t2表示的值进行算数或位操作op后的结果
标签序列

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值