从编译器优化到代码执行:深入剖析VirtualBox VM 逃逸漏洞(CVE-2018-2844)

2019-04-04 约 2028 字 预计阅读 5 分钟

声明:本文 【从编译器优化到代码执行:深入剖析VirtualBox VM 逃逸漏洞(CVE-2018-2844)】 由作者 mss**** 于 2018-08-29 09:42:04 首发 先知社区 曾经 浏览数 2148 次

感谢 mss**** 的辛苦付出!

原文: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

关键词:[‘技术文章’, ‘技术文章’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now