logo资料库

基于深度学习的软件源码漏洞预测综述 .pdf

第1页 / 共10页
第2页 / 共10页
第3页 / 共10页
第4页 / 共10页
第5页 / 共10页
第6页 / 共10页
第7页 / 共10页
第8页 / 共10页
资料共10页,剩余部分请下载后查看
http://www.paper.edu.cn 基于深度学习的软件源码漏洞预测综述 马倩华 ,李晖 北京邮电大学网络空间安全学院,北京  100876 摘要:深度学习方法能自动提取软件源代码的一些语法语义特征进行漏洞预测,已有一些研究 证实了其有效性,但该领域还没有统一的指导原则,本文对深度学习与漏洞预测的相互适应性 进行了探讨,总结出了构建基于深度学习的漏洞预测系统可以参考的指导原则,然后基于这些 原则,分析构建系统所需的关键模块,并将该领域适用的系统简化归类为两种框架,结合对前 人的工作的总结分析,给出如何组织这些模块以构建完整的系统。 关键词:人工智能;漏洞预测;深度学习;特征提取 中图分类号: tp311.5 Review on deep learning based software vulnerability prediction MA Qianhua , LI Hui Cyberspace Security, Beijing University of Posts and Telecommunications, Beijing, 100876 Abstract: Deep learning methods can automatically extract syntactic and semantic features of software sources for vulnerability prediction. Some studies have confirmed its effectiveness. However there is no unified guiding principle in this field. In this paper, the mutual adaptability of deep learning and vulnerability prediction is carried out, and the guiding principles are proposed for a reference to build deep learning based vulnerability prediction system. Based on these principles, we summarize the key modules required by the system, and are classify the frameworks in this field into two. Combined with the analysis of previous work, we also summarized how to organize those modules to a complete framework. Key words: artificial intelligence; vulnerability prediction; deep learning; feature extraction 0 引言 软件漏洞一直是软件企业及用户的一个巨大威胁。近年来,随着各种各样的软件安全事件 及其对广大用户所造成影响的曝光,软件安全越来越引起公众和媒体的关注。为尽快修补软件 作者简介:马倩华(1996-),女,硕士研究生,主要研究方向:深度学习、漏洞预测。通信作者:李晖(1970-),女,副教授,主 要研究方向:移动安全和密码学应用研究,邮箱:lihuill@bupt.edu.cn。 - 1 -
http://www.paper.edu.cn 漏洞、防止漏洞被攻击者利用,需要及时发现软件漏洞,这促使软件安全漏洞检测技术不断发 展。而随着软件规模和复杂性的迅速增加,识别软件代码中的安全漏洞变得越来越困难。 随着机器学习技术的兴起及在许多不同应用领域的有效实践 [1, 2, 3, 4],有相关研究逐渐 引入基于数据科学和机器学习的软件漏洞预测技术。此类技术根据软件数据构建模型,并使用 该模型预测代码区域的新实例(例如文件,代码更改和函数)是否包含漏洞。另外,软件源代 码中具有定义良好的语法 [5] 及潜藏在代码中的语义 [6] 信息,已被证明有助于获取编程模式、 代码完成和错误检测等 [7, 8, 9, 10],利用这些语法、语义信息进行漏洞的特征表示,则可以改 进漏洞预测的效果,同时,这些特征的提取不再依领赖域专家,避免了乏味冗长的工作及人工 可能带来的过时经验和潜在偏差。 深度学习作为一种强大的表示学习方法,能从复杂的表示中发掘信息特征并将其简单表示, 很适合提取源代码的语法语义特征。本文总结分析了基于深度学习的漏洞预测可以参考的指导 原则,根据这些原则,深度学习在该领域的应用可以分为两个方向,粗粒度预测 [11, 12, 13, 14, 15] 和细粒度预测 [16, 17, 18],粗粒度预测基于文件或函数级别,提供较大的信息量,每条输 入数据长度不固定,且存在非常长的情况,细粒度预测针对小代码段或者非常精简的 API 调用 链,长度受到严格的约束。本文通过分析这两个方向上的论文及深度学习算法自身的特性,将 其选择的模型框架分为两种,分析了其优缺点并给出不同粒度上的框架选择原则。 1 相关技术介绍 1.1 漏洞预测 漏洞预测是在机器学习的基础上发展起来的,与传统的漏洞检测不同的是,漏洞检测主要 是利用静态分析、动态分析、符号执行等程序分析方法,研究由特定程序机制产生的漏洞,由 专家制定相应的检查规则、审计点来完成。而漏洞预测一般不涉及漏洞产生原因,只是从统计 角度,发现一些特征与漏洞形成之间的关联,可解释性方面存在不足,但可以在很小的专家工 作量的情况下实现大规模的漏洞预测,且能无偏地发现一些人为分析不了的统计上的特征。 最早进行漏洞预测模型构建的研究工作主要集中在两个方面:1)人工设计新特征或组合特 征以更有效的表示软件组件的漏洞相关信息;2)使用新的和改进的机器学习算法来更准确地区 分出有漏洞组件。研究者们设计了许多代表软件组件的特征,被选作漏洞预测因子 [19, 20, 21, 22, 23, 24],最常用的是软件度量 [22](代码规模,依赖数量和循环复杂度),代码流失度量(例 如代码变化的行数量)和开发者活动 [21],以及依赖性和组织度量 [19]。同时,软件漏洞预测采 用了许多机器学习算法,包括逻辑回归(LR),支持向量机(SVM),朴素贝叶斯(NB),决策 树(DT),神经网络(NN)等。[25] 总结这些工作并对其进行了分类。基于深度学习的漏洞预 测以深度学习提取的特征代替了人工特征设计,在得出预测结果时,可以用提取特征的深度学 习模型同时得到预测结果,也可以利用另外的机器学习算法对提取出的特征计算出预测结果。 按训练集和测试集的来源,软件漏洞预测一般分为项目内预测、跨版本预测、跨项目预测。 项目内预测的训练集和测试集来自同一个软件项目,跨版本预测中则自同一个软件项目的不同 版本,跨项目预测的来自不同的软件项目的。由于同一个软件项目有统一的代码风格和特征表 - 2 -
http://www.paper.edu.cn 现,不同的项目就不一定了,所以项目内预测的准确率一般都较高,跨版本预测稍低些,跨项 目预测的准确率会低好多 [11, 12],但跨项目预测又具有很强的通用性,因此跨项目预测也是该 领域一个比较大的挑战。 1.2 深度学习 深度学习通过建立分层模型结构,突破浅层学习的限制,能够表征复杂函数关系,对输入 数据逐层提取从底层到高层的特征,并且逐层抽象,从而建立从底层简单特征到高层抽象特征 的非线性映射关系 [26]。深度学习已在自然语言处理、图像领域方面取得了巨大的成功,且已 被证明对程序分析也有效,[27] 将深度学习方法循环神经网络(RNN)与软件语言建模相结合, 以提高软件工程中底层抽象的质量。[28] 使用时延神经网络(TDNN)来学习源代码的结构,并 表明它可以成功地捕获 AST 中不同节点之间的相似性和关系。[29] 修改了 RNN 编码器-解码 器,以针对给定的与 API 相关的自然语言查询生成 API 使用序列,并显示了其有效性。 2 基于深度学习的漏洞预测 2.1 设计原则 构建基于深度学习的漏洞预测系统,首先要明确任务目标,要基于何种粒度预测,代码文 件、函数,还是更小的粒度,需不需要进行漏洞类型的识别,需不需要进行漏洞定位。然后要考 虑算法模型的选择,代码也是一种语言,直观上可以借鉴自然语言处理领域的模型,比如利用 LSTM 学习上下文特征,将数据排成二维图像用 CNN 学习其空间特征,在数据进入这些模型 前也还可以利用 word2vec 等方法进行预处理,但具体需要考虑漏洞预测的应用场景选择算法。 同时需要考虑的是,在构建模型到使用的过程中,输入数据都及其重要,训练数据决定模型能 学习到哪些特征,适用于哪些任务,训练数据和测试数据是否同分布决定模型能否在测试数据 上也提取出学习到的特征,且输入数据得是具有自然矢量表示的数据,需要对原始代码进行一 些转化,例如图像识别中用像素作为输入,在自然语言处理中将各个词替换成其 one-hot 向量 或 embedding 向量作为输入。 在漏洞预测时,却不能直接将代码转换成数字向量。自然语言和代码有一个很大的区别是, 自然语言是先有语言再有语法,语法从句子中总结而来,而代码是先定义语法,再严格根据语 法书写代码,有各种手段可以完整解析代码语法,将其表示成抽象语法树 [30],控制流图 [31]、 数据依赖图 [32] 等。另外,对于漏洞预测任务,源代码中的大部分信息都是与其安全性无关的, 不做任何筛选的直接分析不仅会大大降低程序分析的效率,还会因为大量冗余信息导致分析的 精确度下降。因此,面向源代码的分析通常需要在语法解析的基础上,更进一步提取和抽象信 息,用一种更有针对性更精简更统一的形式来表示原始程序,即中间表示,以此作为深度学习 模型的输入。 由此得到设计基于深度学习的漏洞预测系统需要重点考虑的三个问题 [18]:预测的粒度、代 码的中间表示和深度学习算法的选择。三者必须互相适应统一,中间表示具体需要表示出什么 - 3 -
http://www.paper.edu.cn 信息,由预测的粒度决定,中间表示最终要表示成什么形式,由选择的深度学习算法决定,粒度 和中间表示包含的信息量也决定选择怎样的深度学习算法,我们将其适应性原则总结如下。并 在下一小节依据这些指导原则对前人工作进行总结归纳。 预测的粒度 粒度确定具体的任务目标,粗粒度基于文件或函数级别,细粒度只针对很小的代 码段。粗粒度不涉及定位漏洞和识别漏洞类型,但也因此可以在一个统一模型里完成多种漏洞 类型的识别,能捕获源码中较丰富的信息。细粒度可以定位漏洞,可以根据很短的输入数据追 溯到漏洞源,但输入的构造比较复杂,且一个模型只为一种漏洞类型或者同种漏洞类型构建,这 样可以确定漏洞类型,但比较局限,对多种漏洞需要构建多个模型且不能识别新的漏洞模式。两 种粒度各有利弊,需要根据具体任务需求确定预测粒度。 代码的中间表示 中间表示需要尽可能精简完整统一,但针对不同的粒度,有不同的侧重标准。 对粗粒度预测,中间表示需要在保证精简的同时尽可能包含更完整的信息,提供尽可能丰富的 输入让模型去捕捉特征,一般需要从代码的解析树或抽象语法树构建。另外,粗粒度方向存在 跨项目预测问题,需要格外注意中间表示的统一性,尤其对不同项目的表达统一性。对于细粒 度预测,中间表示需要在明确针对何种漏洞的情况下,提取该漏洞在特定位置的相关信息,需 要尽可能精简准确有针对性,一般从代码某一行相关联的数据流图或控制流图构建。由于细粒 度预测只针对特定漏洞,输入数据也很短,相当于在任务可行性上就硬性规定了其通用性,因 此,只要该漏洞及其表现形式具有通用性,就能构造统一的中间表示。 深度学习算法的选择 在算法的选择上,除了要和中间表示的形式相统一,比如 LSTM 对应序 列化的中间表示,CNN 对应二维图形式的中间表示,DBN 对应树形的中间表示,还需要重点 考虑的是与预测粒度的统一,以明确深度学习在该预测系统中的角色,是单纯构建一个代码语 言模型来提取特征还是直接进行漏洞预测的二分类任务。细粒度的中间表示一般是精简短小的 数据,可以直接选择合适的深度学习二分类算法,如图 1,特征提取和漏洞预测一步到位,特 征提取在神经网络的中间层完成,漏洞预测在网络最后一层完成,这种分类模型一般都有严格 的数据输入长度要求,于是需要对偏长的中间表示进行截断,短数据则对其补全。粗粒度的中 间表示长度不确定,且通常都是非常长的情况,不能再用深度学习二分类模型,如图 2,需要 把特征提取和漏洞预测分两步,用两个模型分别完成,选择没有长度限制的特征提取模型,不 以漏洞预测二分类为提取特征的唯一目标,使其学到长输入数据中更丰富的内部特征。 另外,在训练集的构造上也体现了预测的粒度、代码的中间表示和深度学习算法的选择相 互适应性。粗粒度预测对文件或函数所属软件项目比较敏感,项目内预测、跨版本预测、跨项 目预测三种类别的训练数据都只来自一个项目,这样可以学到更统一的信息,虽然数据长度很 长,能提供很多信息,但数量不多,一般可能就几千一万个文件,按深度学习二分类算法的标 准,这个数量是不足以训练出一个准确模型的,特征提取和漏洞预测分两步的框架,同时也解 决了这个问题,使得特征提取只关注数据内部的特征,更在乎数据总量包括长度和数量两方面 的大小,可以更好地利用训练数据集,而不是一条长数据只对应一个漏洞标签去学习特征,导 致浪费甚至提取不到很多特征。细粒度预测的中间表示原本就比较短,一条数据对应一个标签 - 4 -
http://www.paper.edu.cn 去学习特征就已足够,所以不需要将特征提取和漏洞预测分两个模型完成,但这就对数据量的 要求很严格,正好细粒度的中间表示很精细短小,包含项目针对性的特征很少,对跨项目不敏 感,所以训练数据可以取自多个软件项目,甚至可以不是软件里的代码,只需要满足具体任务 要求比如何种函数调用引发的何种漏洞就行,所以可以构造数量大且统一的训练集。 2.2 整体框架 一个完整的漏洞预测系统应该包括三个阶段,中间表示生成、特征提取、漏洞预测。基于 不同的粒度和中间表示的长度,特征提取和漏洞预测可以在一个模型内完成,如图 1,主要针 对细粒度预测,也可以分两个模型完成,如图 2,主要针对粗粒度预测。 图 1: 用于细粒度预测的输入数据很短的框架,特征提取和漏洞预测在一个模型内完成 图 2: 用于粗粒度预测的输入数据较长的框架,特征提取和漏洞预测在两个模型内分别完成 2.2.1 中间表示 中间表示是对源代码的初步解析,之后作为深度学习模型的输入,中间表示对于源码的表 达直接影响到特征提取的有效性。在构造中间表示时,需要具体考虑以下几点。第一,源代码 中存在大量无意义的字符串,比如注释、输出字符串等。第二,对于深度学习模型来说,需要 有一个明确的任务,输入要尽可能精简有效且与目标任务相关,要考虑目标任务针对何种粒度, - 5 -
http://www.paper.edu.cn 该粒度的漏洞特性表现在源码中的哪部分。因此需要规范化特征学习的输入使其包含所选粒度 的精简又完整的信息。第三,不同程序代码具有自己的风格和特点,尤其用户自定义的变量和 函数存在很多差异,需要用统一的方式表示,保留文件内部这些自定义词间的关系,去除不同 文件间的这些词的差异性来保证模型的通用性。第四,需要考虑构建特征提取模型所选深度学 习方法的特性来构造适合的输入,序列还是图像,等长序列还是变长序列。因此需要设计合适 的中间表示构建方案将源代码解析为一种完整、精简、通用性强的中间表示,以便对原始信息 进行进一步的筛选,保留能够反映出漏洞特征的上下文信息。 从源代码生成中间表示可以分为两步,源码解析和中间表示生成。源码解析通常是用现有 工具,基于编程规则和程序依赖关系等,提取代码的关键信息并将其直观表示,表示方式有:语 法解析树 [33]、抽象语法树(AST)[30]、控制流图(CFG)[31]、数据依赖图(DFG)[32]、程 序调用链 [34] 等。在此基础上,针对具体任务及所需的中间表示形式,设定如何对解析后的源 码进行关键节点提取与进一步信息合成,生成最终的树、图、或者文本序列。 粗粒度方向上经常是基于文件或函数的 AST 构建较完整的中间表示,[29] 将源码解析为 AST,将 AST 上的所有对象类型替换为其实际类类型,然后提取 API 序列作为中间表示;[11] 提取方法调用和类实例创建的节点,声明节点,控制流节点,以构造用于项目内预测的中间表 示序列。在跨项目预测中,方法调用和类实例创建的节点,声明节点被其节点类型(例如方法 声明和方法调用)替换,以生成通用性更强的中间表示。[12, 27] 用 num 替换 AST 上的所有 数字,用 str 替换常量字符串,并用 unk 替换不太出现的 token 以构造 token 序列作为中间 表示。[28] 直接将解析出的 AST 作为中间表示。细粒度的工作需要高度压缩的输入比如仅选 择 AST 上很有限的一些节点,或本来较短的输入比如只从一小块代码段构建中间表示,以使 输入的序列不会太长而超出深度分类器的学习范围。[18] 设计了一种精巧的细粒度中间表示方 法 code gadget,考虑到漏洞一般和函数的参数、返回值等数据的传递以及依赖关系密切相关, code gadget 以一行代码为预测粒度,提取该行代码控制流和数据流相关的代码行,再将这几行 代码经过统一化处理生成文本序列。[16] 在 AST 上选择 34 种节点,然后将其排成二维图来表 示源文件。[17] 仅提取长度在 [10,500] 范围内的函数作为训练和预测目标,同样最终构造成二 维图的形式作为 CNN 的输入。 2.2.2 特征提取与漏洞预测 细粒度方向上输入数据都是轻量级的,只需要再选择一个合适的深度学习二分类算法完成 特征提取和漏洞检测,构造成图 1的框架,[18] 选择了 BiLSTM,[16] 选择了 CNN。这些方法 训练模型时以得到正确漏洞标签为目标,所提特征是在预测过程中由中间层网络生成的,所以 特征针对性很强。针对该方向的输入数据包含的信息抽象程度较高,对跨项目的漏洞检测区别 不大,但正是由于信息抽象程度高和数据轻量,适合针对某类漏洞进行检测,即一个模型只能 识别一种漏洞,且只能识别给定的小范围内的漏洞,比如 [18] 针对缓冲区错误漏洞和内存管理 分别构建了模型,而将这两种漏洞统一到一个模型里预测的效果就会差一些,[16] 只针对 34 种 固定节点构建统一的模型。另外,这种使用深度学习分类算法的模型对输入数据的长度有严格 的限制,因为模型训练时只依据序列的分类标签更新参数,适合数据长度比较统一且不会太长 - 6 -
的情况,若输入超出了模型的长度限制则无法为其进行最终的分类,所以该方向经常会对长度 略长的数据进行截断,或者直接丢弃掉过长的数据。 http://www.paper.edu.cn 图 3: LSTM 序列分类中的超长序列问题,梯度按箭头的反方向回传,蓝框的背景颜色深浅表 示其梯度的大小,随着与 softmax 输出的距离的增大,梯度越来越小直至消失。 在粗粒度方向,数据长度超过了深度学习二分类算法的限制,如果还仿照细粒度方向的模 型构建方法,就会存在超长序列问题,以 LSTM 为例,LSTM 在面临超长输入序列——单个 或少量输出的情形进行序列分类时,如图 3,LSTM 每一步接收序列当前步的输入与其之前步 的状态信息,但在梯度回传时,只能传回有限步的距离,更远的地方就会因为梯度消失问题接 收不到梯度,从而无法参与参数更新,不能让模型学习到它们的信息,相当于每条数据只截取 了离 loss 计算最近的有限步作为模型输入。但对于时间序列预测这种每步输入都有一个输出的 任务,LSTM 可以运行得很好,因为每一步的输入都能参与到 loss 计算和参数更新,不再有梯 度消失的问题,且这种不依赖序列类别更新参数的方法,能更多地学习到输入数据内部更丰富 的特征。但这时候 LSTM 只能通过时间序列预测任务来提取特征,并不能进行漏洞预测的二 分类任务,需要再构建一个机器学习分类模型对这些特征向量进行漏洞预测,形成图 2的框架。 [12, 13, 14] 将源代码视为文本序列,并使用基于 LSTM 的序列预测模型提取特征,然后利用 SVM、LR、RF 等简单机器学习算法生成最终的预测结果。[11, 15] 使用 DBN 进行 AST 的树 形结构学习,同样后面接一个简单的机器学习算法。 需要注意的是,这种粗粒度框架下的特征提取相当于是无差别地为整个数据集构建了一个 统一的语言模型,没有利用到每条训练数据是否有漏洞的标签信息,这就存在特征针对性不强 的问题,可以为有漏洞和无漏洞的数据集分别构建特征提取模型,或者利用多任务学习的方法, 让漏洞预测任务成为一个辅助任务,帮助提取更有漏洞针对性的特征,总之,将漏洞标签信息 利用到特征提取过程中来,会更有利与漏洞的预测。 3 总结与展望 深度学习已在漏洞预测领域逐渐显示出其优势,通过总结分析前人的工作及该领域的自身 特性,我们得出,在构建基于深度学习的漏洞预测系统前,首先要明确三个问题:粒度的选择、 中间表示的构建、深度学习算法的选择,然后构建系统时,主要模块有三个:中间表示、特征 - 7 - x1h1xL-2hL-2xL-1hL-1softmax· · ·· · ·hLxL
http://www.paper.edu.cn 提取、漏洞预测,依据不同的粒度和中间表示,组织这些模块为两种主要框架来构建系统,一 种是特征提取和漏洞预测在一个模型中完成,另一种是两个模型完成。两种框架有各种的优势 及适用场景,但各自也都有一些缺陷,未来还有很大的发展空间及挑战。 参考文献(References) [1] Guzella T S, Caminhas W M. A review of machine learning approaches to spam filtering[J]. Expert Systems with Applications, 2009, 36(7): 10206-10222. [2] Caruana G, Li M. A survey of emerging approaches to spam filtering[J]. ACM Computing Surveys (CSUR), 2012, 44(2): 9. [3] Garcia-Teodoro P, Diaz-Verdejo J, Maciá-Fernández G, et al. Anomaly-based network intrusion detection: Techniques, systems and challenges[J]. computers & security, 2009, 28(1-2): 18-28. [4] Zhou C V, Leckie C, Karunasekera S. A survey of coordinated attacks and collaborative intrusion detection[J]. Computers & Security, 2010, 29(1): 124-140. [5] Hindle A, Barr E T, Su Z, et al. On the naturalness of software[C]//2012 34th International Conference on Software Engineering (ICSE). IEEE, 2012: 837-847. [6] White M, Vendome C, Linares-Vásquez M, et al. Toward deep learning software reposi- tories[C]//Proceedings of the 12th Working Conference on Mining Software Repositories. IEEE Press, 2015: 334-345.. [7] Nguyen A T, Nguyen T N. Graph-based statistical language model for code[C]//2015 IEEE/ACM 37th IEEE International Conference on Software Engineering. IEEE, 2015, 1: 858-868. [8] Nguyen T T, Nguyen H A, Pham N H, et al. Graph-based mining of multiple object usage patterns[C]//Proceedings of the the 7th joint meeting of the European software engineering conference and the ACM SIGSOFT symposium on The foundations of software engineering. ACM, 2009: 383-392. [9] Li Z, Zhou Y. PR-Miner: automatically extracting implicit programming rules and de- tecting violations in large software code[C]//ACM SIGSOFT Software Engineering Notes. ACM, 2005, 30(5): 306-315. [10] Tu Z, Su Z, Devanbu P. On the localness of software[C]//Proceedings of the 22nd ACM SIGSOFT International Symposium on Foundations of Software Engineering. ACM, 2014: 269-280. - 8 -
分享到:
收藏