基于深度学习模型的漏洞检测方法研究

Deep Learning based Vulnerability Detection: Are We There Yet

一.简介

背景:

传统的漏洞检测技术,例如:基于静态分析方法的漏洞检测通常会导致高假阳性,动态分析存在高假阴性。到目前为止,这些工具仍然不可靠,给开发人员留下了巨大的开销。

基于深度学习模型的漏洞检测技术,获得了很好的结果,几篇state-of-the-art可以获得95%及以上的准确率。

难点:

深度学习模型通常DL模型的通用性通常受到数据集中隐式偏差的限制,通常在数据集生成/管理/标记过程中引入。

基于token(忽略了语义)和基于graph模型(类别区分性)的编码不充分性。

学习与漏洞无关的无关特征,它们很可能是数据集的人工因素而生成。

数据集中大量的数据重复造成准确率虚高。

不同类别数据不平衡。

动机

为什么这类基于深度学习的模型性能这么好?他们学习到的特征是什么?

最先进的基于DL的技术在现实世界场景下表现如何?

创新点

探究了当下高性能模型在现实场景下的漏洞检测性能。

基于现有的基于DL漏洞检测技术,分析了5个影响该性能的问题。

基于现实场景下的项目,构建了一个数据集。

给出了一个漏洞检测路线图(roadmap)。

二.研究内容

2.1数据集:

合成数据集:例子是用已知的漏洞模式合成的,例如:SATE IV Juliet、SARD 半合成数据集:例子的源代码或是标注由人工生成。例如:Draper,代码是一个开源项目,但是标注是有静态分析器完成。真实数据:例子的源代码与标注由现实场景下获得。FFmpeg、QEMU

Problem-1:使用合成数据集,由于数据简单且为构造漏洞通常对代码进行修改,从而使得代码不符合现实,最终训练的模型只能识别这些简单的模式,且这些模通常很少在实际工程中出现。

Problem-5:所有现有的方法都使用它们自己的评估数据集来评估模型性能。这种评价策略并不能全面展现模型在其他现实世界的例子中的适用性。我们所能从这种评估方法中得到的结论仅仅是:他们的方法有多么的适合他们自己的数据集。

2.2 模型:基于token的模型:

基于token的模型

使用神经网络进行处理。由于模型很难推理长序列,所以序列长度是一个很影响模型性能的因素。

对此VulDeePecker和SySeVR模型使用切片的方法,依据思想--对于漏洞预测任务而言,并非所有代码行都同样重要:将原长序列,分成多个短序列,进行切片级的预测。

基于graph的模型:

将源代码视变换成图结构,即获取源代码的语法图(抽象语法树)和语义图(控制流程图、数据流图、程序依赖图、定义链图等),用于漏洞预测。

Problem-2:

基于token的模型假设token彼此线性相关,只考虑了词汇依赖关系,而丢失了语义,而语义依赖性往往在漏洞预测中发挥重要作用

Problem-3:

而基于graph的模型考虑了语义图中的数据依赖关系,然而,基于图的模型比基于标记的模型需要更大的开销,在资源紧张的环境中表现并不佳。

Problem-4:

模型不能获得区分开漏洞与非漏洞的特征表示。如下是一个使用t-SNE绘制而成的特征分布的例子:

t-SNE图:漏洞(+)和非漏洞(o)示例之间的分离性。


a,b,c,d四图是论文选择的四个篇论文中模型得到特征的t-SNE图,可见,漏洞非漏洞样本训练学习到的特征重叠严重;e图是使用了特征分离之后的t-SNE图,极大地减轻了这种重叠现象。

2.4 解决方法:

数据集:

由于合成数据集的弊端,论文构建了一个完全由真是代码和标注构成的真实数据集:REVEAL,并在真实数据集上进行训练和实验,解决问题1,2。

项目选自:: Linux Debian Kernel 与 Chromium (Chrome的一个开源项目)。收集方法:

基于可获取的补丁,收集所有可以获取到的数据;

通过判断补丁的性质(是否为安全相关),对数据进行标注

对于每个补丁,提取补丁对应的漏洞版本和修改后版本

模型:

上图是论文给出的开放流程图,下面将介绍其中的各个部分。

特征提取:

为了提取代码中的语法和语义,使用的数据为代码函数的代码属性图(CPG),由控制流图、数据流图、AST和程序依赖图的元素组成。其定义可以表示成一个图数据结构:G = (V, E)V是节点集,其中每个节点由:一段上下文相关的代码和节点类型(ArithmeticExpression, CallStatement...)构成。代码通过word2vec编码V,节点类型通过one-hot编码T。结点的最终表示为:Con(C, T)。这种方法将每一个节点孤立的考虑,由此获得的嵌入表示,将会缺乏节点的邻居信息以及全局信息。所以,论文使用门控图神经网络GGNN让每个节点嵌入它本身和邻居节点的信息,REVEAL模型使用GRU对节点的表示进行更新:

模型-训练:

由问题4我们得知,训练得到的特征向量,有很严重的重叠现象,为此,如何将其映射到另一个特征空间,获得一个更有区分性的特征向量十分重要。另外,数据分布不平衡的问题也需要解决。

解决方法:首先,我们使用重新采样来平衡训练数据中脆弱样本和中性例子的比例。接下来,我们在重新平衡的数据上训练一个表示学习模型,以学习一个能够最优地区分漏洞和中性例子的向量表示。

使用重采样解决数据集重复问题:sub-samples the majority class:随即删除。

super-sampling the minority class:合成新样本:对某一个漏洞样本,寻找他的k个最近的漏洞邻居样本S,从这k个里面随机选择一个:S’, interpolate该样本S与邻居S’。

使用表示学习模型分离样本特征:

方法是使用MLP模型以及设定损失函数使得学到的特征在不同类别间的重叠尽可能地小


本文内容参考:

1.Deep Learning based Vulnerability Detection: Are We There Yet? - IEEE Transactions on Software Engineering 

2.论文 | 基于深度学习模型的漏洞检测方法研究 (qq.com)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容