Neutaint:使用神经网络进行高效的动态污点分析
qiyuwang 2024-10-07 15:16 10 浏览 0 评论
引用
D.She,Y.Chen,A.Shah,B.RayandS.Jana,"Neutaint:EfficientDynamicTaintAnalysiswithNeuralNetworks,"2020IEEESymposiumonSecurityandPrivacy(SP),2020,pp.1527-1543,doi:10.1109/SP40000.2020.00022.
摘要
各种应用程序广泛使用动态污点分析(DTA)来跟踪运行时执行期间的信息流。现有的 DTA 技术使用基于规则的污点传播,既不准确(即高误报率)也不高效(即运行时开销大)。很难在正确覆盖所有极端情况的同时为每个操作指定污点规则。此外,在跨多个操作传播污点信息的过程中,过度污染和未充分污染的错误可能会累积。最后,基于规则的传播要求在应用适当的规则之前检查每个操作,从而导致大型现实世界应用程序的性能开销过高。在这项工作中,我们提出了 Neutaint,这是一种使用神经程序嵌入跟踪信息流的新型端到端方法。神经程序嵌入对在污染源和污染池之间发生的目标程序计算进行建模,通过观察不同的执行轨迹集自动学习信息流。为了执行轻量级和精确的信息流分析,我们利用显著性映射来推断不同污染池的最有影响力的污染来源。Neutaint 构建了两个显著映射,这是一种流行的机器学习影响分析方法,用于总结神经程序嵌入中的粗粒度和细粒度信息流。我们将 Neutaint 与 3 种最先进的动态污点分析工具进行比较。评估结果表明,在 6 个真实的程序上,Neutaint 平均可以达到 68%的准确率,比第二好的污点工具 Libdft 降低了 40 倍的运行时开销,提高了 10%。当用于污点引导的模糊测试时,Neutaint 的边缘覆盖率也提高了 61%,表明已识别的有影响的字节的有效性。我们还评估了 Neutaint 检测现实世界软件攻击的能力。结果表明,Neutaint 可以成功检测不同类型的漏洞,包括缓冲区/堆/整数溢出、除以零等。最后,Neutaint 可以检测到总流量的 98.7%,这是所有污点分析工具中最高的。
介绍
动态污点分析(DTA)是一种众所周知的技术,用于在程序执行期间跟踪源变量和接收池之间的信息流。所有现有的 DTA 技术都基于每个执行语句的一组规则,在目标程序执行期间将污点标签从污点源传播到接收池。最终的污点结果是通过将各个语句污点规则传播组合在一起来计算的。本质上,最终输出表明污点源是否影响接收池。不幸的是,这种基于规则的传播方法具有三个基本限制:(i)指定准确的传播规则:即使对于看似简单的操作,准确地指定传播规则通常也很困难,详尽地列举所有这些可能性是极其困难的。(ii)累积错误:即使每个操作的污点传播规则是准确的,它们跨多个操作的组合也会引入大的错误。(iii)高昂的运行时开销:基于规则的传播引入了令人望而却步的运行时开销,因为必须检查每个操作来决定应用哪些规则。
在本文中,我们提出了一种新技术 Neutaint,它通过使用神经程序嵌入和梯度分析对其“源-池”行为进行建模来自动学习程序中的信息流,即污点。神经程序嵌入本质上是神经网络,它学习从程序的不同表示(例如,图表示、输入-输出对)预测程序行为。利用微积分的链式法则,梯度分析是一种更精确的技术,它使用自动梯度计算来准确跟踪程序中源对池的影响。我们的 Neutaint 首先学习程序运行时行为的神经程序嵌入,然后执行梯度分析以进行轻量级和准确的端到端信息流跟踪。
Neutaint 解决了上述基于规则的污点跟踪的局限性。首先,神经网络可以根据过去的程序行为概括和推断新的流,这使我们能够更准确地模拟来自不同污染源的不同程度的影响。其次,由于神经网络是连续的,梯度计算提供了一种有效且精确的数学方法来推导源对特定池的影响,从而避免手动指定传播规则的需要。这也最大限度地减少了困扰现有基于规则的方法的组合错误,并通过降低误报/否定率显着提高了污点跟踪的准确性。最后,可以通过添加轻量级仪器并使用多个输入执行目标程序,使用离线生成的程序跟踪来训练神经程序嵌入。一旦经过训练,与基于规则的传播相比,神经程序嵌入可用于执行污点分析,甚至无需以高效的方式检查目标程序执行的计算。
训练完神经程序后,我们在训练后的网络上使用基于梯度的归因方法来创建显着图,以准确测量从 NN 输入(即污点源)到 NN 输出(即污染池)的信息流。根据应用领域的不同,Neutaint 支持两种类型的显着图来跟踪信息流:(i)一个粗粒度的图,它聚合了所有源对所有池的影响。该地图包含由所有执行的输入在所有采用的路径上总的信息流。(ii)包含对每个源池对的单独影响分析的细粒度地图。此类信息对于零日攻击检测等任务非常有用。这种分析的一个常见用例是污点引导的模糊测试,其中源是输入字节,而池是程序分支中使用的变量。具有高显着性值的输入字节对程序分支中的输出变量有很大影响。改变这些字节可以最大限度地触发一组不同的程序分支的执行。每个字节花费的突变次数可以根据其对所有程序分支的相应聚合影响进行调整,即影响越大,应在相应字节上尝试越多的突变。
我们针对 3 种最先进的动态污点分析工具评估 Neutaint:Libdft、Triton 和 DFSan。
我们的主要贡献如下:
我们提出了一种基于神经程序嵌入和梯度分析的新型信息流跟踪技术。
我们设计和实施我们的技术作为 Neutaint 的一部分,并根据 3 种最先进的 DTA 工具对其进行评估。评估表明,Neutaint 可以比第二好的工具实现平均 10%的污点准确度,同时分析时间减少 40 倍。
我们通过使用真实世界的污点应用程序污点引导模糊测试进一步验证了从 4 种不同工具获得的污点信息。结果表明,Neutaint 的边缘覆盖率比第二好的 DTA 工具高 61%。
我们分析并确定了使 Neutaint 优于传统 DTA 工具的关键因素。此外,我们提供了定量结果,显示了 Neutaint 推断新信息流的能力,并讨论了进一步提高训练数据质量的不同方法。
背景
动态污点分析(DTA)。动态污点分析预先定义了污点源(例如,不受信任的文件、网络等),并在程序执行时跟踪它们对程序状态(例如内部变量)的影响。在大多数情况下,DTA 想要确定污点源是否影响某些预定义的目标位置,通常称为污染池。根据特定的应用程序,污染源和池会有所不同。
图 1:演示 Neutaint 工作流程的简单代码片段。Neutaint 使用轻量级仪器从输入程序中收集一组不同的源和池。然后,我们训练神经程序嵌入并使用基于梯度的分析来推断程序的信息流。
对于许多安全应用程序,用户输入通常用作污染源。
DTA 通常使用污点标签实现。文献中使用的污点标签主要有两种:二进制标签和多标签。二进制标记方法用单个二进制值标记所有污染源:1 或 0 分别表示污染或未污染,常见于简单的任务中。相比之下,独立跟踪每个污点源的多标签 DTA 以更详细的粒度跟踪污点,代价是运行时开销非常大,随标标签大小呈二次方增长。
DTA 的基本问题。taint 的设计和实现存在三个基本问题:欠污点、过污点和大的运行时开销。即使使用导致大量运行时开销的繁重检测,手动设计的污点传播规则在捕获信息流方面的准确性仍然很差。污点的这些局限性严重影响了它在现实世界程序中的适用性。我们选择使用端到端的程序嵌入,我们直接对神经程序进行影响分析来跟踪信息流。
程序嵌入。一般来说,程序嵌入有两种类型,静态和动态。静态程序嵌入首先生成程序表示,然后使用神经网络将表示编码为嵌入。由于此类程序表示无法捕获程序语义,因此动态程序嵌入通过执行程序从输入-输出对中学习程序行为。由于信息流分析反映了程序的运行时行为,我们使用动态程序嵌入来从程序执行轨迹中学习。我们的神经程序模型近似了从污点源到污染池的程序逻辑。然后,我们分析模型中的信息流。
神经网络中的信息流。在神经网络(NN)中跟踪信息流的一种流行技术是显着图,它测量 NN 输出对输入特征变化的敏感性。显着图也已被用于构建具有最小扰动的输入,作为图像分类器的对抗性示例。由于显着图指示影响最终神经网络输出的最关键的输入特征,它通过定位特征所需的变化来改变分类器输出,从而指导攻击者构建对抗性示例。
作为一种基于梯度的归因方法,显着图已被广泛用于解释神经网络。与其他基于梯度的方法(例如,集成梯度)相比,显着图侧重于神经输出对每个特征的敏感性,即神经网络输出如何随着输入的微小变化而变化。在我们的例子中,由于我们想推断输入中的哪个字节影响污点池,即对神经网络输出产生最大的敏感性,我们使用显着图方法。
方法
A.概述
在本节中,我们将给出一个示例来展示 Neutaint 的工作流程。如图 1 左侧所示,我们假设污点源是 x,从用户输入中取出 6 个字节,污染池是变量 z。在这种情况下,基于传播的动态污点分析无法得出准确的信息流。由于变量第 4 行 c 是由 a 和 b 计算的,即用户输入的前两个字节,因此 a 和 b 是 c 的污点值。在第 5 行,z 由 c 和 b 计算得出,因此 z 的污点值由 c 和 b 组成。分析对第 4 行和第 5 行都是准确的,但将传播规则组合在一起会放大错误。分析忽略了在第 5 行 z 实际上等于 a*a 并且仅受用户输入的第一个字节影响的事实。组合在动态污点分析中引入并放大了错误和运行时开销。
Neutaint 使用端到端的方法来构建用于信息流分析的神经程序嵌入。基于一些训练样本(即用户输入,z),Neutaint 从动态执行结果中学习一个神经程序,该程序保留仅受 a 影响的程序上下文 z。如图 1 右侧所示,给定用户输入 x,Neutaint 计算变量 z 相对于 x 的梯度,并构建一个显着图,指示 x 的每个字节如何影响 z 的敏感性。从显着图中,我们发现第一个字节是影响 z 的输入的最关键字节。图 1 展示了我们方法的高级概述。
训练。我们首先训练一个神经程序来学习从污点源到池的信息流。对于给定的程序和一组输入,我们标记这些输入并使用轻量级仪器来收集池变量的值。它们代表程序的动态行为。接下来,我们训练一个神经网络模型(NN)来学习这种动态行为。我们的神经网络近似一个将源映射到池的函数。训练过程最大限度地减少了学习该函数的误差,从而提高了信息流跟踪的精度。
影响估计。我们构建了两个显着图来推断从污点源到池的信息流。显着图分析 Neutaint 输入特征的敏感性。一个特征越重要,它对神经网络输出的影响就越大。我们首先定义一个显着图来总结程序行为的粗粒度信息流,聚合所有输入和所有路径的梯度信息。然后,我们使用 NN 输出相对于输入的一阶偏导数来定义第二个显着图,以识别特定池的最重要的污点源。
Neutaint 通过学习动态程序行为,直接在程序语义层面进行分析,而不是在传统污点分析中的指令语义层面进行分析导致污点不足和过度污点。使用 Neutaint 学习端到端模型可以减少整体信息跟踪错误,从而缓解过度污染和污染不足的问题。因此,与传统的污点分析工具相比,Neutaint 可以获得更准确的结果。
B.程序嵌入
Neutaint 通过从程序执行跟踪中观察大量污染源-池对来学习信息流。给定污点源作为模型输入,该模型预测污染池变量的值。我们正式定义我们的神经网络模型如下。给定一组具体的污点源 x 和指定程序 P 的相应污染池 y,神经程序将污染池预测为 ?,其中以下方程。
我们将 Wk、bk 表示为每一层的可训练参数,其中 k 表示层索引,? 表示 ReLU 函数,σ 表示 sigmoid 函数。等式 1 中,a 表示神经网络隐藏层的输出向量。NN 模型学习函数 f,该函数将大小为 m 的数值向量作为输入并输出 n 个污染池变量。让 θ 表示 f 的可训练权重参数。给定一组训练样本(X,Y),其中 X 是一组污点源,Y 表示正确的污染池值,参数函数 f(x,θ)的训练任务是获得参数 θ^最小化多变量回归损失,其中每个变量都是污点池。
在我们训练完神经网络模型之后,我们构建了两个显着图来分析神经程序中的信息流。从神经程序模型来看,第一个显着图提供了将所有池视为一个整体时粗粒度信息流的全局视图。第二个显着图可以为任何给定的池提取最有影响力的污点源。我们现在解释信息流分析的细节。
C.粗粒度信息流
我们讨论了从 NN 模型中提取粗粒度信息流的方法。我们将粗粒度信息流定义为每个源对所有池的影响。
为了提取粗粒度的信息流,我们首先计算污点池相对于所有源的偏导数。令 fi(θ,x)表示在目标程序与污点源 x 一起执行期间第 i 个污点池变量的输出值。我们计算关于给定污点源 x 的导数,定义如下,其中 xj 表示污点源中的第 j 个字节。
偏导数构成神经网络函数的雅可比矩阵。矩阵的每个元素表示输出神经元 fi(θ,x)相对于污点源字节 xj 的梯度。请注意,我们计算的梯度与通过反向传播训练的神经网络中使用的梯度有两个主要区别。首先,目标函数不同。用于反向传播的梯度是在损失函数上计算的,该函数包括有关模型参数状态和预期输出的信息。相比之下,我们的方法计算神经网络输出的导数,其中仅包含有关模型参数的信息。由于我们旨在解释神经网络在收敛后如何做出决策,因此我们的梯度计算不需要考虑相应的地面实况信息。其次,我们计算相对于输入的梯度,而不是神经网络模型的可训练参数。通过直接计算输入的梯度,我们获得了神经网络输出对输入中所有字节的敏感度。
然后,我们基于神经网络模型的偏导数构建了一个显着图,为粗粒度信息流提供全局视图。显着图 S(x)定义如下。
S(x)[j]是所有对第 j 个字节的池敏感性的总和,表示从当前执行开始,第 j 个字节对整个程序行为的影响。总结对所有池的敏感性包括有关到这些池的所有路径的信息。此外,神经程序包括有关所有输入数据的信息。因此,我们可以使用这个显着图来分析粗粒度的信息流。
D.细粒度的信息流
我们将细粒度信息流定义为每个源对单个池的影响。
为了推理信息如何到达给定的池,我们遵循第 III-C 节中提到的粗粒度信息流分析中的类似步骤。首先,我们使用方程 3 计算雅可比矩阵以获得梯度信息。在获得污点源中每个字节的梯度值后,我们可以构建一个显着图来推断从污点源到特定污点的细粒度信息流下沉。由于我们只对污染池对于污染源中每个字节的敏感度感兴趣,我们取梯度的绝对值来构造显着性图 S(x),定义如下。
导致 NN 输出最大波动的字节被认为是影响 sink 的污点源字节。确定污点池变量的源字节集可以通过查找具有最大值的前 k 个字节来推断,定义如下。
让 Hi(k)表示 K 个源字节的索引集,顶部 k 表示从向量中选择 k 个最大元素的函数,arg 表示返回所选元素索引的函数。由于我们的神经网络从所有训练样本中学习动态程序行为的摘要,因此从神经网络模型推断出的有影响的源字节包含来自程序的大量具体运行的知识。相反,传统的动态污点分析工具仅具有来自一次执行所采取的特定路径的信息。
E.数据收集
作为生成训练数据集的示例,我们可以从一个普通的污点源开始,随机翻转污点源中的字节,并记录相应的污染池值。或者,我们可以使用一个简单的模糊器来生成一组污点源,触发不同的程序状态并记录污点池值。训练数据覆盖率影响 Neutaint 可以跟踪的信息量。我们可以使用更复杂的技术(如覆盖引导模糊测试、符号执行等)进一步提高信息流覆盖率。
污点源通常是可以表示为字节序列的用户输入、文件或用户隐私字符串。因此,我们可以轻松地将字节序列转换为范围在[0,255]范围内的有界数值向量。但是,污点池可以是程序中具有无限值的任意变量,为了解决这个问题,我们将这些无界变量标准化为不同应用程序的有界数据。
评估
在本节中,我们针对三种最先进的动态污点分析工具(Libdft、Triton 和 DFSan)评估 Neutaint 的有效性和效率。我们在评估中回答了以下有关 Neutaint 的研究问题。
1. 热字节准确率:Neutaint 在为 6 个实际程序的输入中查找热字节(即决定不同程序行为的最有影响的字节)时是否更准确?
2. 运行时开销:与最先进的动态污点分析工具(有和没有 GPU)相比,Neutaint 的运行时开销是多少?
3. 利用分析:Neutaint 能否检测到现实世界程序中的漏洞?
4. 在污点引导模糊测试中的应用:由于模糊测试是污点最重要的安全应用之一,与其他污点分析工具相比,Neutaint 是否有助于污点引导模糊测试实现更好的边缘覆盖?
5. 模型选择:Neutaint 在处理神经网络以外的不同机器学习模型时表现如何?
6. 信息丢失:Neutaint 错过了哪些流?训练数据质量如何影响这种信息损失以及如何减轻这种损失?
A.实验设置
环境设置。我们所有的测量都是在带有IntelXeonE5-2623v4@2.60GHzCPU[1]、NvidiaGTX1080TiGPU 和 256GBRAM 的 ubuntu16.04 系统上进行的。我们在 Keras-2.1.4 中实现了 Neutaint,以 Tensorflow-1.8.0 作为后端。
1)Libdft
Libdft 是一种广泛使用的基于 IntelPIN 框架的动态污点分析引擎。对于现实世界的应用程序,大多数指令都包含污点信息,因此由于外部函数调用的数量庞大,这种设计会导致大量的运行时开销。
设置。我们设置了一个支持多个污点标签的修改版本 libdft。依赖 PIN 版本为 2.13。
2)Triton
Triton 是一个支持 concolic 执行、动态污点分析和抽象语法树表示的平台。Triton 为用户提供与底层 PINAPI 的 Python 绑定,以便他们可以编写脚本来执行自定义分析任务。但是,这些绑定是有限的,无法捕获 PIN 的全部功能。此外,有限的 Python 绑定会导致不精确的动态污点分析结果,此外还有大量检测和监控 PIN 中的污点传播的运行时开销。
设置。我们建立了一个开发分支 Triton 来支持多个污点标签功能。依赖 PIN 版本为 2.13。我们使用 TritonPython 绑定编写分析脚本,根据不同的程序设置相应的污点源和污点池。
3)DFSan
DFSan(DataFlowSanitizer)是 Clang 提供的数据流分析框架。它由一个编译时检测模块和一个运行时动态库组成,DFSan 无法在依赖于外部共享库的程序上运行。由于在编译给定程序时无法检测动态共享库,因此 DFSan 无法插入这些污点跟踪函数并且无法在依赖动态共享库的程序上工作。这与污点标签(第 IV-C 部分)的耗尽和解决一起限制了 DFSan 在实际应用中的适用性。
表 1 动态污点分析引擎。
设置。我们从 Clang 运行时库设置了 DFSan。底层 LLVM 版本是 7.0.0。我们使用 DFSan 的 API 为不同的程序设置 taintsource 和 sink。
4)Neutaint
模型架构。对于每个程序,我们训练一个神经程序模型,该模型学习从污点源到污染池的程序逻辑。NN 模型由 3 个全连接层组成。隐藏层使用 ReLU 作为激活函数,有 4096 个隐藏单元。输出层使用 Sigmoid 作为激活函数来预测 sink 变量。由于每个程序具有不同的污点源和污染池,相应的神经程序模型具有不同数量的输入/输出神经元。我们描述了表 II 中所有程序的污点源和污染池。我们使用前 6 个程序来评估热字节准确性和污点引导的模糊测试实验,因此我们将多个污点池设置为分支变量(即条件谓词中使用的变量)。后面的 5 个程序在漏洞利用分析实验中进行了评估,因此它们在指定变量上只有一个污点池。所有 11 个程序都将程序输入的每个字节设置为污点源。因此,污点源的总数就是输入字节的总数。
训练数据收集。为了收集训练数据,我们首先使用初始种子运行 AFL 模糊器以收集其变异语料库。接下来,我们使用一个简单的 LLVMpass 添加轻量级仪器,用于在运行时记录 CMP 指令的两个操作数。CMP 指令的这些操作数是在条件谓词中评估的分支变量(即我们的污点池)。我们使用生成的输入运行检测程序并记录污点池值。我们在每个程序上收集大约 2K 个输入-输出对(每个输入有多个源字节并到达多个池)用于训练。对于热字节评估,我们将污点池变量规范化为二进制,即,如果池值满足条件谓词,则为 1,否则为 0。我们通过计算 CMP 指令的两个操作数的差来检查谓词的值。对于漏洞利用分析,我们使用类似的 LLVMpass 来获取指定的污点池值,然后对池值执行标准的最小-最大归一化(即 ynorm=(y?ymin)/(ymax?ymin))。请注意,数据收集和规范化可以通过简单的 Python 脚本轻松完成,无需手动标记。
训练程序。我们根据特定的模型输出数据类型采用随机权重初始化和交叉熵损失函数或均方误差损失。NN 模型使用 Adam 优化器训练 100 个 epoch,初始学习率为 0.01,每 10 个 epoch 衰减率为 0.7。我们选择了一个 mini-batch 大小 16。对于漏洞利用分析评估,我们使用均方误差作为损失函数和度量来评估我们的模型性能。训练过程非常高效,所有测试程序平均需要 73 秒。在第 IV-B 节中,我们测试了我们的神经程序模型在识别热字节方面的准确性和误报率。此外,我们评估了第 IV-G 节中的信息丢失。
表 2 我们将程序输入字节设置为污点源,并使用不同类型的污点池。对于前 6 个程序,我们在程序分支处选择池变量来评估 Neutaint 的准确性、开销和在 taint-guidedfuzzing 上的应用。对于其余 5 个程序,我们根据漏洞信息设置污点池进行漏洞利用分析。
B.Neutaint 在查找 6 个真实世界程序的输入中的热字节(即最有影响的字节)时是否更准确?
热字节定义。我们将可以最大程度地影响程序分支中的变量的重要性字节定义为热字节。
对于解析器程序,我们可以近似认为热字节主要位于结构化格式部分。此外,通过分析文件的固定结构位置,我们可以获得特定解析程序的热字节的估计基本事实。这些真实的热字节可用作评估动态污点分析工具对特定解析程序的有效性和功效的指标。
表 3 对于每个程序,我们测量识别热字节的准确率和误报率,以及不同 DTA 工具和 Neutaint 的运行时开销。
标记数据。请注意,本节中所有评估的实际程序都是文件解析程序。由于这 6 个解析程序在它们的文件格式上具有特定的结构,我们可以通过分析这些文件格式来估计热字节的基本事实。图 2 显示了所有 6 种文件格式的真实情况。
提取热字节。
我们执行以下步骤从我们的神经程序模型中提取热字节。1)对于每个程序,我们将种子输入提供给 NN 模型。2)我们计算污点源相对于污点源(种子输入)的梯度,并使用等式 4 构建显着图。显着值表示污点源中的字节影响所有污点源变量的程度。3)我们使用等式 6 从输入显着性图中选择具有最高值的前 5%字节作为可能的热字节。我们设置此阈值的原因是在实践中,输入中只有少量热字节决定程序行为。在分析了所有 6 种文件格式后,我们发现地面实况热字节的总数从 250 到 500 不等,约占总输入字节的 5%。
计算热字节精度。
我们通过检查从污点工具分析的热字节是否与真实热字节一致来计算热字节准确度。具体来说,如果 Neutaint 识别的热字节位于估计的 ground truth 范围内,我们认为它是真正的热字节识别(即 truepositive);否则,我们将其视为错误识别(即误报)。对于其他 3 个最先进的动态污点分析工具,我们还评估了它们寻找热点字节以与 Neutaint 进行比较的能力。然后我们通过计算指定字节被污染的总次数来聚合这些被污染的字节。通过这种方式,我们为这 3 个工具构建了与 Neutaint 类似的显着图。然后我们选择相同阈值 5%的顶级污染字节作为可能的热字节并计算热字节准确度。最后,我们测量总运行时间以获得 4 个工具的最终热字节准确度。对于 3 个动态污点分析工具,我们记录了跟踪数据集中所有输入样本的总运行时间。对于 Neutaint,我们记录了 NN 训练和梯度计算的总运行时间成本。基于 6 种文件格式的尽力而为基础事实,我们计算了以标准方式识别热字节的准确率和误报率。
结果。热字节准确度的结果如表三所示。对于 readelf 与 harfbuzz 等具有简单直接解析逻辑的程序,我们观察到所有四种工具都可以高精度地找到热字节。对于 libjpeg 和 zlib 等具有复杂解析和转换逻辑的程序,所有工具的准确度都会下降。尽管如此,Neutaint 在 5 个程序上实现了最高的热字节准确度。即使对于由于大量污点传播流而导致显着运行时开销的剩余程序 libjpeg,Neutaint 也是唯一一个能够在合理的时间(几分钟而不是几小时)内完成分析的程序。图 2 显示了使用热图对热字节准确性的详细可视化。
传统的污点传播可能会导致大型现实世界应用程序中时间敏感操作的显着减慢。事实上,所有三个传统的动态污点分析工具都无法在 24 小时内完成对 libjpegon 数据集的分析。此外,第二好的工具 Libdft 在 libjpeg 上花费超过 3 分钟完成一次执行(数据集中所有 993 个输入超过 2 天)以跟踪解压缩算法内的所有污点流,而 libjpeg 的普通执行没有动态污点分析需要 0.015 秒。强烈污点跟踪的运行时开销可能是 104 倍以上,而 Neutaint 通过识别热字节的轻量级神经网络模型避免了如此繁重的检测开销。
分析:热字节准确性。Neutaint 准确率较高的原因在于,Neutaint 是通过学习动态程序逻辑基于程序语义的分析,而不是传统动态污点分析工具基于指令语义的分析。Neutaint 可以通过固定的、预定义的污点传播规则,灵活地适应动态污点分析工具无法准确建模的各种执行上下文。
图 2 六个热图显示了每个工具如何识别给定文件格式的热字节。x 轴分为字节间隔,间隔的暗度与工具预测的热字节数成正比。由于第一行代表基本事实,正确性由每个后续行与基本事实行的对齐方式定义。
分析:热门字节误报率。对于所有程序,Neutaint 在识别热字节方面的误报率最低(表 III)。结果表明,学习端到端的程序嵌入可以有效地减少过度污染问题。
结果 1:与最先进的动态污点分析工具相比,Neutaint 在六种流行的文件格式中实现了最高的热字节准确度和最低的误报率。平均而言,与第二好的 DTA 工具 Libdft 相比,Neutaint 将准确率提高了 10%,并将误报率降低了 0.44%。
C.与最先进的动态污点分析工具(有和没有 GPU)相比,Neutaint 的运行时开销是多少?
我们测量了 Neutaint 和所有三个动态污点分析工具的运行时开销。我们测量处理数据集中所有输入所需的总时间,如表 III 中的运行时间。对于 Neutaint,Neutaint 的总运行时间由三部分组成,收集程序行为数据、训练神经网络和计算神经网络的显着图。
表 III 总结了结果。总体而言,与其他工具相比,Neutaint 对所有六个程序的运行时开销最少,因为训练和计算显着图的时间成本可以忽略不计。此外,计算显着图在计算上是高效的。因此,在所有评估的四种工具中,Neutaint 享有最快的运行时间。
结果 2:与之前最快的动态污点分析工具 Libdft 相比,Neutaint 的运行时开销在 GPU 上快了 40 倍,在 CPU 上快了 10 倍。
消融研究。我们将 Neutaint 处理 2,000 个输入的总运行时间开销分解为三个部分:数据收集、训练和 GPU 和 CPU 设置上的显着性图。结果示于表 IV。Neutaint 在 6 个程序中的平均运行时间为 244 秒,比在 CPU 上(898 秒)快 4 倍。即使在只有 CPU 计算的机器上,Neutaint 的运行时开销仍然比传统 DTA 工具低 10 倍。由于我们的 NN 模型具有少量超参数,因此无论是否使用 GPU,都可以有效地训练模型。使用 GPU,训练时间大约需要 60%。显着图和数据集的构建分别占 30%和 10%左右。仅使用 CPU,运行时间分为训练、显着图计算和数据收集,分别为 88%、9%和 3%。与使用 GPU 相比,仅使用 CPU 会导致训练和显着图构建平均分别慢 4.5 倍和 0.16 倍。一般来说,训练时间占总运行时间的大部分。然而,数据收集占用的运行时间最少,因为程序的轻量级检测仅在执行期间记录污点池值,并且比普通执行引入的开销最小。
表 IV:Neutaint 的运行时分解。该表显示了为数据收集、训练和显着图计算处理 2,000 个输入的总运行时间。
表 V:Neutaint 可以在以下漏洞利用中成功识别从源到池的信息流。
结果 3:对于六个程序中的每一个,Neutaint 处理所有 2,000 个输入的总运行时间平均为 244 秒。训练时间占总运行时间开销的大部分,使用 GPU 时约为 60%,不使用 GPU 时约为 88%。
D.Neutaint 能否检测到实际程序中的漏洞?
我们评估了 Neutaint 在软件攻击分析中的有效性。我们选择了表 V 中列出的 5 个已知的现实世界漏洞。关键的结果是,Neutaint 成功定位了控制污染池变量的热字节,从而可以推断出污染源对污染池的影响。
表六:24 小时时间预算下 5 个污点引导模糊器的边缘覆盖率比较
结果 4:Neutaint 可以成功找到已知 CVE 中从 source 到 sink 的信息流。
E.由于 taint-guidedfuzzing 是 taint 最重要的安全应用之一,与其他 taint 分析工具相比,Neutaint 是否有助于 taint-guidedfuzzing 实现更好的边缘覆盖?
在本节中,我们比较了所有工具在应用于最重要的安全应用程序之一,污点引导模糊测试时的性能。
Fuzzer 后端实现。动态污点分析已被许多模糊器用作前端,以识别用于指导进一步突变的热字节。尽管这些模糊器利用动态污点分析工具来查找热字节,但它们中的每一个都应用不同的算法来变异热字节。为了消除不同搜索策略和不同模糊测试模块执行后端的影响,我们用 C 语言构建了一个简单高效的模糊测试后端。对于每个动态污点分析前端,我们使用一个公共后端,它根据热字节的变化生成新的输入。因此,我们总共有四个使用相同变异算法的模糊器原型,如算法 1 所示。我们用于比较的指标是从不同前端实现的边缘覆盖率。
边缘覆盖比较。我们在表 VI 中显示的 6 个程序上运行每个模糊器原型 24 小时。平均而言,Neutaint 的边缘覆盖率比第二好的分析前端 Libdft 高 61%。Triton 是最差的分析前端,因为它具有极大的运行时开销和最低的热字节准确度。DFSan 前端只能在两个程序上运行并达到中间结果。总而言之,污点引导的模糊测试结果进一步验证了 Neutaint 在实际应用中的四种污点分析工具中获得最准确的热字节。污点引导的模糊测试结果和热字节准确性评估(第 IV-B 部分)的一致性证明了 Neutaint 的效率和有效性。
结果 5:Neutaint 比其他动态污点分析工具实现了 61%以上的用于污点引导模糊测试的边缘覆盖率,表明从 Neutaint 获得的污点信息更有效。
F.Neutint 在使用神经网络以外的不同机器学习模型时表现如何?
逻辑回归:我们使用相同的神经网络架构实现逻辑回归,但在隐藏层中没有任何非线性激活。我们使用 sigmoid 作为最后一层,并使用第 IV-A 节中提到的相同设置进行训练。为了提取热字节信息,我们执行第 IV-B 节中提到的梯度分析程序。
SVM 模型:我们使用 scikit-learn 库实现了 SVM 模型(线性、多项式核和 RBF 高斯核)。我们的数据集有大量输出标签(即每个输入最多 2K 个池变量)。此类数据集上的 SVM 模型的运行时开销很大,因为它使用简单的一对一方案。因此,我们利用标签之间的相关性并将大量标签编码成更小更紧凑的标签。为了获得每个输入特征的重要性,我们计算与每个输入特征相关的所有权重到最终模型输出的点积。更大的权重意味着输出对相应特征的变化更敏感。
结果:表 VII 显示了来自五个不同 ML 模型的热字节准确率和误报率。神经网络模型在所有 6 个程序上都取得了最好的结果,平均 68%的热字节准确率。
结果 6:神经网络模型平均达到了 68%的热字节准确率和 2.07%的 FPR,是五个机器学习模型中最好的。
图 3:当训练数据集覆盖率增加时,Neutaint 检测到的流总数。覆盖率较高的训练数据可以增加 Neutaint 的流覆盖率。
G.Neutaint 遗漏了哪些类型的流?训练数据质量如何影响这种信息损失以及如何减轻这种损失?
流定义:DTA 的目标是基于动态执行检测流。因此,我们收集了一个真实数据集,其中包含基于看不见的测试输入的流总数。我们将一个流定义为(inputvalue,source,sink)的元组,并且从所有测试输入收集总流。为了测量信息损失,我们评估了 Neutaint 和动态污点分析工具可以从地面实况的总流量中检测到多少流量。
FlowDataset:由于我们需要准确的总流数作为基准,我们选择了四个程序(包括三个小程序和一个真实世界的小程序)。对于每个程序,我们在条件谓词中选择 50 个池变量,例如文件魔术字节、字段值和偏移量。我们通过轻量级仪器获得这些池值,并将它们归一化为第 IV-A 节中提到的二进制数据。这些池变量通常用于执行确定程序行为的条件检查。如果特定输入可以达到 20 个池,我们为该输入计算 20 个流。为了收集数据集,我们使用简单的模糊器随机翻转指定输入的字节,生成涵盖所有 50 个池变量的 6K 输入。然后我们将数据集拆分为 5K 训练输入和 1K 测试输入。训练和测试数据集都可以覆盖所有 50 个池变量。我们平均达到了 99%的测试准确率。在训练完神经程序后,我们执行第 IV-B 节中提到的梯度分析,以推断池变量是否被污染。如果池变量的梯度值大于指定的阈值,则认为它是受污染的。
表七:不同 ML 模型的 Neutaint 性能。神经网络模型平均实现了 68%的热字节准确率和 2.07%的 FPR,是五种机器学习模型中最好的。
表八:不同污点跟踪工具在三个小程序和一个真实世界程序上的信息流损失比较。我们使用静态分析和人工检查来估计总流量的数量。
信息丢失:所有动态污点分析工具都会丢失信息,因为它们无法跟踪程序中的所有流程。Neutaint 的信息丢失可以分为两类。
机器学习模型不准确。没有模型在看不见的测试数据上是 100%准确的。当神经网络模型对看不见的测试数据做出错误预测时,就会发生信息丢失。
为了研究由训练数据覆盖率(即训练输入覆盖的池变量的数量)引起的信息丢失,我们将 5K 训练输入下采样为具有不同覆盖阈值的五个子集。每个子集涵盖不同数量的池变量,从 10、20、30、40 到 50。然后我们用每个子集训练 Neutaint,并评估在 1K 未见测试输入上检测到的流的总数。结果如图 3 所示。Neutaint 检测到的流总数随着训练数据覆盖率的增加而增加。当训练数据覆盖所有池时,Neutaint 可以检测到看不见的测试数据集中的最高数量的流。
此外,我们评估了由神经网络模型的不准确性引起的信息损失。具体来说,我们将 Neutaint 检测到的流数量与四个程序上的三个最先进的 DTA 工具进行了比较。我们从所有测试输入中获得基本事实(即流的总数)。结果示于表 VIII 中。平均而言,Neutaint 检测到 98.7%的流量,是所有工具中最高的。
Neutaint 的优点:Neutaint 性能优越的原因在于,Neutaint 可以检测通过外部库调用复杂代码传递的信息流。DTA 工具很难通过库调用传播污点标签。此外,Neutaint 还检测到一些常见 DTA 工具不支持的隐式控制流依赖性。Neutaint 在所有四个工具中的 3 个程序(TinyELF、TinyXML 和 Zlib)上取得了最好的结果,在 TinyJPG 上排名第二。对于 TinyJPG 程序,Triton 发现的流比 Neutaint 略多。TinyJPG 在选定的 taintsinks 中不包含任何外部库调用或隐式控制依赖项,而 Neutaint 在估计看不见的输入中的 sink 变量时可能会犯一些小错误。Lifdft 在程序 TinyELF 上的表现最差,因为 TinyELF 中的大多数函数都通过浮点指令 MOVSD 传递参数,而 Libdft 不支持。与其他工具相比,DFSan 找到的流数最少。结果表明,所有测试工具都存在信息丢失的情况。
如何提高 Neutaint 的训练数据覆盖率?为了减少信息丢失,我们可以添加更多的训练数据来达到更多的池变量。使用模糊器生成具有覆盖指导的数据比仅在没有指导的情况下随机翻转输入更有帮助。此外,我们可以使用符号执行等现有技术来生成高质量的训练数据。在任何形式的 DTA 中寻找新路径都是难题。一旦我们在 source 和 sink 之间找到了一条路径,我们就可以通过输入变异生成更多的路径。尽管训练神经程序需要在源和池之间至少有一条路径,但与基于规则的传统 DTA 工具相比,我们可以实现更低的误报率和更高的准确度。
结果 7:覆盖率较高的训练数据增加了 Neutaint 的流覆盖率。平均而言,Neutaint 检测到 98.7%的流量,比第二好的工具 Triton 高 20%。
结论
我们提出了一种使用神经程序嵌入进行污点分析的新方法 Neutaint。我们的神经程序直接学习从污点源到污染池的信息流。我们使用显着图来分析神经程序中的信息流。为了评估 Neutaint 的准确性、开销和应用效用,我们与三种最先进的动态污点分析工具进行了比较。结果表明,与第二好的动态污点分析工具 Libdft 相比,Neutaint 的准确率平均提高了 10%,运行时开销减少了 40 倍。Neutaint 还可以成功地跟踪漏洞利用中从源到池的信息。我们通过流行的污点应用程序模糊测试进一步评估 Neutaint。污点引导的模糊测试结果表明,与最先进的动态污点分析工具相比,Neutaint 的边缘覆盖率平均提高 61%。
致谢
本文由南京大学软件学院 2021 级硕士洪华转述翻译。
References
[1] IntelXeonE5-2623v4@2.60GHzCPU: mailto:IntelXeonE5-2623v4@2.60GHzCPU
相关推荐
- 别再乱找了!这才是 Alist 本地安装挂载的正确打开方式
-
一、探秘Alist的神奇世界在这个数据爆炸的时代,我们的生活里充斥着各种各样的网盘服务,百度网盘、阿里云盘、腾讯微云等等,它们成了我们存储资料的得力助手。但随着网盘数量的增多,管理这些分散在不同平...
- 如何将数据从旧iPhone传输到新iPhone 16?这五个方法你必须知道!
-
前不久,苹果发布了备受期待的iPhone16系列,新机型搭载了更强大的芯片、更流畅的操作体验,还有备受热议的全新摄像系统。无论你是冲着A18仿生芯片,还是更丰富的动态岛功能,相信很多果粉早已跃跃欲试...
- 大数据传输的定义与大数据传输解决方案的选择
-
当我们需要处理大量的数据时,我们就要把数据从一个地方移动到另一个地方。这个过程就叫做大数据传输。它通常需要用到高速的网络连接、分散的存储系统和数据传输协议,以保证数据的快速、可靠和安全的移动。常用的大...
- 【工具】在线传输文件工具(在线文件互传)
-
前言在线传输文件工具主要是用于在不同的设备之间,如手机、电脑、平板等快速便捷地传送文件。告别使用USB传统传输文件的方式。...
- 如何使用 CAN-FD 在 LPC5500 上传输数据
-
目录1引言2CAN-FD3示例演示1引言...
- 轻松同步:将照片从三星手机传输到iPad的简便方法
-
概括想要在新iPad上查看三星照片吗?但是,如果您不知道如何将照片从三星手机传输到iPad,则无法在iPad上查看图片。为此,本文分享了7个有用的方法,以便您可以使用它们在不同操作系统之...
- 常见又地道的网络缩写:美剧中常说的SFW到底是个啥?
-
在这堂课中,让我们来学习更多在数字网络世界中常用的有趣网络用语。7shifts/unsplashhttp,https“http”和“https”是万维网(www)传输文件用的协议。“http”是hy...
- 每天学会一个计算机网络协议之FTP
-
开始行文之前提出一个问题,相信大家在看完本文后一定可以回答当我们在网站上填写注册信息的时候,需要我们上传照片,上传的过程发生了什么?下面引入我们的主角,FTP文件传输协议FTPFileTransf...
- 即用即走,这3款文件分享工具真香
-
打工人的日常,免不了「文件分享存储服务」的需求。我们一般会选择不同的网盘,但是大家也知道,网盘不是限速就是叫你充值。今天跟大家简单推荐3款文件分享工具,既可以免登录匿名使用,而且操作简单稳定性也不错。...
- 安卓手机里的文件和照片与Mac互传的办法
-
因为HandShake一段时间未更新,似乎目前不可操作。我一时间未找到更好的「传输」办法,经实践操作,向大家介绍一下「安卓手机」,包括「一加」、「索尼」,都可用此方法,来进行文件传输到Mac的...
- 软网推荐:同一个平台选择不同的传输方法
-
平时上网的时候,我们经常要分享一些文件给其他朋友,一般通过云服务平台来实现。今天笔者给大家介绍的Worksphere传输服务,它提供了两种不同的分享方式,方便我们根据实际需要进行选择。一个链接分享所有...
- 跨平台不限速的免费文件传输网站(跨平台不限速的免费文件传输网站是什么)
-
大家好,欢迎来到天天惠分享,不知道各位平时都是用什么方法来进行文件跨平台传输的呢?是百度网盘?微信还是QQ?亦或是有线传输。虽然这些方法都可以达到传输的目的,但都有各自的缺陷,使用起来一言难尽。比如百...
- 全网最全最详细的全平台文件传输方法,解决你文件传输问题(一)
-
前言想必现在大多数人文件传输的方法还是使用qq微信,但是qq微信的文件传输有时候真是,...
- 文件传输工具有哪些?这3款堪称办公必备!
-
在不同设备间,想把文件从一台设备传输到另一台,尤其是大体积文件,更是免不了用到文件传输工具,可以说文件传输工具已成为提升效率的关键载体。面对海量文档、设计素材、会议纪要的流转需求,传统邮件附件、U盘拷...
- 小白也能用的跨网文件交换系统!10款简单易上手的文件摆渡工具
-
跨网文件交换系统对于需要频繁在不同网络环境中进行文件共享的用户来说至关重要。以下是10款简单易上手的文件摆渡工具,适合小白用户使用,帮助他们高效地分享和传输文件。10款简单易上手的跨网文件交换工具1....
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- navicat无法连接mysql服务器 (65)
- 下横线怎么打 (71)
- flash插件怎么安装 (60)
- lol体验服怎么进 (66)
- ae插件怎么安装 (62)
- yum卸载 (75)
- .key文件 (63)
- cad一打开就致命错误是怎么回事 (61)
- rpm文件怎么安装 (66)
- linux取消挂载 (81)
- ie代理配置错误 (61)
- ajax error (67)
- centos7 重启网络 (67)
- centos6下载 (58)
- mysql 外网访问权限 (69)
- centos查看内核版本 (61)
- ps错误16 (66)
- nodejs读取json文件 (64)
- centos7 1810 (59)
- 加载com加载项时运行错误 (67)
- php打乱数组顺序 (68)
- cad安装失败怎么解决 (58)
- 因文件头错误而不能打开怎么解决 (68)
- js判断字符串为空 (62)
- centos查看端口 (64)