|Home » Industry Watch
Microsoft VDM Bug Affects All Versions of Windows
Affects all versions including Windows 7. When it rains, it pours. Especially in the Seattle area.
REDMOND (Rixstep) -- When it rains, it pours. Especially in the Seattle area. Tavis Ormandy has published full details on a privilege escalation hack of all versions of Windows including Windows 7.
The exploit takes advantage of a bug in the Windows implementation of the 'virtual DOS machine' used to run legacy 16-bit programs. The exploit can be avoided by turning the VDM 'feature' off but the danger of course is that enough Windows lusers won't know about the bug and/or bother turning the 'feature' off.
16-bit applications need BIOS support; the Windows kernel supports virtual BIOS interrupts in its 'Virtual-8086' mode monitor code. The code is implemented in two stages. The #GP trap handler transitions to the second stage when CS:EIP faults with specific 'magic' values.
The transition requires (subsequent to authentication) restoring the context and the call stack from the faulting trap frame. But the authentication process is flawed, relying as it does on three incorrect assumptions.
- Setting up a VDM context requires SeTcbPrivilege.
The barrier to getting a VDM context can be subverted by requesting the NT VDM subsystem and then using CreateRemoteThread() to run code in the context of the VDM subsystem. The VDM subsystem already has the necessary flag set.
- Ring 3 (unprivileged) code cannot install arbitrary code segment selectors.
Using the two least significant bits of CS/SS to calculate the privilege of a task doesn't work when it comes to Virtual-8086 mode. The 20-bit addressing (by adding CS << 4 to the 16-bit IP) is also used to map onto the protected linear Virtual-8086 address space. If CS can be set to an arbitrary value, then the privilege calculation can be circumvented.
- Ring 3 (unprivileged) code cannot forge a trap frame.
Returns to user mode are through IRET. An invalid context can cause IRET to fail pre-commit, which in turn forges a trap frame. And even with address randomisation it's trivial to use NtQuerySystemInformation() to obtain the address of the second stage BIOS handler.
This bug dates back 17 years and affects all systems released since 27 July 1993 - Windows 2000, Windows XP, Windows Server 2003, Windows Vista, Windows Server 2008, and Windows 7. See the links below for further details.
Windows plagued by 17-year-old privilege escalation bug
NEOPHASIS: Trap Handler Allows Users to Switch Kernel Stack