【DEFCON & HITB】Bug Hunting In VMware Device Virtualization(下篇)

本文是天工实验室在DEFCON上发表的议题《Dragon Slaying Guide: Bug Hunting in VMware Device Virtualization》的第三部分内容。在该议题的前两篇文章中,分别介绍了VMware虚拟化实现和虚拟USB设备漏洞挖掘。 本周将继续讲解议题最后一个部分:SCSI Device Virtualization。主要介绍虚拟磁盘系统SCSI相关设备模拟在VMware Workstation和ESXI下的异同,以及我们在VMKernel中发现的有关磁盘设备模拟的设计缺陷。 一、前言 磁盘设备的代码架构和USB设备类似,首先他有许多作为前端的主机控制器设备模拟代码,比如 LsiLogic,NVME,PVSCSI,AHCI,有趣的地方在与作为连同主机控制器与磁盘设备的中间层代码实际上只处理SCSI协议指令,VMware为每种主机控制器都设计了用于将主机控制器请求翻译成SCSI请求的代码,所有不同磁盘设备的主机控制器请求在最终都会被统一成SCSI指令,后端设备模拟代码同样使用了类似面向对象的设计,从基本的SCSI设备对象可以派生出各种不同类型的设备,CDROM,Disk 等等。 无论是Esxi还是Workstation的 vmx 都有几乎一样的处理代码,但真正引起我们注意的是 Esxi 在默认情况下并没有使用 vmx 中对磁盘请求处理的代码,只有在启用了 HostEmulated 配置时,才会由vmx负责处理。 通过前文对 vmm 部分的分析,我们发现Esxi默认情况下正是通过 vmm 中对 VMKernel 的调用使用 VMKernel 中对应的模拟代码进行处理,这很快就引起了我们的兴趣,在 VMKernel 的范围下,哪怕是出现断言错误都可能带来整个 Hypervisor 的瘫痪,从而引起单个Esxi上所有客户机拒绝服务。 二、漏洞一:CVE-2024-22273:Out-of-bounds Read/Write 关于磁盘部分的第一个漏洞,如果按照控制器-后端设备模型来看,它处于后端设备模拟部分。 VMware会将所有请求在模拟阶段统一转化为SCSI指令,接着解析你访问的磁盘ID,根据磁盘ID来将SCSI指令转发到对应的设备上。转发这一过程,在VMware中有一个专门的函数进行处理,我们将其称为SCSIDevice_Dispatch。在SCSIDevice_Dispatch函数中,首先会解析你SCSI指令中的CDB部分,判断CDB请求是否符合要求。处理完CDB请求后,会来到我们将其称为HBAHosted_PostIo的函数中。 该函数中有一段特别的代码逻辑,这段代码逻辑可以理解为磁盘验证器功能,磁盘验证器负责检测磁盘是否存在坏扇区。验证原理如下:硬盘以块为单位(扇区)写入数据,硬盘每次更新扇区时,也会更新校验和(紧接在扇区数据之后存储)。当从硬盘驱动器读取扇区时,预计扇区校验和将与扇区数据匹配,如果不匹配,则表示磁盘在写入操作期间出现了问题,存在坏扇区。 VMware的磁盘验证器代码中,申请了一块等价磁盘大小的堆作为校验和的存储内容,对磁盘进行访问操作时(Read/Write),磁盘验证器并没有对命令中访问扇区的边界做任何检测与限制,直接计算用户访问的目标扇区的校验和并将其写入对应内存,这就导致了用户访问的目标扇区可能超出磁盘的扇区上限,引发严重的堆越界访问问题。 又因为CDB命令中,读写指令的最大范围为Write16/Read16。 即允许访问的扇区数最大数据类型为uint64,从而形成了骇人听闻的任意写漏洞。 该漏洞同时存在于Workstation/Esxi中,但对应的触发路径不尽相同。在Workstation中,可以从CD/ROM或SCSI磁盘两个方面分别去触发该漏洞;但在Esxi中,只能从CD/ROM去触发漏洞,无法从SCSI磁盘角度去触发。 因为在Esxi中,VMM会判断主机是否处于hostedEmulation模式,如果处于,就将请求通过UserRPC发送到VMX中处理,如果不处于,就将请求通过vmkcall发送到VMKernel,这就导致了在Esxi的磁盘设备上无法触发该漏洞。 当然,正因为Esxi会将磁盘请求发送到VMKernel中去处理,这也引出了后续关于VMKernel中磁盘的漏洞。 三、漏洞二:CVE-2024-37086:Out-of-bounds Read 我们发现,VMware在VMKernel中对发送来的磁盘请求处理已经尽可能的小心翼翼,禁用了许多不必要的SCSI命令,只启用小部分必要的SCSI命令。但即使是在如此谨慎的情况下,被启用的SCSI命令中依然存在严重的设计问题。 SCSI命令中的UNMAP命令允许一个或多个LBA(Logical Block Address)被取消映射,该命令常用在精简配置技术中,以提高存储利用率、灵活的容量规划和不间断存储配置服务。 在SPC-6(SCSI Primary Commands - 6)中对于UNMAP命令的设计如下图所示: 先来解释一下图里重要的数据结构: Table 204 UNMAP command中最重要的字段为PARAMETER LIST LENGTH,表示应用客户端发送到设备服务器的 UNMAP 参数数据的长度...

2024年09月18日 · 1 分钟 · s0duku

【DEFCON & HITB】Bug Hunting In VMware Device Virtualization(中篇)

本文是天工实验室在DEFCON上发表的议题《Dragon Slaying Guide: Bug Hunting in VMware Device Virtualization》的第二部分内容。在该议题的第一篇文章中,介绍了VMware虚拟化实现的内容。 本周将继续讲解议题第二个重要部分:USB Device Virtualization,通过讲解我们挖掘的漏洞,介绍主机控制器、VUsb及模拟USB设备,即整个USB系统视角下各处可能出现的安全问题。 一、前言 我们对vmm和vmx以及是其他位于Host上的服务上进行逆向分析,并且尽可能全面的分析整个 USB 设备的模拟过程,从USB主机控制器的实现(UHCI, EHCI, XHCI)到具体后端USB设备的模拟,并在其中发现了 多个错误,其中一些甚至与天府杯2023的所使用的漏洞达成了一致,接下来我们会介绍VMware对USB系统模拟的实现,以及其中一些典型错误产生的原因,以及所能它们带给我们的启示。 VMware 实现 USB 模拟的代码,大体上可以结构为三个部分,第一个部分为 USB 主机控制器模拟,这部分代码负责模拟 USB 主机控制器设备,包括 UHCI,EHCI,XHCI 三种,这部分代码负责处理整个USB传输中与主机控制器相关的数据传输部分,三种控制器的mmio处理基本都是现在 vmm 中,vmm 负责按照手册标准处理内存寄存器访问的各种实现,并通过UserRpc调用vmx配合实现具体主机控制器的数据传输过程。整个模拟最重要的部分为将Guest传输的数据从主机控制器表示形式转换成保存在URB对象的USB Request形式,并将URB对象通过VUsb中间层传输给后端USB设备。 第二个部分我称为 VUsb 中间层,这层代码负责对接主机控制器和后端USB设备,他在所有后端USB设备上形成了一层抽象,USB主机控制器代码大多负责将Guest的输入重新封装成 URB 对象,VUsb 这层代码则负责管理URB相关的对象,他会更具后端目标设备类型的不同选择不同URB对象分配和释放方式,不同的后端USB设备还会在VUsb层形成一个统一表示后端设备的 VUsbDeviceObj,在传输URB时VUsb还会将Urb交给VUsbDeviceObj中目标Endpoint对应VUsbPipe对象管理。 第三个部分即VUsb 后端设备,VMware实现了大量不同类型USB设备的模拟,包括 HID,Bluetooth,CCID,他们大多采用一个回调函数处理URB对象,并根据URB对象的保存的数据进行行为模拟。其中比较特殊的时VUsbGeneric这类设备,这类设备在Guest Machine表示通用USB设备,一般用来直通Host上的物理USB设备,VMware通过Host上的本地 usbarbitrator 服务转发vmx中的请求数据。 二、漏洞一:CVE-2024-22255: Uninitialized Memory 我们分享的第一个漏洞来自于UHCI控制器模拟部分。在USB设备的控制传输中,USB设备使用有效载荷之一是Standard Device Request,他以 Setup Packet 格式开始。 Setup Packet Format Offest Field Size 0 bmRequestType 1 1 bRequest 1 2 wValue 2 4 wIndex 2 6 wLength 2 其中最有趣的字段在于 wLength,他将提醒 Usb 设备请求跟随的后续数据的长度。Standard Device request 是Usb设备的有效载荷,对于USB主机控制器来说它并不以此为单位传输数据,对于UHCI,他以 Transfer Descriptor 为单位传输数据,并在Guest内存中以Queue Head (QH) 类似链表的形式链接起来。VMware的UHCI控制器在处理控制传输时,需要以单次Standard Device request为单位分配URB对象,他将合并位于Queue Head上所有与请求相关的Transfer Descriptor (TD)中的待传输数据。...

2024年09月11日 · 2 分钟 · s0duku

【DEFCON & HITB】Bug Hunting In VMware Device Virtualization(上篇)

奇安信天工实验室安全研究成果,入选国际顶级安全会议DEFCON 32 和 HITBSecConf 2024,议题名称《Dragon Slaying Guide: Bug Hunting In VMware Device Virtualization》。 我们将该议题分为三篇文章进行详细讲解。本文是第一篇,主要介绍VMware虚拟化实现,为后续深入探讨VMware虚拟设备漏洞挖掘打下坚实的理论基础。 一、Introduction VMware Workstation/ESXi是市场上最流行的商用虚拟化软件之一。其复杂的虚拟化系统设计和在基础设施中的关键地位使其长期成为黑客的顶级目标。对于安全研究人员来说,发现VMware Hypervisor中的虚拟化逃逸漏洞就像在角色扮演游戏中与巨龙较量一样具有挑战性。 本议题揭露了一个新型攻击面:Device Virtualization in VMKernel 。这是迄今为止,尚未被安全研究探索的未知领地。且该攻击视角尚未被VMware考虑进防御体系,其现有的沙箱机制理论上完全无法防御从VMKernel发起的攻击。在对本次攻击面的分析和VMware Hypervisor的逆向工程中,我们发现了8个与设备虚拟化相关的漏洞,其中5个漏洞已经被分配了CVE编号(CVE-2024-22251、CVE-2024-22252、CVE-2024-22255、CVE-2024-22273、CVE-2024-37086),其余3个漏洞已经被VMware确认。 本议题将从VMware虚拟化实现、USB Device Virtualization 和 SCSI Device Virtualization 三个部分递进讲解,如何发现VMKernel这个攻击面,找到多个未知漏洞的过程。 本周将为大家介绍第一部分:VMware虚拟化实现。该部分会深入介绍 vmm 的加载过程,vmm与vmx数据共享功能的实现,VMware的UserRPC这一Hypervisor与Host通信的实现,这些都是在虚拟设备模拟中至关重要的机制。 二、VMware Virtualization Details 我们将通过介绍我们对VMware 设备虚拟化的逆向工作,来展示我们是如何发现VMKernel这一与设备虚拟化相关的新攻击面的。为了方便阐述我们会用自己逆向所定义的符号名配合代码片段进行解释,其中也有部分符号直接来自于open-vm-tools,我们发现open-vm-tools与vmx共享很多通用数据结构,这加速了我们的逆向分析过程。 我们都知道VMware利用UserRpc机制完成了对很多虚拟设备的实现,在分析具体UserRpcHandler时我们总是会发现vmx经常会使用一些与vmm称为SharedArea 的共享数据,只审计UserRpcHandler我们无法判断这些数据的来源与去向,这时常会让我们有些抓狂。所以我们决定首先分析 UserRpc 的实现,以了解VMware在设备虚拟化方面的工作流程,判断我们在Guest中的数据可以影响的二进制代码块。 三、UserRpc In VMX 当 vmx 进程启动时,其最重要的部分就是按顺序初始化系统需要使用的所有模块,这个模块的表项由模块名和启动初始化函数组成,他很容易从二进制入口点静态分析追踪到,除此之外我们还使用了API Monitor 来监控vmx与内核模块vmx86.sys的通信过程,通过IOCTL指令立即数,我们能在vmx中定位到对应请求发起的位置,以及在vmx86.sys中对应的处理代码。幸运的是,我们能在IDA中看到一些调试日志字符串,这让我们更容易理解相应IOCTL指令的含义。 首先引起我们注意的便是 “IOCTL_VMX86_RUN_VM” 这条指令,他被调用于一个线程的循环内。代码结构上,它一直保持循环调用并会使用 IOCTL_VMX86_RUN_VM 的返回值作为参数之一传递给 Monitor_ProcessUserRpcCall 负责调用对应的处理函数。这种代码结构正是我们需要寻找的 vmm 切回宿主机并调用 vmx 处理UserRpc请求的过程代码,Monitor_ProcessUserRpcCall 其中调用功能函数表就是 Vmware 的 UserRPC 功能在 vmx 侧的实现,并且这些UserRpcHandler函数使用了称为userRpcBlock的共享内存区域指针作为其唯一的参数。...

2024年09月04日 · 2 分钟 · s0duku