谈起0day漏洞挖掘,大家也许都知道源码审计,模糊测试,污点分析,符号执行。上述四种方法固然可行,今天给大家带来一种发现0day的全新方法——采用人工智能领域的机器学习来挖掘漏洞。
基于机器学习的漏洞发现先后包括四个过程:代码语法树的抽象,嵌入向量空间(源码向量映射),结构化漏洞模式的识别(机器学习),漏洞外推。机器学习发现漏洞的整个过程如下图所示。
代码语法树抽象
通过机器学习来发现源码中的漏洞,首先得解决一个问题——如何将源码中漏洞的口头描述表示成为能够搜索的模式。此时需要对源代码做语法分析,控制流分析及数据流分析。通过语法分析使得理解整个代码的基本组织结构;通过控制流分析使得理解程序代码执行的顺序,以及它的执行路径有哪些;通过数据流分析使得理解代码怎么处理其中的数据。
通过以上分析将分别得到抽象语法树(AST, Abstract Syntax Tree),控制流图(CFG, Control Flow Graph),程序依赖图(PDG,Program Dependence Graph)。AST是由编译器的代码解析器生成的第一个中间表示形式,它构成了生成许多其他代码表示的基础;CFG显示地表示源码中语句执行的顺序以及程序中满足特定路径执行的条件分支;PDG用于确定程序中影响指定语句中变量值的所有语句和谓词,它可以显示地表示语句及谓词的依赖关系。如以下代码:
经过语法分析生成的语法树、控制流图、程序依赖图如下。
语法树的节点包括语句、声明、函数调用、操作数,语法树的边为语句结构的嵌套。
控制流图的节点包括语句、条件,控制流图的边为控制的条件流,控制流图的生成需要依靠语法树的节点。
程序依赖图的节点包括语句和条件,边为控制和数据的之间依赖,程序依赖图的生成需要依靠语法树的节点和边。
最后将语法树的节点以及语法树的边,控制流图的边,程序依赖图的边组合得到源码的属性图(CPG, Code property graph),它是一个依附于节点的边标记的具有属性的图。
AST,CFG,PDG各有优势,有些漏洞源码只需要其中一种就可以表示,有些可能需要多种。经过分析得出以下12种漏洞中的10种容易使用上述模型表示,如内存泄露、缓冲区溢出、空指针引用等,其他设计错误较难通过上述模型表示,而竞态条件漏洞需要考虑运行时间。
代码特征映射
首先机器得能够学习代码,但是机器学习算法操作的是特征向量,而非代码,所以需要将分析的对象映射为特征向量。构建代码的映射是整个方法成功的关键。通常向量化后的特征空间是高维的,因此还需要降维,采用主成分分析方法(PCA, principle component analysis)进行降维。
将代码映射至向量可以采用以下方法:基于令牌的特征映射(需要词法分析);基于符号的特征映射(需要语法分析);基于树的特征映射(需要枚举子树);基于图形的特征映射(需要枚举和散列图形);多阶段特征映射(特征的聚类,嵌入簇);
机器学习和漏洞外推
在将漏洞源码映射到特征向量空间后,使得机器可以学习漏洞源代码的特征,从而生成一批漏洞模式(每个漏洞可以得到一个模式),通过漏洞模式将漏洞进行外推即可发现新的漏洞。漏洞外推是指将已知的漏洞映射到整个工程项目,识别与漏洞最接近的函数,另外相似的功能也可能遭受同样的漏洞。
比如说某软件新公布了一个漏洞,因为编码人员的某种编码习惯,那么该软件其他代码是否也存在相似特征的漏洞了?如将该方法用于实际发现FFmpeg漏洞过程中,发现了与漏洞CVE-2010-3429源码相似性为0.89的函数处存在类似漏洞,该函数为vpa_decode(),分配的漏洞编号为CVE-2011-4364,如下图所示。
本文内容参考:
1.Vulnerability Extrapolation: Assisted Discovery of Vulnerabilities using Machine Learning, Dr. Fabian Yamaguchi
2.Intelligent Vulnerability Discovery—Machine Learning for Computer Security, Dr. Fabian Yamaguchi