Lucene search

K
packetstormDerek SoederPACKETSTORM:111404
HistoryMar 30, 2012 - 12:00 a.m.

VMware High-Bandwidth Backdoor ROM Overwrite Privilege Elevation

2012-03-3000:00:00
Derek Soeder
packetstormsecurity.com
81

0.002 Low

EPSS

Percentile

62.1%

`VMware High-Bandwidth Backdoor ROM Overwrite Privilege Elevation  
  
Derek Soeder  
[email protected]  
  
Reported: December 5, 2011  
Published: March 30, 2012  
  
  
AFFECTED VENDOR  
---------------  
VMware, Inc.  
  
  
AFFECTED ENVIRONMENTS  
---------------------  
The following VMware product versions are known to be affected:  
VMware Server 1.0.10 and earlier  
VMware Server 2.0.2 and earlier  
VMware Workstation 7.0.0  
VMware Workstation 7.1.1 and earlier  
VMware ESXi 3.5.0 Update 5  
VMware ESXi 4.0.0 Update 4 Build 504850 and earlier  
VMware ESXi 4.1.0 Build 320137 (ESXi410-201011401-BG) and earlier  
Other related versions not tested but assumed to be affected  
  
The following guest operating systems are known to enable exploitation:  
Windows NT 4.0  
Windows 2000  
Windows XP (32-bit)  
Windows Server 2003 (32-bit)  
  
  
UNAFFECTED ENVIRONMENTS  
-----------------------  
The following VMware product versions are not affected:  
VMware Workstation 7.1.2 and later  
VMware ESXi 4.0.0 Update 4 with patch ESXi400-201203401-SG  
VMware ESXi 4.1.0 Update 1 Build 348481 (ESXi410-201101201-SG) and later  
VMware ESXi 5.0.0  
  
The following guest operating systems do not appear to permit exploitation:  
Windows XP (64-bit)  
Windows Server 2003 (64-bit)  
Windows Vista (32-bit and 64-bit)  
Windows Server 2008 (32-bit and 64-bit)  
Windows 7 (32-bit and 64-bit)  
Windows Server 2008 R2  
  
  
IDENTIFIERS  
-----------  
CVE-2012-1515  
  
  
IMPACT  
------  
The vulnerability described in this document can be exploited by  
unprivileged code running on certain guest operating systems in a  
VMware virtual machine in order to execute arbitrary code with kernel  
privileges.  
  
  
VULNERABILITY DETAILS  
---------------------  
The VMware backdoor interface consists of a number of operations  
issued via I/O instructions executed in the guest with a command  
number in CX and data or "magic" values in a number of other  
registers. Command 0x1E / 30 (BDOOR_CMD_MESSAGE) and its subcommands  
(MESSAGE_TYPE_*) allow messages to be exchanged between the guest and  
host. Since the regular backdoor would only allow for the exchange of  
no more than one machine word of data per I/O instruction, a  
"high-bandwidth" backdoor exists on port 0x5659 (BDOORHB_PORT) to  
permit bulk transmission of data from and to the guest via the REP  
OUTSB and REP INSB instructions respectively. If the direction flag  
is clear, the host performs the transfer by memcpy'ing directly from  
or to its mapping of guest memory, after performing any applicable  
address translations and memory access checks.  
  
One special case that the host fails to consider, however, is when a  
REP INSB is targeting memory that would normally be emulated as  
read-only. If the guest operating system allows an unprivileged user  
to address a writable view of read-only memory, the user can exploit  
this vulnerability to modify the ROM's contents whereas he otherwise  
could not. To then parlay this ability into a successful attack  
requires causing privileged code that trusts the ROM to act on the  
altered contents in an exploitable way.  
  
  
EXPLOITATION  
------------  
Only 32-bit editions of Windows prior to Vista allow an unprivileged  
user to map a PAGE_READWRITE view of the BIOS ROM by launching a  
Virtual DOS Machine (NTVDM.EXE). On 32-bit Windows Vista and Windows  
Server 2008, NT!VdmpInitialize is hard-coded to map physical addresses  
0xC0000 through 0xFFFFF at the corresponding virtual addresses as  
PAGE_READONLY, while 32-bit Windows 7 allocates writable virtual  
memory at 0xC0000 and copies in the contents of the BIOS ROM, and VDM  
support does not exist at all in 64-bit editions of Windows.  
(Presumably, ROM was originally mapped as writable so that 16-bit code  
that tried for any reason to write to ROM could do so and have it  
silently fail while still causing the expected side effects like  
updating the flags. One wonders what prompted the change on Vista.)  
  
Although this vulnerability allows modification of the in-guest BIOS  
ROM, there seem to be few opportunities to get Windows to execute  
modified BIOS code. One possible attack involves putting the modified  
code in place and initiating or waiting for a soft reboot, after which  
the planted code would execute and could mount a BootRoot-style attack  
to alter the guest kernel as it loads. Another possibility is to  
modify BIOS code and wait for some other user to run a 16-bit program  
that changes the video mode or makes an exotic BIOS call unhandled by  
NTVDM, but this is obviously flimsy. The third and best possibility,  
discussed below, is to cause the kernel to change the video mode,  
which will execute an INT 10h instruction from one of two Virtual-8086  
mode environments, either of which can be escaped to infiltrate the  
kernel.  
  
As the author mentioned in the advisory for CVE-2007-1206 (which  
allowed modification of the Interrupt Vector Table rather than the  
BIOS code it references), HAL.DLL will issue an INT 10h to prepare for  
hibernation or a blue-screen, both of which could be considered "local  
denial-of-service" conditions. However, the author has since found  
that requesting full-screen text mode or switching to a VGA display  
mode will also cause the INT 10h handler to be executed, although by  
NTOSKRNL.EXE rather than HAL. Rough reverse call trees for both are  
depicted below:  
  
HAL!HalpBiosCall  
^ HAL!HalpBiosDisplayReset (via NT!HalPrivateDispatchTable)  
. ^ BOOTVID!VidResetDisplay  
. . ^ NT!VidResetDisplay  
. . . ^ NT!InbvResetDisplay  
. . . . ^ NT!KeBugCheck2  
. . . . . ^ (blue-screen)  
. . . . ^ HAL!InbvResetDisplay  
. . . . . ^ HAL!HalHandleNMI  
. . . . . . ^ NT!KiTrap02  
. . . . . . . ^ (catastrophe)  
. . . . ^ NT!PopSaveHiberContext (via DPC)  
. . . . . ^ NT!PopInvokeSystemStateHandler  
. . . . . . ^ NT!PopShutdownSystem  
. . . . . . . ^ NT!PopGracefulShutdown  
. . . . . . . . ^ NT!NtSetSystemPowerState  
. . . . . . . . . ^ NT!NtShutdownSystem  
. . . . . . ^ NT!PopSleepSystem  
. . . . . . . ^ NT!NtSetSystemPowerState  
. . . . . . . . ^ NT!NtShutdownSystem  
  
NT!Ke386CallBios  
^ VIDEOPRT!Ke386CallBios  
. ^ VIDEOPRT!VideoPortInt10  
. . ^ VGA!VgaSetMode  
. . . ^ VGA!VgaStartIO  
. . . . ^ VIDEOPRT!pVideoPortDispatch  
. . . . . ^ NT!IofCallDriver  
. . . . . . ^ WIN32K!GreDeviceIoControl  
. . . . . . . ^ WIN32K!EngDeviceIoControl  
. . . . . . . . ^ (...)  
. . . . . . . . . ^ WIN32K!DrvChangeDisplaySettings  
. . . . . . . . . . ^ WIN32K!xxxUserChangeDisplaySettings  
. . . . . . . . . . . ^ WIN32K!NtUserChangeDisplaySettings  
. . . . . . . . . . . . ^ USER32!NtUserChangeDisplaySettings  
. . . . . . . . . . . . . ^ USER32!ChangeDisplaySettings*  
. . . . . . . . ^ (...)  
. . . . . . . . . ^ WIN32K!xxxbFullscreenSwitch  
. . . . . . . . . . ^ WIN32K!xxxConsoleControl  
. . . . . . . . . . . ^ WIN32K!NtUserConsoleControl  
. . . . . . . . . . . . ^ WINSRV!NtUserConsoleControl  
. . . . . . . . . . . . . ^ WINSRV!ChangeDispSettings  
. . . . . . . . . . . . . . ^ WINSRV!HandleSysKeyEvent  
. . . . . . . . . . . . . . . ^ WINSRV!ConsoleWindowProc  
. . . . . . . . . . . . . . . . ^ (...)  
. . . . . . . . . . . . . . . . . ^ NTDLL!CsrClientCallServer  
. . . . . . . . . . . . . . . . . . ^ KERNEL32!SetConsoleDisplayMode  
. . ^ VIDEOPRT!VpInt10CallBios  
. . . ^ VGA!GetVideoMemoryBaseAddress  
. . . . ^ VGA!VgaSetMode  
. . . . . ^ (...)  
  
As suggested above, unprivileged code can cause execution of the BIOS  
INT 10h handler from either HAL or NTOSKRNL, the former through a  
blue-screen or shutdown (such as hibernation), and the latter by  
changing the video mode, which requires console access. Assuming that  
malicious code has access to the console, and assuming that the video  
driver does not prevent it (as the VMware Tools video driver in some  
cases does), the malicious code could call ChangeDisplaySettings[Ex]  
or SetConsoleDisplayMode to force a video mode change without needing  
SeShutdownPrivilege or an independent blue-screen flaw. The following  
paragraphs cover exploitation in both the HAL and NTOSKRNL cases,  
starting from the assumption that an attacker has already modified the  
BIOS's INT 10h handler code.  
  
To infiltrate the kernel when invoked via HAL!HalpBiosCall, the  
malicious INT 10h handler code can simply modify the pages of memory  
containing HAL!HalpRealModeStart, the V86-mode stack, and  
HAL!HalpRealModeEnd, which HAL!HalpBiosDisplayReset maps with write  
permissions at virtual address 0x20000. Once execution returns to  
HAL!HalpRealModeEnd following attempted execution of the C4h/C4h  
sequence, the attacker will be executing code in the familiar Windows  
kernel environment, albeit with some cleanup necessary. Malicious  
code might detect the HAL case by observing if SS = 0x2000.  
  
Infiltrating the kernel from the NT!Ke386CallBios environment, on the  
other hand, is a little more indirect. NTOSKRNL issues an INT 10h  
from a proper VDM with no interesting kernel code targets, but the VDM  
TIB is accessible to V86-mode code (at address 0x12000). The  
malicious INT 10h handler can modify the kernel stack pointer stored  
in 'CONTEXT.Esi', just as described in Tavis Ormandy's CVE-2010-0232  
advisory ("Microsoft Windows NT #GP Trap Handler Allows Users to  
Switch Kernel Stack"), in order to hijack execution after the cleanup  
code at NT!Ki386BiosCallReturnAddress completes. Malicious code might  
detect the NTOSKRNL case by checking for SS = 0x1000.  
  
Of course, none of this matters without the ability to meaningfully  
modify BIOS code. Malicious code in the guest can only modify ROM  
through the high-bandwidth backdoor REP INSB instruction, meaning it  
can only overwrite ROM with bytes it can read from the host. Although  
VMware Server 1.0 permits the guest to read host stack memory beyond  
the end of any host-to-guest message, which allows reading of (and  
therefore overwriting with) arbitrary bytes by first "seeding" the  
buffer with a long REP OUTSB, a more version-independent approach is  
to first use the "info-set" command to store an arbitrary low-byte  
string in the VMDb "guestinfo" database, and then use "info-get" to  
read the string from the host and overwrite the desired portion of  
guest ROM.  
  
The author's proof-of-concept exploit uses this technique to implement  
a six-stage approach, comprising: (1) the replacement INT 10h handler,  
a tiny, low-byte arithmetic / PUSH / Jcc sequence that computes the  
offset of the next stage, pushes it, and branches to a nearby RET,  
RETF, or IRET; (2) a larger, low-byte sequence stored over the 8x8  
graphics font table (hopefully in video BIOS ROM pointed to by the INT  
1Fh vector) that computes the bytes of the next stage, pushes them  
onto the stack, and branches to a nearby RETF or IRET; (3) a small,  
base-64-like decoder that decodes and executes the next stage, which  
was also stored in the font table; (4) a loader that reads the  
subsequent stages into RAM from the "guestinfo" database via the  
VMware backdoor interface, decodes them, and executes the next stage;  
(5) the main V86-mode payload, which prepares the next stage to  
execute in ring 0 using the appropriate, aforementioned HAL or  
NTOSKRNL infiltration technique; and (6) the main kernel payload,  
which creates an interrupt gate for convenient kernel access and  
cleans up the environment so that execution can resume without  
crashing. The Win32 portion of the exploit can then use the interrupt  
gate as needed.  
  
With ring-0 privileges, the payload can restore the original contents  
of BIOS ROM (assuming it preserved them) by making ROM writable via  
PCI configuration space. In the eight bytes of PCI configuration  
space starting at address 0x80000058, bit 0 and bit 4 each indicate  
whether or not a segment of BIOS ROM is mapped, and bits 1 and 5  
determine whether or not those segments are writable. Setting the  
writable bits for all mapped segments, then, allows the ROM to be  
directly overwritten with arbitrary bytes, as opposed to being  
overwritten indirectly and only with low bytes through re-exploitation  
of the vulnerability.  
  
Another ramification of exploitation requiring rectification is the  
unavoidable change in video mode. Before it invokes the INT 10h  
handler, the kernel has already changed the display mode and  
consequently blacked out the screen, so programming the malicious  
handler to return without executing the original handler doesn't help  
and could actually make it more difficult to properly restore the  
display. One easy means of recovering from the mode change is to  
inject code into session 0's WINLOGON.EXE process that enumerates  
desktops and calls "ChangeDisplaySettings(NULL, CDS_RESET)" while  
attached to each, although some amount of display flickering is  
nevertheless inevitable.  
  
  
MITIGATION  
----------  
  
* Disable NTVDM in the guest operating system  
  
Disabling Virtual DOS Machine (NTVDM) support in the guest should deny  
an unprivileged user the ability to obtain a writable mapping of ROM  
on affected versions of Windows, thereby preventing exploitation of  
the vulnerability. To disable NTVDM, follow the guidance presented in  
one of the following Microsoft Knowledge Base Articles:  
  
http://support.microsoft.com/kb/979682  
http://support.microsoft.com/kb/220159  
  
Or, manually set the "VDMDisallowed" registry value, which is  
mentioned on the following page: (Note that this registry value is  
not recognized by all versions of Windows.)  
  
http://technet.microsoft.com/en-us/library/cc783069.aspx  
  
Be aware that disabling NTVDM will break 32-bit applications that rely  
on DOS functionality, in addition to 16-bit applications.  
  
* Run untrusted programs in a Remote Desktop session, and do not allow  
the guest to power down or restart  
  
The most likely exploitation scenarios require that the attack code be  
able to trigger a kernel BIOS call, which is most easily accomplished  
by changing the guest's video mode. Running suspect code in a Remote  
Desktop session--as opposed to a console session--prevents the code  
from changing the video mode, thereby reducing the likelihood of  
successful elevation to kernel privileges. (Of course, make sure that  
dangerous Remote Desktop features, such as local drive sharing, are  
disabled when running untrusted code in this way.)  
  
Another feasible exploitation scenario involves overwriting the BIOS  
and then causing a shutdown, a restart, or hibernation. Run untrusted  
code in the guest as an unprivileged user without shutdown privileges,  
and force the virtual machine to power down afterwards; do not allow  
the guest to gracefully power down or restart, as that might give  
modified code an opportunity to execute.  
  
Because this workaround does not prevent modification of BIOS ROM,  
malicious code could still attempt to exploit the vulnerability by  
causing a blue-screen or planting code for other users' VDMs to  
execute.  
  
* Disable the "info-get" and "info-set" commands  
  
Exploitation depends on the attacker being able to overwrite ROM with  
the contents of backdoor command responses, which the "info-set" and  
"info-get" commands facilitate by allowing the attacker to store and  
retrieve arbitrary data. These commands can be disabled in a specific  
guest by adding the following lines to the virtual machine's .vmx  
configuration file:  
  
isolation.tools.getInfo.disable = "TRUE"  
isolation.tools.setInfo.disable = "TRUE"  
  
Note that the second line also disables the "SetGuestInfo" command.  
It is not known if disabling these commands disrupts any guest  
monitoring or other VMware Tools functionality.  
  
* Restrict access to the VMware backdoor interface  
  
Adding the following line to the virtual machine's .vmx configuration  
file will prevent unprivileged code (code with CPL > IOPL) from  
accessing the VMware backdoor interface, rendering the vulnerability  
unexploitable for the sake of privilege elevation:  
  
monitor_control.restrict_backdoor = "TRUE"  
  
With this setting in place, an unprivileged attempt to execute a  
VMware backdoor port I/O instruction will result in a privileged  
instruction exception. Note that this setting crashes the user-mode  
portion of VMware Tools, and thus disrupts certain features such as  
guest-host copy-and-paste and drag-and-drop.  
  
  
CONCLUSION  
----------  
This document discloses a guest privilege elevation vulnerability  
arising from fairly arcane behavior of VMware's backdoor interface,  
and makes a case for its exploitability by presenting at a high level  
the steps performed by the author's own functioning proof of concept.  
  
It is not known if other machine virtualization software is  
susceptible to similar issues regarding incomplete emulation of  
read-only memory.  
  
  
GREETINGS  
---------  
www.ridgewayis.com  
www.ftmband.com  
`