VulHawk Cross-architecture Vulnerability Detection with Entropy-based Binary Code Search 论文笔记

中文译名:VulHawk:基于熵的二进制代码搜索的跨架构漏洞检测
作者:Zhenhao Luo
单位:国防科大
国家: #中国
年份: #2023年
来源: #NDSS会议
关键字: #二进制代码搜索
代码地址: https://github.com/RazorMegrez/VulHawk
笔记建立时间: 2023-03-20 13:59

摘要

目的:对不同架构、不同编译器、不同优化级别编译的 IoT 固件映像进行二进制代码搜索来识别代码重用
方法:

  • 提出了一种新的中间表示函数模型,是一种用于跨体系结构二进制代码搜索的体系结构不确定模型
    • 将二进制代码提升为 IR,通过补充隐式操作数和删除冗余指令来保留二进制函数的主要语言
    • 使用 NLP 和卷积生成函数嵌入
    • 将编译器、架构和优化级别的组合称为一个文件环境,采用 divide-and-conquer 策略将 C N 2 C_N^2 CN2 个跨文件环境场景的相似性问题转化为 N − 1 N-1 N1 个嵌入转化子问题。
  • 提出了一种基于熵的适配器,将不同文件环境中的函数嵌入传输到同一文件环境中,以缓解不同文件环境造成的差异
  • 提出了一种渐进搜索策略
    • 用细粒度特征补充函数嵌入,以减少修补函数造成的误报

意义:提高检测代码重用带来的漏洞的效率
效果:VulHawk 的性能优于 Asm2Vec、Asteria、BinDiff、GMN、PalmTree、SAFE 和 Trex。

引言

现状:

  • 二进制代码搜索方法不够健壮,不能跨平台
    • Asm2Vec[10]、DeepBinDiff[11]和 PalmTree[27]使用自然语言处理 (NLP) 技术取得了令人鼓舞的结果(不能跨平台)
    • InnerEye[60]将来自不同 isa 的二进制作为不同的自然语言,并使用神经机器翻译来计算二进制代码的相似度。SAFE[35]使用来自多个 isa 的二进制来训练其语言模型,以跨体系结构搜索二进制代码。(严重依赖于训练数据,很难实现多个 isa)
    • 将特定于体系结构的二进制代码提升为与体系结构无关的中间表示 (IR) 是解决物联网固件中跨体系结构挑战的有效方法。但是 IR 和自然语言有本质区别。
  • 相同源码经过不同优化级别的编译器编译后得到的二进制文件语义相似但结构不同
    • 在本文中,我们考虑了 3 种架构 (x86、arm 和 mips)、2 种字大小 (32 位和 64 位)、2 个编译器 (Clang 和 GCC) 和 6 个优化级别 (O0、O1、O2、O3、Os 和 Ofast),总共 72 种组合 (3 × 2 × 2 × 6)。

本文提出了一种新的跨架构二进制代码搜索方法 VulHawk

  • 新的中间表示函数模型 (IRFM)——来生成健壮的函数嵌入——解决跨架构和指令简化
  • 部署了一个基于熵的适配器——对不同编译器、体系结构和优化级别的二进制文件进行处理,缓解不同环境造成的差异
  • 渐进搜索策略来搜索候选函数
  • 提出一种相似度标定方法——减少误报

背景

问题定义

一个有效的跨架构的二进制代码搜索需要实现:

  • 支持跨架构
  • 支持跨编译器
  • 支持跨优化
  • 高精度和效率

熵理论

香农的熵理论可以用来衡量系统中的随机性和平均信息量
通过熵分析,我们可以在深入研究系统之前预先了解系统中的平均信息量。在二进制代码搜索任务中,我们通过二进制文件熵得到二进制文件的信息分布,它可以推断出二进制文件的编译器和优化级别等信息。这有助于我们的模型为不同的输入二进制选择合适的参数。

设计

image.png

IR 函数模型(IRFM)

将二进制代码的 IR 作为中间表示函数模型 (IRFM)(基于 RoBERTa 模型)的输入,输出是 IR 的词嵌入。
IRFM 将 IR 函数嵌入到高维嵌入空间中,使得语义相似函数的嵌入在数值空间中更加紧密。

Tokenization

  • 将一条指令分割为一个操作码和三个操作数
  • 用特殊标记 addr 来规范地址
  • 对于 OOV (Out-Of-Vocabulary))问题,作者引入 16 个根操作数,表内的操作数就使用自己的 token,非表内操作数就使用对应的根 token
    • 在预训练阶段,我们将频率小于 100 次的令牌替换为其根操作数令牌,以构建根操作数令牌嵌入。

语言模型

IRFM 基于 RoBERTa 模型,但是 IR 和自然语言有所不同,所以作者进行了部分改动

  • Token 类型层
    • 使用令牌类型层来帮助 IRFM 区分操作码和操作数。将令牌分为三种类型: 操作码、操作数和其他。其他类型包括没有实际语义的特殊标记。
  • 指令简化
    • 二进制代码包含 EFLAGS (即标志寄存器) 作为隐式操作数。不考虑 EFLAGS,重要的语义会丢失,考虑所有的 EFLAGS,冗余的 eflag 不仅会引入额外的开销,而且可能会模糊二进制代码的主要语义。
    • 所以只考虑使用过的 eflags,通过 IR 将每个隐式操作数指令的赋值转换为实赋值指令,并将其使用的 EFLAGS 保存为指令序列
    • 如下图所示 a 到 b 删除了没有使用到的寄存器和标志寄存器,b 到 c 又对值传递进行了优化(化简)
    • image.png
    • 提出了一种基于 def-use 关系的指令简化方法
      • 标记重要指令(使用松散规则,以确保不会错误地删除主语义):
        • 目标操作数为内存地址的赋值指令(因为全局变量和局部变量存储在内存中而不是寄存器中)
        • 在所有路径的返回指令附近根据调用约定标记特定的寄存器(因为返回值通常存储在特定的寄存器)
      • 修剪未使用的指令
        • 将其定义的寄存器或 EFLAGS 未在后续指令中使用的指令视为未使用的指令
      • 优化冗余指令(值传递指令)

预训练任务

在训练阶段,我们使用 Masked Language Model (MLM)、根操作数预测 (ROP) 和相邻块预测 (ABP) 进行预训练。

  • Masked Language Model
    • 我们引入了 MLM 模型来理解之间的关系,并建立合适的词嵌入。
  • 根操作数预测
    • 用于解决 OOV 问题,为 OOV 操作数匹配根操作数 token
  • 邻块预测
    • 因为数据流的存在,所以基本块数顺序敏感的,ABP 预训练是为了让模型捕获这种数据流关系
    • 具体来说,给定两个基本区块 A 和 B,其中 B 是 A 的后继区块,变量 x 定义在区块 A 中,变量 x 使用在区块 B 中,我们将 A-B 的顺序标记为正,B-A 的顺序标记为负。注意,A 和 B 不是同一个块,A 也不是 B 的后继块。另外,我们不认为这些情况下 A 和 B 只有控制流关系而没有数据流关系。因为如果不支持数据流关系,块的顺序也可能颠倒。我们将 IRFM 中令牌[cls]的最终隐藏状态输入到 ABP 头中,这是一个线性变换,以识别输入的两个微码序列是否正序。

函数嵌入生成

首先生成基本块嵌入

  • 对于输入的 IR 块,IRFM 转化编码器输出隐藏状态序列,然后在倒数第二层的隐藏状态上使用均值池来生成基本块嵌入。(因为研究表明倒数第二层的隐藏状态比最后一层的隐藏状态具有更强的泛化能力。)

集成基本块嵌入和 cfg 来生成函数嵌入

  • 使用 GCNs 捕获 CFG 结构,将二进制函数视为属性图,其中它们的基本块是图中的节点,它们的嵌入是节点的属性。我们将属性控制流图 (acfg) 输入到 GCN 层。

基于熵的适配器

Divide-and-conquer

image.png
图 5 显示了在嵌入空间中匹配相似函数的示例。可以看到混合文件环境的文件经过适配器后进行了统一。(可以理解为一个翻译器)
首先,我们将混合文件环境的嵌入空间拆分为多个嵌入子空间。
其次,选择其中一个文件环境 V 作为中间文件环境,将 N 个具有 C2 N 个场景的文件环境中的函数相似度问题划分为 N−1 个子函数嵌入传递问题。
最后,我们使用经过训练的适配器将不同文件环境的函数嵌入传递到同一个文件环境 V 中进行相似度计算,可以缓解不同文件环境造成的差异。

Entropy-based Binary Analysis

用于识别文件环境
因为二进制文件中没有直接指示编译器和优化级别的信息,所以从信息理论的角度来理解二进制文件,并引入熵来识别二进制文件的编译器和优化级别
image.png
图 6 显示了来自 3 个文件环境的 12 个不同二进制文件的熵流。可以观察到,来自相同文件环境的熵流似乎是相似的,而来自不同文件环境的熵流却不同。使用熵流和熵理论,我们可以识别不同的编译器和优化。
image.png
使用残差神经网络 (ResNet) 作为分类器,并使用上述特征作为识别文件环境的输入。基本残块结构如图 7 所示。它由批量归一化和线性变换组成,激活函数为 ReLU。使用来自输入的标识映射的跳过连接被添加到基本剩余块输出中,这保留了函数语义,并有助于解决梯度消失问题。我们使用卷积层对输入进行采样,该层将 258 维输入转换为 64 维特征。在 16 层剩余基本块之后,我们使用线性预测和 softmax 函数进行多类分类。由于 Os 和 Ofast 分别是对 O2 和 O3 的增量优化,因此我们将 Os 和 Ofast 分别包含在 O2 和 O3 中。这里,softmax 的目标是 8 个类 (2 个编译器× 4 个优化)。熵分析帮助我们识别文件环境 (编译器和优化级别),为后续的函数嵌入传输做准备。

Entropy-based Adapter layer

为了计算来自不同文件环境的二进制函数的相似性,我们在 IRFM 之后提出了一个基于熵的适配器层。基于熵的适配器层作为映射 F,将不同文件环境中的函数嵌入传递到相同的中间文件环境 V 中,以缓解不同文件环境造成的差异。映射 F 既应保留函数语义,又应减轻因不同文件环境而产生的偏差。

渐进搜索策略

现状
使用函数嵌入来搜索相似函数,这种属于粗粒度检测方法,导致较高的假阳性
使用匹配网络等方法在细粒度上计算每个函数对的相似性,结果好,但是计算成本高
方法:
提出了一种新的搜索策略,称为渐进式搜索策略,该策略包含两个子策略。首先,使用函数嵌入作为粗粒度搜索的全局摘要。其次,设计了候选函数的成对相似度校准,用细粒度信息补充函数嵌入,以保持漏洞检测的高精度

  • 函数嵌入搜索:为了在大型函数库中高效地检测相似函数,采用函数嵌入的欧式距离相似度对候选函数进行粗粒度检索,大大减小了细粒度检测的范围,减轻了计算负担。(算法 2 行)
  • 相似度校准:它结合基本块、字符串常量和导入函数的信息,计算成对相似度得分,从中提取向量,并与函数级信息相结合,提高漏洞检测性能。
    • 基本块级特征:如块嵌入分布和函数大小,可能会在函数级嵌入中丢失。(算法第 6 行)计算查询函数与其候选函数之间的基本块相似度,以补充块级信息
    • 字符串常量特征:由于字符串常量和导入的函数在相似的函数对中是相同或相似的,它们的相似度也起到指示函数相似度的作用。(算法第 7 行)
    • 导入函数:(算法第 8 行)使用 jaccard 指数计算两个导入函数集的相似度
      image.png
      在计算完上述三个向量后,我们将这些向量和函数嵌入搜索中的相似度 s 连接到向量 V 中。然后,我们将向量 V 输入前馈网络学习权重并预测最终函数相似度 s '。我们使用交叉熵损失函数来优化网络权值。最后,我们使用默认阈值 h 来过滤出与结果相似的函数。

评估

image.png

一对一比较

我们用一对一的函数相似度检测对 VulHawk 和基线的性能进行基准测试,这在之前的方法[27],[34],[41],[55]中广泛执行。与他们的实验设置一样,我们为每个任务构建了一个由 50k 个正函数对和 50k 个负函数对组成的平衡评估集,以及一个由 1400 个正函数对和 140k 个负函数对组成的非平衡评估集。我们使用 (AUC) 作为测量值。AUC 是一个综合了所有可能分类阈值的模型的综合性能度量。表三显示了 VulHawk 与其他基线的比较结果。
image.png
如图所示,在所有实验设置中,VulHawk 在平衡集和非平衡集上的 AUC 得分均优于 SAFE、Asteria、GMN、PalmTree、Asm2Vec 和 Trex。

一对多搜索

在本节中,我们将评估一对多搜索的性能。在研究[34]中,我们使用排名测量来评估模型在搜索应用程序中的性能,例如,漏洞搜索,它从一个大型数据库中检索候选函数。我们使用不同 K 阈值的召回率 ( Recall@K ) 作为指标,这是一个广泛使用的排名指标。我们使用不平衡集 (在第 IV-B 节中) 作为评价集。在评估中,模型计算每个查询函数与其正/负样本之间的相似性并进行排序。
image.png
我们收集了不同 top-K 结果下的召回率,并在图 9 中绘制了召回率与 k 的关系。结果表明,VulHawk 优于最先进的方法,在 XO 任务中获得了最好的 recall@1 ,为 0.935,在 XC+XO+XA 任务中获得了 0.879。在 XC+XO+XA 任务中,当检索到的结果数量超过 30 个时,每种方法的召回率趋于稳定,其中 VulHawk 在 0.994 左右达到 recall@30 , VulHawk- es 在 0.968 左右达到 recall@30 , VulHawk- s 在 0.988 左右达到 recall@30 , Trex 在 0.888 左右达到 recall@30 , SAFE 在 0.310 左右达到 recall@30 。XC+XO+XA 任务中 SAFE 的 recall@K 接近于随机概率 (K 100),因为 SAFE 在跨架构任务中由于严重的 OOV 问题而不健壮,这在一对一的比较中已经得到了证明。在对大型函数库进行一对多搜索时,SAFE 的弱点被放大,只能得到 0.007 的 recall@1 。回答 r 问题 2: VulHawk 可以在大型函数库中准确地检索最佳候选函数。

多对多匹配

多对多匹配用于在函数级测量两个给定二进制文件的相似性。作为他们的实验设置,我们为每个任务构造一个二进制对的评估集,并为每个二进制对生成最佳函数相似度匹配工具。我们在表 IV 中报告了每种工具在不同任务下的平均召回率和精度结果。
image.png
其中,基线在 XO 实验的 O0O3 中结果最低。在本实验中,VulHawk 的召回率为 0.876,比 SAFE、Asteria、Asm2Vec、BinDiff、PalmTree、GMN 和 Trex 的召回率分别提高了 385.9%、292.9%、208.6%、240.0%、211.6%、621.3%和 202.8%。有趣的是,VulHawk 最差的结果 (0.805) 是在 XC 实验中,而不是在 O0-O3 实验中。尽管如此,在 XC 实验中,VulHawk 仍然优于最先进的方法。O3 选项中,为了减小二进制函数的大小,提高效率,将 O0 选项中的冗余指令压缩为简洁的指令,强化了主要语义,去掉了函数的冗余语义,导致语义差异。VulHawk 使用简化指令提取二进制函数,并保留了主要语义,这有助于减轻优化级别的影响,使其能够适应交叉优化级别的实验。
image.png
图 10 用小提琴图展示了 XC、XA 和 XO 任务的查全率和查准率分布,我们在图上方标注了每种方法的平均结果。与 SAFE、BinDiff、Asteria、Asm2vec、PalmTree、GMN、Trex 相比,VulHawk 的召回率和精度概率分布更接近于 1 且更集中,而其他方法在不同场景下的结果分布分散且不稳定。这表明,VulHawk 的性能比其他基线更好,更稳定。
与一对一比较相比,多对多匹配的查全率和准确率较低,这是因为多对多匹配的负样本较多,错误匹配对会影响匹配算法的后续结果 (如匈牙利算法[25])。回答 RQ.3: VulHawk 可以用于在两个二进制文件之间匹配相似的函数,并且它在多对多匹配方面优于最先进的方法。

运行时效率

我们评估了 VulHawk 在不同设置下的运行效率。给定一个函数,我们使用被评估模型提取特征并生成其函数嵌入,然后从存储库中检索前 10 个候选函数。记录时间是从提取特征到返回候选函数的相似度,每次测试测量十次,尽量减少意外因素。存储库大小设置为 103、104、105 和 106。
image.png
表 V 显示了在不同大小的存储库中搜索函数的时间成本及其吞吐量。吞吐量表示一秒钟内可以检索到的存储库函数的数量,它没有考虑嵌入生成的开销。结果表明,VulHawk 比 VulHawk- es 和 VulHawk- s 慢,这是因为 VulHawk 在嵌入生成过程中使用了基于熵的适配器,在搜索过程中使用了相似度校准。用较小的开销换取更高的精度和召回率是可以接受的。通过 GPU 加速,VulHawk 可以在大约 2 秒内从 106 个函数中搜索一个函数。回答 RQ.4: VulHawk 可以在大型函数库中保持高效率 (106)。

Ablation Study

  • 基于熵的适配器:从表 III 可以看出,在 7 个一对一的功能比较任务中,VulHawkS 的 AUC 高于 VulHawk-ES。在图 9 中,VulHawk-S 在一对多搜索中获得了比 VulHawk-ES 更高的 recalls@K 。这些结果表明,VulHawk-S 的性能优于 VulHawkES,这表明性能的提升来自于基于熵的适配器的贡献,而不是额外的神经网络。基于熵的适配器将不同文件环境中的函数嵌入转移到相同的文件环境中,减轻了编译器和优化级别带来的差异。例如,在多对多匹配场景下,O0-O3 实验中,VulHawk-ES 的召回率为 0.793,而 VulHawk-S 通过基于熵的适配器缓解了不同文件环境造成的差异,召回率为 0.873。
  • 相似度校准:从表 III 和图 9 可以看出,在一对一功能对比和一对多搜索场景下,VulHawk 的搜索结果优于 VulHawk- s。表四还显示,在多对多匹配场景中,VulHawk 比 VulHawkS 更精确。在 O0-O3 多对多匹配任务中,VulHawk 的精度从 0.593 提高到 0.818,这是因为 VulHawk 使用相似度校准从块级特征、字符串特征和导入函数中补充了函数相似度,使得相似度计算中考虑的信息更加全面,提高了检测精度。

文件环境识别

我们还评估了基于熵的文件环境识别的准确性。在这里,我们使用 10 倍交叉验证来分割所有二进制文件进行训练和评估,就像在传统的机器学习设置中一样。这些二进制文件来自不同的体系结构 (x86、arm 和 mips) 和不同的编译器 (GCC 和 Clang)。Pizzolotto 等人在函数字节上使用 CNN 模型和 LSTM 模型来识别文件环境。为了更好地演示我们的方法的性能,我们下载了他们预先训练好的模型,并将它们 (CNN 和 LSTM) 设置为比较。请注意,给定二进制文件的编译器和优化级别是未知的,并且在实践中是不同的,因此在评估一个参数 (例如编译器) 时,我们不会固定其他参数 (例如架构和优化级别) 以确保实用性。
image.png
图 11 显示了 VulHawk 等方法精度随时间的变化趋势。结果表明: (1) VulHawk 在编译识别和优化级别上均优于 CNN 和 LSTM。(2) VulHawk 的识别速度比 CNN 和 LSTM 的识别速度快。(3) VulHawk 的精度曲线稳定,而 CNN 和 LSTM 的精度曲线波动较大。这说明 VulHawk 在各种场景下更加泛化,而 CNN 和 LSTM 在某些情况下受到打击。我们深入分析如下。与 CNN 和 LSTM 相比,VulHawk 采用了包含二进制全局信息的熵流,而不是单个函数的原始字节,这使得函数的意外偏差对 VulHawk 影响不大。熵在不同的文件环境中保持明显的区别,而在原始字节上差异不明显。这使得 VulHawk 保持了较高的泛化性能,优于 CNN 和 LSTM。此外,VulHawk 在精度和效率上都优于 CNN 和 LSTM。由于 VulHawk 使用了一个强大的特征 (熵),而且我们的模型比 CNN 和 LSTM 轻得多,例如,我们模型中的参数大小仅为 CNN 的 1.3%。
image.png
为了全面评估我们基于熵的文件环境识别,我们在不同架构 (x86、mips 和 arm)、文件大小 (小尺寸和大尺寸) 和文件类型 (库和可执行文件) 的各种场景中进行了实验。在这里,考虑到文件大小的分布,我们将小于 1024 KB 的文件视为小文件,反之则视为大文件。结果如图 12 所示,每个块都标注了分类比例。例如,在 O3 组预测中,95.4%被正确划分为 O3, 4.6%被划分为 O2,其中总体准确率为 96.2%。O0 选项实现了很高的精度,因为 O0 使用默认优化来减少编译时间,这与其他选项有很大不同。在 mips 和库文件中对 O2 和 O3 的识别达到了最差的结果,其中大多数错误识别集中在 O2 和 O3 的区别上。与 O0 相比,O3 选项增加了 285 个以上的优化,而 O3 只比 O2 多 3 个优化。因此,O2 和 O3 的双星具有高度相似的结构。由于来自 O2 和 O3 的二进制是高度相似的,这些错误识别是可以接受的,对二进制函数搜索的影响很小。当我们同时考虑 O2 和 O3 时,在所有情况下,区分它们与 O0 和 O1 的准确性都超过 90%。结果表明,我们的基于熵的文件环境识别在不同架构、文件大小和文件类型的各种场景下都是强大的。

漏洞识别

。。。懒得看了,反正效果很好吧

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值