V-Fuzz: Vulnerability-Oriented Evolutionary Fuzzing

出处:arXiv预收录

作者:Yuwei Li, Shouling Ji, Chenyang Lv, Yuan Chen, Jianhai Chen, Qinchen Gu, and Chunming Wu

1. 背景

  • 黑盒模糊器将程序视为黑盒,只是随机产生输入。
  • 灰盒模糊器也不知道程序的源代码。 他们通常对二进制程序进行一些反向分析。分析只是简单的二进制仪器,主要用于测量代码覆盖范围。
  • 白盒模糊测试,虽然能看到源代码,但是应用符号执行来探索有意义的路径是不实际的,特别是对于大型软件来说。由于难以产生足够的有效输入,白盒模糊器盲目追求高代码覆盖率的策略是不明智的,可能会浪费大量的时间和精力。

模糊测试器可以从不同的角度分为几种类型:

  • 基于不同的输入生成方法,模糊器可以分为基于生成的和基于突变的。

  • 基于探索策略,模糊器可以被分类为定向和基于覆盖。

例如,AFL是一种面向安全的引信,它采用进化算法来生成输入,从而在目标二进制文件中触发新的内部状态。 更具体地说,如果输入发现新路径,则将选择此输入作为种子输入。 然后,AFL通过改变种子输入来生成新的输入。 AFL只是将发现新路径的输入视为良好的输入。 一旦一条路径很难探索,AFL就会“卡住”,并选择另一条更容易到达的路径。

另一种最先进的引信是Vuzzer,它是一种应用感知的进化引信。 VUzzer的设计是为了更多地注意产生能够到达更深路径的输入。 对于这个例子,VUzzer将赋予更多的权重来模糊嵌套在条件语句中的代码。 然而,在更深的路径上的代码并不意味着他们有更高的可能性脆弱。 因此,Vuzzer的模糊策略也不能很好地工作。

深度学习已成功地应用于缺陷预测、程序分析和漏洞检测等领域。

  • 二进制需要转换成一些中间形式,如汇编语言,具有足够有意义的特征信息。 遵循这一思想,我们选择分析二进制程序的控制流图(CFG),因为CFG包含丰富的语义和结构信息。 此外,为了方便地训练深度学习模型,需要将二进制程序表示为数值向量。 因此,我们利用分布控制流图(ACFG)来描述和表示具有数值向量的二进制程序。
  • 我们寻求一个权衡,选择函数作为粒度进行分析
  • 我们利用ACFG来表示二进制程序,我们利用图嵌入网络来建立我们的模型,因为它已经成功地应用于提取结构数据的有效特征。 此外,徐等人。 [56]应用这种方法检测类似的跨平台二进制码。 因此,利用这个模型来预测程序的脆弱组件是可行的。 由于我们的模型的目的不是检测相似的代码,因此有必要改变图嵌入网络,使其适合于我们的问题。

2. 方法

V-Fuzz包含两个主要部分:基于神经网络的脆弱性预测模型和面向脆弱性的进化模糊器。 给定一个对V-Fuzz的二进制程序,漏洞预测模型将给出一个先验估计,在此基础上,预测软件的哪些部分更脆弱。 利用进化算法生成输入,这些输入往往到达脆弱的位置,并以脆弱性预测结果为指导。

过程如下:对于易受攻击概率的二进制程序的每个函数,V-Fuzz将给函数中的每个基本块一个静态易受攻击分数(SVS),它表示基本块的重要性。 详细评分方法详见第五节。 然后,V-Fuzz开始用用户提供的一些初始输入模糊程序。 它利用进化算法生成适当的输入。 对于每个执行的输入,V-Fuzz给出了它的适应度分数,这是在其执行路径上的所有基本块的SVS的总和。 然后,具有较高适应度分数或导致崩溃的输入将被选择为新的种子输入。 最后,通过改变种子输入,将不断产生新的输入。 这样,V-Fuzz往往产生更有可能到达脆弱地区的投入。

2.1 vulnerability prediction model

首先,训练一个漏洞预测模型,需要将二进制转换成深度网络进行训练的矩阵。

  1. 每一个函数都具有一个漏洞可行性概率值

  2. 二进制程序函数转换为数值向量,首先,我们对二进制程序进行分解,得到其函数的CFG。提取基本块的属性,并将每个基本块转换为一个数值向量。主要有三种属性:指令相关属性,操作数相关属性和字符串相关属性。 然后,每个基本块都可以用255维向量表示,现在二进制程序用一组255维向量表示。

  1. 图嵌入神经网络可以看作是一个映射λ,它将函数的ACFG映射到向量λ(G)中。我们将图嵌入网络与pooling层和softmax层相结合。 pooling层将嵌入向量转换为二维向量,每个维数的值在[0,1]的范围内。整个模型通过标记数据端到端训练,通过最小化一个损失函数可以学习模型的参数。输出p代表二进制程序g的漏洞可能性概率值。

  1. 对于函数g的ACFG,g的标号l为0或1,其中l=0表示函数至少有一个漏洞,l=1表示函数安全。然后通过优化下列方程可以学习M的参数:

2.2 vulnerability-oriented evolutionary fuzzer

fuzz是一个循环过程。 与大多数基于突变的进化模糊器一样,V-Fuzz保持着一个种子池,用于将高质量的输入保存为种子。 V-Fuzz开始使用用户提供的一些初始输入执行二进制程序。 同时,使用动态二进制仪表(DBI)跟踪程序的执行信息,如基本块覆盖。 基于SVS和执行信息,V-Fuzz将计算每个执行测试用例的适应度分数。 适应度分数高的测试用例被认为是高质量的输入,并将被发送到种子池。触发崩溃的执行测试用例也将被发送到种子池,而不管它们的适应度分数如何。 接下来,V-Fuzz通过在种子池中变异种子来生成下一代测试用例。 这样,V-Fuzz继续使用新生成的输入执行程序,直到满足结束条件为止。

  1. Static Vulnerable Score

SVS用于评估执行的测试用例。

  1. Seed Selection Strategy

  1. Mutation Strategy

V-Fuzz是一种基于突变的进化模糊系统,它通过变异种子产生新的输入。与大多数基于突变的模糊器一样,突变操作是位/字节翻转、插入“有趣”位/字节、更改一些位/字节、从几个种子中选择一些字节并将它们拼接在一起等等。

引信应根据实际引信状态动态调整其突变策略。我们定义了崩溃窗口(CW),它是确定突变策略选择的阈值。

碰撞窗口跳跃算法的主要思想是:首先,我们假设CW的初始值为iniCW,其最大值为maxCW,其最小值为minCW。 CW的值从inicw开始,引信选择轻微突变作为其初始突变策略。 在引信过程中,如果ζ>CW,引信将改变其突变策略为重突变,并将CW的值增加一倍。 一旦输入找到新的路径或崩溃,我们将ζ=0和CW的新值设置为其前值的一半。

3. 评估

使用National Institute of Standards and Technology[NIST]公开的数据集,使用Juliet Test Suite v1.3的代码(C/C++ language, label with good or bad)。

评测参数:accuracy,recall,loss

调整参数:embedding size,depth,iterations

效率评测:ACFG extraction time,training time with different model structures

表现评测:unique crashes,identified vulnerabilities,vulnerability discovery,code coverage

4. 局限性

  • 样本标记不足,影响预测性能
  • 无法基于源代码进行模糊测试

5.思考

  • 静态分析可以与模糊测试相结合
  • 使用强化学习进行fuzz,设置好对应的规则(代码覆盖率)进行训练即可
  • 创造新的代码审计指标
  • 添加代码的权重部分,一般bug的位置是较少访问的地点,所以使用权重标记细枝末节训练
  • 使用docker封装自己的实验
  • 概率使用贝叶斯

感谢观看,如有不足或错误,恳请大佬指正 (^_^)#