工作来源

NDSS 2021

工作简介

在利用沙盒进行恶意软件分析时,执行时间是一个非常关键的参数。时间过长会导致可分析数量下降,时间过短样本可能还未表现出行为。但一直以来这个时长的平衡点都是经验值,本文首次探讨时长对恶意软件分析的影响。通过测量系统调用和代码覆盖的变化,衡量恶意软件执行情况。再利用机器学习分析不同时间点观察到的事件的相关性。大多数样本运行时间少于两分钟或者超过十分钟,但是大多数行为(98% 的基本块)在前两分钟即可被观察到。

用于恶意软件分析的沙盒在安全分析中起着非常基础的作用,业界也有很多开源和商用的沙盒方案。尽管沙盒已经是一个经过充分研究的技术,但是如何最大程度利用沙盒来产生效果还是一个未研究的问题。随着样本数量不断增加,大家对样本的分析时间越来越短,但时间缩短对分析效果有多大的影响?这对恶意软件分析平台很重要。

基于 PANDA 平台收集了十万个样本的细粒度信息,系统调用的数量会随着时间线性增长,但在最开始的一两分钟内,就会有非常多的调用。整体的代码覆盖率在 10% 到 40% 之间,且传统上停滞执行代码对样本的影响并不大(接近3%)。从机器学习的角度上看,样本执行的前两分钟数据最有代表性。

工作背景

学术界的工作

  • 2007 年,Willems 等人在开创性的提出沙盒时指出:“我们发现,执行恶意软件两分钟可以产生最准确的结果”,但作者没有解释为什么选择了这个时间。

  • 在 2011 年 Rossow 等人执行样本时间长达一个小时,并且指出分析的前五分钟只有 23.6% 的连接端点和 95% 的网络协议,两分钟可能不足以收集足够的网络行为。

  • 2017 年,Kilgallon 等人利用 Cuckoo 沙盒分析了 3320 个样本,发现其中 82% 的样本只需要执行不到一分钟即可,尤其是 53% 的样本只需要执行 20 秒就够了。

通过对比多项工作,下图显示了沙盒执行时间与分析的样本数量。两者之间没有明确的关系,这证实了一个事实:即学术研究人员选择的样本执行时间更多的是作者个人判断的结果,而不是基于数据集大小决定的选择。

工业界的工作

学术界有公开披露的信息,而工业界似乎没有任何一家公司透露其内部分析恶意软件流程的细节。为此,我们写了一个探针程序(就像 Yokoyama 在 2016 年做的那样),该程序旨在定期(每 10 秒)向我们控制的服务器发出 HTTP 请求。请求中包含进程的 PID、执行样本生成的随机数、增量计数器,程序并没有收集有关沙盒、环境或者执行样本网络的其他信息。探针程序提交给 VirusTotal,在提交给 VirusTotal 之后,我们观察到了样本的多次重新执行。并且,根据 Yokoyama 的沙盒列表,一一提交了探针程序。

提交一个月后,探针程序被 32 个不同的沙盒分析过,根据结果可分为三类:

  • 有 23 个沙盒在固定的时间间隔就运行一次,时间从 30 秒到 4 分钟不等

  • 有 4 个沙盒控制 sleep 时间运行样本,会突然受到所有 HTTP 请求,样本运行时间在 2 分钟到 3 分钟不等

  • 有 5 个沙盒进行了重复分析,分析时间始终为 2 到 3 分钟,但都没有控制 sleep 时间

公司分析恶意软件的时间在 30 秒到 4 分钟不等,考虑到这些公司每天要分析的样本数量,为了可扩展性做出的妥协是可以理解的。

工作设计

模拟程序行为的常见方法是观察其 ABI 或系统调用,这提供了程序与环境作用的视图。新的系统调用不是新行为产生的标志,例如勒索软件可以打开大量文件,大量读取和写入文件,大量调用 NtOpenFile 时每次参数不同。而如果程序打开另一个可执行程序,然后打开多个文档渗出数据,此时对 NtOpenFile 的系统调用发生在完全不同的上下文中。

使用三种方法测量样本运行情况。首先,关注系统调用列表和高级操作(例如网络流量、文件系统活动或注册表操作)的出现。其次,收集实际执行的代码,捕获执行每个系统调用的上下文(如前所述,勒索软件的 NtOpenFile 调用可能来自相同的代码段,而用于感染和外带的 NtOpenFile 调用很可能来自不同的代码段),只有执行了新代码才算产生了新行为。系统调用和二进制代码块提供了一种捕获行为执行度量的方法,但表现出的多数行为并不一定就是样本的核心行为。最后,使用机器学习捕获那些可以将样本标记为恶意的新行为。如果执行前几分钟的信息可以带来更高的准确性,意味着这些行为更重要。

由于要跟踪程序的基本块执行,执行会被拖慢,经过测试最小减速 1.4 倍,最大减速 3.7 倍,远低于 PANDA 记录的 10 倍的最坏情况减速。

跟踪系统调用

为了收集所有系统调用,要以单个基本块 (BBs)的形式监控已执行的指令。所以使用 PANDA 加载样本并记录执行时间(阈值 15 分钟), 整体方案与 Malrec 类似区别在于使用 PANDA2。

  • PANDA 已有跟踪系统调用的插件,基于此修改后记录系统调用和发生的时间戳、进程 PID 和系统调用参数。

  • 许多系统调用都是结构体的指针,而 Windows 7 SP1 的偏移表中提取相关信息,还使用了 Petritsch 提供的关于如何从系统调用中检索网络数据包的方法。

  • 此外,PANDA 的 win7proc 插件可以推断出与进程、注册表、文件系统和共享内存相关的多个系统调用中的高级信息。

另外要对 kernel32 中的 sleep、sleepex 和 NtCreate 等函数进行 hook。

跟踪基本块覆盖

  • PANDA_CB_AFTER_BLOCK_TRANSLATE 提供了插桩基本块的方法。

  • 使用 Rekall 内存取证框架提取进程的内存镜像,并分析进程内存内容的虚拟地址描述树。通过分析其输出,提取所有标记为可执行但不属于任何命名模块的区域(例如共享库)。

  • 每个区域都由定制过的 SMDA(通过 PANDA 中已执行的地址边界内的代码区域,从而提高了反汇编器探索代码的能力)处理,SMDA 是一个开源递归反汇编器,经过优化可从内存 dump 中恢复代码。

机器学习

行为特征的顺序模式,如执行系统调用,在表征恶意软件上起着重要的作用。本文利用梯度增强回归树(100 棵树)以避免高密集的计算训练 LSTM 模型。此前的研究表明,级联梯度增强树在捕获输入特征、预测恶意软件类别之间的非线性关系方面表现很好,且与决策树相比,梯度树模型以对类不平衡问题的耐受性而闻名。这部分不是研究重点,我们也不认为我们的方案比现有方案好。

衡量指标

  • 相对覆盖率,执行到 t 时刻覆盖的行为数/分析结束的总行为数,包括系统调用(Rs)和代码块(Rc)两个维度

  • 绝对覆盖率,执行的代码/执行的代码+未执行的代码

  • 机器学习准确率,窗口内系统调用序列得到的分类是否准确

工作准备

希望数据集能够模仿安全公司定期分析的数据集。我们下载了提交给 VirusTotal 首次发现的样本。为了避免由于收集日而出现偏差,我们仅在 2000 个样本的一小部分中检索数据,并每隔几天重复一次该过程。这样,我们可以保证样品在收集后始终进行分析,从而最大限度地提高保持活动状态的概率,从而在执行时正确运行。由于我们的解决方案的可扩展性有限,需要长达一个小时才能完成每个样本的分析并生成有关其执行情况的详细报告,因此当我们收集到 10 万个样本时,我们就停止了数据收集。这总共花了 6 个多月的时间。总体而言,数据集包含 8.6 万个恶意样本和 1.4 万个良性样本。

在 VirusTotal 上至少 5 个 AV 检测识别为恶意的样本被认为是恶意的,而未被任何 AV 判定为恶意的样本被认为是良性的。六个月的时间,为 AV 提供足够的时间来调整其签名以覆盖新家族,从而最大限度地降低选择未知恶意文件判定为良性的概率。

利用 AVClass 对数据集中的样本归类了 806 个不同的恶意软件家族和 6989 个无法归类的样本。最多的家族只有 4000 个样本,数据集比较平衡。

工作评估

在 80 多个并行的虚拟机上,进行了 590 万分钟的恶意软件执行,收集了 2.05 亿次系统调用和 8400 万个基本块。

分析基于 2019 年 11 月至 2020 年 5 月期间提交的六个月内提交的新样本。因此,分析的结果应定期更新,以反映恶意软件生态系统或收集的数据类型的变化。

数据筛选

未测量使用反分析技术的样本数量,赛门铁克在 2014 年的报告显示反虚拟机技术正在下降,只有 18% 的样本拒绝在虚拟环境中运行。

保守地筛选出在执行过程中没有表现出足够活动的样本,只需要讨论运行的样本,不包括损坏的二进制文件、因参数错误或丢失依赖项而退出的程序,或检测到我们分析环境存在的恶意软件。这影响着我们的结论是建立在”成功执行的恶意软件”这个前提上的,必须牢记这一点。

  • 要求至少调用 50 个相关系统调用

  • 要求至少执行 4000 个基本块

共计删除了 8402 个(10.5%)恶意样本和 1456 个(10.9%)良性样本。

执行时间

大多数恶意软件在达到沙盒阈值之前就终止执行了,成功执行的样本中 81% 都不会达到十分钟的阈值,其中超过一半在一分钟内就停止了。

细节如下所示:

更细致的查看第一分钟内终止的样本,分别有 51% 的恶意样本和 67% 的良性样本显示出网络活动的迹象。且数据量大的家族占据了这些短时执行样本很大的比例,43% 的样本属于 TOP9 的家族,而这些家族只占到整个数据集的 29%。

下图显示了执行结束时每个示例(在 X 轴上)达到的绝对代码覆盖率(在 Y 轴上)。

该图再次确认了大多数样本在前两分钟内就退出或者一直执行到 15 分钟窗口结束。它还表明,在这两个极端中,绝对代码覆盖率变化不大,从第一分钟终止的样本的 18.8% 到图右侧的样本的 26.4% 不等。同样,良性样本在执行结束时的平均绝对代码覆盖率达到 24%。

下图为恶意样本的相对覆盖率对比图:

大多数基本块在一分钟内即可被观察到,但系统调用的增长相对缓慢。三分钟后,Rc 即超过 90% 而 Rs 仍然只有 16%。

所有样本的累计图如下所示:

系统调用

系统调用近乎线性增长,而基本块则是在前两分钟迅速增长,一分钟达到 97%,三分钟达到 99%。尽管有 19% 的样本运行时间超过 10 分钟,但在 10 到 15 分钟之间,基本块覆盖度的增幅为可忽略不计的 0.2%。故而,调用的系统调用多,并不意味着这些系统调用触发了新功能,很可能是此前功能的重复。

只统计执行到 15 分钟结束的样本,如下所示:

代码覆盖率

那些一直运行到停止沙盒的样本,超过 90% 的基本块已经在第一分钟访问过了。

下图显示了我们在 15 分钟时间跨度内在一定时间分别观察到 100%、90% 和 75% 基本块的样本百分比:

两分钟后有 71% 的样本终止了执行,但超过 80% 的样本,已经观察到了 100% 的相对代码覆盖率。

下图比较了使用字节和基本块两种方式评估的差异:

相对代码覆盖度指标几乎没有差异,对绝对代码覆盖的影响更为明显。

延迟执行的影响

14% 的恶意样本和 6% 的良性样本至少执行 1 次 sleep。下图显示了对 sleep 类函数的不同处理方式的影响:

sleep 时间对代码覆盖的影响几乎可以忽略不计,而在 15 分钟内收集的系统调用累计数量减少了约 10%。在 11874 个表现出 sleep 行为的恶意软件样本中,75% 的样本延迟执行 1 分钟,3.1% 的样本延迟执行超过 3 分钟,2.3% 的样本延迟执行超过 10 分钟。

我们只跟踪代码注入到与恶意软件同一进程树的进程中,总共有 19% 的样本写入其他进程的内存,只有 2% 的样本将代码注入到自己进程树外的进程中,这部分能够部分避开我们的数据收集。

恶意代码家族

下图显示了三个不同家族(sivis、mepaow、blackmoon)的结果:

不同的家族表现出来的行为和覆盖差异很大,很难预测样本会运行多长时间以及会触发多少代码,即便在已知的家族也很难。

网络行为

执行了 15 分钟的样本中的 22.45% 在整个时间段内都与远程服务器联系,可分为三类:

  • 10.45% 的长时间运行样本,接收远程服务器的命令,并表现出一些不断重复的模式,例如打开和写入文件

  • 9.71% 的长时间运行样本大概是僵尸网络的样本,与多个 IP 地址连接,有些是失陷主机,有些是 C&C 服务器

  • 2.29% 的长时间运行样本,大部分时间都使用 NtWaitForSingleObject/NtWaitForMultipleObject 系统调用,即向服务器发送请求并等待服务器的响应

文件操作

当达到 15 分钟时,总共有 40.17% 的样本在整个执行时间内一直重复文件操作。19.75% 的长时间运行恶意样本确实使用图形界面与用户通信并接收输入,因为我们使用导入地址表来处理,会被加壳影响,所以这是个下限。最后确认 11.19% 的样本其 15 分钟的持续时间是合理的,占到触及 15 分钟阈值的样本的 93.57%。对于剩余的 6.43%,无法识别出一个共同的模式。

机器学习评估

如前所示,大量良性和恶意样本运行时间均小于 5 分钟。为了防止设计的分类器因样本的停止而过拟合,我们决定只处理运行至少 5 分钟的样品,并使用前 5 分钟来了解是否在较长的分析时间内观察到更翔实的行为。

利用在前 1、2、3、4 和 5 分钟越来越大的时间窗口内分别观察到的系统调用评估恶意软件分类的准确性,如下所示:

在大多数情况下,执行恶意软件样本两分钟足以观察其大多数行为,在此窗口期间收集的数据也为我们的机器学习分类器带来了最佳的准确性。长时间的执行时间(5分钟或以上)往往是没有道理的,只会增加整体分析时间。

工作思考

本文主要发现即在绝大多数情况下,两分钟的阈值就足以分析新收集的恶意软件样本。当然,实际也需要考虑可用资源的数量。具体如下所示:

  • 无论良性样本还是恶意样本,要么运行时间短于两分钟或者超过十分钟

  • 系统调用会在程序执行期间持续增加,但是代码覆盖范围往往在前两分钟就趋于稳定

  • 延迟执行代码只影响 2-3% 的样本,一些商业沙盒也作出了针对性处理

  • 在沙盒内单次执行通常会覆盖其代码的 10% 到 40%

  • 收集数据的数量与质量大多集中在执行的前两分钟

长期以来,分析人员对沙盒中的恶意软件应该运行多长时间存在争议,但大多数都赞同需要运行 2-3 分钟,但这一经验值没有具体的数据支撑。本次通过大量详实的数据分析证实了能够正常执行的样本在 2-3 分钟这一时间段确实能够支撑跑出效果,可以根据资源的限制进行动态调整。

论文原文:https://www.ndss-symposium.org/wp-content/uploads/ndss2021_4C-5_24475_paper.pdf

声明:本文来自威胁棱镜,版权归作者所有。文章内容仅代表作者独立观点,不代表士冗科技立场,转载目的在于传递更多信息。如有侵权,请联系 service@expshell.com。