SySeVR论文技术路线

本文介绍了SySeVR框架,该框架利用深度学习技术来检测代码中的漏洞。首先,通过抽取漏洞语法特征来识别潜在的危险代码段。接着,定义并提取程序中的结构化语法脆弱性(SyVC),并通过控制流图、数据依赖和程序依赖图将其转化为语义脆弱性(SeVC)。然后,将SeVC编码为向量,并对其进行标记以区分有漏洞和无漏洞的代码。最终,训练深度神经网络来学习这些模式,用于检测新的SeVCs是否存在安全问题。
摘要由CSDN通过智能技术生成

SySeVR:A Framework for Using Deep Learning

整体技术路线

(img-kBVv6dFr-1669812399989)(C:\Users\25659\AppData\Roaming\Typora\typora-user-images\image-20221111155200112.png)]

2.1抽取漏洞语法特征(Vulnerability Syntax Characteristics)

本文使用漏洞语法特征来识别代码片段作为漏洞检测的初始候选,例如,与指针使用相关的漏洞会显示标识符的声明包含字符*“*”*。鉴于存在许多漏洞,我们预计定义和提取它们的语法特征将非常耗时,因为这需要从易受攻击的程序中提取易受攻击的代码行。因此,我们将提出一种提取漏洞语法特征的具体方法;我们注意到这种方法还远远不够完美,因为它只覆盖了我们收集到的93.6%的脆弱程序,但足以证明SySeVR的有用性。在我们的方法中,使用程序抽象语法树(AST)上的节点属性来描述漏洞语法特征。

不考虑漏洞语法特征的具体描述,我们可以用H = {hk}(1≤k≤β)表示一组漏洞语法特征,其中hk代表一个漏洞语法特征,β为漏洞语法特征的个数。给定H,我们需要确定一段代码是否匹配语法特征hk。由于这些匹配操作特定于漏洞语法特征的表示,我们将其描述推迟到我们的案例研究中,该案例研究具有漏洞语法特征的特定表示。

2.2定义和提取SyVC

定义1(程序、函数、语句、符号 program, function, statement, token)

程序P由一组函数f1, . . . , fη构成,表示为P = {f1, . . . , fη},一个函数fi(1 ≤ i ≤ η),是语句si,1, . . . , si,mi的有序集合,表示为fi ={si,1, . . . , si,mi},一条语句si,j(1 ≤ i ≤ η,1 ≤ j ≤ mi),是符号ti,j,1, . . . , ti,j,w(i,j)的有序集合,表示为si,j={ti,j,1, . . . , ti,j,w(i,j)}

注意,符号可以是标识符、操作符、常量和关键字,可以通过词法分析提取。

给定一个函数fi,有一些标准的例程来生成它的AST。AST的根对应函数fi AST的叶对应标记ti,j,g(1≤g≤wi,j), AST的内部节点对应语句*si,jsi,j*的多个连续标记。

直观地说,SyVC对应于AST的叶节点(这意味着它是一个标记),或者对应于AST的内部节点(这意味着它是一条语句或由多个连续标记组成)。

定义2(SyVC)

考虑一个程序P = {f1, . . . , fη},其中fi ={si,1, . . . , si,mi}si,j={ti,j,1, . . . , ti,j,w(i,j)},代码元素ei,j,z是由si,j中的一个或多个连续符号组成,即ei,j,z={ti,j,u, . . . , ti,j,v},其中1≤u≤v≤wi,j。给定一组漏洞语法特征H = {hk}(1≤k≤β),其中其中*hk表示漏洞语法特征,β为前文提到的漏洞语法特征个数,匹配漏洞语法特征hk的代码元素ei,j,z*称为SyVC,其中如上所述的“匹配”操作与漏洞语法特征的具体表示有关。

算法1给出了从给定程序*P = {f1, . . . , fη}和一组中漏洞语法特征H = {hk}(1≤k≤β)中提取SyVC的高级描述。具体来说,算法1使用一个标准例程为每个函数fi生成一个AST Ti。然后,算法1遍历Ti来识别SyVCs,即“匹配”某些hk*的代码元素,其中“匹配”操作与漏洞语法特征的表示有关,因此将在处理特定漏洞语法特征时详细说明(见原文3.3.1节)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-83qh0DPC-1669812399990)(C:\Users\25659\AppData\Roaming\Typora\typora-user-images\image-20221111164941175.png)]

为了帮助理解这个思路,我们现在看一个例子。在图中,我们使用方框突出显示从程序源代码中提取的所有SyVC,这些SyVC使用漏洞语法特征,将在原文3.3.1节中描述。我们将详细说明如何提取这些SyVC。值得一提的是,一个SyVC可能是另一个SyVC的一部分。例如,从第18行提取了三个SyVC,因为它们是根据不同的漏洞语法特征提取的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D4kXCQSd-1669812399991)(C:\Users\25659\AppData\Roaming\Typora\typora-user-images\image-20221111165515526.png)]

2.3将SyVC转化成SeVC

2.3.1 基本定义

为了检测漏洞,我们建议将SyVC转换为SeVC(即SyVC→SeVC),以适应与所讨论的SyVC语义相关的语句。为此,我们建议利用程序切片技术来识别与SyVCs语义相关的语句。为了使用程序切片技术,我们需要使用程序依赖图(PDG)。这要求我们使用数据依赖关系和控制依赖关系,它们是在控制流图(CFG)上定义的。

定义3 (控制流图 CFG)

对于程序P = {f1, . . . , fη},函数fi的CFG是一个图Gi = (Vi, Ei),其中*Vi = {ni,1,…, ni,ci}*是一组节点,每个节点代表一个语句或控制谓词,*Ei = { ϵ \epsilon ϵi,1,…, ϵ \epsilon ϵ i,di}*是一组直接边,每条边代表一对节点之间可能的控制流。

定义4(数据依赖 data dependency)

对于程序P = {f1, . . . , fη},函数fi的CFG Gi = (Vi, Ei)Gi中的两个节点ni,j, ni,l (1 ≤ j,l ≤ ci,j ≠ l)。如果Gi中有从ni,lni,j的路径,并且在节点ni,j处使用在节点ni,l处计算的值,那么ni,j的数据依赖于ni,l

定义5(控制依赖 control dependency )

对于程序P = {f1, . . . , fη},函数fi的CFG Gi = (Vi, Ei)Gi中的两个节点ni,j, ni,l (1 ≤ j,l ≤ ci,j ≠ l)。如果从ni,l到程序末尾的所有路径都穿过ni,j,就称*ni,j后位控制(post-dominates)ni,l,如果存在一条从ni,l开始结束于ni,j*的路径,那么:(i)ni,j后位控制这条路径上除了ni,lni,j之外的所有节点;(ii)ni,j并不后位控制ni,l,称ni,j控制依赖于ni,l

定义6 (程序依赖图 PDG)

对于程序P = {f1, . . . , fη},函数fi的PDG记为Gi ‘= (Vi, Ei’) ,其中Vi和CFG Gi中的相同,*Ei ‘= { ϵ \epsilon ϵi,1’,…, ϵ \epsilon ϵ i,di’}*是一组直接边,每条边代表一对节点之间的数据或控制依赖关系。

2.3.2 定义程序片(Program Slices)

给定PDG,我们可以从SyVC中提取程序片。我们同时考虑前向切片和后向切片,因为(i)SyVC可能会影响一些后续语句,因此可能包含漏洞;(ii)语句影响SyVC可能会使SyVC变得脆弱。

定义7(SyVC的前向、后向、和程序切片 forward, backward, and program slices of a SyVC)

对于程序P = {f1, . . . , fη},每个函数*fi(1 ≤ i ≤ η)*的PDG Gi ‘= (Vi, Ei’),和Gi '中语句si,j的一个SyVC ei,j,z

  • SyVC *ei,j,zfi中的前向切片,用fsi,j,z表示,定义为一个有序的节点集 {ni,x1, . . .,ni,xµi } ⊆ Vi,其中ni,xp(1 ≤ x1 ≤ xp ≤ xµi ≤ ci是可从Gi中的ei,j,z到达的。即fsi,j中的节点是来自于从Gi中的ei,j,z*开始的所有路径。

  • 程序P中SyVC *ei,j,z的过程间前向切片(interprocedural forward slice),用fs’i,j,z表示,定义为一个有序的节点集,其中(i)一个节点属于一个或多个PDG,(ii)每个节点从ei,j,z*开始通过一系列函数调用可达。也就是说,*fs’i,j,z*是一个有或没有跨越函数边界(通过函数调用)的前向切片。

  • SyVC *ei,j,zfi中的后向切片,用bsi,j,z表示,定义为一个有序的节点集 {ni,y1, . . .,ni,yµi } ⊆ Vi,其中ni,yp(1 ≤ y1 ≤ yp ≤ yµi ≤ ci是可到达Gi’中的ei,j,z的。即bsi,j,z中的节点是来自于在Gi中的ei,j,z*结束的所有路径。

  • 程序P中SyVC ei,j,z的过程间后向切片(interprocedural backward slice),用bs’i,j,z表示,定义为一个有序的节点集,其中(i)一个节点属于一个或多个PDG,(ii)每个节点可通过一系列函数调用可达ei,j,z。也就是说,*bs’i,j,z*是一个有或没有跨越函数边界(通过函数调用)的后向切片。

    (也就是说前向切片是从SyVC向后,后向切片是从SyVC往前)

  • 给定程序间前向切片fs’i,j,z和程序间后向切片bs’i,j,z,通过在SyVC ei,j,z处合并fs’i,j,zbs’i,j,z,将SyVC *ei,j,z的(程序间)程序切片(psi,j,z)定义为节点的有序集合(属于P中函数的PDGs),用psi,j,z表示。即psi,j,z是将前向切片fs’i,j,z与后向切片bs’i,j,z*按保序方式连接,忽略相邻重复节点(即用一个节点替换同一节点的多个相邻出现)得到的有序集。

2.3.3 定义SeVCs (Defining SeVCs)
定义8 (SeVC)

给定一个程序P = {f1, . . . , fη}和函数fi中的语句si,j中的一个SyVC ei,j,z,则SyVC ei,j,z所对应的SeVC记为δi,j,z,定义为P中的有序子集,记为δi,j,z = {sa1,b1, . . . , sa(v(i,j,z)),b(v(i,j,z))},其中语句*sap,bq(1≤p, q≤vi,j,z)*与SyVC *ei,j,z*之间存在数据依赖或控件依赖。换句话说,SeVC *δi,j,z是一个有序的语句集,对应于(程序间)程序片psi,j,z*的节点。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-exkbpjB2-1669812399991)(C:\Users\25659\AppData\Roaming\Typora\typora-user-images\image-20221114212204788.png)]

2.3.4 计算SeVCs (Computing SeVCs)

算法2将前面的讨论总结为三个步骤:生成PDG;用算法1生成SyVCs输出的程序切片;将程序切片转换为SeVC。在接下来的内容中,我们详细说明这些步骤,并使用图3来说明一个运行示例。具体而言,图3描述了SyVC “data”(与指针使用有关)的SyVC→SeVC转换,同时兼顾了数据依赖和控制依赖引起的语义信息。

步骤1 (算法2中的第2-4行)

该步骤为每个函数生成一个PDG。为此,有一些标准算法。作为一个运行的例子,图3的第二列显示了分别对应于函数func和println的PDG,其中每个数字表示语句的行号。

步骤2 (算法2中的第6-9行)

这一步为每个SyVC ei,j,z生成程序片psi,j,z。将fsi,j,zfi调用的函数的前向切片合并,得到过程间前向切片fs’i,j,z。过程间向后切片bs’i,j,z是通过合并bsi,j,z和来自fi调用的函数和调用fi的函数的后向切片获得的。最后将fs’i,j,zbs’i,j,z合并为程序片psi,j,z

作为一个运行的例子,图3中的第三列显示了SyVC “data”的程序切片,其中后向切片对应函数func,前向切片对应函数func和println。值得一提的是,为了获得SyVC的转发部分,我们只利用数据依赖关系,原因有两个:(i)通过控制依赖关系受SyVC影响的语句在大多数情况下不会受到攻击;(ii)利用对SyVC有控制依赖关系的语句将涉及许多与漏洞几乎没有关系的语句。例如,考虑一个"while"循环的条件表达式中的指针变量SyVC。如果在"while"循环体中没有引用指针变量,"while"循环体中的语句仅通过控制依赖关系受到SyVC的影响,这意味着SyVC不会在"while"循环体中造成任何漏洞。如果上面提到的与SyVC相关的指针变量的转发部分涉及到控制依赖,那么“while”循环主体中的所有依赖于SyVC的控制语句都将包含在SeVC中,尽管它们与漏洞几乎没有关系。另一方面,为了获得SyVC的后向片,我们同时利用了数据依赖性和控件依赖性。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hse3SgIi-1669812399992)(C:\Users\25659\AppData\Roaming\Typora\typora-user-images\image-20221115134058542.png)]

图3:在算法2中为SyVC “data”细化SyVC→SeVC转换,其中实线箭头(即有向边)表示数据依赖,虚线箭头表示控制依赖。注意,每个实线箭头(即数据依赖项)都用引起相关数据依赖项的变量名进行了注释。

步骤3(算法2中的第10-19行)

该步骤将程序片转换为SeVC,如下所示。首先,该算法将属于函数*fi且出现在psi,j,z中的语句作为节点转换为SeVC,同时保持这些语句在fi*中的顺序。作为图3所示的运行示例,13条语句属于函数func, 3条语句属于函数println。根据这些语句在两个函数中的顺序,我们得到两个有序的语句集:第{7、9、10、11、12、14、16、18、22、23、24、25、26}行和第{1、3、4}行。

其次,该算法将属于不同函数的语句转换为SeVC。对于在psi,j,z中作为节点出现的语句si,j∈fisap,bq∈fap(i ≠ ap),如果fi调用fap,则*si,jsap,bq*的函数调用顺序相同,即si,j < sap,bq;否则,si,j > sap,bq

如图3所示,SeVC是第{7,9,10,11,13,14,16,18,22,23,24,25,26,1,3,4}行,其中函数func中的语句出现在函数println的语句之前,因为func调用了println。

图3的第四列显示了与SyVC “data”对应的SeVC,即与SyVC “data”语义相关的语句顺序集。

2.4 将SeVCs编码成向量

算法3分三步将SeVCs编码为向量。

步骤1(算法3中的第2-6行)

为了使SeVC独立于用户定义的变量和函数名,同时捕获程序语义信息,每个SeVC *δi,j,z*被转换为符号表示。为此,我们建议删除非ascii字符和注释,然后以一对一的方式将用户定义的变量名映射到符号名(例如“V1”,“V2”),最后以一对一的方式将用户定义的函数名映射到符号名(例如“F1”,“F2”)。注意,不同的sevc可能具有相同的符号表示。有关映射过程的详细信息,请参阅[11]。

步骤2(算法3中的第8-13行)

这一步是将符号表示编码为向量。为此,我们建议通过词法分析将secc δi,j,z的符号表示(例如,“V1=V2-8;”)划分为符号序列(例如,“V1”,“=”,“V2”,“-”,“8”,和“;”)。我们把一个符号转换成一个固定长度的向量。通过连接这些向量,我们得到了每个SeVC的一个向量Ri,j,z

步骤3(算法3中的第14-22行)

因为(i)符号的数量(即表示SeVCs的向量)可能不同(ii)神经网络取与输入长度相同的向量,我们使用阈值θ作为神经网络输入向量的长度。当一个向量小于θ时,零被加到该向量的末尾当一个向量比θ长时,有三种情况,但基本思想是使SyVC出现在结果向量的中间。

  1. 向量开头到SyVC的子向量小于θ/2。在这种情况下,我们删除Ri,j,z的最右边部分,使得到的向量的长度为θ
  2. SyVC到向量末尾的子向量小于θ/2。在这种情况下,我们删除Ri,j,z的最左边部分,使得到的向量的长度为θ
  3. 其他情况下(SyVC在向量中间且到向量开头结尾的子向量都大于θ/2),则保持长度为*(θ−1)/2的子向量紧靠SyVC的左侧,保持长度为(θ−1)/2*的子向量紧靠SyVC的右侧。

结合SyVC,我们得到一个长度为θ的向量。例如,假设θ = 15000,每个符号的长度是30,这意味着每个SeVC有500个符号。假设一个SeVC中的符号数是510(因此需要减少到500),而SyVC位于第255个符号的位置(在510个符号中),那么我们保留紧靠SyVC左侧的249个连续符号和紧靠SyVC右侧的250个连续符号。结合SyVC,我们得到了一个500=249+1+250个符号的向量。我们强调前面的操作是很好的定义的,因为每个SyVC都转换为SeVC,并且在SeVC中只出现一次。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kXd09trp-1669812399992)(C:\Users\25659\AppData\Roaming\Typora\typora-user-images\image-20221115143039748.png)]

2.5 标记SeVCs和其对应的向量

为了训练深度神经网络,我们将向量(即它们所代表的SeVCs)标记为有漏洞的或无漏洞的,如下所示:包含已知漏洞的SeVCs(即表示它的向量)标记为“1”(即有漏洞的),否则标记为“0”(即无漏洞的)。一个训练好的的深度神经网络编码漏洞模式,可以检测给定的SeVCs是否有漏洞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值