模糊测试的概念第一次在20世纪90年代提出.
多年来的实践中表明传统的模糊测试只能找到程序运行初期的简单的内存冲突bug. 除此之外, 模糊测试的随机性和盲目性导致找bug效率低.
流程很简单: 不断生成测试用例调用程序执行, 如果出现错误或异常则认为是一个bug.
有两种常见的生成器:
给出一个例子:
若路径 B B 1 → B B 2 → B B 3 → B B 4 BB_1\rightarrow BB_2\rightarrow BB_3\rightarrow BB_4 BB1→BB2→BB3→BB4已经执行, 若仅考虑执行基本块的数量, 则四个基本块都已覆盖, 会遗失了 B B 1 → B B 3 BB_1\rightarrow BB_3 BB1→BB3和 B B 2 → B B 4 BB_2\rightarrow BB_4 BB2→BB4的信息.
然后是个AFL工作流程图, 看就完事了:
AFL的工作Mutation过程中, 除了会随机变异还会使用额外的有名的有趣的输入字典, 如整数中的0, 1, INT_MAX等…
好的初始输入应该另fuzzing高效且有效. 目前常用的方法是收集来自标准集, 网络上爬取和已有的字典的种子输入.
好的测试用例可以探索更多的程序执行状态, 在尽可能短的时间内覆盖尽可能多的代码.
微软研究院使用基于神经网络的统计机器学习技术自动生成测试用例. 同时也已有研究也尝试使用GAN辅助重新初始化系统.
已有研究证明好的种子选择策略可以有效地改进fuzzing效率, 加快找bug的进程.
可以考虑的做法:
创建和结束进程会耗费大量的cpu时间, 频繁地创建和结束进程会降低fuzz的效率. 传统系统特性和新特性用于优化过程. AFL使用forkserver
的方法, 创建一个已加载的程序的克隆, 并在每个单独运行中重用.
smart fuzz收集程序的控制流和数据流, 并应用这些信息改进测试用例的生成, 使测试用例生成更有目的性.
接下来选择两个重要阶段介绍如何改进fuzzing: 测试用例生成阶段和程序执行阶段.
在fuzzing生成阶段, 根据输入数据格式的知识生成测试用例. 尽管已有一些常用的文件格式开源提供, 但是更多地格式并没有提供. 如何获取这些输入的格式知识是个主要问题. 已有工作使用循环神经网络(RNN)解决这个问题.
很多已有的模糊测试工具使用基于变异的策略. 如何确定修改的位置和修改的值是另一个主要挑战. 微软的研究者使用DNN预测变异的字节和变异为什么值, 使用LSTM, 由于LSTM可以.
如何指导fuzzing过程和如何开发新路径.
fuzzing过程以覆盖更多代码和在短时间内发现更多 bug 为指导.
以是否提供源代码为依据分类, 可以分为编译内插桩和外部插桩.
使用静态分析技术收集控制流信息, 如: 路径深度.
通过插桩收集到的路径执行信息可以帮助指导fuzzing 过程.
使用符号执行技术可以获得达到程序点所需满足的约束.
已有研究也使用具体执行(concolic execution)技术绕过条件判断以找到更深的 bug.
核 API 函数的 fuzzing 存在两个主要挑战:
两个主要挑战:
这篇文章概括了近几年的 fuzzing 进展. 首先, 本文将 fuzzing 与其他攻击点发现技术作比较, 然后介绍了 fuzzing 的技概念和主要挑战. 之后主要介绍了最先进的基于覆盖的 fuzzing 技术. 最后, 总结了 fuzzing 的继承技术, 和今后新的发展趋势.