最近看了BlackHat2018的议题《Hardening Hyper-V through offensive security research》,觉得很有兴趣,查找相关资料,发现了一篇ERNW关于hyper-V研究的文章《Security Assessment of Microsoft Hyper-V》,虽然有些信息相对较老,但是作为hyper-v入门资料,提供的思路仍然是比较不错的,翻译记录一下共同学习。
1 引言
Hyper-V是微软的第一个裸机hypervisor,也是第一个完全支持x86-64体系结构的本地hypervisor。作为类似的虚拟化解决方案(如vmware esxi、xen或kvm)的竞争替代品,Hyper-V在市场上占有很大的份额,并且由于其易与Microsoft解决方案集成,市场份额在不断增加。除了这种企业定位之外,Hyper-V还应用于各种其他平台,如Microsoft Azure或Xbox One游戏控制台。
尽管Hyper-V越来越重要,但到目前为止,公开提供的研究很少。在市场上运行了近六年之后,只有少数拒绝服务漏洞得到了修补。尽管微软的SDL在生产安全软件方面有着令人印象深刻的记录,但对于如此复杂的软件来说,这样低的漏洞数量似乎是不切实际的。
本文描述了我们关于Hyper-V防止恶意的非特权来宾VM攻击,这方面的安全性研究。我们关注内存破坏、协议解析和设计缺陷等相关的漏洞,但没有对诸如侧通道、定时攻击或周围环境非安全管理等问题进行研究。
本文的组织结构如下:第2章给出了有关Hyper-V体系结构的技术概述,包括其对设备仿真和合成设备的支持。此外,我们还将重点介绍如何在Azure环境中使用Hyper-V,及其随之而来的安全需求。第三章从恶意虚拟机的角度讨论了所存在的攻击面。这些攻击面将被分解为单独的功能,并描述为攻击者可用的输入向量以及我们评估这些向量的方法。第4章讨论了我们研究所关注的结果:hyper-v的hypercall功能中的重要漏洞ms13-092。第5章描述了进一步研究所关注的目标,并得出最终结论。
2 Hyper-V的架构
该章将详细描述Hyper-V的内部架构,其中所涵盖的术语、组件和内部架构会在第3章的攻击面分析中有所涉及。
2.1 概述
Hyper-V是I型虚拟机管理程序(hypervisor),因此可以直接在不依赖底层操作系统的硬件上运行。然而可能另许多用户感到诧异的是,Hyper-V又是通过常规Windows服务中的添加附加角色来安装的。
其实在安装过程中,Windows操作系统将变为一个Hyper-V partition(高权限),并在重启后由hypervisor所管理。
图1 高级架构
图1中显示了Hyper-V架构的概况。 微软将虚拟化操作系统分区分为root partition(特权)和child partition(非特权)。root partition受hypervisor完全信任,负责管理和配置所有其他partition(类似于Xen的Dom0)。Hyper-V支持对未修改(无Hyper-V接口)操作系统的虚拟化,但运行时操作系统并不知道自身处于虚拟环境中,这种情况被称为Unenlightened 。 为了实现这种情况,hypervisor透明地模拟了现代操作系统所支持的标准设备。
另一种Enlightened操作系统由于支持Hyper-V接口,可以利用更多的高级特性来提高性能。 Hypercalls是公开的Hyper-V API,通过使用Hypercalls可以直接与hypervisor通信,该机制类似于操作系统内核提供的systemcall接口。 此外,VMBus机制可以用于root partition和child partition之间的直接高速通信。 这些特性主要在合成设备中,能够被Enlightened partition所使用的,且快于模拟设备。
由于微软决定尽可能减少Hyper-V hypervisor的大小,所以大部分功能都是外包给root partition,这其中包括了模拟设备、合成设备和所有高级管理接口。 该决定将hypervisor代码的自身复杂性显着地降低到大约100000行。但是,对整个Hyper-V环境的安全性影响却有限,稍后将对此进行演示。
2.2 VMWP, VSC和VSP
图2 Hyper-V组件
图2中显示了root partition和Enlightened child partition内的核心组件。对于每个child partition而言,在root partition中都运行了一个与之相应的普通用户空间进程,即虚拟机工作进程(VMWP)。该工作进程执行快照或迁移等管理职责,但同时它也实现了上述设备和一些非性能关键的合成设备的仿真。
在用户空间进程中实现这些功能有许多优点:首先,由于bugs和高资源消耗所导致的崩溃,不会影响到root partition、其余VMs以及hypervisor整体的稳定性;其次,VMWP可以在低权限中执行,这意味着攻击者想要利用设备模拟层中漏洞的,还需要在root partition中提权。但是,由于额外上下文切换的需要,这种用户空间实现方式并不适用于性能重要的设备,如网络和存储等。
此类性能重要的设备在虚拟化服务提供者(VSP)中实现。 VSP是在root partition的内核中运行的驱动程序,因此是攻击者非常感兴趣的目标。child partition中类似VSP功能的是虚拟化服务客户端(VSC)。所有现代版本的Windows都已包含这些内核驱动程序,并为合成设备提供操作系统支 持。此外,Linux和FreeBSD包含由Microsoft工程师提供的多个VSC的开源实现。对于Linux,此代码称为Linux Integration Services,现在直接包含在kernel tree中。不过,在Github仓库中也可以找到具有其他功能的更新版本。
仅仅有设备支持对于虚拟化解决方案来说是不够的,hypervisor的核心任务是CPU和内存的虚拟化。与几乎所有的x86-64 hypervisor一样,Hyper-V使用硬件辅助虚拟化。这意味着Hyper-V使用Intel VT和AMD-V等扩展的rtualization指令集。由于我们所有的研究都是在英特尔硬件上进行的,因此我们将在本文中使用英特尔的特定功能术语。
2.3 硬件辅助虚拟化
Intel VT添加了两种不同处理器操作模式:VMX root模式和VMX non-root模式。hypervisor运行在VMX root模式,所有的分区都运行在non-root模式。
在非root模式下运行的VM不会受到任何性能影响,但某些事件可能会触发上下文从而切换到hypervisor。这些上下文切换称为VM exits,可能由于某些诸如执行某些指令(如中断处理)或访问特殊系统寄存器等原因而产生。
英特尔VT的目标之一是对客户操作系统透明。因此,由指令或系统寄存器访问触发的VM exits需要hypervisor完全模拟其行为。虽然这对于许多VM exits的原因来说无足轻重,但对于完全支持x86架构的所有极端情况来说却是困难且易出错。完整讨论硬件辅助虚拟化的安全问题超出了本文的范围,因此后面的部分将只详细地描述VT体系结构的几个属性。
尽管英特尔VT设计为对客户操作系统透明,但Hyper-V对enlightened partition的支持要求虚拟化操作系统可以检查它是否在Hyper-V中运行。这需要下面部分所描述的专用接口发现机制来提供支持。
2.4 接口发现
当虚拟分区执行CPUID指令时,将触发VM exit,Hyper-V通过添加Hyper-V特定信息来修改典型的CPUID返回值。 EAX = 1的CPUID调用将设置ECX寄存器与MSB。 这表明hypervisor是存在的。 可以通过执行输入值介于0x40000000和0x40000006之间的CPUID来查询有关Hyper-V版本和分区权限的更多信息。 图3显示了在Windows Server 2012 Hyper-V系统上执行小程序的输出。
图3 CPUID指令
有趣的是,返回的信息包括Hyper-V的确切版本,以及调用分区的超级调用权限。 这些详细信息可以帮助攻击者确定是否存在某些漏洞,并对攻击进行定位。
此外,在Azure VM中使用此接口发现机制会返回非常有趣的结果,如下一节中所述。
2.5 Azure Hypervisor=Hyper-V?
正式地说,Microsoft Azure云运行在称为“Azure hypervisor”的hypervisor上,该管理程序与Hyper-V不同。 但是,即使粗略地看一下Azure VM,也会发现这两个hypervisor至少具有很强的相关性。 图4显示了Azure VM的屏幕截图,其中运行标准Hyper-V VSC服务,并在Azure VM中执行CPUID指令。
图4 Azure中的Hyper-V集成服务和Azure中的CPUID指令
此外,我们可以使用上一节中讨论的接口发现机制。 图5显示了CPUID命令的输出:唯一可识别的差异在Service Pack和服务分支编号中。 甚至分区权限也与默认Hyper-V VM的权限相同。
从工程角度来看,在Hyper-V和Azure之间共享代码库是合乎情理的。 对于针对Azure的安全研究人员或恶意攻击者而言,在离线分析hypervisor方面有巨大优势。 通过专注于与Azure相关的Hyper-V攻击面,发现对Azure云产生严重影响漏洞的机会非常高。
2.6信息来源
尽管Hyper-V是一种专有软件产品,但有一些公共信息源可用于更好地理解其实现:
hypervisor顶级功能规范:此规范包括对Hypercall API和接口发现机制的详细讨论。
专利申请:多个公共专利申请描述了Hyper-V的实现细节。 这包括用于Child-Parent通信的机制以及协议规范。 虽然与普通技术文档相比,大多数应用程序都很难阅读,但它们仍然有助于理解内部命名和高级架构。
Linux集成服务:如前所述,Linux集成服务是VSC,VMBus和Linux的hypercall API的开源实现。 它们简化了Hyper-V这些部分中实现细节的理解,在开发评估和攻击这些API的工具时非常有用。
Singularity头文件:Singularity是由Microsoft Research开发的开源研究操作系统。 其SVN存储库包含许多专有的Windows头文件,包括用于Microsoft Hyper-V来宾界面的多个。
通用标准认证文件:通用标准认证要求提供全面的文件。 该文档是公开的。
二进制文件:当然,可以从实现本身中提取最准确和最详细的信息。 表1列出了我们在研究期间分析的几个文件。 下一节将介绍逆转这些文件所涉及的一些挑战。
文件名 | 描述 |
---|---|
hvix64.exe / hvax64.exe | Hypervisor核心可执行文件,适用于Intel和AMD。 包括引导过程完成后在VMX root模式下运行的所有代码 |
vmwp.exe | VM工作进程的可执行文件。 包括设备仿真的代码,以及几个合成设备 |
vmswitch.sys | 实现Networking VSP的Windows内核驱动程序 |
storvsp.sys / vhdmp.sys | 存储VSP的内核驱动程序 |
表1 Hyper-V可执行程序
2.7 逆向工程陷阱
Hyper-V及其一些核心功能的逆向工程,我们必须克服几个挑战。 这些挑战对于分析Hyper-V的任何安全研究人员都非常重要,我们希望以下小节中的描述将提供有帮助的见解。
2.7.1 符号移植
为了解安全相关核心功能的实现,如VM exit处理或hypercall API,对hypervisor二进制文件的逆向工程是必不可少的。 我们的研究是在英特尔硬件上进行的,因此我们使用了hivx64.exe。 在尝试初步了解所包含的功能时,我们必须克服一些挑战。
首先,没有可用于二进制文件的公共调试符号。 这增加了识别安全相关代码区域所需的工作量。 其次,通过搜索调试输出和其他人类可读字符串来识别关注功能的标准方法不起作用,因为hypervisor中的此类功能非常少。最后,我们不能依赖于已知API或库的使用。 与用户空间程序或内核驱动程序相比,hypervisor是单个静态链接的可执行文件。
但是,我们可以使用一些技术来识别所关注的功能:名为Gerhart的研究人员在securitylab.ru上的一篇详细博客文章中描述了他的符号移植方法:hvix64.exe与winload.exe和hvloader.exe共享大量代码。 公共调试符号对于它们都可用。 使用流行的BinDiff软件,我们可以识别共享功能,并将包含的符号移植到我们的可执行文件中。 不幸的是,共享功能主要涉及网络代码,USB堆栈以及WinDBG调试器存根,并且对于我们识别攻击面的目标并不那么关注。
2.7.2 VMCS
如前所述,hypervisor不依赖任何外部库。 它使用的唯一有用的文档功能是用于配置和管理不同虚拟机的Intel VMX指令。 如英特尔官方手册14第3卷所述,VMX的核心部分是称为VMCS(Virtual-Machine Control Structures 虚拟机控制结构)的数据结构。 VMCS分为四个逻辑部分:
- Guest-state区域
- Host-state区域
- VM-execution, VM-exit 和 VM-entry控制字段
- VM-exit信息字段
Guest-state区域用于存储VM退出时的处理器状态,并将控制权传递给hypervisor。这包括某些控制寄存器,以及MSR和段选择器,但最重要的是RIP,RSP和RFLAGS的值。 当hypervisor处理VM exit并继续虚拟机时,处理器状态从VMCS加载,并且可以(潜在地)继续透明地执行。
Host-state区域在VM-exit期间加载,并在处理这些exits时描述hypervisor的初始状态。 这是我们特别关注的,因为存储的RIP和RSP值允许我们快速识别主exit处理程序及其堆栈位置。
VM-execution的控制字段控制VMX non-root模式下的操作。 这些字段控制中断和某些类型的指令的处理,并决定哪些操作触发VM exit。 它们是安全研究的一个关注目标,因为不安全的控制领域设置可能导致严重的逻辑缺陷。
最后,VM-exit信息字段包含有关VM-exit原因的信息。 这些信息在整个VM出口处理程序中使用,因此从逆向角度来看非常相关。
读写VMCS字段的专用指令:VMREAD和VMWRITE。 两个指令都需要编码的参数来描述所访问的VMCS字段。 对于我们的研究,我们决定以半自动化方式使用这些信息。 使用IDAPython脚本,我们将所有VMCS访问转换为可读的版本。 这简化了对涉及VMCS字段的所有代码部分的理解,并允许我们识别主要功能,如VM exit处理和hypercall处理程序。
图5 具有可读字段名称的VMREAD指令
2.7.3 调试
尽管静态分析被证明是可行的,用以获得初步的理解,但我们很快就决定进行额外的动态分析以进行更全面的分析。
有趣的是,微软的WinDBG集成了Hyper-V调试功能。 调试Hyper-V本身的工作方式几乎与调试Windows内核的方式相同,但由于缺少符号和功能而不太顺手。
像Firewire,以太网和USB等不同的访问方法都可以被支持,但实际上我们在带有标准串口的物理硬件上获得了最可靠的结果。 尽管使用物理硬件调试绝对是可能的,但基于虚拟化的方法会更加顺手。 幸运的是,当前版本的VMware Workstation和VMware Fusion支持称为嵌套虚拟化的功能。 嵌套虚拟化允许在虚拟机内部使用Intel VT,并且可以将Hyper-V作为普通VM运行。
通过虚拟化Hyper-V本身,我们获得了许多优势。 除了上面提到的WinDBG接口,我们现在还可以使用VMware的内置GDB存根作为替代调试环境。 此外,快照可以用作获取物理内存转储的简单快捷方式。 VMware Workstation / Fusion还支持在虚拟机之间共享串行端口,从而可以在虚拟机中同时运行调试器和被调试机器。
虽然这仍然不会带来舒适或功能丰富的调试环境,但事实证明,这足以进行我们研究所需的分析。
3 攻击面和测试方法
基于第2章中介绍的体系结构概述,对于VM突破攻击,我们将以下组件确定为的潜在并有希望的目标:
- 1.设备模拟
- 2.VMBus和合成设备
- 3.Hypercall API
- 4.VM Exit 处理
以下部分将更详细地描述每一个组件,并介绍我们发现安全问题的方法。 我们还没有粗略评估过一般VM exit处理,因此本章不包括此主题。
3.1 设备模拟
设备虚拟化是每个虚拟化解决方案的核心任务之一。 虽然合成设备具有更好的性能特征和更好的接口,但它们不足以用于通用虚拟化。 没有明确支持这些设备的旧操作系统仍然依赖于虚拟环境中“标准”硬件的可用性。 此问题通常使用设备仿真来解决,,其中具有广泛支持的旧硬件由hypervisor模拟。
由于仿真设备的高复杂性和高性能要求,设备仿真通常是虚拟化软件的薄弱环节。 2007年,Tavis Ormandy描述了他在多个虚拟化解决方案中模拟仿真设备的方法,该解决方案发现了多个漏洞。 此外,设备仿真层是Xen和KVM管理程序的流行目标,它们使用QEMU来实现其设备。
Hyper-V支持许多普通虚拟机的仿真设备:
- 网络适配器
- S3 Trio显卡
- 键盘/鼠标
- IED控制器
所有这些都在虚拟机工作进程vmwp.exe中实现。 因为模拟设备的攻击面很容易理解,并且fuzzing它们不需要特定于单个hypervisor的知识,所以我们没有期望很多结果。 所有设备的基本fuzzing测试都会触发VM的永久性崩溃,这些崩溃是由工作进程中的断言触发的。 此外,我们能够以100%的CPU消耗冻结工作进程,这需要使用父分区的任务管理器杀死硬件。 这可能是某些云环境的相关问题,但不会以任何方式影响其他VM,因此并不重要。
对 vmwp.exe二进制文件的进一步静态分析,表现出了许多防御性检查,并且没有明显的安全漏洞。
3.2 VMBus和合成设备
3.2.1 VMBus
如前所述,VMBus是用于分区之间通信的机制。 在Hyper-V的默认配置中,仅允许在child partition和root partition之间进行通信。 VMBus本身通过映射到多个分区的内存页来实现的,在默认情况下映射到root partition和目标child partition。 这意味着通过总线发送的数据不需要通过hypervisor“复制”,减少了必要的上下文切换次数,从而显着提高了性能。
VMBus通信分为多个通道,每个通道由一个输入和输出环形缓冲区组成。 由于环形缓冲区空间非常有限,因此性能关键组件利用访客物理地址描述符列表(Guest Physical Address Descriptor Lists GPADLs)的附加机制,该机制允许root partition将客户机内存的其他页面直接映射到其自己的地址空间。
VMBus基础架构的主要用户是合成设备。 这包括存储和网络,还包括视频驱动程序和一些其他实用程序服务(例如时间同步,VM的动态内存分配和键值服务)。
如2.2节所述,存储和网络是作为内核驱动程序实现的。 这使得它们成为关注的目标,因为这些驱动程序中的漏洞(例如,解析来自攻击者控制的分区的输入)将导致root partition的内核空间直接损害,从而破坏整个root partition。 相反,视频驱动程序以及所有实用程序服务却都是作为VM工作进程的一部分实现。
3.2.2 存储
图6 合成存储设备高级概览
对于我们的研究,首先关注存储VSP。 它的设计非常有趣,因为VSC通过VMBus发送(在其他数据包类型中)封装的SCSI命令,然后将其解析并转换为存储VSP的简单文件访问操作。 图6显示了在enlightened Linux客户机上实现合成存储设备所涉及的组件。
Child partition中的存储VSC将SCSI命令封装在所谓的vstor数据包中。 该数据包由VMBus驱动程序封装到VMBus数据包中,并通过上述环形缓冲区传输。 在root partition中,VMBus驱动程序将数据包交给storvsp.sys驱动程序,该驱动程序将其分派到vhdump.sys驱动程序中的相应处理程序函数中。 图7显示了这种SCSI命令处理程序的示例。 请注意BSWAP指令的使用,该指令用于在大端SCSI协议和小端系统架构之间进行转换。
图7 SCSI命令处理程序
为了评估存储VSP的安全性,我们再次从基本fuzzing开始。 这种率直的做法被证明是不可行的,因为vstor和vmbus数据包的fuzzing导致存储VSC的永久性崩溃,并因此导致整个child partition的崩溃。 为了解决这个问题,我们改进了fuzzing测试框架,允许对执行的SCSI命令进行细粒度fuzzing:我们的fuzzer使用kprobes接口,它允许hooking几乎任意的内核函数。 通过挂钩通用VMBus packet_send函数并根据调用者操作传递的参数,我们可以将fuzzing限制为不会触发永久VM崩溃的数据。 当然,这会减少主动fuzz面,因此需要通过手动分析来提供这种方法。
最后,我们没有发现存储VSP中的任何关键漏洞。 然而,我们的分析非常有限,并且由于普通fuzzing的无效性,人工分析是绝对必要的。
4 HYPERCALL API
我们要在本文中讨论的最后一个组件是Hypercall API。 Hyper-V中的hypercalls类似于系统调用,但在来宾内核和hypervisor之间运行。 它们被enlightened partitions用于增强性能并启用VMBus等高级功能。 此外,根分区使用管理超级调用来管理所有其他分区。 API本身非常强大,包括创建和销毁新分区,设置和读取不同VM的寄存器值等功能。 当然,此类功能受权限检查保护,通常仅限于root partition。
图8 HvGetVPRegisters说明文档
与VMBus及其合成设备相比,Microsoft在Hypervisor顶级功能规范中完全记录了Hypercall API。 例如,图8显示了HvGetVPRegisters这个hypercall接口描述,它允许对虚拟机的寄存器进行读访问。 所有其他可用的超级调用都以相同的格式记录。
图9 host_rip涉及vmwrite的相关VMCS 字段
为了审计hypercalls,我们首先要识别相应的处理函数。 使用第2.7.2节中概述的方法,我们可以通过搜索相应的VMWRITE指令快速识别主VM exit处理程序,如图9所示。
所有hypervisors的VM exit处理程序遵循相同的基本结构:
- 1.存储Guest State
- 2.根据exit的原因调用相应的处理函数
- 3.恢复Guest State
基本hypercalls的接口如下所示:
- 1.将调用号存储在RCX中
- 2.将指向输入的Guest物理地址存储在RDX中
- 3.将指向输出的可写内存的GPA存储在R8中
最后,执行VMCALL指令以触发VM exit。 通过识别VMCS退出原因为VMCALL时调用的函数,我们可以识别负责处理hypercalls的代码。
通过分析此功能,我们可以快速识别处理hypercalls的主要数据结构,如图10所示。
图10 Hypercalls 处理程序表
利用此数据结构,可以快速识别所有相关的处理函数。 在审计单个hypercall处理程序的漏洞时,我们有几个优势:首先,处理函数本身是相对孤立的。 这样只有一个目的,可以更容易地识别被调用函数的功能。 其次,因为输入和输出接口由顶级规范记录,所以关于实际代码流的推理相对容易。
图11显示了HvGetPartitionId超级调用的处理函数。 在每个处理函数的开始处,RCX寄存器指向输入位置,而RDX指向输出。 两个内存区域都不直接映射到VM内存。 而是在启动处理程序之前复制输入,并在处理程序完成后将输出写入VM内存。 这消除了在处理程序运行时操纵hypercall输入的可能性,因此排除了整个类型的漏洞。
图11 HvGetPartitionId处理程序
当实际审核hypercall处理程序本身的漏洞时,我们可以快速识别一个大问题:最关注的功能仅适用于root partition,并受到严格的早期权限检查的保护。 但是,在实际的hypercall处理程序执行之前,会执行大量检查。 当我们查看它们时,我们很快发现了导致MS13-092的一个关键问题。
5 MS13-092
在调用实际的hypercall处理程序之前,将执行多个健全性检查。 例如,必须确保hypercall实际上来自VM的ring0层。 此外,还执行输入和输出GPA的完整性检查。 它们是否正确对齐? 它们看起来“合理”吗?
图12 GPA输入检查
其中一项检查如图12所示:输入的GPA存储在RSI寄存器中,并根据位图进行检查。 如果输入的GPA太大,则会引发错误情况。 漏洞位于错误处理函数之一的调用堆栈中:
图13 EPT 错误处理程序
图13显示了负责处理EPT(Extended Page Table)错误的函数。 当VM触发正常的EPT违规时,也会在设置上述错误条件时调用它。
图14 越界内存访问
如果EPT破坏是由内存读取触发的,则名为ept_read_error的函数会被调用。 在无效输入GPA作为hypercall参数的情况下执行的代码路径也是如此。 在函数开始时,RDX容纳攻击者控制的输入GPA。 然后将RDX复制到RAX,向右移动12位。 该值用作控制VM的页表项(page table entries PTE)的页表索引。
页表的目的是将客户物理页面映射到系统页表项。 每个VM只有一个这样的表,有趣的是它们以相互恒定的偏移量分配。
因为输入GPA几乎可以任意大小,所以阵列访问可以用于访问页表范围之外的内存。 通过触发无效的内存访问非常容易导致hypervisor崩溃。 输入GPA设置为0x4141414141的任何有效超级调用编号都将足以导致整个hypervisor的Hyper-V蓝屏和拒绝服务(DoS)情况,同时也包括所有操作的客户:
图15 Hyper-V蓝屏
我们向Microsoft报告了此错误,并于2013年11月在公告MS13-092中进行了修补。 有趣的是,Microsoft将此错误视为不同分区之间潜在的权限提升。 所以我们决定深入研究如何将这个bug从DoS转变为PrivEsc。
图16 简化的伪代码
图16显示了易受攻击的函数的简化版本。 在大多数情况下它将简单地返回0,并且仅当PTE中的页面帧号(page frame number PFN)等于某个值时才执行相关操作。
分析Microsoft提供的补丁显示,作为唯一明显的变化,在函数调用前进行另外的大小检查,在失败时强制返回0。 这意味着在易受攻击的函数返回0之后执行的所有代码路径,对于利用漏洞都将失效。
总之,我们必须找到一种方法来读取包含“特殊”PFN号码的PTE(来自不同的VM),以便触发潜在的恶意内存访问。 使用纯静态分析,我们无法识别此PFN的用例,并且我们实验室中的VM未使用它。 这可能意味着它仅在某些可能与配置相关的情况下使用。 由于64位地址空间较大,且输入GPA值具有上述上限,并不能试图读取完全由攻击者控制的变量值。
如果攻击者能够通过此检查,他就可以获得有趣的代码。 但是,能够影响的只有PTE和输入GPA这两个值。 由于上述的PFN检查,这些影响都非常有限,所以对下一个执行步骤比较受限。
不仅无法把违规读内存转换为某种写内存损坏,而且将PTE从一个VM映射到另一个的可能性也同样是一个问题。尽管我们还没有利用这个特定问题的简单方法,但我们将进一步分析补丁和结果行为,并鼓励其他研究也这样做。
6 进一步研究和结论
本文总结了我们所做的关于Hyper-V安全性的研究。 尽管大部分时间都在详细理解架构,描述VM突破攻击的攻击面,但是也发现了处理hypercalls时的一个关键漏洞。
基于这项工作,我们计划对其他VSP进行更详细的分析,并开发技术来改进我们的fuzzing功能(主要是改善崩溃恢复/减少客户机崩溃的总体数量/需求)。 此外,分析不同版本Hyper-V的静默修补漏洞似乎是一项很有前景的活动,我们计划在今年晚些时候展示这些。
我们的研究表明,hypervisors是庞大而复杂的软件,具有显着的攻击面。 即使“虚拟隔离”这个术语现在非常流行,我们的研究表明这个隔离远弱于物理隔离。 虽然Hyper-V是可靠的软件,开发时考虑了安全性,但它仍然存在严重的安全漏洞。 这应该推动其他研究人员利用我们的结果,介入Hyper-V巨大的攻击面分析,跟随古老的“Make the Theoretical Practical”黑客精神!