基于机器学习的软件漏洞挖掘方法综述

摘要:传统漏洞挖掘方法由于存在高误报率和高漏报率的问题,已无法满足复杂软件的安全性分析需求.近年来,随着人工智能产业的兴起,大量机器学习方法被尝试用于解决软件漏洞挖掘问题.首先,通过梳理基于机器学习的软件漏洞挖掘的现有研究工作,归纳了其技术特征与工作流程;接着,从其中核心的原始数据特征提取切入,以代码表征形式作为分类依据,对现有研究工作进行分类阐述,并系统地进行了对比分析;最后,依据对现有研究工作的整理总结,探讨了基于机器学习的软件漏洞挖掘领域面临的挑战,并展望了该领域的发展趋势.

    早期漏洞挖掘技术依据是否依赖程序运行划分为静态分析方法(源代码)与动态分析方法(符号执行、模糊测试),其中,静态分析方法一般应用于软件的开发编码阶段,无需运行软件,通过扫描源代码分析词法、语法、控制流和数据流等信息来发现漏洞;动态分析方法则一般应用于软件的测试运行阶段.在软件程序运行过程中,通过分析动态调试器中程序的状态、执行路径等信息来发现漏洞。同时,也有相关研究尝试通过动静态相结合的分析方法来提高检测效率和准确率.传统的静态分析方法往往依赖于人工专家构造漏洞模式,随着软件复杂性的增加,人工构造成本过高,且人的主观性会影响误报率和漏报率.动态分析方法中,监测目标程序的崩溃是模糊测试发现漏洞的重要依据之一,因此测试效果依赖于输入种子的质量,存在测试冗余、测试攻击面模糊、难以发现访问控制漏洞和设计逻辑错误等问题.动态分析方法中的符号执行方法虽然能以较少的测试用例覆盖更多的程序路径。从而挖掘复杂软件更深层次的漏洞,但仍存在路径爆炸、约束求解难、内存建模与并行处理复杂等问题,单独处理大型软件系统时仍存在较大困难.

      在基于机器学习的软件缺陷预测方法中,数据预处理比分类器的选择更为重要。在训练阶段,首先需要通过随机欠采样、随机过采样和合成少数类过采样等方法对训练数据集进行平衡预处理;接着软件程序相关数据通常是文本表示形式,需要转换成向量表示形式才可用于模型计算,因此将预处理后的训练数据集通过数据表征模块进行一系列处理.【在数据表征模块中,从训练数据集中按照代码度量、Token序列、抽象语法树和图等代码的表征形式(由于训练数据集多为代码数据,因此文章将这类数据表征形式统称为代码的表征形式)抽取相应的代码表征】

基于机器学习的软件漏洞挖掘工作流程

    基于机器学习的软件漏洞挖掘模型主要对数据表征模块中的代码表征形式与编码模型、模型训练模块中的机器学习模型进行改进,以优化漏洞挖掘的准确率和效率.其中,数据表征模块主要实现代码的特征选择过程,即从源数据(数据获取模块收集到的软件程序相关数据)中根据代码表征形式提取最具代表性的信息,并转化成可供后续机器学习模型训练的数值数据.

    通过以上分析以及综合梳理近年来的相关研究,发现用到的编码模型集中于统计量化、word2vec、词袋模型、TF-IDF算法和N-gram模型.针对不同的表征方式,选取合适的编码模型和机器学习模型。

深度学习也被逐渐引入到漏洞挖掘领域.常用的深度模型有多层感知机(multilayer perception.简称MLP)、卷积神经网络(convolutional neural network。简称CNN)、循环神经网络(recurrent neural network.简称RNN)以及长短期记忆网络(long short-term memory,简称LSTM)等,其中,MLP模型需要大量的训练参数来实现拟合,因此不适合处理较长的输入序列;CNN模型的卷积操作在处理树和图等二维结构以及长文本序列时非常适用,但不适用于处理函数名等单个单词;RNN模型在输入序列的长度过大时,存在梯度消失问题。可能导致训练无效甚至失败;LSTM模型则在RNN模型的基础上引入了记忆单元和遗忘门,使LSTM模型在处理序列数据时具有更好的性能.由于代码是具有逻辑和语义的结构,具有紧密耦合的性质,因此易受攻击的代码片段的出现,通常与其上下文代码都相关,选用的神经网络应该能够对输入序列进行正向和反向处理.近期研究常采用双向长短期记忆网络(bidirectional long short-terra memory,简称BLSTM),以获得更深层的表示,达到更强的鲁棒性.

代码的表征形式

    向量表示是机器学习模型的实际输入,所以需要将源数据转换为能够表现漏洞特性的向量形式.由于需要保留源数据的语义信息(例如数据依赖和控制依赖),通常引入中间表示作为源数据与其对应的向量表示之间的“桥梁”.中间表示即本文提到的代码表征,好的表征形式可以最大程度地从原始数据中提取特征,具有更丰富的漏洞特性表达能力.常用的代码表征形式有代码度量、Token序列、抽象语法树和图,目前,相关研究主要基于这4种表征形式进行优化和变种。4种形式的特征来源、检测速度及检测效果的对比关系如图。

代码的表征形式

总结

    (1)对于研究目标而言,基于机器学习的漏洞挖掘方法的研究目标大体分为两类:一类是构建通用漏洞检测模型,这种模型不会限制检测到的漏洞的类型,是漏洞类型无关的,但是这类模型的检测结果往往只能提供潜在的可能性,一般可以认定为软件缺陷,但并不保证检测到的缺陷一定是安全漏洞;另一类则针对如缓冲区溢出、内存破坏等特定类型的漏洞,这类模型在漏洞模式的分析及特征选取时更有针对性,但是由于只关注一类或几类漏洞,构建模型时会过滤掉无关的属性,导致模型泛化性较差,若需要挖掘其余类型的漏洞,还需要再次对漏洞模式加以分析,并对模型进行重建;

    (2) 对于被分析对象而言,现有研究集中于通过对代码的分析,得到含漏洞代码和不含漏洞代码在指定特征表达上的差别,进而得到含漏洞代码的模式.在代码分析中,对源代码的分析占比更大,其中大多数模型以C/C++语言为分析对象,也有对PHP、Java以及Python等编程语言进行分析的.虽然在恶意攻击中二进制代码才是真正执行的部分,理论上直接分析二进制代码会得到更有说服力的结果,但是直接分析二进制代码的研究占比重小可能是由于二进制代码的可读性差,研究者难以从中发现含漏洞代码的一般规律并据此选取合适的特征,分析面临更大的挑战.除了对代码的分析,少数研究对提交和变更等非直接相关的信息进行尝试,也取得不错的检测效果;

    (3) 对于提取程序特征的方式而言,虽然直观上代码文本自身能够带来最多的程序相关信息,但是,基于代码度量的研究也占很大比重.基于文本挖掘的模型比基于代码度量的模型具有更高的召回率.实际应用中基于文本和代码度量的模型能取得相同的效果,甚至基于代码度量的模型所需成本更低,是实际生产中的更优选择.通过分析,本文也发现:基于文本挖掘和代码度量的漏洞检测研究都在不断地发展,面向各自针对的研究问题取得有价值的研究成果;

    (4)漏洞挖掘需要依赖上下文环境,这与NLP的需求相同,所以借鉴在NLP领域较为成功的模型能够挖掘更深层次的代码特征,从而更加细粒度地发现漏洞.



注原文:李韵,黄辰林,王中锋,袁露,王晓川.基于机器学习的软件漏洞挖掘方法综述.软件学报,2020,31(7):2040-2061.http://www.jos.org.cn/1000—9825/6055.htm

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容