文献翻译之二。

摘要

恶意软件是当今互联网世界中最大的安全威胁之一,部署有效的防御性解决方案需要对不断增加的恶意软件样本进行快速分析。在变异的恶意软件快速增长的情况下,由于基于签名的静态分析系统的效率急剧降低,对恶意软件的分析变得更加复杂。尽管恶意软件动态分析是一个非常有效的替代方法,但由于分析样本的数量不断增加,给硬件资源带来了巨大的负担,该方法也面临着巨大的挑战。与此同时,现代的恶意软件可以在检测到监控的环境的同时,还能隐藏在系统没有监控到的角落里。

在本文中,我们提出 DRAKVUF,这是一种新颖的动态恶意软件分析系统,旨在通过基于最新的硬件虚拟化扩展和 Xen 虚拟机管理程序来应对以上挑战。我们提出了一种通过启动执行恶意软件样本而不会在分析机器中留下任何痕迹来提高隐身性的技术。我们还提出了一些新颖的技术,通过扩展监视范围到内核内部函数,并通过内核的堆分配件事文件系统访问,以此来消除内核中 rootkit 制造的一些监视盲区。通过对近期恶意软件样本的广泛测试,我们发现 DRAKVUF 在节省硬件资源方面取得了显著的改进,同时为现代恶意软件行为的分析提供了更隐秘和深入的了解。

1、简介

在过去的几十年里,恶意软件已经成为了犯罪组织用于网络犯罪的主要工具。由于安全漏洞广泛发生的财务影响,对恶意软件内部的深入了解对于设计和部署有效的防御解决方案至关重要。但是,数量庞大的恶意软件样本为手动逆向工程无法比拟的挑战。由于现代恶意软件日益变异的性质,使得使用静态分析创建签名以快速检测的方法不再有效,同时也使得在恶意软件感染之间的二进制文件得以重构。又伴随着反调试技术的发展,制定有效解决方案所需要的时间更多了。

自从变异的恶意软件快速地扩散,动态恶意软件分析成为了一种通过观察恶意软件样本在隔离环境中的行为来理解和分类恶意软件的有效手段。执行恶意软件样本和宿主操作系统之间的交互,使得动态恶意软件分析系统可以收集一些行为特征来帮助制定防御步骤。因而,动态恶意软件分析依赖于收集信息的广泛性和保真度。

因为动态恶意软件分析系统已经被广泛应用,恶意软件慢慢开始出现拒绝在沙箱环境中执行或者修改其运行时的行为来误导分析系统,逐渐进化出了可以检测到分析系统并逃逸的特性。因而,非常重要的一点是,动态恶意软件分析系统需要提供一个隐蔽的环境来隐藏收集到的信息,而不被执行样本发现。但是,最近几年的一些满足隐蔽性要求的分析系统对资源有一定要求,且需要手动和恶意软件样本进行交互,为进行可伸缩,自动化的动态软件分析构造了一道障碍。

在本文中,我们提出了 DRAKVUF,一个动态恶意软件分析系统,其使用了最新的硬件虚拟化扩展来提供一个透明和可伸缩的环境,且能对恶意软件样本进行深入的分析。通过利用虚拟化扩展的有效性来隐藏监视环境,DRAKVUF 可以对用户空间和内核空间的恶意软件都能有深入的了解。此外,DRAKVUF 通过在内存和磁盘上应用写时复制的技术吗,实现了较小的资源利用率以及对分析虚拟机的快速部署。

我们的工作作出了以下贡献:

  • 我们提供了具有隐蔽性和防篡改的监视引擎的部署细节,其位用户空间和内核空间的恶意软件以及 rootkit 的执行提供了深入的了解。
  • 我们介绍了一种新颖的技术来直接监视内核中的堆分配,以此来检测由 rootkit 创建的隐藏结构。借助这项新技术,DRAKVUF 还获得了只通过内存自省就能观察文件系统访问的能力。
  • 我们展示了实用主动虚拟机自省的一种新技术的应用,该技术可以启动恶意软件样本的执行,而不会在分析环境中留下任何痕迹。
  • 我们使用了共享硬件资源评估系统,以通过写时复制和磁盘进行大规模恶意软件分析。
  • 我们对一组野生的恶意软件样本进行了详细的实验,这些样本展现出了系统的功能。

本文的其余部分安排如下。在第 2 节中我们确定并概述系统的设计。在第 3 节我们提供了有关系统实现的详细信息。第 4 节中介绍了使用最新的野生恶意软件样本执行的实验以及系统的性能评估。第 5 节介绍本文的相关工作。第 6 节介绍了未来相关的工作,最后第 7 节提出一个简短的总结。

2、系统设计

DRAKVUF 的目标是提供一个自动化动态恶意软件分析的平台。这个分析必须满足透明性和高效性的特点,这样可以更加深入地观察分析虚拟机(VMs)系统组件的运行时行为。DRAKVUF 是使用虚拟化技术实现的,但在本文中,我们认为对虚拟机管理器(VMM)和较低级别的系统组件的攻击不在范围之内。在基于虚拟化的恶意软件研究中,通常标准的假设是认为 VMM 值得信赖,因此在 DRAKVUF 中,我们还考虑了 VMM 暴露给非特权访客的有限接口,从而为不受控制的恶意软件传播提供了合理的屏障。

我们为我们的系统设置的一些需求如下定义:

  • (R1)可伸缩性:分析样本的性能开销应保持最小,而同时分析大量样本的能力应最大化。
  • (R2)保真性:数据收集必须捕获范围广泛的运行时信息,同时还要提供抵御篡改的能力,以便可以准确检查分析系统的状态。
  • (R3)隐蔽性:受监视的环境不应能够检测到 DRAKVUF 的存在。
  • (R4)隔离性:应该讲 DRAKVUF 和分析虚拟机高度隔离,以防篡改。

DRAKVUF 通过使用虚拟化技术来实现,因为虚拟化提供了动态恶意软件分析中可以利用的很多好处。与创建物理机镜像和还原镜像相比,创建和恢复分析容器可以更快完成。虚拟化提供了一种观察恶意软件执行的方法,即直接通过提供对虚拟机硬件组件状态的外部访问,通常被称为虚拟机自省技术。

为了利用虚拟化的上述又是,DRAKVUF 建立在开源的 Xen 虚拟机管理器之上。系统组件的高层组织如图 1 所示。为了允许快速部署分析虚拟机,DRAKVUF 通过 Xen 的本地写时复制(CoW)内存接口和 Linux 逻辑卷管理器(LVM)副本创建完整的虚拟机克隆。通过写时复制使用完整的虚拟机克隆可以优化硬件的实用,因为仅在需要时才分配附加资源,从而满足(R1)中的要求。虽然分析虚拟机的内存和磁盘的静态组件是共享的,但写时复制的实用可以防止克隆虚拟机相互交互,因为它们无权访问分配给其他克隆的独占资源,因此满足(R4)的要求。

DRAKVUF 在控制域(DOM0)中运行,以通过 LibVMI 库进行直接内存访问(DMA)。在控制域中,DRAKVUF 还可以访问虚拟机监控程序功能,以控制 CPU 提供的虚拟化扩展,例如扩展页表(EPT)。为了方便访问与分析虚拟机的执行相关事件,DRAKVUF 使用多种技术组合以在需要时触发并将控制权转移到管理程序(VMEXIT)。我们采用的核心技术是使用断点注入,其中将 #BP 指令(INT3,指令操作码是 0xCC)写入虚拟机的内存中被认为是感兴趣的代码位置。

这些位置的自动确定方法将在第 3.2 节中进一步介绍。通过配置 CPU 在执行断点时发出 VMEXIT 并将 Xen 配置为将此类事件转发到控制域,DRAKVUF 能够捕获分析虚拟机中任何代码的执行。迄今为止,#BP 注入技术仅用于隐身调试。在 DRAKVUF 中,我们是第一个将该技术用于整个操作系统并自动执行跟踪的团队,同时成功演示了它如何成为主动虚拟机自省的关键组件。借助这项技术,DRAKVUF 可以深入了解内核空间和用户空间的代码执行,从而满足(R2)的要求。

在先前的研究中,通过更改客户机对时间戳计数寄存器(TSC)的视图,可以有效地解决由于将客户机陷入虚拟机管理器而导致的时间偏差。尽管仍然可以使用其他时间资源,尤其是在允许网络访问的情况下,但我们认为此问题不在本文的讨论范围之内。在 DRAKVUF 中,我们解决了一个以前被忽视的问题,即开始执行恶意软件样本后,却没有留下任何痕迹的情况:到目前为止,该任务要么必须手动执行,否则会阻碍系统的可伸缩性。或者使用可以检测到的客户机内部代理。DRAKVUF 不需要使用在客户机内部的代理程序,通过启用自动执行样本来解决这一问题,因为此类代理程序的存在可用于检测监视环境。相反,DRAKVUF 通过 #BP 注入使用主动虚拟机自省来劫持虚拟机中的任意进程以启动恶意软件样本,该技术将在第 3.3 节中进一步介绍。通过使用虚拟机中运行的现有进程,DRAKVUF 不会在分析虚拟机中引入新的代码或工作,从而极大地提高了隐蔽性,满足了(R3)的要求。

众所周知,恶意软件可以使用外部的输入和资源来启动,因此还需要提供对分析虚拟机的网络访问。为了保持 DRAKVUF 和分析虚拟机之间的隔离,如(R4)所述,网络流量通过运行 Open vSwitch 的域,并利用 Intel VT-d 通过包含一张物理网卡的 VLAN NAT 域。克隆虚拟机被放置在单独的 VLAN 上,因此它们只能通过 NAT 引擎进行网络访问,这可以主动阻止分析虚拟机在本地网络上互相发现。该设置旨在最大程度地减少 DOM0 内将接口暴漏给受到恶意软件攻击的克隆虚拟机组件的数量,因为与虚拟机管理器暴露的最小接口相比,我们认为模拟的设备后端更可能成为攻击面。

总结并反思一下我们的设计需求:通过联合使用写时复制内存和磁盘,并使用 #BP 注入技术,可以满足(R1)。在不可或缺的操作系统代码位置采用 #BP 注入来满足(R2),这些代码直接显示了运行时的环境状态。使用 EPT 页面权限保护断点,并不使用任何客户机代理程序,使得 DRAKVUF 可以满足(R3)。根据(R4)的要求,从控制域中删除网络堆栈,并在克隆虚拟机上采用 VLAN 隔离可提高隔离度。

3、实现

接下来,我们对 DRAKVUF 使用的相关技术实现进行详细的叙述。

3.1、可伸缩性

防御解决方案的构建需要快速分析恶意软件样本,但是,需要处理的庞大数据量带来了巨大的挑战。通常,视频音频销售商每天需要处理 10 万个以上的样本。因此,我们一直关注与 DRAKVUF 是否能最大化用于分析的物理机的吞吐量。尽管施加于单个恶意软件样本的性能开销也很重要,应将其保持在最低水平,但在我们看来,这类开销仅仅在其积极干扰分析时才值得关注。在我们的系统中,我们利用 Xen 的写时复制(CoW)内存功能来限制内存需求,并利用 LVM 写时复制磁盘功能来限制主机上的硬盘空间需求。通过结合使用这些写时复制技术,我们可以大大增加可在给定物理计算机上同时执行的分析会话数量。

DRAKVUF 使用的写时复制技术要求存在一个静态域,该静态域的磁盘和内存可以用作参考点,称为原始域。可以在克隆原始域之前将其配置为常规域,然后再创建克隆虚拟机后将其静态冻结。启动克隆虚拟机后,首先会安装 LVM 写时复制磁盘,然后 Xen 位克隆虚拟机创建域。将原始域的内存内容通过管道传输到新创建的克隆域中,然后立即通过内存共享进行内存重复数据删除。共享内存后,唯一的内存开销是用于给克隆虚拟机提供磁盘和网络 IO 而分配给 QEMU 的内存,以及插入断点的页面。在我们的测试中,创建具有 2GB 的写时复制内存和写时复制磁盘的完整虚拟机克隆花费了不到 10 秒的时间。

尽管这样的完整虚拟机克隆有只需要最少的硬件资源来执行这一优点,但由于克隆虚拟机的 IP 和 MAC 地址相同,因此为网络的并发访问带来了挑战。当多个这样的克隆虚拟机放置在同一个交换机上时,会发生 MAC 地址冲突,并且共享的 IP 地址会阻止上游流量的 NAT。但是,传统在虚拟机中重新配置 IP 堆栈需要使用客户机代理,而这是我们在 DRAKVUF 中避免使用的方法。为解决此问题,我们使用 Open vSwitch 为每个克隆虚拟机分配唯一的 VLAN ID,以为克隆虚拟机提供 VLAN 隔离。

VLAN NAT 使用 pcap 库构建,该库直接从干线接口和上行链路读取原始数据包,从而绕过 Linux 网络堆栈访问第二层网络信息。通过此设置,VLAN NAT 引擎可以访问唯一标识克隆分析虚拟机的 VLAN ID。通过使用额外的唯一 ID 执行 NAT,我们的系统成功绕过了 MAC 和 IP 冲突的问题。此外,由于我们不使用 Linux 网络堆栈,因此,当发出针对预配置默认网关的请求时,我们还向每个分析虚拟机的 VLAN 中实施了 ARP 应答注入。通过动态注入 ARP 答复,我们避免了必须在分析虚拟机中设置静态 ARP 条目的情况。这消除了静态 APP 条目隐藏分析环境的可能性,同时也为我们在第 6 节讨论的一些新颖的分析方案打开了大门。

3.2、监控

由于动态恶意软件分析依赖于观察恶意软件的实时执行,因此手机数据的保真度至关重要。此外,由于 rootkit 使用多种技术来隐藏它们在系统中的存在,因此数据收集的范围越广,分析就越有可能揭示有用的功能。在下面的内容中,我们讨论了为 Windows 7 SP1 的 32 位和 64 位版本实现的一组数据收集机制。在当前的原型系统中,我们将重点放在 Windows 上,但是由于基本的监视技术与操作系统无关,因此我们的系统可以轻松扩展以监视 Linux 和其他操作系统。

3.2.1、执行追踪

现有动态恶意软件分析系统的关键功能是通过监视系统调用来跟踪程序流程的执行。但是,仅监视系统调用将执行跟踪限制为了用户空间程序与内核之间的交互,其中不包括内核模式 rootkit 的执行。为了克服这个问题,在 DRAKVUF 中,我们采用了另一种方法,即通过 #BP 注入直接捕获内部内核函数。通过直接捕获,DRAKVUF 能够监视恶意驱动程序以及 rootkit,而以前仅通过系统调用的拦截是不可能实现的。

内核函数的位置是通过从为内核提供的调试数据中提取信息来确定的。调试信息的使用已成为取证界的一种既定方法,它是了解操作系统状态的最便捷途径。在 DRAKVUF 中,我们使用 Rekall 取证工具来解析 Microsoft 提供的调试数据,以建立内部内核函数的映射。

在运行时,DRAKVUF 可以自动在内存中定位内核,而不必执行基于签名的扫描,与现有的取证工具相比,它可以提高弹性。为了自动在内存中定位内核,我们观察到 Windows 7 使用 FS 和 GS 寄存器存储指向 _KPCR 结构体的内核虚拟地址,该地址始终加载到已确定的内核内的固定相对虚拟地址(RVA)中,其由 KiInitialPCR 符号表示。当我们获得了包括 KiInitialPCR 在内的所有内核符号的相对虚拟地址时,我们只需从 vCPU 寄存器中找到的地址中减去符号的已知相对虚拟地址即可获得内核基地址。

一旦建立了内核基本地址,DRAKVUF 就可以通过 #BP 注入来捕获所有内核函数。由于捕获了内部内核函数,因此生成的日志从执行恶意软件样本起就提供了操作系统执行的完整跟踪。

3.2.2、应对 DKOM 攻击

rootkit 显著的特征就是修改了内部内核结构体,以隐藏它们在系统中的存在,通常称为直接内核对象操控(DKOM)。标准的 DKOM 攻击是通过从内核链接列表(如运行进程的列表)中取消结构体来执行的,以此来防止根据这些列表来枚举结构体的工具发现其他元素。取证工具早已发现,Windows 内核堆中的对象是通过附加标头(_POOL_HEADER)创建的。该标头包括结构体四个字符的描述,可通过在物理内存中进行简单的暴力字符串搜索标签来探测未被挂钩的结构体。

随着池标签扫描成为了取证的一种标准方法,已知恶意软件会尝试覆盖标头,以防止扫描工具随后发现这些结构。其他的 rootkit 技术通过将请求的对象大小修改为大于 4096KB,从而将分配的对象与其标头断开连接来隐藏结构,因为此类分配请求导致对象被放置到大页池中,而没有此类标头附加到目的地。此技术有效地防止了基本池标签扫描例程对对象进行指纹识别。

在当前实现中,DRAKVUF 跟踪内核堆上所有对象的分配,并根据结构的关联标签生成日志。如果结构的标签是已知的 2254 个标签之一,则日志中包含有关对象类型的更多详细信息,以帮助分析人员识别可能更感兴趣的分配。为了检测例如一个隐藏的过程,分析人员现在可以进行交叉验证,以确定是否也可以通过标准列表访问分配的结构体。DRAKVUF 进一步捕获了释放这些结构体的例程,,从而提供了对结构体生命周期的全面了解。在下一节中,我们将进一步说明此方法如何使我们能够跟踪 _FILE_OBJECT 的活跃使用情况。

3.2.3、通过内存时间监控文件系统访问

监视文件系统访问是任何动态恶意软件分析系统的核心功能之一,但是,以前无代理的虚拟机自省方法已经尝试通过修改磁盘模拟器来拦截事件来监视文件系统访问。尽管这种方法很有效,但是从低级磁盘仿真的角度重建高级文件系统访问(如路径和权限)本身就是语义鸿沟的一种形式,并且需要对文件系统内部进行广泛的了解。但是,DRAKVUF 跟踪的内部内核结构体会揭示有关系统执行状态的非常有价值的信息,例如完整的运行进程集,内核模块,线程,甚至是操作系统分配给文件系统访问的对象。

图 2 展示了通过我们获取文件系统访问的进程。当一个文件被访问时,无论是操作系统还是一个用户空间进程,在内核堆中都会创建一个 _FILE_OBJECT 结构体,并带有 Fil\xe5 标签。在捕获到分配地址后,我们在扩展页表中将分配了该结构体的页面标记为不可写。由于 _FILE_OBJECT 之前是一组可写的对象标头(以灰色背景表示),因此,通过从堆分配的末尾减去 _FILE_OBJECT 的已知大小,可以得出访问标志和文件名的准确位置。这使我们能够确定文件的完整路径以及访问文件的访问权限,例如读取,写入和/或删除权限,而无需对文件系统本身有更加深入的了解。

3.2.4、从内存中获取删除的文件

恶意软件删除程序的一个共同特征是快速创建和删除在传播过程中使用的临时文件。这些临时文件可能包含解压缩后的恶意软件二进制文件,然后再加载到内存中,或者包含其他取证相关信息。但是,恶意软件作者非常清楚这一事实,恶意软件的标准过程通常都是完成安装恶意软件之后清理临时文件。

当删除文件操作初始化时,使用客户机内代理程序实现的现有恶意软件分析系统可以轻松检索这些文件。从虚拟机自省的角度来看,Windows 默认情况下要在所有硬盘驱动器上启用写入缓存,因此检索这些临时文件非常复杂。快速创建和销毁文件时(就像在系统上放置恶意软件时一样),永远不会讲文件写入磁盘。单单将分析虚拟机的磁盘挂载到控制域,不会获取到这些文件的访问权限,唯一可能的情况是直接从内存中获取文件。

在 DRAKVUF 中,通过拦截负责文件删除的特定内部内核调用(如 NtSetInformationFileZwSetInformationFile)来实现已删除文件的获取。一旦函数被拦截,将通过检查传递的参数来识别文件,其中包括文件处理信息。该句柄并不直接指向文件对象,它只是拥有进程的句柄表中条目的指向数字。通过解析进程的句柄表,我们可以找到相应的 _FILE_OBJECT 并通过 Volatility 自动将其从内存中删除。

3.3、隐蔽性

基于虚拟化的分析系统的隐蔽性一般是在检测监视环境本身,而通常不是在检测虚拟化的情况下考虑的。该差别的理由是,已经在商品系统中进行了大规模的虚拟化部署,这使得经济上的诱因是恶意软件,而不排除虚拟化系统。有了这些假设,DRAKVUF 扩展了先前的研究,该研究表明断点注入和扩展页表保护的组合使用是一种有效的技术,即使对最先进的反调试技术也可以达到隐蔽的效果。在先前的研究中,通过更改客户机对硬件时间源的访问权限,也可以有效地解决由于将客户机困在虚拟机管理器中而导致的时间偏差,就算允许网络访问,外部时间源仍然可以用于恶意软件。

在 DRAKVUF 中,我们将注意力转移到了迄今为止在自动化动态恶意软件分析中被忽略的关键步骤:我们开始执行恶意软件样本,而没有留下可识别的监视环境痕迹。对于使用客户机内部组件的系统,可以由监视代理程序本身启动执行,但是即使只是自动启动脚本,也可以使用相同的客户机内部组件监测监视。另一方面,当不存在客户机内代理时,必须手动启动样本。因此,为了避免在分析虚拟机中创建任何工作,但允许自动执行,我们实现了一种注入机制,该注入机制劫持了虚拟机中一个正在运行但任意的进程,以代表我们启动了样本程序。

在 Windows 上,任何用户空间应用程序都可以通过 CreateProcessA 函数创建新进程,该函数是操作系统提供的 kernel32.dll 库公开的标准 Windows API 的一部分。尽管不是 Windows 上的每个应用程序都加载了 kernel32.dll,但通常只有视图系统进程是例外,因此在实践中 DRAKVUF 可以劫持任何正常的应用程序。

注入机制依赖于一组事件(如图 3 所示)成功劫持一个进程,而不会引起系统不稳定或改变机器状态,从而不会泄漏监视环境。创建克隆分析虚拟机之后的第一步,DRAKVUF 陷入将发生在控制寄存器 CR3 上的写事件捕获,以在发生进程上下文切换时捕获该事件。当一个事件被捕获时,我们会通过遍历进程加载的所有模块来检查正在运行的进程的地址空间中加载了哪些库文件。如果该进程在其地址空间中加载了 kernel32.dll,则虚拟机的执行将切换为单步模式,直到该进程开始执行用户级代码为止。

劫持机制接管了在用户级别第一条指令的执行,并在 kernel32.dll 的导出表中找到了 CreateProcessA 例程。进程的堆栈已更新,以包含调用函数所需要的输入参数,以及 x86_64 上的 RCX,RDX,R8 和 R9 寄存器,而 RIP 寄存器的原始内容被作为返回地址压入栈。例程结束后,将在返回地址中注入一个断点来通知我们。将 CreateProcessA 的地址放入 RIP 寄存器后,将继续执行分析虚拟机。

当到达返回断点时,我们可以通过检查 RAX 寄存器来确定该进程是否已成功创建,如果成功,我们还将获得执行恶意软件样本对应的 PID 和该进程的句柄信息。由于执行 CreateProcessA 时可能发生上下文切换,因此返回陷阱将检查返回陷阱处的进程是否是被劫持的进程。在恢复被劫持进程的原始执行之前,将还原堆栈和 vCPU 寄存器,从而无缝衔接恢复该进程的执行。

在我们的实现中,我们使用此机制在干净的虚拟机中启动恶意软件样本。通过使用这种劫持例程,不会在系统上留下任何可被检测为监视环境指纹的痕迹。如果在已经被感染的计算机上启动了恶意软件样本,则该属性可能不成立。在我们看来,这种情况是我们实现范围之外的用例。

4、实验结果

接下来,我们讨论了为建立性能指标并评估系统的有效性和吞吐量而进行的大量实验。实验在一个 3.4GHz 的 Intel 二代 i7-2600 CPU 上进行。

除非另有说明,否则实验是在 Windows 7 SP1 x64 分析平台上以 60 秒的运行时间执行的。在这些测试期间内,DRAKVUF 被设置为监视以 NtZw 开头的每个内部内核函数的执行。以 Nt 开头的函数是通过 SSDT 中列出的可用于用户空间应用程序功能的常规系统调用,并且监视这些功能的 Zw 版本可揭示内核级代码的执行。我们还捕获了另外两个内核内部函数 ExAllocatePoolWithTagObCreateObject,它们负责内核堆分配,如第 3.2.2 节中所述。虽然在这些测试期间内可以监视所有内部函数,但我们减小了跟踪范围,以减少所收集数据的详细程度,而不会影响对系统执行的了解。

4.1、TDL4

我们测试的第一个样本是 TDL4。之所以选择该样本,是因为对样本进行逆向工程后,病毒防御公司已经写了一些深入的技术文章。这与我们的自动分析形成了对比。VirusTotal(VT)对其的检测率为 45/46。在 Windows 7 SP1 x64 分析虚拟机中执行样本后,我们在 C:\Windows\System32\sysrep 文件夹中获得了由放置程序创建的两个其他临时文件:cryptbase.dllsyssetup.dll

这些临时文件是在删除文件创建时从内存中获取的,在删除之间磁盘从未刷新过。将文件提交到 VirusTotal,检出率分别为 19/50 和 22/50。原始分析报告中未提及的对这些临时文件性质的进一步调查显示,它们是通过绕过 Windows 7 和 8 上的用户访问控制(UAC)来提升特权的已知一部分方法。漏洞利用脚本和有效负载执行后,系统将会被关闭,而此时分配给虚拟机的 2GB 内存中有 1.1GB 的内存仍然是共享的。

4.2、Zeus

我们分析的下一个样本是 Zeus 的最新样本,VirusTotal 的检测率为 44/50。在我们的分析中,没有文件被删除。但是,在我们的日志中,可以看到该样本与临时文件夹中的两个文件进行交互,包括在 VirusTotal 的检测率为 43/50 的 GoogleUpdate.exe,以及没有被 VirusTotal 检测且为真正的 Adobe 安装程序的 FlashPlayer.exe。msimg32.dll 也位于这个临时文件夹中,其 VirusTotal 的检测率为 25/47,且以前从未被提交过。后来在我们的日志中看到,该 DLL 被正在执行的 Flash Player 安装程序放入 \Windows\System32。该样本的安装行为非常接近于 ZeroAccess 的安装行为,HP 也对此进行了分析。在执行样本 60 秒后,分析虚拟机处于共享状态的内存有 1.4GB。

4.3、ShadowServer 的样本

为了大规模测试 DRAKVUF,我们从 ShadowServer 获得了 1000 个最近的恶意软件样本。选择带有 AlienVault YARA 签名的样本,其说明应用了抗虚拟化技术。

在 1000 个样本中,有 241 个无法通过 CreateProcessA 注入执行。这些执行失败的原因不是由于恶意软件自行关闭,而是因为 Windows 无法执行样本。在执行的 60 秒内,平均有 159222 个断点,池分配请求平均有 67950 个断点。图 4 展示了在所有样本中使用率最高的堆分配相关内部函数触发的 10 个 API 调用。

在删除之前,通过从内存中对其进行获取,从分析虚拟机中总共提取了 8797 个唯一文件。为了更好地了解分析虚拟机中已删除文件的性质,我们按文件类型对文件进行了分类,如图 5 所示。1412 个 PE 文件也已经提交给了 VirusTotal。561 份是新提交的(占 39%),几乎所有文件都至少有一个杀毒软件检测到。平均只有 20.4% 的杀毒软件将这些文件归类为恶意软件。

4.4、测量开销和吞吐量

在本节中,我们将注意力转移到测量系统的开销,为人和监视引擎计算的标准度量,以及测量我们实现系统的有效吞吐量。

为了说明系统开销的来源,我们测量了当捕获所有内部内核函数时,通过监视出发了多少 VMEXIT。通过使用 Windows 7 SP1 内核的调试符号,对 x86 的所有 10853 个内部函数和 x86_64 的 11011 个函数进行了陷入。陷入使用扩展页表进行执行权限保护,使得分别在 x86 上陷入了 727 个内存页,x86_64 上陷入了 915 个内存页。虚拟机恢复 60 秒,并在空闲状态下仅启动了默认 Windows 系统进程。如图 6 所示,断点是我们在虚拟机中针对两个 Windows 版本触发的 VMEXIT 的主要来源。

为了测量由 #BP 注入导致的 VMEXIT 造成的 CPU 周期开销,我们执行了与 SPIDER 类似的基准测试。该测试由受监视的域组成,该域在循环中通过增加一个计数器来调用一个函数。该循环以 104 的步长值迭代到 106.通过在循环之前和之后读取 TSC 寄存器来收集时序信息。执行基准测试时,通过函数入口点是否有陷入来确定开销。这样测得的开销平均为 10502,与 SPIDER 中的开销相当。开销的差异可能是由于使用不同的虚拟机管理程序而产生的,分别是 DRAKVUF 中的 Xen 和 SPIDER 中的 KVM,因为通过设计 Xen 对于转发到控制域的每个陷入都需要额外的 VMENTRY/VMEXIT。

这两个实验都表明,我们的方法对单个样本的分析具备可接受的一个开销范围。我们认为,基于每个样本的开销主要是动态恶意软件分析的隐患。也就是说,开销不应显示监视环境的存在。

从可伸缩性的角度来看,系统的吞吐量非常重要,我们根据第 4.3 节中描述的实验对其进行了进一步评估。我们系统中的主要硬件限制时可用内存的数量为 16GB。考虑到推荐用于运行 Windows 7 的标准内存 2GB,与现有开放源代码工具的并发会话的最大数量将限制为 8 个会话(不计算为控制域分配的内存)。在我们的实验中,通过使用写时复制内存,平均有效内存节省为 62.4%,标准偏差为 7.3%。将内存节省投影为并发会话,如图 7 所示,我们可以看到通过写时复制内存(黑色区域)立即实现的内存节省。在我们的实验中,并发分析会话的数量提高了两倍,吞吐量显著提高。

5、相关工作

CWSandbox 是最早的动态恶意软件分析系统之一,它利用沙箱环境来监视操作系统和恶意软件之间的交互。CWSandbox 的运行方式是将内核驱动程序注入 Windows,该内核驱动程序会钩住所有导出的 API,以拦截用户空间程序执行的系统调用。除了易于检测和篡改之外,CWSandbox 提供的系统调用监视接口还不足以跟踪内核模式 rootkit。Cuckoo 是目前最受欢迎的开源动态恶意软件分析系统之一,其使用的方法和 CWSandbox 相同。Cuckoo 支持各种各样的虚拟机管理器。但是,由于 Cuckoo 和 CWSandbox 都依靠客户机代理来监视恶意软件的执行,它们无法利用虚拟机管理器超越隔离。由于没有从虚拟机管理器向客户机代理提供特殊保护,因此无法保证隐身性或防篡改性,从而可能导致错误的分析结果。在 DRAKVUF 中,我们通过外部的角度观察内核内部功能直接解决了这些缺点,从而提供了对系统执行的隐蔽性以及深入的了解。

。Vrable 等人在 2005 年首次有效地部署了虚拟机克隆,他们基于 Xen 实现了名为 Potemkin 的高度可扩展的蜜罐系统。Potemkin 通过引入内存共享解决了与运行大量几乎相同的虚拟机相关的扩展问题,该内存共享对重复出现在虚拟机之间的相同内存页面进行重复数据删除。尽管 Potemkin 仅限于半虚拟化(PV)Linux 系统,但后来的作品(例如 SnowFlock)也支持完全虚拟化(HVM)系统。从 Xen 的最新版本开始,虽然仅处于“技术预览”阶段,但本地支持完全虚拟化系统的 Potemkin 式虚拟机克隆。我们对这一领域现有工作的贡献是通过自动 VLAN 标记和 NAT 创建网络堆栈,从而使克隆域的 MAC 和 IP 地址不需要重新配置。在先前的工作中,这种重新配置是通过客户机的内部代理或手动 iptables 配置执行的,我们已经以透明和自动的方式成功解决了这个问题。

Ether 还利用硬件需扩展来执行虚拟机自省。基于 Xen 修改版的 Ether 利用了以下几个方面:可以将页面错误配置为在特定代码位置触发 VMEXIT。Ether 用它来有效地跟踪观察到的虚拟机中的系统调用。尽管 Ether 为隐藏这些修改付出了巨大的努力,但 Pek 等人质疑其有效的隐蔽性,其在实践中存在一些实现问题,且可能向客户机操作系统揭示 Ether 的存在。在 DRAKVUF 中,我们仍然基于虚拟化扩展。但是,DRAKVUF 中使用的跟踪系统执行的技术也可以分析内核模式的 rootkit,这对于 Ether 的系统调用跟踪方法是不可见的。此外,在 DRAKVUF 中,我们还解决了分析的可伸缩性以及有关在不留痕迹的情况下启动恶意软件样本的担忧。还有一个额外的优势,与 Ether 不同,DRAKVUF 不需要对 Xen 进行任何修改。

CXPinspector 专门基于扩展页表进行执行跟踪。当扩展页表在客户机物理地址和机器物理地址之间进行转换的地方增加了一个附加层时,该层内的任何访问冲突都将触发 VMEXIT,从而对客户机保持透明。通过将某些页面标记为不可执行,CXPInspector 能够监视虚拟机的执行。但是,众所周知,使用扩展页表进行执行跟踪仍然会给虚拟机的执行增加大量开销,这主要是因为扩展页表的粒度被设置为了违反触发。在 DRAKVUF 中,我们还利用了扩展页表的页面权限,但是我们仅使用它来为注入的陷阱添加保护,从而避免了页面上多次执行违规的性能开销。

在现有技术中已经提出了进程植入(PI),内核模块注入(XTIER)和进程劫持(SYRINGE)作为虚拟机自省的方法。为了确保这种自省,虚拟机管理器需要提供额外的保护,以拒绝对植入代码的堆栈数据进行运行时修改。例如,SYRINGE 在客户机内原子地执行注入的函数调用。尽管此类方法可以确保注入的代码完整性,但它们不能确保潜在的受到威胁的操作系统提供给它们的数据的完整性。因此,如果攻击者通过执行如 DKOM 攻击向监视应用程序提供虚假信息,则这些技术将无法检测到篡改。在 DRAKVUF 中,我们首次为 Windows 实施了进程劫持,并且仅使用它来秘密执行恶意软件样本,从而避免了因依赖于观察到的操作系统中不可信数据而引起的任何问题。

SPIDER 评估了 #BP 注入的使用来用 KVM 管理程序对虚拟机中的进程进行隐式调试的情况。但是,使用 SPIDER 启动恶意软件样本仍然需要收到操作或使用客户机代理,这会影响可伸缩性或阻碍系统的隐蔽性。同样,使用 SPIDER 确定断点的位置是一个手动过程,通常是通过调试完成的。我们对 DRAKVUF 的贡献包括应用了 #BP 注入的核心技术来自动跟踪操作系统的执行并提取取证相关的高级状态信息,而无需任何手动操作。

6、未来的工作

尽管动态恶意软件分析系统可以减轻分析数量不断增加的样本负担,但该方法的固有局限性在于样本执行的不确定性。通常认为恶意软件样本在给定时期内能否表现出真正的恶意性质(即脱壳或是失速)这是不确定的,尽管有关该主题的最新研究为在空间和时间限制的情况下该问题的解决提供了方向。将来可以集成到 DRAKVUF 中的可能解决方案是通过对分析虚拟机进行主动快照来进行多路径探索,以及通过基于虚拟机自省的程序流控制修改来防止失速。

在我们的 VLAN NAT 引擎中访问二层网络信息为新的恶意软件评估方案打开了大门。虽然在当前设置中,路由引擎仅在请求是针对默认网关的情况下才注入 ARP 答复,但我们也可以向任何请求本地 IP 注入 ARP 答复。通过将路由引擎与 DRAKVUF 进一步集成,我们可以部署新的分析虚拟机来构建动态 LAN 环境,从而提供简单的设置来测试恶意软件如何在 LAN 上传播。

当前在启动恶意软件样本的执行之前会使用分析虚拟机的内存共享,因此,随着分析虚拟机的执行,内存节省空间逐渐减少。但是,可以通过捕获对客户机页表的更新并评估可以安全删除重复的物理页面来执行更积极的内存共享。这种方法还使我们能够重新启动分析虚拟机,在某些情况下,这是出发感染执行所必须的,同时又不放弃内存共享的优势。

我们的流程注入机制着重于通过在创建克隆虚拟机之前将样本放在磁盘上来开始执行恶意软件样本。尽管这种方法在我们的原型中是可行的,但在以后的工作中,我们计划通过使用过程挖空技术将恶意软件二进制文件直接放置在内存中。

DRAKVUF 当前遵循恶意软件执行的单一路径的原则。由于恶意软件可能正在寻找某些条件以执行或表现出其恶意行为,因此通过监视样本执行的检查可用于潜在地探索多个执行路径。

7、总结

在本文中,我们介绍了 DRAKVUF,一种新颖的动态恶意软件分析系统。其中 DRAKVUF 的一部分内容中,我们基于最新的虚拟机管理程序技术和硬件虚拟化扩展,介绍了几种新颖的技术,以提高恶意软件分析的可伸缩性,保真性和隐蔽性。通过监视内核内部函数,DRAKVUF 可以全面了解用户和内核空间的恶意软件行为。使用主动虚拟机自省分析虚拟机中的任意进程,DRAKVUF 可以启动恶意软件样本的执行而不会留下其他任何痕迹。DRAKVUF 还展示了通过内存自省来跟踪文件系统访问并提取未刷新磁盘的临时文件的独特功能。在我们的实验中,我们使用了大量野生恶意软件样本对 DRAKVUF 进行了评估。这些实验表明,该系统既可以有效分析现代恶意软件,又可以通过最大化共享物理硬件上运行的并发分析会话来提高硬件利用率。