发表时间: 2024-03-20 11:48:38
作者: 北京青草莓科技有限公司
浏览:
不同于黑盒模糊测试工具通过模型变异生成用例 灰白盒模糊测试工具主要通过样本进化,然后基于样本库生成用例
灰白盒模糊测试一般基于样本库开始,甚至大多数测试之初并没有初始样本或只有工具给的简单初始样本
仅仅基于这样的样本进行变异测试很难达到理想的效果,因此灰白盒模糊测试工具引入了样本进化的概念
通过对被测程序进行插装,在运行的过程当中得到被测程序的运行状态,基于运行状态进行样本进化,然后继续循环测试
面临的问题1是插装,这个目前一般有以下几种
编译插装 一般在编译的过程中由编译器完成,比如 c,c++的gcc编译器和clang编译器都支持
编译中间文件插装 通过编译过程中生成的中间汇编文件进行插装,AFL等采用
二进制插装 这个一般是运行时结合一些动态插装工具插装,比如使用pin工具
面临的问题2是得到被测程序的运行状态
通常得到的是某一次运行被测程序代码块pc运行的顺序流
简单来说,模糊测试工具会将出现过的pc指针记录下来,当新出现一个pc值,认为被测代码运行到了一个以前没有覆盖过的代码,因此将本次变异的样本保存到样本库
实际上我们通过pc运行的顺序流得到的不仅仅是这些信息,我们可以得到的信息有
这次运行一共运行了那些代码块
运行了那些新的代码块
代码执行的顺序
循环语句执行的次数
我们可以细化我们得到的信息,来优化我们的样本进化
不仅仅通过代码覆盖,我们还可以通过其他信息来进行样本进化,比如一次运行分配了多少内存,消耗了多长时间等
各种各样的信息都可以用来进行样本进化,当然要避免样本爆炸这样的情况发生
面临的问题3是样本库的生成和选取
样本库来自用户定义,工具赋予和样本进化
每次选取新的样本进行变异,简单随机抽取显然是不够的,不同的样本应该赋予不同的权重,比如有些样本是刚刚新增的,有些样本能都到达更多的新路径,为不同的样本设置不同的权重也是要考虑的问题
除了上诉情况,还有一种,我们得到的是被测程序执行路径的完整符号表达式
当我们判断出执行路径的if语句已经被执行,但是else语句还没有被执行时,我们可以使用数学的手段通过符号表达式将能够进入 else分支的样本计算出来
这种情况就是符号执行技术与模糊测试结合
当然由于种种条件的限制,符号执行技术目前只作为灰白盒模糊测试工具的辅助被少量应用,而且效果貌似并不好
现在比较火的AI也经常被讨论用于和灰白盒模糊测试工具进行结合来优化样本进化
一种是通过代码覆盖情况给变异算法进行打分,来训练工具尽量采用那些分数高的变异算法
一种是通过代码覆盖情况给样本进行打分,来训练工具进行采用那些分数高的变异样本来调用被测程序进行测试,丢弃分数低的变异样本
还有一种是通过大量的已发现问题和对应的触发样本来进行训练,尽量让模糊测试工具变异出分数高的样本进行测试
利用AI面临的问题是,不同的测试用例和被测对象,都要进行不同的训练,真实应用中往往不现实
目前很多项目采用局部符号执行和变异结合或者局部AI训练和变异结合的手段,作为普通灰白盒模糊测试的辅助的尝试
还有一种是将静态扫描与灰白盒结合
这样可以得到那些路径还没有覆盖,这些没有覆盖的路径与那些已经变异出来的样本路径更近,优先调度这些样本
总之,样本进化的主要目的是提高被测程序测试的时候的代码覆盖率,毕竟低的代码覆盖率,测试效果一定好不到哪里去不是
北京青草莓科技有限公司(模糊测试-解决方案提供商)
wanghao@cyan-strawberry.com
客服1