[系统安全] 三十九.恶意代码同源分析及BinDiff软件基础用法

2022-11-25 10:04:58 浏览数 (2)

十一月,冬至快乐,继续加油!

该系列文章将系统整理和深入学习系统安全、逆向分析和恶意代码检测,文章会更加聚焦,更加系统,更加深入,也是作者的慢慢成长史。漫漫长征路,偏向虎山行。享受过程,一起加油~

前文详细介绍Metasploit技术。这篇文章将详细讲解恶意代码同源分析和BinDiff软件基础用法,首先介绍恶意代码同源分析原理,其次介绍BinDiff工具的原理知识和安装过程,最后介绍BinDiff软件基础用法和Diaphora开源工具。希望这篇文章对您有帮助,也推荐大家去阅读论文,且看且珍惜。

文章目录:

  • 一.恶意代码同源分析 1.恶意代码同源分析简述 2.基于同源判定的恶意代码溯源 (1) 特征提取 (2) 特征预处理 (3) 相似性计算 (4) 同源判定
  • 二.BinDiff软件安装及原理 1.原理知识 (1) 通用匹配策略 (2) 函数匹配 (3) 基本块匹配 (4) 置信度和相似性 (5) IDA的BinDiff插件 2.安装过程
  • 三.BinDiff软件基础用法
  • 四.Diaphora开源工具
  • 五.总结

作者的github资源:

  • 逆向分析: https://github.com/eastmountyxz/ SystemSecurity-ReverseAnalysis
  • 网络安全: https://github.com/eastmountyxz/ NetworkSecuritySelf-study

作者作为网络安全的小白,分享一些自学基础教程给大家,主要是关于安全工具和实践操作的在线笔记,希望您们喜欢。同时,更希望您能与我一起操作和进步,后续将深入学习网络安全和系统安全知识并分享相关实验。总之,希望该系列文章对博友有所帮助,写文不易,大神们不喜勿喷,谢谢!如果文章对您有帮助,将是我创作的最大动力,点赞、评论、私聊均可,一起加油喔!

声明:本人坚决反对利用教学方法进行犯罪的行为,一切犯罪行为必将受到严惩,绿色网络需要我们共同维护,更推荐大家了解它们背后的原理,更好地进行防护。(参考文献见后)


一.恶意代码同源分析

1.恶意代码同源分析简述

当前恶意代码呈爆炸式增长,传统基于特征码与签名的恶意软件分析技术易已不能满足新兴的恶意代码检测需求,主动防御、云安全、启发式扫描等技术被提出。然而,安全技术人员通过分析大量的恶意样本发现,许多新出现的恶意代码是已有恶意代码的变种。恶意代码作者会通过变形、加壳、多态等技术手段混淆已有恶意代码的特征,企图逃避安全软件的分析检测。

尽管基于行为的主动防御、虚拟机脱壳等技术可以检测经过变形加壳的恶意代码,但如何快速有效地鉴别这些恶意代码之间的关联性,确定相似代码的同源性,进而实现恶意家族分类是一个值得研究的话题 [1]。

恶意代码同源分析旨在判断不同的恶意代码是否源自同一套恶意代码或是否有同一个作者、团队编写,其是否具有内在关联性和相似性。

  • 学术界主要通过代码相似性计算实现恶意代码同源分析,比如系统调用图、API调用图、数据依赖图、控制流图、代码执行流程等,再通过图匹配或聚类算法实现家族分类。
  • 产业界更多通过恶意代码的结构特征进行同源判定,比如C&C地址、哈希值、调用信息路径、互斥量名称等。

下图展示了钱雨村大佬提出的恶意代码同源分析方法,包括提取行为特征和控制流程,其重点关注的行为操作及对应API如表1所示。


2.基于同源判定的恶意代码溯源

此外,宋文纳老师给出了学术界通过同源分析实现恶意代码溯源的基本流程。通常而言,学术界会采用静态或动态的方式获取恶意代码的特征信息,通过对恶意代码的特征学习,建立不同类别恶意代码的特征模型,通过计算待检测恶意代码针对不同特征类别的相似性度量,指导恶意代码的同源性判定。常见的恶意代码溯源主要包括4个阶段:特征提取、特征预处理、相似性计算、同源判定,各阶段间的流程关系如下图所示。

上图是将溯源对象Windows平台的PE恶意文件或Android平台的APK恶意文件输入溯源系统,经过特征提取、特征预处理、相似性计算、同源分析获取溯源结果,最终判定攻击家族或作者。

(1) 特征提取

特征提取是溯源分析过程的基础,具有同源性的恶意代码是通过它们的共有特征与其他代码区分开来的。所提取的特征既要反映出恶意代码的本质和具有同源性恶意代码之间的相似性,又要满足提取的有效性。

依据溯源目的,溯源特征提取包括溯源家族的特征提取和溯源作者的特征提取。Faruki等在字节码级别提取统计性强的序列特征,包括指令、操作码、字节码、API代码序列等。Perdisci R等通过n-gram提取字节码序列作为特征。Ki Y等提出了捕获运行过程中的API序列作为特征,利用生物基因序列检测工具ClustalX对API序列进行相似性分析,得到恶意代码的同源性判定。DNADroid使用PDG作为特征,DroidSim是一种基于组件的CFG来表示相似性代码特征,与早期的方法相比,该系统检测代码重用更准确。

(2) 特征预处理

特征提取过程中会遇到不具有代表性、不能量化的原始特征,特征预处理针对这一问题进行解决,以提取出适用于相似性计算的代表性特征。特征预处理一方面对初始特征进行预处理,另一方面为相似性计算提供基础数据。常见的特征类型包括序列特征和代码结构特征。

序列特征预处理: 包括信息熵评估、正则表达式转换、N-grams序列、序列向量化、权重量化法等,序列特征预处理会将初始特征中冗余特征消除、特征语义表达式增强、特征量化等以便于进行相似性计算。L. Wu通过分析恶意软件敏感API操作以及事件等,将API序列特征转换为正则表达式,并在发生类似的正则表达式模式时检测恶意代码。IBM研究小组先将N-gram方法应用于恶意软件分析中,使用N-gram的统计属性预测给定序列中下个子序列,从而进行相似度计算。Kolosnjaji等提出对API调用序列进行N-gram处理获取子序列,采用N-gram方法将API调用序列转换为N-gram序列,实现过程下图所示。

代码结构特征预处理: 在相似度比较时存在边、节点等匹配问题即子图同构算法复杂性,同时代码结构特征中存在冗余结构,因此除去冗余、保留与恶意操作相关的代码结构是预处理的主要目的。常见的方法包括API调用图预处理、CFG图预处理、PDG图预处理等。


(3) 相似性计算

溯源旨在通过分析样本的同源性定位到家族或作者,样本的同源性可以通过分析代码相似性来获取。相似性计算旨在衡量恶意代码间相似度,具体为采用一种相似性模型对恶意代码的特征进行运算。根据预处理特征类型的不同以及溯源需求、效率、准确性等差异,采用不同的相似性运算方法。

目前比较流行的相似性计算方法主要集中在对集合、序列、向量、图等特征表现形式的处理。Qiao等基于集合计算相似性,在不同恶意样本API集合的相似性比较中采用了Jaccard系数方法,将为A、B两个集合的交集在并集中所占的比例作为相似度,比例值越大,证明越相似,如公式所示。

Faruki等提出了采用SDhash相似性散列技术构建样本的签名序列,并采用汉明距离法对序列进行相似性计算,从而识别同源性样本。Suarez-Tangil 等用数据挖掘算法中向量空间模型展示家族的恶意代码特征形式,将同家族提取出来的具有代表性的CFG元素作为特征中维度,采用余弦算法对不同家族的向量空间模型进行相似度计算,根据余弦值来判断它们的相似性,从而识别出相似性样本,进而归属到对应的家族。用于比较向量的余弦相似度反映了恶意代码间的相似性,其具体公式如公式所示。

Cesare等提出了最小距离匹配度量法,比较不同样本的CFG图特征的相似性。Kinable等通过静态分析恶意代码的系统调用图,采用图匹配的方式计算图相似性得分,该得分近似于图的编辑距离。利用该得分比较样本的相似性,采用聚类算法将样本进行聚类,实现家族分类。

(4) 同源判定

学术界常见的同源判定方法主要包括基于聚类算法的同源判定、基于神经网络的同源判定等。Kim等采用DBSCAN算法对基于调用图聚类,发现类似的恶意软件。Feizollah等提出采用层聚类算法,构建家族间演化模型,进而发掘家族功能的演化。Niu等提出了层次聚类和密度聚类算法结合的快速聚类算法对操作码序列特征进行聚类,以识别恶意软件变体,该方法识别变体效率较高。

神经网络是一种多层网络的机器学习算法,可以处理多特征以及复杂特征的同源判定。基本思想为:将样本特征作为输入层数据,然后不断调整神经网络参数,直到输出的样本与该样本是一种同源关系未为止。它会将恶意代码特征送输入层,即可判断恶意代码的同源性.。赵炳麟等提出了基于神经网络的同源判定方法,其整体实现框架如下图所示。


二.BinDiff软件安装及原理

BinDiff和DeepBinDiff是两个经典的恶意代码同源分析工具,接下来作者将详细介绍BinDiff软件的原理知识及安装流程。

1.原理知识

首先,推荐大家认真学习BinDiff官方用法文档。

  • https://www.zynamics.com/bindiff/manual/

BinDiff是一款领先的可执行文件或二进制文件分析和比较工具,适用于补丁分析、恶意软件变体分析或对两个可执行文件之间的逆向分析。由于BinDiff是IDA的附加产品,它需要安装Hex-Rays IDA Pro 7.4以上版本。请注意,对旧版本 IDA Pro 的支持已停止,最新支持IDA Pro 7.6版本。

BinDiff将来自IDA的函数显示为突出的流程图,颜色表示边缘和代码块的特殊属性,如下图所示:

BinDiff处理可执行文件的抽象结构,忽略反汇编中的汇编级指令。基于函数(标准化)流程图的结构,每个函数都得到一个签名。签名包括:

  • 代码块数目(Number of codeblocks)
  • 代码块之间的边数(Number of edges between codeblocks)
  • 子函数调用次数(Number of calls to subfunctions)

一旦生成了两组签名(针对两个可执行文件),就会创建初始匹配。这是通过选择每个可执行文件中具有共同特征的所有函数的子集来实现的。如果一个签名在两个被检查的签名子集中有且仅出现一次,则创建一个匹配。

在此步骤之后,将利用调用图Callgraph(包含有关函数之间调用关系的信息图)来生成更多的匹配:如果已知一个匹配,则检查从匹配函数调用的所有函数的子集。这些子集比所有函数的集合要小得多,因此找到新的唯一匹配的可能性要高得多。重复此过程,直到找不到新的匹配为止。

换句话说,当您成功运行BinDiff后,您将拥有一个相互关联的函数列表,以及两个无法关联的函数列表。

(1) 通用匹配策略

BinDiff有一个适合生成匹配的函数属性列表。它从全局级别开始,考虑二进制文件的所有函数,并计算每个函数的第一个属性。有以下几种可能的结果:

  • 该属性在两个二进制文件中都是唯一的,则函数匹配。
  • 该属性在两个二进制文件中多次出现,则匹配不明确。BinDiff继续“Drill Down(类似于递归)”步骤,仅考虑该属性的等效函数集。Drill Down意味着尝试下一个最佳属性,直到我们用完算法、唯一匹配函数,或者因为属性不匹配其任何函数而导致集合解散。
  • 该属性在另一个二进制文件中没有匹配项,则该函数保存在不匹配集合中。

在初始全局匹配步骤之后,考虑每个新匹配的父母(调用者)和孩子(被调用者)。BinDiff尝试通过对每个父项和子项执行如上所述的“向下钻取”步骤来匹配父项和子项集中的函数。最后BinDiff对所有新匹配的函数执行基本块匹配,并匹配从匹配的基本块调用的函数(函数:调用引用匹配)。这结束了单个属性的全局匹配。使用下一个最佳属性对剩余的不匹配函数重新启动整个过程。


(2) 函数匹配

函数属性有两种用法:函数或边。 如果源函数和目标函数属性匹配,则会尝试匹配边(Edge matching),即调用图中的调用或流程图中的跳转。因此,边匹配是较强的判断依据,通常会产生更好的匹配。然而,由于图中每个顶点都可能有很多条边(对于调用图尤其如此,因为边的数量通常与顶点的数量成超线性增长),所以边匹配可能非常缓慢。

如果您确实遇到某些二进制文件的性能问题,您应该首先尝试禁用基于边缘匹配的算法。此外,可以将有问题的二进制文件发送给谷歌的zynamics团队。正是该团队发明了BinDiff,后被谷歌公司收购。

根据结果匹配质量大致排序的函数匹配算法:

  • 函数:哈希匹配(hash matching) 根据原始函数字节的哈希值匹配函数。该算法匹配的两个函数在字节级别上应该是相同的。 匹配质量:非常好 算法性能:非常好
  • 函数:函数名哈希匹配(name hash matching) 根据函数名的哈希值匹配函数。只考虑真实名称,不使用反汇编程序自动生成的名称。这是少数几个可以匹配导入函数(二进制文件中没有实际主体的函数)的算法之一,错误匹配的可能性很小。 匹配质量:非常好 算法性能:非常好
  • 函数:控制流图边的MD索引(edges flowgraph MD index) 根据源函数和目标函数的MD索引匹配调用图的边。因此,两个结构相同的函数之间的调用是匹配的。 匹配质量:非常好 算法性能:中等
  • 函数:边缘调用图MD索引(edges callgraph MD index) 根据调用图MD索引匹配调用图的边。这意味着,在两个二进制文件中,指向该特定调用的调用图在结构上是相同的。匹配质量取决于通向该边的调用堆栈的深度:深度越深,错误匹配的可能性越小。 比赛质量:好 算法性能:中等
  • 函数:MD索引匹配(MD index matching,flowgraph MD index, top down) 根据结构的MD索引来匹配函数。由于MD索引采用拓扑图排序作为其输入之一,因此可以通过从入口点(自顶向下)调用或从出口点(自底向上)调用将图顶点排序为不同级别来进行参数化。 比赛质量:好 算法性能:非常好
  • 函数:素数签名匹配(prime signature matching) 根据函数的指令素数乘积匹配函数。每个助记符都被分配一个唯一的小素数。对于函数的所有指令,这些质数都要相乘。这将产生一个结构不变、指令顺序无关的产品,随后将其用作匹配属性。 匹配质量:好 算法性能:非常好


(3) 基本块匹配

flow graph级别的基本块匹配在算法上与函数匹配非常相似。全局属性匹配之后是向下钻取的(drill downs),并尝试在已经匹配的基本块上减少的父/子集来执行匹配。

基本块匹配算法大致按匹配质量排序:

  • BasicBlock:边素数乘积(edge prime product) 如果源基本块和目标基本块指令素数乘积匹配,则流程图的边匹配。因此,两个基本块都包含相同的指令,可能顺序不同。 匹配质量:非常好
  • BasicBlock:哈希匹配(hash matching,最少 4 条指令) 基本块根据其原始字节的二进制哈希进行匹配。仅用于具有至少4条指令的基本块。 匹配质量:非常好
  • BasicBlock:素数匹配(prime matching,最少 4 条指令) 基本块根据它们指令的素数乘积进行匹配。仅用于具有至少 4 条指令的基本块。 匹配质量:非常好
  • BasicBlock:调用引用匹配(call reference matching) 如果基本块调用了至少一个函数,并且所有调用的函数都已匹配,则它们匹配。 匹配质量:非常好
  • BasicBlock:字符串引用匹配(string reference matching) 如果基本块引用至少一个字符串,并且该字符串在两个二进制文件中相同,则基本块匹配。 匹配质量:非常好


(4) 置信度和相似性

BinDiff呈现的置信度值是平均算法置信度(匹配质量),主要用于查找由sigmoid压缩函数加权的特定匹配。

这些值并不是简单的平均,因为在一个完全匹配的函数/二进制文件中,很少有单一的弱匹配,也不应该过多降低置信度。类似地,即使是一些强匹配也不会“拯救”主要由地址序列和类似的弱算法匹配的二进制对。

函数相似度将考虑以下因素的加权和:

  • 权重~25%:匹配的流图边占总边的比例
  • 权重~15%:匹配的基本块占总基本块的比例
  • 权重~10%:匹配指令占总指令的比例
  • 权重~50%:控制流图MD指数差值

最终结果是相似度乘以置信度,如果由弱算法产生,即使看似好的匹配也不值得信任。

整个二进制文件的相似度是一个加权和,考虑了以下因素:

  • 权重~35%:匹配的流图边对总边的比例
  • 权重~25%:匹配的基本块占基本块总数的比例
  • 权重~10%:匹配函数占总函数的比例
  • 权重~10%:匹配指令占总指令的比例
  • 权重~20%:调用图 MD 指数的差异

再次乘以置信度。计数仅考虑非库函数。这是为了避免夸大仅使用相同运行库(runtime library)但在其他方面完全不同的二进制文件的相似性。


(5) IDA的BinDiff插件

同样,我们可以在IDA中使用BinDiff 插件。在启动IDA后,加载一个数据库并按Ctrl 6以显示插件主窗口。如下图所示,左边是IDA窗口的BinDiff插件,右边是执行Diff后的效果,可以通过“Diff Database”实现比较。

后续的博客会结合案例详细介绍如何在IDA中使用BinDiff,这里仅给出部分功能截图。

  • The Unmatched Functions Subviews:查看未匹配函数的差异
  • The Matched Functions Subview:匹配函数子视图显示了差异结果,如相互关联的函数对。
  • Function Flowgraphs:BinDiff将来自IDA的函数显示为突出的流程图,颜色表示边缘和代码块的特殊属性。

2.安装过程

接下来介绍BinDiff的安装过程,具体的版本信息如下:

  • IDA v7.5
  • BinDiff 7

第一步,安装IDA工具。

第二步,从官网下载Windows安装包。

  • https://www.zynamics.com/software.html

第三步,双击“bindiff7.msi”程序点击下一步安装即可。

第四步,安装完成后打开BinDiff工具(可能需要重启)。

  • 如果需要管理员权限,用CMD实现:msiexec /package bindiff7.msi

第五步,在设置中绑定IDA的路径文件,接下来就可以正常使用BinDiff工具了。

  • C:SoftwareIDAPro7.5

三.BinDiff软件基础用法

接下来,我们将以两个简单的恶意软件为例,进行同源分析简单的尝试。

第一步,通过IDA导入可执行PE文件并导出idb文件。由于BinDiff需要导入idb文件,因此需要进行转换。

  • 样本1 HASH:02b****722
  • 样本2 HASH:9b7****866

第二步,打开BinDiff,新建工作空间。

第三步,新建Diff。

第四步,依次导入刚才的两个idb文件,主要对它俩进行同源分析。

导入结果如下图所示,建议全英文路径。

第五步,成功显示了两个样本的相似度,如下图所示。

同时可以查看更详细的信息,包括:

  • Call Graph
  • Matched Functions
  • Primary Unmatched Functions
  • Secondary Unmatched Fun

同源比较的内容主要集中于:

  • 函数(Functions)
  • 调用(Calls)
  • 基本块(Basic Blocks)
  • 跳转(Jumps)
  • 指令(Instructions)

第六步,在匹配的函数中查看详细信息,并分析同源函数,尽量选择非系统调用函数进行对比。

写到这里,一个简单的BinDiff案例就介绍结束。注意,本文是该系列的第一篇文章,以基础知识和原理介绍为主,后续博客会持续深入,包括基于机器学习的同源分析。


四.Diaphora开源工具

如果您想在IDA中实现源码分析,可以借助Diaphora开源工具,推荐大家试试。

Diaphora(διαφορά,希腊语为“差异”)是最先进的程序差异分析工具,作为IDA插件工作。它在SyScan 2015期间首次发布,并得到积极维护。Diaphora 支持 IDA 6.9 到 8.0,但主分支仅支持 IDA >= 7.4,因为代码仅在 Python 3.X 中运行。

下载地址如下:

  • https://github.com/joxeankoret/diaphora

官方文档:

  • https://github.com/joxeankoret/diaphora/blob/master/doc/diaphora_help.pdf

Diaphora拥有许多最常见的程序同源分析或差异分析(bindiffing)技术,包括:

  • Diffing assembler(汇编程序)
  • Diffing control flow graphs(控制流图)
  • Porting symbol names and comments(符号名称和注释)
  • Addig manual matches(手动匹配)
  • Similarity ratio calculation(相似度计算)
  • Batch automation(批量自动化)
  • Call graph matching calculation(调用图匹配计算)
  • Dozens of heuristics based on graph theory, assembler, bytes, functions’ features, etc…(数十种基于图论、汇编程序、字节、函数特征等的启发式算法)

此外,Diaphora也有许多独特的功能,在任何其他公共工具中都没有。以下是非广泛的独特功能列表:

  • Parallel diffing(相似差异)
  • Pseudo-code based heuristics(基于伪代码的启发式)
  • Pseudo-code patches generation(伪代码补丁生成)
  • Ability to port structs, enums and typedefs(能够移植结构、枚举和类型定义)
  • Diffing pseudo-codes (with syntax highlighting!)(伪代码差异、语法高亮)
  • Scripting support (for both the exporting and diffing processes)(脚本支持)

它也得到积极维护,以下是“正在制作”的功能列表:

  • 支持编译单元(查找和区分编译单元)
  • 与Pigaios直接集成
  • 基于“机器学习”的技术,逆向工程师可以教 Diaphora 什么是好的匹配或坏的匹配,以及如何搜索更多

最后给出简单的示例截图。下图是Diaphora对iOS 9.3.5中修复的 PEGASUS iOS 内核漏洞进行比较的截图:

这是Diaphora区分Microsoft公告MS15-034的旧屏幕截图:

这些是Diaphora区分Microsoft公告MS15-050的一些屏幕截图。

这是Diaphora将iBoot从iOS 10.3.3与iOS 11.0进行比较的屏幕截图。


五.总结

写到这里这篇文章就介绍介绍,希望对您有所帮助。作者最近太忙了,等忙完后好好写几篇安全博客,加油!

  • 一.恶意代码同源分析 1.恶意代码同源分析简述 2.基于同源判定的恶意代码溯源
  • 二.BinDiff软件安装及原理 1.原理知识 2.安装过程
  • 三.BinDiff软件基础用法
  • 四.Diaphora开源工具
  • 五.总结

十月应该是今年最忙碌的一个月了,好多事情。希望一切顺利,更希望十一月后能沉下心来读论文和写论文,继续加油,只争朝夕,重阳节后倍思亲。最近是真的冷,大家注意保暖。

学安全两年,认识了很多安全大佬和朋友,希望大家一起进步。这篇文章中如果存在一些不足,还请海涵。作者作为网络安全初学者的慢慢成长路吧!希望未来能更透彻撰写相关文章。同时非常感谢参考文献中的安全大佬们的文章分享,深知自己很菜,得努力前行。

祝大家冬至快乐,加油喔!爱你们~

(By:Eastmount 2022-11-07 夜于地球 )

参考文章如下,感谢这些大佬。

  • [1] 钱雨村, 彭国军, 王滢, 梁玉. 恶意代码同源性分析及家族聚类[J]. 计算机工程与应用, 2015, 51(18): 76-81.
  • [2] 宋文纳, 彭国军, 傅建明, 等. 恶意代码演化与溯源技术研究[J]. 2019, 30(8): 2229−2267.
  • [3] 苏打呀. Bindiff原理及官方文档手册[EB/OL]. (2021-07-26). https://blog.csdn.net/weixin_49393427/article/details/119108295.
  • [4] BinDiff官方文档:https://www.zynamics.com/bindiff/manual/
  • [5] BinDiff下载地址:https://www.zynamics.com/bindiff.html
  • [6] Chris Eagle. The IDA Pro Book. 2nd Edition. No Starch Press. July 2011. 1-59327-289-8. 672.
  • [7] Thomas Dullien and Rolf Rolles. Graph-based comparison of Executable Objects. http://www.zynamics.com/downloads/bindiffsstic05-1.pdf. 2005.
  • [8] Halvar Flake. Structural Comparison of Executable Objects. http://www.zynamics.com/downloads/dimva_paper2.pdf. 2004.
  • [9] https://github.com/joxeankoret/diaphora
  • [10] https://github.com/joxeankoret/diaphora/blob/master/doc/diaphora_help.pdf

0 人点赞