Windows VDM Zero Page Race Condition Privilege Escalation
Release Date: April 10, 2007
Date Reported: December 12, 2006
Severity: Medium (Local Privilege Escalation to Kernel)
Systems Affected: Windows NT 4.0 SP6 Windows 2000 SP4 Windows XP SP2 (x86) Windows Server 2003 SP2 (x86)
Overview: eEye Digital Security has discovered a local privilege escalation vulnerability in the Windows kernel that allows an unprivileged user with the ability to execute a program to fully compromise an affected system. All x86 versions of Windows up to and including Windows Server 2003 SP2 are vulnerable.
The Windows kernel's Virtual DOS Machine (VDM) implementation features a race condition through which a malicious program can modify the first 4KB page of physical memory (also known as the "zero page"). The data in this region of memory is trusted and may be subsequently used by other Virtual DOS Machines, including a VDM instantiated by the Windows kernel as part of hibernating or effecting a blue-screen crash. Exploitation of this vulnerability therefore allows arbitrary code to run within other users' VDM processes, and even within the kernel if hibernation or a blue-screen can be provoked by any available means.
This vulnerability was silently fixed within Windows Vista in June 2006 or earlier.
Technical Details: As part of VDM initialization, NT!VdmpInitialize (invoked by calling NtVdmControl(3)) copies the contents of the zero page to virtual address 0, so that the VDM can have a duplicate of the system's original Interrupt Vector Table (IVT) and BIOS data area. To accomplish this, VdmpInitialize opens "\Device\PhysicalMemory" with SECTION_ALL_ACCESS, then maps a view of the first 4KB of the section. What happens next is a memmove from this view to virtual address 0, wrapped in an exception handler which will unmap the view and abort the function in the event of an exception; the view is also immediately unmapped if the memmove completes successfully.
Regrettably, the physical memory view is mapped with PAGE_READWRITE memory permissions into the user-mode portion of the address space, so a malicious thread may be able to regain execution before the view is unmapped, and then directly modify the zero page by writing into the view. Although the window of opportunity presented by the race condition is brief, the base address of the mapping is dynamic, and VdmpInitialize can only successfully execute once per process, it is nevertheless possible to quickly and reliably exploit this vulnerability. Working out the details, however, is left as an exercise for the reader.
By creating a number of high-priority, CPU-bound threads within the NTVDM process, the chances of preempting the VdmpInitialize thread while the view is available (for instance, when virtual page 0 is first touched, or during the call to ZwUnmapViewOfSection) increase greatly. As for the address of the view, it can be corralled to the point of predictability by filling the virtual address space of the process, with the exclusion of one hole which the CPU-bound "writer" threads will repeatedly target. And while it is true that VdmpInitialize can only succeed once per process, it can fail endlessly, each time mapping and attempting to duplicate the zero page. If there is no writable memory at virtual address 0 when VdmpInitialize calls memmove, an access violation occurs and the function fails. (Note that this trick does not apply to NT 4.0, as the exception is unhandled and will result in a blue-screen.)
Code executing in Virtual-8086 mode within a VDM may call software interrupts from the IVT at will; the most interesting example is within the VDM established by HAL.DLL!HalpBiosDisplayReset. Here, HalpBiosCall is invoked to transfer execution to HalpRealModeStart, which is simply the instructions "MOV EAX, 12h / INT 10h" followed by a VDM "BOP." The physical page of HAL.DLL containing this code is mapped at virtual address 20000h with write permissions, and therefore the INT 10h handler may patch code within HAL.DLL (for instance, HalpRealModeEnd) in order to transcend V86 mode and infiltrate the kernel directly. (It is also worth noting that the V86-mode code necessarily executes with EFlags.IOPL set to 3.)
Although the kernel is currently only known to use BIOS interrupts in the event of hibernation or a blue-screen (via InbvResetDisplay), this vulnerability does thereby enable what would otherwise be a local denial-of-service to become a local elevation of privileges.
On Windows NT 4.0, which does not support the OBJ_KERNEL_HANDLE ObjectAttributes flag, a second race condition exists wherein the temporary "\Device\PhysicalMemory" section handle opened during VdmpInitialize may be abused by an unprivileged program, allowing write access to the entirety of physical memory.
Protection: Retina - Network Security Scanner has been updated to identify this vulnerability.
Vendor Status: Microsoft has released a patch for this vulnerability. The patch is available at: http://www.microsoft.com/technet/security/bulletin/MS07-022.mspx
Credit: Derek Soeder
Related Links: eEye Research - http://research.eeye.com Retina - Network Security Scanner - Free Trial: http://www.eeye.com/html/products/retina/download/index.html Blink - Unified Client Security Personal - Free For Personal Use For One Year: http://www.eeye.com/html/products/blink/personal/download/index.html Blink - Unified Client Security Professional - Free Trial: http://www.eeye.com/html/products/blink/download/index.html Blink - Unified Client Security Neighborhood Watch - Free For Personal Use: http://www.eeye.com/html/products/blink/neighborhoodwatch/index.html
Greetings: Jim H. RB, SB, MB, SJ, Doc. GLin, CSam, and Tamara
Copyright (c) 1998-2007 eEye Digital Security Permission is hereby granted for the redistribution of this alert electronically. It is not to be edited in any way without express consent of eEye. If you wish to reprint the whole or any part of this alert in any other medium excluding electronic medium, please email alert@eEye.com for permission.
Disclaimer The information within this paper may change without notice. Use of this information constitutes acceptance for use in an AS IS condition. There are no warranties, implied or express, with regard to this information. In no event shall the author be liable for any direct or indirect damages whatsoever arising out of or in connection with the use or spread of this information. Any use of this information is at the user's own risk.