原文:https://www.voidsecurity.in/2018/08/from-compiler-optimization-to-code.html

目前,Oracle公司已经修复了本人在2010年4月提交的VirtualBox某些高危漏洞。CVE-2018-2844漏洞是一个有趣的Double Fetch型漏洞,该漏洞存在于 VirtualBox 的核心图形框架的VirtualBox视频加速功能(VBVA)中,影响Linux宿主机操作系统。VBVA功能是建立在VirtualBox宿主机-客户机共享内存接口(HGSMI)的基础之上的,而HGSMI则是通过视频RAM缓冲区实现的共享内存。其中,该VRAM缓冲区的物理地址为0xE0000000。

sudo lspci -vvv

00:02.0 VGA compatible controller: InnoTek Systemberatung GmbH VirtualBox Graphics Adapter (prog-if 00 [VGA controller])
 ...
 Interrupt: pin A routed to IRQ 10
 Region 0: Memory at e0000000 (32-bit, prefetchable) [size=16M]
 Expansion ROM at  [disabled]
 Kernel modules: vboxvideo

客户机将使用如下所示的HGSMI来设置命令缓冲区,并将VRAM中的偏移量写入IO端口VGA_PORT_HGSMI_GUEST(0x3d0)中,以此来通知宿主机。

HGSMIBUFFERHEADER header; 
 uint8_t data[header.u32BufferSize]; 
 HGSMIBUFFERTAIL tail;

该漏洞正好位于处理从客户机传递给宿主机的视频DMA(VDMA)命令的代码中。VDMA命令处理函数vboxVDMACmdExec()会根据VDMA命令的类型来调度相应的函数。实际上,这个调度过程是利用switch case语句实现的。

static int
vboxVDMACmdExec(PVBOXVDMAHOST pVdma, const uint8_t *pvBuffer, uint32_t cbBuffer)
{
 /* pvBuffer is shared memory in VRAM */
        PVBOXVDMACMD pCmd = (PVBOXVDMACMD)pvBuffer;

        switch (pCmd->enmType) {
                case VBOXVDMACMD_TYPE_CHROMIUM_CMD: {
                        ...
                }
                case VBOXVDMACMD_TYPE_DMA_PRESENT_BLT: {
                        ...
                }
                case VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER: {
                        ...
                }
                case VBOXVDMACMD_TYPE_DMA_NOP: {
                        ...
                }
                case VBOXVDMACMD_TYPE_CHILD_STATUS_IRQ: {
                        ...
                }
                default: {
                         ...
                }
        }
}

编译时,编译器将其中的条件分支优化为跳转表。经过优化后,代码将会变为:

; first fetch happens for cmp
.text:00000000000B957A                 cmp     dword ptr [r12], 0Ah ; switch 11 cases
.text:00000000000B957F                 ja      VBOXVDMACMD_TYPE_DEFAULT ; jumptable 00000000000B9597 default case

; second fetch again for pCmd->enmType from shared memory
.text:00000000000B9585                 mov     eax, [r12]
.text:00000000000B9589                 lea     rbx, vboxVDMACmdExec_JMPS
.text:00000000000B9590                 movsxd  rax, dword ptr [rbx+rax*4]
.text:00000000000B9594                 add     rax, rbx
.text:00000000000B9597                 jmp     rax             ; switch jump

.rodata:0000000000185538 vboxVDMACmdExec_JMPS dd offset VBOXVDMACMD_TYPE_DEFAULT - 185538h
.rodata:0000000000185538                                         ; DATA XREF: vboxVDMACommand+1D9o
.rodata:0000000000185538                 dd offset VBOXVDMACMD_TYPE_DMA_PRESENT_BLT - 185538h ; jump table for switch statement
.rodata:0000000000185538                 dd offset VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER - 185538h
.rodata:0000000000185538                 dd offset VBOXVDMACMD_TYPE_DEFAULT - 185538h
.rodata:0000000000185538                 dd offset VBOXVDMACMD_TYPE_DEFAULT - 185538h
.rodata:0000000000185538                 dd offset VBOXVDMACMD_TYPE_DEFAULT - 185538h
.rodata:0000000000185538                 dd offset VBOXVDMACMD_TYPE_DEFAULT - 185538h
.rodata:0000000000185538                 dd offset VBOXVDMACMD_TYPE_DMA_NOP - 185538h
.rodata:0000000000185538                 dd offset VBOXVDMACMD_TYPE_DMA_NOP - 185538h
.rodata:0000000000185538                 dd offset VBOXVDMACMD_TYPE_DEFAULT - 185538h
.rodata:0000000000185538                 dd offset VBOXVDMACMD_TYPE_DMA_NOP - 185538h
.rodata:0000000000185564                 align 20h

问题已经很明显了,这是一个TOCTOU错误。由于变量未标记为volatile,因此,GCC的优化处理将导致共享VRAM内存的Double Fetch型漏洞。需要注意的是,由于Windows和OSX平台上的VirtualBox中没有进行这种优化处理,因此,该漏洞只影响Linux主机。

请注意,这类漏洞并不是现在才发现的。我们的研究人员发表的Xenpwn - Breaking Paravirtualized Devices报告中,就指出Xen也存在类似问题。

漏洞利用


虽然这个竞争条件的时间窗口非常小,但是对于拥有多个vCPU的客户机来说,还是可以进行“稳定的”利用的。

RAX  0xdeadbeef
 RBX  0x7fff8abf2538 ◂— rol    byte ptr [rdx - 0xd], 1
 RCX  0x7fff9c508ac0 —▸ 0x7ffff7e30000 ◂— 0x5
 RDX  0xe7b
 RDI  0xeeb
 RSI  0x7fffdc022000 ◂— xor    byte ptr [rax], al /* 0xffe40030; '0' */
 R8   0x7fff89d20000 ◂— jmp    0x7fff89d20010 /* 0xb020000000eeb */
 R9   0x7fff8ab06040 ◂— push   rbp
 R10  0x7fff9c50ad48 ◂— 0x1 
 R11  0x7fff9c508d48 ◂— 0x0
 R12  0x7fff89d20078 ◂— 0xa /* '\n' */ 
 R13  0xf3b
 R14  0x7fff9c50d0e0 —▸ 0x7fff9c508ac0 —▸ 0x7ffff7e30000 ◂— 0x5
 R15  0x7fff89d20030 ◂— 0xffffffdc0f3b0eeb
 RBP  0x7fffba44dc40 —▸ 0x7fffba44dca0 —▸ 0x7fffba44dce0 —▸ 0x7fffba44dd00 —▸ 0x7fffba44dd50 ◂— ...
 RSP  0x7fffba44db80 —▸ 0x7fffba44dbb0 —▸ 0x7fff9c508ac0 —▸ 0x7ffff7e30000 ◂— 0x5
 RIP  0x7fff8ab26590 ◂— movsxd rax, dword ptr [rbx + rax*4]


  0x7fff8ab26590    movsxd rax, dword ptr [rbx + rax*4]
   0x7fff8ab26594    add    rax, rbx
   0x7fff8ab26597    jmp    rax

其中,RAX是由客户机控制的。并且,R8、R12和R15存放的是指向崩溃期间HGSMI缓冲区内的相关偏移量的指针。由于跳转表使用相对寻址方式,因此,无法直接访问指针。我的初步计划是找到一个这样的功能,可以将受控的值从客户机写入VBoxDD.so中,然后将其用作伪跳转表。遗憾的是,我没有找到符合要求的功能。

下一个选项是通过可用于伪跳转表的值,直接跳转到具有RWX权限的VRAM缓冲区。

// VRAM buffer
    0x7fff88d21000     0x7fff89d21000 rwxp  1000000 0


    // VBoxDD.so
    0x7fff8aa6d000     0x7fff8adff000 r-xp   392000 0      /usr/lib/virtualbox/VBoxDD.so
    0x7fff8adff000     0x7fff8afff000 ---p   200000 392000 /usr/lib/virtualbox/VBoxDD.so
    0x7fff8afff000     0x7fff8b010000 r--p    11000 392000 /usr/lib/virtualbox/VBoxDD.so
    0x7fff8b010000     0x7fff8b018000 rw-p     8000 3a3000 /usr/lib/virtualbox/VBoxDD.so

接下来,我们需要在VBoxDD.so(用作伪跳转表)中寻找一个在相对地址计算期间指向16MB共享VRAM缓冲区的值。对于概念验证漏洞利用代码来说,可以使用NOP填充整个VRAM,并将shellcode放置在映射的最后内存页中。由于该跳转指令是相对寻址的,因此不需要绕过ASLR。

在客户机中,将vboxvideo添加到/etc/modprobe.d/blacklist.conf。在vboxvideo.ko驱动程序中,建立一个自定义分配器来管理VRAM内存和HGSMI客户端的实现。将vboxvideo列入黑名单,可以减少VRAM上的活动,从而保证有效荷载的完整性。该漏洞利用代码的测试环境为:Ubuntu Server作为客户机,Ubuntu Desktop作为宿主机,其上运行VirtualBox 5.2.6.r120293。

大家可以在virtualbox-cve-2018-2844找到具有进程延续和网络连接功能的POC代码。

相关的演示视频,读者可以从这里观看。

参考文献:


[1] Xenpwn - Breaking Paravirtualized Devices by Felix Wilhelm
[2] SSD Advisory – Oracle VirtualBox Multiple Guest to Host Escape Vulnerabilities by Niklas Baumstark
[3] VM escape - QEMU Case Study by Mehdi Talbi & Paul Fariello
[4] Xen Security Advisory CVE-2015-8550 / XSA-155
[5] Oracle Critical Patch Update Advisory - April 2018

源链接

Hacking more

...