其他可参考链接:
DeepReflect:通过二进制重构标识具体恶意行为 - 知乎
[论文阅读] (20)USENIXSec21 DeepReflect:通过二进制重构发现恶意行为(恶意代码ROI分析经典)_Eastmount的博客-CSDN博客_deepreflect
https://www.csdn.net/tags/MtjaAgzsNDA1MDMtYmxvZwO0O0OO0O0O.html
DeepReflect: Discovering Malicious Functionality
through Binary Reconstruction
DeepReflect: 通过二进制重构发现恶意功能
深度学习已在恶意软件分类任务中表现出良好的结果。然而:
为了提高静态(或手动)逆向工程的生产力,我们提出了DeepReflect:一种用于定位(localize)和识别(identify)恶意二进制文件中恶意软件组件的工具。
方案对比
我们通过5个恶意软件分析人员对超过26k个恶意软件样本进行评估。实验发现,DeepReflect让每个分析人员需要逆向工程的函数数量平均减少了85%。本文方法还可以检测到80%的恶意软件组件,而当使用基于签名的工具CAPA时,该值仅为43%。
此外,DeepReflect提出的自动编码器(autoencoder)比Shap(一种人工智能解释工具)表现得更好。这一点很重要,因为Shap是一种最先进(state-of-the-art)的方法,需要一个标记的数据集,而我们的自动编码器不需要。
静态逆向工程恶意软件可能是一个手动且乏味的过程。 公司每周最多可以收到 500 万个可移植可执行 (PE) 样本。 虽然大多数组织提前对这些样本进行分类以减少要分析的恶意软件数量(即,检查 VirusTotal以获取防病毒 (AV) 引擎结果、在受控沙箱中执行样本、提取静态和动态签名等) ,最终仍然会有需要静态逆向工程的恶意软件样本。这是因为总是会有新的恶意软件样本,之前没有防病毒公司分析过,或者没有精心设计的签名来识别这些新样本。最后,样本可能会拒绝在分析师的动态沙盒中执行。
目前的解决方案存在于恶意软件样本的创建签名、分类和聚类的形式。然而,这些解决方案只预测样本的类别(例如,良性vs.恶意,或一个特定的恶意软件家族)。他们无法定位或解释恶意软件样本本身内部的行为(定位恶意函数位置、解释恶意函数行为),而分析师需要执行(perform)这些行为来生成报告并改进他们公司的恶意软件检测产品。事实上,由于工作量过大,该领域已经有过倦怠的报道。
为了确定他们的需求,我们咨询了四位逆向工程师恶意软件分析师。我们发现,如果恶意软件分析师有一种工具可以(1)识别恶意软件中恶意功能的位置(2)标记这些恶意函数的行为。那么他们的工作效率就会更高。
开发这样一个工具的挑战是:(1)人们需要能够区分什么是良性的(benign),什么是恶意的(malicious) (2)理解已识别的恶意行为的语义。
对于第一个挑战,区分什么是良性的和什么是恶意的是困难的,因为恶意软件和良性软件的行为经常在很高的程度上重叠。对于第二个挑战,自动标记和验证这些行为是困难的,因为没有发布的单独标记恶意软件功能的数据集(与使用反病毒标签的开放数据集的恶意软件检测和分类系统不同)。
为了解决这些挑战,开发了DEEPREFLECT,这是一个新颖的工具,它使用:
(1)一个无监督深度学习模型,它可以在二进制文件中定位恶意函数;
(2)一个半监督聚类模型,它使用从分析师的日常工作流程中获得的很少标签对识别的函数进行分类。
为了在二进制文件中定位恶意软件组件,我们使用了自动编码器 (AE)。 AE 是一种基于神经网络的机器学习模型,其任务是将其输入重建为输出。 由于网络内层存在压缩,AE 被迫学习训练分布中的关键概念。 我们的直觉是,如果我们在良性二进制文件上训练 AE,它将难以重建恶意二进制文件(即我们没有对其进行训练的样本)。 自然,AE 将无法重建包含恶意行为(在良性样本中不可见或罕见)的二进制区域。 因此,重构错误可用于识别恶意软件中的恶意组件。 此外,由于 AE 是以无监督的方式训练的,我们不需要数百万个标记样本,公司可以利用他们自己的内部恶意软件二进制数据集。
为了对所定位的恶意软件组件进行分类,我们
(1)对恶意软件样本中所有已识别的功能进行聚类;
(2) 使用分析人员在日常工作流程中所做的注释(即少量人工分析的函数行为标签)来标记聚类结果。
这种方法是半监督的,因为每个集群只需要几个标签(例如,三个)就可以将大多数标签分配给整个集群。随着时间的推移,我们可以通过将AE识别的功能映射到聚类模型来预测它们的类(例如,C&C,特权升级等)。这反过来又节省了分析人员的时间,因为他们不必一次又一次地对相同的代码进行逆向工程。
我们注意到,无监督AE为恶意软件分析人员提供了直接的效用,无需训练或使用半监督聚类模型。这是因为它
(1)将分析人员的注意力吸引到最相关的函数上,通过对它们进行排序(根据它们的重构错误)
(2)过滤掉分析人员可能需要花费数小时甚至数天来解释的函数。
DEEPREFLECT是根据四位恶意软件分析师的反馈进行设计和修改的, 并评估其有效性和实用性。我们评估了DEEPREFLECT的性能,包括五个工作:(1)识别恶意软件中的恶意活动,(2)聚集相关恶意软件组件,(3)将分析师的注意力集中在重要的方面,(4)揭示不同恶意软件家族之间共享行为的洞察力 (5)处理涉及混淆的对抗性攻。
我们的贡献如下:
图1展示了一个典型的恶意软件分析师Molly的工作流程。当给定一个恶意软件样本,Molly的任务是了解该样本在做什么,以便她写一份技术报告并改进公司的检测系统,从而在未来识别该类样本。
(1) 首先查询VT(virtotul)和其他组织,以确定他们以前是否见过这个特定的样本,然而并没有
(2) 在一个自定义的沙箱中执行样本以了解其动态行为,然而没有显示任何恶意行为或拒绝执行;运行一些内部工具,诱使恶意软件执行其隐藏的行为,但仍无效时
(3) 尝试脱壳(unpacking)和静态逆向分析恶意样本,以了解其潜在行为
(4) 在反汇编程序(IDA Pro 或 BinaryNinja)中打开脱壳后的样本,被数千个函数淹没,接着运行各种静态签名检测工具来识别恶意软件的某些特定恶意组件,但仍无效
(5) 逐个查看每个函数(可能通过 API 调用和字符串过滤)以尝试了解它们的行为
(6) 在分析样本的行为后,撰写分析报告(包含基本信息、IOC、静态签名等)
然而,当新的样本出现时,Molly需要重复同样的任务。由于这种重复的体力劳动,这项工作对Molly来说变得单调乏味和耗时。
恶意软件分析师的一般工作流程。 当分析人员必须对未知恶意软件样本进行静态逆向工程时,DEEPREFLECT 可为他们提供帮助
DEEPREFLECT旨在减轻恶意分析师的分析工作,能逆向一个未知的恶意软件样本,从而减轻他们繁重的任务,并为相似的函数标注行为标签。
我们提出了DEEPREFLECT,该工具能:
(1) 定位恶意软件binary中的恶意函数
locates malicious functions within a malware binary
(2) 描述这些函数的行为
describes the behaviors of those functions
虽然分析人员可能首先尝试通过搜索特定的字符串和API调用来静态地识别行为,但这些行为很容易被分析人员混淆或隐藏( obfuscated or hidden)。DEEPREFLECT没有做出这样的假设,并试图通过控制流图(control-flow graph,CFG)特性和API调用(API calls)的组合来识别这些相同的行为。
DEEPREFLECT通过学习正常情况下良性的二进制函数来工作。因此,任何异常都表明这些函数不会出现在良性二进制文件中,而可能被用于恶意行为中。这些异常函数更可能是恶意函数,分析师可以只分析它们,从而缩小工作范围。如图5所示,DEEPREFLECT将分析师必须分析的函数数量平均减少了 85%。此外,实验表明我们的方法优于旨在实现相同目标的基于签名的技术。
本文有四个主要目标:
DEEPREFLECT的目标是识别恶意软件二进制中的恶意函数。在实践中,它通过定位异常基本块(感兴趣区域 regions of interest,RoI)来识别可能是恶意的函数。然后,分析人员必须确定这些函数是恶意行为还是良性行为。DEEPREFLECT有两个主要步骤,如图2所示:
RoI检测(RoI detection):通过AE(AutoEncoder)来执行的
RoI注释(RoI annotation):通过对每个函数的所有RoI聚类,并将标记聚类结果来执行注释。注意,一个函数可能有多个ROI,用每个函数自己的ROI的均值表示该函数,然后对函数聚类。
DEEPREFLECT概述。我们的系统将脱壳的恶意软件样本作为输入,从每个输入(基本块(BB))中提取CFG特征,将它们应用到预训练的自动编码器模型中,以突出RoI(感兴趣的区域)。最后,对这些区域进行聚类和标记。
(1) 术语 Terminology
首先定义恶意行为(malicious behaviors)的含义。我们根据识别恶意软件源代码的核心组件(例如,拒绝服务功能、垃圾邮件功能、键盘记录器功能、命令和控制C&C功能、利用远程服务等)来生成真实情况(ground-truth)。通过MITRE ATT&CK框架描述,如表3所示。
然而,当静态逆向工程评估恶意软件二进制文件时(即在野恶意软件二进制 in-the-wild malware binaries),我们有时无法肯定地将观察到的低级函数归因于更高级别的描述。例如,恶意软件可能会因为许多不同的原因修改注册表项,但有时确定哪个注册表项因什么原因而被修改是很困难的,因此只能粗略地标记为“防御逃避:修改注册表(Defense Evasion: Modify Registry)”。即使是像CAPA这样的现代工具,也能识别出这些类型的模糊标签。因此,在我们的评估中,我们将“恶意行为”表示为可由MITRE ATT&CK框架描述的函数。
(2) RoI Detection
检测的目标是自动识别恶意软件二进制文件中的恶意区域。例如,我们希望检测C&C逻辑的位置,而不是检测该逻辑的特定组件(例如,网络API调用connect()、send() 和 recv())。RoI检测的优点是分析人员可以快速定位启动和操作恶意行为的特定代码区域。先前的工作只关注于创建临时签名,简单地将二进制文件标识为恶意软件或仅基于API调用的某些函数。这对于分析人员扩大他们的工作特别有用(即不仅仅依赖手动逆向工程和领域专业知识)。
(3) RoI Annotation
注释的目标是自动标记包含RoI的函数的行为,即识别恶意函数在做什么。由于分析人员为标记集群所执行的初始工作是一个长尾分布。也就是说,只需要前期做比较重要的工作,随着时间推移,工作量会减少。这个过程的优点很简单:它为分析人员提供了一种自动生成未知样本的报告及见解的方法。例如,如果恶意软件示例的变体包含与之前的恶意软件示例相似的逻辑(但对于分析人员来说看起来不同以至于不熟悉),我们的工具为他们提供了一种更快实现这一点的方法。
首先介绍了AutoEncode(AE)神经网络。此外,先前的工作已经证明,当自动编码器在良性分布上进行训练时,AE可以检测到恶意(异常)行为。我们的假设是,与良性二进制文件相比,恶意软件二进制文件将包含相似但独特的功能。
当使用大量良性样本训练AE后,给定一个随机的样本,可以利用公式(2)计算,超过MSE的即认为是恶意区域,突出显示ROI异常基本块。与先前识别整个样本为恶意区域的工作相比,我们识别了每个样本中的恶意区域。具体而言,我们计算的 localized MSE
定义如下:
We denote the mapped set of RoIs identified in sample x as the set
(1) Features
我们特征(c)的灵感来自于先前工作中发现的特征,即属性控制流图(attributed control flow graph,ACFG)特征。在这些工作中,ACFG特征被选择来执行二进制相似性,因为它们假设这些特征(由结构和数字CFG特征组成)将在多个平台和编译器上是一致的。
控制流图(Control Flow Graph, CFG)也叫控制流程图,是一个过程或程序的抽象表现,是用在编译器中的一个抽象数据结构,由编译器在内部维护,代表了一个程序执行过程中会遍历到的所有路径。它用图的形式表示一个过程内所有基本块执行的可能流向, 也能反映一个过程的实时执行过程。
Gemini
为了在二进制样本中定位恶意行为的位置,编码使用的特征必须一对一的映射回原样本。因此,作者将每个二进制文件表示为一个 m×c 的矩阵,该矩阵使用c个静态特征捕获前m个基本块以总结样本的behavior。m设置为20k个基本块,是因为95%的数据集样本具有20k或者更少的基本块, c设置为18个特征。
Our features consist of counts of instruction types within each basic block (a more detailed form of those extracted for ACFG features), structural features of the CFG, and categories of API calls (which have been used to summarize malware program behaviors).
结构特征2个,每个基本块的后代(offspring)数量和betweenness score,可以描述不同功能的控制流结构,比如网络通信(connect, send, recv)或文件加密(findfile, open, read, encrypt, write, close)。如图6所示。
算术指令3个,每个基本块基本数学、逻辑运算、位移指令的数量(“basic math”, “logic operation”, and “bit shifting”)。这些算术指令特征可以用来表示如何对更高层次的行为执行数学运算,以及数字如何与函数交互。例如,加密函数可能包含大量的xor指令,混淆函数可能包含逻辑和位移操作的组合等。
转移指令3个,每个基本块内堆栈操作,寄存器操作和端口操作的数量(“stack operation”, “register operation”, and “port operation”)。这些底层特征可描述更高级别函数的传输操作,比如函数的参数和返回值是如何与函数内其余数据交互的,从而描述更复杂的逻辑和数据操作。例如去混淆、解密函数可能设计更多move-related指令,C&C逻辑设计更多堆栈相关指令。
API类别10个, 包括"filesystem", “registry”, “network”, “DLL”,“object”, “process”, “service”, “synchronization”, “system information”, and "time"相关的API调用数量。调用不同类型API可执行不同类型功能,直接的表示了高层的函数行为,是很关键的特征。
(2) Model
Autoencoder使用U-Net模型,U-Net的优点是其在编码器和解码器之间有跳过连接(skip connections),对样本x可以跳过某些特征的压缩以在重构的x’中保持更高的保真度。
首先收集大量的良性样本,对每个二进制文件抽取上述18个静态特征用于表示该二进制文件。设有用feature表示的样本x,AE重构后得到x’,训练的目标是最小化重构损失,即输入x和输出x’之间的损失。
RoI Detection会在m个基本块中检测出一些异常基本块。这些基本块分别属于不同的函数,使用例如BinaryNinja的工具就可以确定ROI属于哪些函数,即认为这些函数可能是恶意函数,也就完成了恶意函数定位的任务。后续RoI Annotation就是对这些函数聚类,完成恶意函数行为标记(分类)的任务。
给定一个新样本x,我们希望识别其每个函数的行为(类别),并将其报告给Molly。由于标记所有的函数都是不实用的,所以我们只注释了少量的函数,并使用聚类分析来传播结果。
(1) Clustering Features聚类特性
假设一组脱壳恶意软件,按上述特征提取方式(18种特征)得到每个binary的特征表示,其中一个binary为x。
(2) Clustering Model
使用PCA将特征数从18降维至5,然后使用HDBSCAN算法对5维特征聚类。
接下来,我们将描述如何部署和使用它。
(1) Initialization
人工分析恶意软件手动打标,这些label注释到聚类训练集中,从而评估实验结果。换句话说,每个cluster只需要其中几个函数的label,就可确定整个cluster的label,即确定整个cluster中函数的恶意行为。
(2) Execution
当Molly收到一个新的样本x,DeepReflect会自动定位恶意函数并标注恶意行为。
接下来,Molly分析highlighted functions,从而实现:
根据CNET爬取PE文件,然后经过脱壳、过滤得到23307个良性样本。根据VirusTotal ,脱壳、过滤,在沙箱中执行获取家族标签。得到36396个恶意样本,4407个家族。
特征18个:
百度百科对roc的解释如下:ROC曲线指受试者工作特征曲线(receiver operating characteristic curve), 是反映敏感性和特异性连续变量的综合指标,是用构图法揭示敏感性和特异性的相互关系,它通过将连续变量设定出多个不同的临界值,从而计算出一系列敏感性和特异性,再以敏感性为纵坐标、(1-特异性)为横坐标绘制成曲线,曲线下面积越大(AUC area under roc curve),诊断准确性越高。在ROC曲线上,最靠近坐标图左上方的点为敏感性和特异性均较高的临界值。
ROC关注两个指标:
true positive rate ( TPR = TP / [TP + FN] ) ------正例分对的概率
false positive rate ( FPR = FP / [FP + TN] ) ------负例错分的概率
直观上,TPR代表能将正例分对的概率,FPR代表将负例错分为正例的概率,FPR 预测的是正例,但是实际上是负例。这部分在负例中占得比例。也就是将负例错分为正例的概率。
auc是什么意思
auc被定义为ROC曲线下的面积。往往使用auc值作为模型的评价标准是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而作为一个数值,对应AUC更大的分类器效果更好。
PE文件的全称是Portable Executable,意为可移植的可执行的文件。
为了评估DeepReflect自动编码器的定位能力,我们与一般方法和领域特定方法进行比较:
SHAP(分类模型解释工具)
Scott M. Lundberg and Su-In Lee. A unified approach to interpreting model predictions. In Advances in Neural Information Processing Systems, pages 4765–4774, 2017.
CAPA (FireEye公司的一种基于签名的工具,用于识别二进制文件中的恶意行为)
https://github.com/fireeye/capa
FunctionSimSearch(谷歌的函数相似度工具)
https://github.com/googleprojectzero/functionsimsearch.
静态的分析了三个恶意软件的源代码(rbot, pegasus, carbanak),分析了其中恶意组件的位置。结果如Figure 3,横线为80% True Positive Rate。
测试DeepReflect聚类的凝聚性,对恶意函数行为分类的能力。生成了22469个类簇,最大的簇包含6321个函数,最小的簇包含5个,如图10所示。在图10中,我们展示了类簇大小上的分布。图中显示,存在一个长尾分布(这在基于密度的聚类中很常见),其中最多的前10个集群占函数的5%。
在聚类质量分析中,89.7%的分析人员手工聚类功能与DeepReflect创建的功能相匹配。
DeepReflect缩小需要人工分析的函数的范围的能力。如图5所示,很多样本需要分析的函数数量降低了90%以上。平均降低85%。
为了评估DeepReflect是否为恶意软件家族间的关系及其行为提供了有意义的见解,我们探索了集群多样性。图4的左侧绘制了C中每个类簇中不同家族的数量。由图可知,在家族之间有许多共享的恶意软件技术和变体,部分恶意软件家族间分享了相同的函数,新的恶意软件家族的样本也可以被成功的分类。
使用LLVM混淆,继续测试模型的鲁棒性;同时使用对抗样本攻击,将包含本文使用的特征的良性样本的代码插入到恶意样本中,但均未对结果产生显著影响。
在本文中,我们介绍了DEEPREFLECT:一种用于本地化和识别恶意软件二进制文件中的恶意组件的工具。该工具是实用的,因为它不需要标记的数据集执行定位和少量的标签分类-从分析师的常规工作流程中逐步收集。我们希望这个工具和发布的代码将帮助世界各地的分析人员识别恶意软件样本中存在的位置和什么恶意功能。
七、个人总结:
这篇文章确实是恶意代码分析领域的顶级论文,写得非常棒,真心值得我去学习。同时,论文的写作方式及框架、实验都非常棒,工作量也很大,每个部分甚至都需要我们去理解,具体优点如下:
DeepReflect是一种新颖的用于定位(localize)和识别(identify)恶意二进制文件中恶意软件组件的工具,能有效提高静态(或手动)逆向工程的生产力。DeepReflect可以帮助分析人员实现:(1) 在静态恶意软件样本中自动定位和识别恶意行为,(2) 洞察分析不同恶意软件家族之间的功能关系。
本文对比实验非常详细和充分。一方面,本文同企业界和学术界经典的工具进行了对比实验,包括CAPA、SHAP和FunctionSimSearch,这也是系统安全论文经典的实验比较方式;另一方面,本文涵盖了五个方向(Reliability、Cohesiveness、Focus、Insight、Robustness)的详细实验分析,包括Appendix部分的各种特征案例、恶意家族行为共享分析都非常值得我们学习。
本文模型方面主要是AutoEncoder实现半监督学习,能在少样本标注的情况下识别更多的恶意行为或类别,有效减少了分析人员的手工标注压力。同时,采用了HDBSCAN聚类,并利用PCA降维,这些都是很常见的模型。但整个模型的框架非常精彩(图2胜万语),并且融合了RoI detection和RoI annotation描述故事,故事讲得非常棒。ROI区域之前在做APP地图热点开发时经常使用,没想到在二进制领域也有这么好的表达,确实ROI一个词就能准确表示想做的工作。或许,这种跨方向或学科专业词汇值得注意。
特征方面本文采用4大类(Structural Characteristics、Arithmetic Instructions、Transfer Instructions、API Call Categories)18个特征(之前论文已提出),并且提出了一种解释框架定位恶意软件重要部分的方法,该方法可以映射回原始二进制或控制流图的特征。就我而言,我们也应该思考,在进行恶意代码分析或系统安全研究时,如何尽可能全地覆盖研究问题来提出特征非常重要,并且结合我们的故事。