The Vulnerability Is in the Details Locating Fine-grained Information of Vulnerable Code Identified by Graph-based Detectors

0 Abstract

漏洞检测是软件开发生命周期中的关键组成部分。现有的漏洞检测器,尤其是基于深度学习(DL)模型的检测器,已经取得了很高的效果。尽管它们能够从给定的代码片段中检测到易受攻击的代码片段,但通常无法进一步定位与漏洞相关的精细信息,比如精确的漏洞触发位置。在本文中,我们提出了VULEXPLAINER,这是一个用于自动定位由DL-based检测器报告的粗略级易受攻击代码片段中的漏洞关键代码行的工具。我们的方法利用了代码结构和漏洞的语义。具体来说,我们利用程序切片来获得一组包含漏洞触发和漏洞依赖语句的关键程序路径,并对它们进行排名,以确定最重要的一个(即子图),作为与漏洞相关联的数据流。我们证明了VULEXPLAINER在四个最先进的基于图表示(GP)的漏洞检测器上表现一致良好,即它可以针对八种常见的C/C++漏洞以约90%的准确率标记漏洞触发代码语句,优于五种广泛使用的基于GNN的解释方法。实验结果证明了VULEXPLAINER的有效性,它提供了一个有前景的研究线索:整合程序切片和深度学习来解释易受攻击的代码片段。

1 Intro or Overview

1.1 Problem and Challenge

To counteract the potential exploitation, both academia and industrial communities have proposed numerous techniques for identifying and locating those vulnerabilities.

  • 传统方法,例如基于规则的分析技术利用预定义的签名或规则来识别漏洞。问题是,通常报告高误报和漏报率。

  • 基于 DL 的检测技术通常在提取的代码特征表示上运行,已经显示出在标记包含漏洞的代码片段(即函数或片段)方面的巨大效果。然而,分析的粗粒度和黑盒性质使得检测结果的可解释性较差。例如,一个函数或代码片段可能包含十几行代码,这对开发人员来说仍然是一个具有挑战性的任务,以理解漏洞的根本原因并进一步采取行动来修复它们。解决这个问题的一种有希望的方法是利用解释方法来选择 DL-based 检测器的重要特征,然后将它们映射到相应的代码行。

  • 最近图形解释技术的快速发展显示出了解决这个问题的巨大潜力。现有的图解释方法通常从三个角度促进模型的可解释性:为图边分配数值 [10],[11],计算节点的重要性分数 [12],以及在通过 GNN 时计算图遍历的分数 [13]。

尽管它们在诸如子图分类之类的任务中取得了成功,但现有的基于 GNN 的解释技术仍然存在固有的不足,这些不足阻碍了直接应用以获得有关漏洞的细粒度信息,例如触发代码行。

**第一个不足之处在于捕捉潜藏在良性和脆弱代码库中的微妙但丰富的语义能力有限。**程序的功能由提取的代码图中的语句(即节点)及其信息流(即边)定义。因此,针对程序的特定语义对于解释方法至关重要。然而,现有的解释方法无法定位到这种细粒度的信息,因为它们通常忽视了程序图中丰富的语义信息。

这可能归因于程序漏洞检测的复杂性相对于现有任务(即,较简单的拓扑结构)而言。例如,由边表示的两个语句之间的控制流或程序依赖关系几乎没有反映出来。此外,节点中包含的语义信息难以编码到潜在空间中。

**第二个不足之处源于对关键漏洞检测语句的不足考虑。**大多数易受攻击的程序及其修补版本通常具有类似的拓扑结构,因为它们都包含触发漏洞的语句,如图1所示。唯一的区别可能在于一些修复漏洞的语句,涉及与漏洞触发相关的控制流和程序相关信息。

image-20240419095734769

1.2 Motivation

提出了VULEXPLAINER,这是一种新颖的方法,用于从GNN-based漏洞检测器报告的脆弱代码中识别细粒度信息。给定一个检测到的脆弱代码片段,VULEXPLAINER首先从中提取程序切片,然后构造控制和数据依赖信息。与先前的工作(例如,DEEPWUKONG[6])相比,VULEXPLAINER仅保留脆弱性触发和脆弱性依赖的程序路径级信息,而不是完整程序的信息。这显着提高了分析效率,因为程序路径包含较少的代码行。利用程序切片方法,VULEXPLAINER捕获了更多包含在代码行中的语义信息。因此,它可以提供比仅关注拓扑特征的方法更准确的解释结果。

VULEXPLAINER的目标是识别漏洞的根本原因。 最近的工作[14]表明,错误触发路径是定位和修复漏洞的关键。 因此,为了评估我们方法的有效性,我们提出了一个新的评估指标,漏洞触发代码行覆盖率(以下简称LC,在第V-B节中详细说明)。 我们对VULEXPLAINER的有效性进行多维评估。 在第一个比较维度中,我们将VULEXPLAINER应用于解释四种基于图代码表示的最新漏洞检测器的输出,包括DEEPWUKONG [6],REVEAL [7],IVDETECT [8]和DEVIGN [9]。 这四个检测器都使用程序依赖图(PDGs,DEVIGN仅使用数据依赖图,不使用控制依赖图)作为代码图表示。

1.3 Contribution

总之,我们做出以下主要贡献:

• 一种新颖的基于 GNN 的漏洞检测器的漏洞细粒度信息定位技术。鉴于现有的基于 GNN 的漏洞检测器的解释能力不足,我们提出了 VULEXPLAINER 框架作为解决方案。它可以识别程序中包含漏洞触发语句的重要流路径,为识别出的漏洞提供更细粒度的语义上下文。我们在匿名仓库 [16] 上发布了本文中使用的源代码和数据集。

• 方法效果。通过对全面基准数据集的多维评估,我们展示了 VULEXPLAINER 在 LC 方面优于现有的解释方法,LC 是影响漏洞定位和修复的关键因素。平均而言,VULEXPLAINER 对本研究中使用的所有漏洞检测器的 LC 均高于 85%,显示出对不同基于 GNN 的漏洞检测器的良好泛化能力。

2 Architecture & Method

2.1 System Overview

AN EXAMPLE OF LOCATING VULNERABILITY

如图 3 所示。它包含一个缓冲区溢出漏洞,该漏洞通过复制更多数据(即代码片段第 11 行定义的 100 字节)来触发,而数组的最大容量为(即代码片段第 2 行定义的 50 字节)。基于 GNN 的漏洞检测器只输出检测结果为 1,表明代码片段是易受攻击的(或反之为 0)。漏洞定位任务的目标是构建一个包含漏洞触发代码行和漏洞相关变量的关键赋值的控制和数据依赖路径,或者此后称为流路径。为此,我们首先通过将语句映射到节点并根据节点之间的依赖信息构造流路径将源代码转换为图形表示。从路径中,我们选择满足我们漏洞定位目标的路径。具体来说,在图 3 中我们的示例中,从原始代码片段中提取了多条流路径,例如“8-11”、“2-6-7-13”等。其中,“2-6-7-11”被认为是最关键的路径,因为既包括第 2 行(关键变量赋值)又包括第 11 行(漏洞触发)。
技术挑战。根据这个漏洞定位示例,对于一般和自动定位检测到的漏洞代码,技术挑战至少有两个方面:
• 挑战#1 通过基于 GNN 的检测器正确检测到易受攻击的代码后,缺乏一种有效的漏洞定位方法,该方法生成覆盖漏洞触发和相关关键变量赋值的流路径。
• 挑战#2 给定生成的流路径,缺乏一种有效的路径选择机制,该机制识别最合适的路径作为检测到的漏洞的最合理最终数据流。为了解决这两个挑战,我们提出了 VULEXPLAINER,它可以从代码片段中导出的 PDG 中自动生成可行的流路径,并对它们进行排名以选择最合理的路径。该框架的技术细节将在第四节中介绍。

image-20240419194551637

LOCATING VULNERABILITY STATEMENTS USING GNN-BASED DETECTORS

image-20240419195905435
  • 流路径生成。

给定一个以图形表示的脆弱代码片段,其控制和数据依赖已计算(见图4(a)),VULEXPLAINER 首先识别程序中可能触发漏洞的语句(即节点),表示为潜在汇点(potential sink points,PSPs)。接下来,VULEXPLAINER 在程序图中沿着从 PSP 开始的流路径迭代遍历,直到到达 PSP 的源(例如,表示关键变量赋值的节点)。类似地,VULEXPLAINER 生成图中所有符合条件的流路径,每个流路径以一个 PSP 结束。

  • 流程路径选择。

VULEXPLAINER首先对每个流程路径进行向量化,并计算与漏洞概率相关的重要性分数(见图4(b))。接下来,VULEXPLAINER选择具有最高重要性分数的流程路径作为漏洞数据流。请注意,我们不会直接针对路径选择训练分类器,因为每个路径被视为数据流而不是代码片段。

流路径生成

从原始代码图(即PDG)生成流路径,我们利用基于DLVD方法的程序切片,这种方法已被之前的作品广泛采用,例如DEEPWUKONG,REVEAL,IVDETECT,DEVIGN。切片原理基于PDG的控制依赖和数据依赖。更具体地,详细的流路径生成方法由算法1中的“GENERATESLICE”函数描述。它以代码图G和路径长度限制k(即,为了有效地移除后续搜索中的冗长路径)作为输入。我们将算法详细描述如下。

image-20240419202206854

流路径选择

在流程路径中,我们的目标是根据预测结果选择一个可以最好地定位触发漏洞的语句的路径。

关键直觉是,如果一条路径包含了PSP及其源节点,则应选择该路径。例如,第III节中的示例中的路径“2 - 6 - 7 - 11”。如果有多条符合条件的路径,我们进一步根据路径重要性对它们进行排名,并选择具有最高重要性得分的路径。更正式地说,给定一个代码图G,我们从中提取流程路径并对每个流程路径进行向量化。

向量化一个流程路径的过程与检测器向量化相应代码图的过程相同。然后,我们通过将每个向量化的流程路径视为原始代码图的子图并将其输入经过良好训练的基于GNN的漏洞检测器来计算每个流程路径的重要性得分。这个过程可以正式描述为:

image-20240419204002233

在这里,g 是从 G 中提取的流路径,Φ 是基于 GNN 的漏洞检测器之一。最后,我们计算每条路径的重要性分数 ISg,衡量它们对于检测器预测相应代码片段的贡献。

image-20240419204044559

假设在对G进行切片后有n个流路径,表示为{g1, …, gi, …gn}。漏洞数据流g∗表示为:

image-20240419204114457

image-20240419203043537

3 Experiment and Evaluation

评估了VULEXPLAINER在DEEPWUKONG、REVEAL、IVDETECT和DEVIGN的预测结果中定位漏洞语句的有效性。评估是为了检测CWE中排名前30位的8个漏洞,与GNN的五种最先进的解释器进行比较。为此,我们概述了本研究中使用的数据集以及涉及其标记过程(第V-A节)。接下来,我们详细阐述了实验设置。

3.1 DataSet and Process

目标漏洞:此处使用的数据集必须支持细粒度检测,这需要明确的有关易受攻击代码行的信息。许多实际数据集中的缺陷行,如DEVIGN [9],REVEAL,Fan [26],都标有从提交的版本修补程序中提取的代码更改信息。如图7所示,包含CVE-2015-2029漏洞ID的示例代码包括标记为绿色的漏洞修复代码行。然而,这种标记方法只能检测到漏洞修复行,而未检测到漏洞触发行。

image-20240419221207069

在图7中的同一示例中,受污染流程中的语句被标记为粉红色,这并未涵盖触发漏洞的代码行。此外,fA函数处修复的漏洞可能会在fB函数处触发。在这种情况下,fA将被标记为易受攻击,而fB则为非易受攻击。更糟糕的是,Roland Croft等人[27]报告了真实数据集中约20-71%的假阳性漏洞样本的存在。由上可见,在实际数据集中准确标记易受攻击的代码行可能具有挑战性。由于噪声数据集可能会影响深度学习模型的性能[28],我们从SARD [24],一个合成漏洞数据库中组装我们的数据集。在SARD数据集中,每个程序(即测试用例)可能与一个或多个CWE ID相关联,因为一个程序可能包含不同类型的漏洞。更重要的是,每个易受攻击程序的触发漏洞语句已经被正确标记。我们的目标是检查2021年C/C++中30种最危险的软件缺陷中的八种,具体关注CWE20,CWE22,CWE78,CWE119,CWE125,CWE190,CWE400和CWE787。我们使用与DEEPWUKONG [6]相同的网络爬虫来收集所有可用程序。

基准数据集处理:从 SARD 收集的数据按以下步骤进行处理。首先,我们将 SARD 程序的功能解析为供 REVEAL 和 IVDETECT 使用的 CPGs。我们直接利用由 DEEPWUKONG 生成的切片级别 XFGs(PDG 的子图),因为它们在其存储库中可用。然后,我们按照先前的工作对这些 CPGs 和 XFGs 进行标记和去重。任何包含一个或多个易受攻击语句的 CPG 或 XFG 将被标记为易受攻击,反之亦然。除此之外,我们将易受攻击样本中的关键语句标记为节点索引。

基准数据集分布:经过处理阶段,我们从 SARD 数据集中收集了 82,243 个易受攻击的 CPGs 和 164,736 个非易受攻击的 CPGs,如表 I 所示。我们从 DEEPWUKONG 下载了 XFGs 数据集。重新标记后,我们总共组装了 151,774 个易受攻击的 XFGs 和 384,062 个非易受攻击的 XFGs。

3.2 Evaluation

评估指标:我们首先使用六个常用的指标评估四种漏洞检测工具的有效性,包括准确率(ACC)、误报率(FPR)、漏报率(FNR)、召回率(R)、精确率(P)、F1分数(F1)。简化结果总结在表II中,详细结果可在我们的存储库[16]中找到。

评估解释方法以及VULEXPLAINER的有效性,我们提出度量行覆盖率,即LC。请注意,评估指标仅适用于真正阳性样本,即标记并检测为易受攻击的样本。**LC的定义如下:给定包含n个易受攻击代码行的代码片段C的流路径g,则LC = n/m,其中m(m ≥ n)表示数据集中标记为易受攻击的代码行的总数。**如果g包含数据集中标记的所有易受攻击语句,则LC为1;如果g不包含标记的易受攻击语句,则LC为0。

请注意,我们考虑使用忠实度[36]来衡量解释器和VULEXPLAINER的性能。然而,目前缺乏一种通用且标准的计算忠实度的方法,导致不同方法得出的结果差异巨大。这使得将忠实度作为评估指标之一变得不可靠。此外,我们的目标是定位和解释检测到的漏洞的原因,并不一定需要构建一个最大程度保留原始图属性的子图。

RQ1 VULEXPLAINER能否准确定位触发漏洞的代码行?

设置两个参数,sparsity和k,用来控制flow path的节点数量,参数稀疏度由 1 − n/m 计算,其中 m 和 n 分别是图中和路径中的节点总数。直观地说,稀疏度控制着图中节点的分布均匀程度。更多节点集中在较少的路径中(即相对较长的路径)会导致较低的稀疏度。参数 k 指定了路径中的节点最大数量,如算法 1 所述。考虑这两个参数,流路径中的最大节点数 MaxN 由 min(k, (1 − 稀疏度) ∗ m) 给出。

RQ1.1:VULEXPLAINER在各种类型的漏洞中能否表现一致?

image-20240420100351781

如表III所示,VULEXPLAINER在定位不同类型的漏洞时表现出不同的性能。对于CWE-78漏洞,它取得了最高的LC分数(98%),对于CWE-20(84%)和CWE-119(87%)则相对较低。为了更好地理解这种差异背后的原因,我们对几个特殊案例进行了手动审查,并确认了以下三个可能的原因。

首先,所选的PSPs可能是不完整的。各种类型的语句可能会触发漏洞。某些漏洞,比如CWE-78,只能通过与系统命令相关的API触发,使得漏洞模式相对比较简单。然而,其他类型的漏洞(例如缓冲区溢出)可能会被各种语句触发,包括与内存相关的API、数组操作和指针操作。这导致代码图中出现更多的PSPs,随后在路径生成和选择过程中产生更多的干扰,这对我们的方法构成挑战。此外,我们目标的PSP模式可能不完整,可能会在解释过程中排除某些漏洞类型。

我们利用程序切片生成流程路径,以保留漏洞语义。在这个过程中,我们会筛选掉一些与漏洞有关的控制和数据依赖关系,而不包含变量。然而,使用我们的方法分析大量路径可能会变得困难,考虑到要探索和解析的指数级扩展可能性。

基于深度学习的检测器并不像我们期望的那样可靠。在某些情况下,检测器的输出分数显著低于预期,即使路径与漏洞强相关。这种不可靠性可能会影响到VULEXPLAINER的测量有效性。这也表明传统评估指标可能无法完全捕捉这些检测器的有效性。

image-20240420101118758

RQ1.2:VULEXPLAINER在不同基于图的漏洞检测器上能否表现一致?换句话说,VULEXPLAINER的性能是否受到检测器选择的影响?

image-20240420101152223

RQ2 VULEXPLAINER能否超越现有的GNN漏洞检测解释方法?

结果:在使用评估指标LC对八种漏洞进行评估时,VE在比较中超越了所有五种解释方法。由于当k的值变化时可以观察到解释器表现的相同趋势,我们基于页面约束使用k = 7呈现和分析最终结果。以CWE-20为例,基于DEEPWUKONG的预测定位易受攻击行时,VE在LC方面比GL大约30%。至于CWE-125,用于REVEAL的定位易受攻击行时,GR仅获得51%的LC,而我们的方法达到96%。对于IVDETECT,DL仅获得4%的LC,而VE达到97%。与GE相比,在CWE-787上为DEVIGN定位易受攻击行时,VE达到91%的LC,几乎比GE高出33%。对于PE也观察到类似的模式,仅实现33%的LC。

image-20240420102009538

分析:实验结果表明,仅依赖节点嵌入和代码图的拓扑结构来定位易受攻击代码片段的根本原因是不足够的。

image-20240420101815581

4 Discussion

首先,我们只在SARD数据集上进行实验,该数据集包含合成和学术程序,但可能不代表真实世界的软件产品。我们在第V-A节中讨论了现有真实世界数据集中的问题。生成可靠的细粒度数据集仍然是一个悬而未决的问题。其次,我们的框架使用关键库API调用、数组或指针操作和操作符语句来执行程序切片作为PSPs。如第VI-A1节所述,这意味着某些边缘情况可能被忽视。此外,它还可能引入无关的语句作为汇点。增强我们的方法的一种方式是检测附加的补充类型的PSP模式,随后筛选出多余的汇点以减少潜在的不准确性。这需要对触发真实世界漏洞以及如何修复这些漏洞有额外的见解。我们只考虑分析PSPs,虽然进一步分析与漏洞相关数据输入到程序的潜在源点是一个有希望的对角线研究方向。第三,我们的实验仅限于C/C++程序中的八种漏洞类型。尽管如此,我们的方法可以轻松扩展到包括其他源-汇漏洞和其他编程语言。第四,我们的方法仅考虑基于四种基于图的漏洞检测器定位脆弱语句。然而,我们的方法很容易适用于其他检测器,并有可能用于其他程序分析任务。

Conclusion