论文笔记《DeepTective》

DeepTective: Detection of PHP Vulnerabilities Using Hybrid Graph Neural Networks∗

  • 摘要
  • 1 简介
  • 2 模型概述
    • 2.1 预处理
    • 2.2 GRU
    • 2.3 GCN
    • 2.4 Classification
  • 3 DATTASETS
    • 3.1 SARD
    • 3.2 GIT
  • 4 EXPERIMENTS
    • 4.1 实验构建
    • 4.2 Classification Performance
    • 4.3 Tool Comparison
    • 4.4 Case Studies
  • 5 Conclusion
  • 参考

Graph Neural Networks∗)

摘要

本文介绍了DeepTective,这是一种基于深度学习的方法来检测PHP源代码中的漏洞。DeepTective实现了一种新的混合技术,该技术结合了门控循环单元和图卷积网络,以利用句法和语义信息检测SQLi,XSS和OSCI漏洞。 实验结果表明,我们的模型在合成数据集和现实数据集上都优于相关解决方案,并且能够在已创建的WordPress插件中发现4个新漏洞。

1 简介

研究社区投入了大量精力来自动发现 PHP 漏洞,使用静态、流和污点分析 [3、8] 和数据挖掘 [12、18]。这些解决方案在分析大量代码方面非常有效,但在误报或漏报方面往往会受到检测性能的限制。随着深度学习和自然语言处理的最新进展,安全研究人员开始开发深度学习方法来检测 C 和 C 进程中的软件漏洞 [11、15]。直到最近,我们才看到深度学习在 PHP 漏洞发现中的首次应用 [5-7]。这些方法都应用长短期记忆 (LSTM) 神经网络来捕获对源代码各种转换的非局部依赖性。 LSTM 擅长在顺序数据中寻找模式,但并不同样适合从树或图结构数据中学习,后者是进程语义的更自然表示。
在本文中,我们概述了DeepTective,这是一种检测PHP 源代码中的SQL注入(SQLi),跨站脚本(XSS)和操作系统命令注入 (OSCI) 漏洞的机器学习模型。为了从源代码中学习句法和结构属性,DeepTective 将其转换为一系列标记,由门控循环单元 (GRU) 进行分析,门控循环单元是一种与 LSTM 相关的神经网络,能够嵌入顺序信息,在本例中是关于代码结构。我们的 PHP 方法新颖,我们尝试通过使用图卷积网络 (GCN) 分析控制流图 (CFG) 来学习源代码的语义属性,这是一种最近的神经网络架构,旨在处理训练期间的类图数据结构可以将源代码的语义和上下文信息嵌入到分类模型中。对于我们最好的模型,这种混合架构在来自 SARD [19] 的合成数据上获得了 99.92% 的 F1 分数,在来自 GitHub(我们自己的数据集)的真实数据上获得了 88.12% 的 F1 分数,优于相关方法。我们在野外测试了 DeepTective,并在为 WordPress 部署的插件中发现了 4 个新的 SQLi 和 XSS 漏洞。

2 模型概述

DeepTective 分为两个关键组件:一个门控循环单元 (GRU),它对源代码令牌的线性串行进行操作,以及一个图卷积网络 (GCN),它运行在源代码的控制流图 (CFG) 上。每个组件都为模型提供不同的机制,以有效地检测多种类型的漏洞。
论文笔记《DeepTective》_第1张图片

2.1 预处理

我们的数据样本是 PHP 代码的片段。作为第一步,我们将代码的抽象级别提高到一种在概念上有助于学习过程的格式。我们提取解析标记的线性串行以捕获语法依赖关系,并提取过程内 CFG 集以捕获语义依赖关系。我们还将Token串行和 CFG 转换为适合神经网络使用的格式,即数字矢量。我们使用 phply [16](一个用于 Python 的 PHP 解析库)解析一个示例,并获得有序的令牌串行。 为了将学习重点放在一组可管理的有趣token上,我们将用户定义的函数、变量和常量值的长尾混为抽象token,并仅为与我们研究的漏洞相关的选定函数以及每个样本中变量和值的前 k 个实例保留具体令牌。例如,我们将样本中的前 200 个变量令牌替换为人工令牌 VAR0 - VAR199,并替换所有其他的变量为抽象令牌 VAR 。我们使用 scikit-learn[17] 中的 LabelEncoder 将每个标记转换为一个数字,给定一个标记词汇表,将每个标记映射到一个连续的自然数。
接下来,我们使用 joernphp [1] 从代码中提取进程内 CFG,其中每个图节点代表一行代码。为了将控制流图转换为适合我们的 GCN 使用的张量,我们将节点整理成一个 2d 矩阵,其中每行包含与行索引对应的节点的特征。
图 1 说明了 DeepTective 的整体架构。嵌入层的作用是将预处理阶段产生的每个数值输入转换为矢量,将该输入编码为低维空间中的因子组合。我们有两个嵌入层: 一个用于令牌串行,一个用于 CFG 表示形式。两个嵌入层都使用长度为 100 的矢量,这些矢量在训练期间通过反向传播学习并随机初始化。更正式地说,这些层只是从数字标记化函数ti到矢量vi∈R(100)的映射。

2.2 GRU

我们使用多层双向门控循环单元 [2] 从令牌表示串行中提取特征,该单元可以学习令牌之间的长期依赖关系。源代码在很大程度上取决于编程语言的语法。大多数令牌都带有有关串行中下一个令牌的信息。 此信息流将传播到代码语句的末尾。 GRU 通过在整个源代码中学习代码令牌的双向串行(即向前和向后)来利用此信息流。我们从 GRU 获取的输出是每层开头和结尾隐藏状态的串联。

2.3 GCN

CFG 表示代码示例中函数和语句的控件依赖项。因此,我们使用图卷积网络[9]从CFG中提取特征,该网络能够将此类依赖关系嵌入到我们的模型中,并通过反向传播了解它们的重要性。在内部,我们使用三层 GCN,然后是边缘池。

2.4 Classification

我们获取图卷积层的输出,并使用最大池化将其展平。图卷积层的输出是长度为 4000 的节点矢量。最大池化扫描每个节点的第 i 个元素,并选择最大值作为输出矢量的第 i 个元素。我们将 GCN 的输出矢量与 GRU 的输出矢量相结合,并将它们馈送到线性分类层。我们有 3 个线性分类层,每个分类层的 dropout 为 0.3 以对抗过拟合,然后是 ReLU 激活函数。ReLU 的最终输出是长度为 4 的概率矢量,表示将样本分配给每个类的置信度。

3 DATTASETS

我们使用脆弱和非脆弱样本构建数据集,这些样本是从合成数据(SARD)和现实世界项目(GIT)中提取的。

3.1 SARD

每个 SARD 样本 [19] 都是一个简短的独立文档,没有外部依赖关系。该数据集包含XSS,SQLi和OSCI的安全和不安全示例。SARD 示例旨在测试安全工具,相当简单,不太可能反映实际项目中的代码。尽管如此,SARD已被广泛用于以前的漏洞研究,包括专门用于PHP[5,10]。 SARD 的优点是保证漏洞在样本中是自包含的,并且每个样本都有很少的不相关的代码行,有助于集中学习过程。此外,SARD样本的标签非常准确,这是监督机器学习方法的主要关注点。

3.2 GIT

我们还收集了一个代表实际 PHP 项目中实际出现的漏洞的数据集。 GitHub 托管各种规模的 PHP 项目的源代码,从极受欢迎的 WordPress 框架到初学者的第一个 PHP 片段。为了选择代表性漏洞,我们在国家漏洞数据库 (NVD) [13] 中搜索了标有 CWE 标识符 79 (XSS)、89 (SQLi) 和 78 (OSCI) 的 CVE 条目。我们从每个相关 CVE 的引用中提取了任何 GitHub 提交 URL,并克隆了相应的 PHP 存储库。结合起来,我们还从 GitHub 克隆了一些最大和最常用的开源 PHP 项目:Moodle、CodeIgniter、Drupal、ILIAS、phppmyadmin、wikia、magento2、simplesamlphp 和 WordPress。我们在每个克隆项目的提交历史中搜索与我们感兴趣的漏洞相关的关键字,包括“xss”、“sqli”和几个变体。有一些报告修复了 XSS 和 SQLi 漏洞的提交消息:我们将这些排除在外,因为多标签分类超出了该项目的范围。当我们遇到相关提交时,我们提取受影响文档的漏洞版本,并为每个文档添加相应漏洞的标签。这些构成了我们的阳性样本。从相同版本的存储库中,我们保存不受提交影响的文件作为我们的负样本。尽管我们预计会有相当数量的错误标记,但我们手动检查了 10% 标记为阳性的文档,并且没有检测到任何错误标记。

4 EXPERIMENTS

我们根据来自SARD,GitHub和两者的数据评估DeepTective。这使我们能够比较使用合成样本和真实世界样本之间的差异,并研究模型的泛化能力。此外,我们将DeepTctive的分类性能与以前的工作进行了比较,并确定了方法之间的有趣差异。最后,我们报告了使用DeepTective发现的新CVE。

4.1 实验构建

对于这两个实验,我们在 Python 3.8.1 之上使用 Pytorch 1.5 和 Torch Geometric 1.5.0 以及 CUDA 10.1。我们在运行 Intel Xeon Skylake CPU(40 核)、128GB RAM 和 Nvidia GTX Titan XP 的计算机上训练模型。在整个实验过程中,我们报告了真阴性 (TN)、假阴性 (FN)、真阳性 (TP)、假阳性 (FP)、准确度、精确度、召回率和 F1 分数。准确性衡量正确预测样本的百分比,但在测试类不平衡时不是很重要,例如与安全样本相比非常罕见的漏洞情况。将一切都标记为安全的简单分类器在现实世界中具有非常高的准确性,但用处不大。精度测量报告的漏洞中有多少是实际漏洞:它告诉我们是否值得调查分类器的结果。召回率衡量分类器能够发现的现有漏洞的百分比:它告诉我们在运行该工具后我们应该有多担心。最后,F1 分数在数字上总结了精度和召回率之间的平衡。
由于这是一个多类分类问题,我们使用交叉熵作为损失函数。训练过程使用 64 的批量大小以及 Adam 优化器和 0.00001 的学习率。 除此之外,我们还实现了一个学习率调度器,如果损失稳定,它会降低学习率。最后,我们将用于训练/验证/测试的数据集拆分为 80/10/10,并根据它们的类对数据进行分层。有了模型和超参数,我们将模型训练了 150 个 epoch,以最大限度地发挥模型的学习潜力。

4.2 Classification Performance

论文笔记《DeepTective》_第2张图片

4.3 Tool Comparison

论文笔记《DeepTective》_第3张图片

4.4 Case Studies

我们测试了 DeepTective 是否可用于检测已部署的 PHP 项目中的新漏洞。我们选择了 5 个用户数量有限(少于 20,000)的 WordPress 插件,以增加它们包含未被发现的安全漏洞的可能性。用户群有限的项目可能拥有较小的开发团队,缺乏安全专业知识,或者比流行项目受到更少的审查。
在没有 ground truth 的情况下,我们需要借助人工检查来验证结果。我们手动检查了 277 个报告的阳性结果。有几个看起来很可疑,但我们对应用进程的熟悉程度不够,无法明确确定它们是否构成漏洞。我们能够确认其中 4 个是实际的安全漏洞,并且我们负责任地向相应的开发人员披露了我们的发现。我们在修补后公开披露了其中两个:CVE-2020-14092 和 CVE-2020-13892。我们在这些项目上测试了第 4.3 节中的工具,看它们是否可以检测到上述任何一个漏洞,但均未成功。

5 Conclusion

我们介绍了DeepTective,这是一种新颖的漏洞检测方法,旨在从现实世界的漏洞中捕获上下文信息,以减少误报和漏报。我们的方法结合了门控循环单元和图卷积网络,前者学习源代码令牌的长期顺序依赖关系,后者将控制流图中的上下文信息相结合。DeepTective 在合成和现实数据集上都实现了比最先进的性能更好的性能,并且能够在 WordPress 插件中检测到 4 个新的安全漏洞,而其他检测工具无法检测到这些漏洞。 有关更多详细信息,请参阅本文的完整版本[14]。

参考

  1. DeepTective: Detection of PHP Vulnerabilities Using Hybrid Graph Neural Networks∗——论文PDF
  2. A Hybrid Graph Neural Network Approach for Detecting PHP Vulnerabilities——arxiv中的历史版本论文,讲解更详细

你可能感兴趣的:(论文阅读)