MOKB-06-11-2006

Bug details
Title: Microsoft Windows kernel GDI local privilege escalation
Description: A vulnerability in the handling of GDI kernel structures of Microsoft Windows leads to an exploitable memory corruption condition, causing a denial of service (so-called BSoD) or arbitrary code execution on successful exploitation. This would allow a local user to escalate privileges, gaining full control of the system.
Author/Contributor: Cesar Cerrudo - Contributed proof of concept and information, found vulnerability.
NA<NAgt; - MoKB release, testing, debugging information.
References: None right now.
Proof of concept or exploit: Compile with (cl.exe should be in your PATH, use the Visual Studio command-line shortcut if present to get it ready):
cl GDIKernelPoc.cpp
Debugging information:

The bug has been found by Cesar Cerrudo from Argeniss, and was reported to Microsoft on 22-10-2004. Remains unpatched to date.

Cesar's explanation:

Microsoft Windows GDI Kernel data structures are mapped on a global shared memory section that is created automatically on any windows process that uses GDI objects (process with a GUI, etc.), this section is mapped as read-only, but any process can re-map it as read-write (by default this kernel shared section has read, write, execute permissions), thus processes can write to this section overwriting the GDI kernel data structures, causing a denial of service (BSoD)/ crashing Windows. If certain selected data structures are overwritten with specific data it is possible to perform arbitrary code excecution.
Affected versions:

  • Microsoft Windows 2000
  • Microsoft Windows 2000 Service Pack 1
  • Microsoft Windows 2000 Service Pack 2
  • Microsoft Windows 2000 Service Pack 3
  • Microsoft Windows 2000 Service Pack 4
  • Microsoft Windows XP
  • Microsoft Windows XP Service Pack 1
  • Microsoft Windows XP Service Pack 2

Not affected:

  • Microsoft Windows Server 2003
  • Microsoft Windows Vista (tested with beta 2)

Related debugging information and source code:

typedef struct
{
   DWORD pKernelInfo;
   WORD  ProcessID; 
   WORD  _nCount;
   WORD  nUpper;
   WORD  nType;
   DWORD pUserInfo;
} GDITableEntry;

Microsoft (R) Windows Debugger  Version 6.4.0007.2
Copyright (c) Microsoft Corporation. All rights reserved.

Opened \\.\pipe\com_1
Waiting to reconnect...
Connected to Windows 2000 2195 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established.  (Initial Breakpoint requested)
Symbol search path is: C:\WINDOWS\Symbols
Executable search path is: 
Windows 2000 Kernel Version 2195 UP Free x86 compatible
Kernel base = 0x80400000 PsLoadedModuleList = 0x80481580
System Uptime: not available
Break instruction exception - code 80000003 (first chance)
*******************************************************************************
*                                                                             *
*   You are seeing this message because you pressed either                    *
*       CTRL+C (if you run kd.exe) or,                                        *
*       CTRL+BREAK (if you run WinDBG),                                       *
*   on your debugger machine's keyboard.                                      *
*                                                                             *
*                   THIS IS NOT A BUG OR A SYSTEM CRASH                       *
*                                                                             *
* If you did not intend to break into the debugger, press the "g" key, then   *
* press the "Enter" key now.  This message might immediately reappear.  If it *
* does, press "g" and "Enter" again.                                          *
*                                                                             *
*******************************************************************************
nt!RtlpBreakWithStatusInstruction:
80455554 cc               int     3
kd> g
(...)
Access violation - code c0000005 (!!! second chance !!!)
win32k!HmgDecrementShareReferenceCount+0xc:
a0002b44 8b06             mov     eax,[esi]
*** WARNING: Unable to verify timestamp for NTDLL.DLL
*** ERROR: Module load completed but symbols could not be loaded for NTDLL.DLL
kd> k
ChildEBP RetAddr  
be805ce8 a0001eaf win32k!HmgDecrementShareReferenceCount+0xc
be805d18 a0002109 win32k!XDCOBJ::bCleanDC+0x16d
be805d24 a00034ca win32k!GreCleanDC+0x21
be805d38 a00032d2 win32k!ReleaseCacheDC+0x69
be805d44 a0005331 win32k!_ReleaseDC+0xb
be805d54 80465014 win32k!NtUserCallOneParam+0x20
be805d54 77e415b5 nt!KiSystemService+0xc4
WARNING: Frame IP not in any known module. Following frames may be wrong.
0006fc80 7175f039 0x77e415b5
0006fce0 7175f2a0 0x7175f039
0006fe18 77e4158f 0x7175f2a0
0006fe38 77e41dc9 0x77e4158f
0006fec4 77e41e7e 0x77e41dc9
0006fefc 7cfa9f9b 0x77e41e7e
0006ff1c 7cfa9aed 0x7cfa9f9b
0006ff60 00408201 0x7cfa9aed
0006ffc0 79478989 0x408201
0006fff0 00000000 0x79478989
kd> !analyze -v
Connected to Windows 2000 2195 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
..............................................................................................
Loading unloaded module list
........
Loading User Symbols
..............................................................
*** WARNING: Unable to verify timestamp for ntdll.dll
*** ERROR: Module load completed but symbols could not be loaded for ntdll.dll
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

Unknown bugcheck code (0)
Unknown bugcheck description
Arguments:
Arg1: 00000000
Arg2: 00000000
Arg3: 00000000
Arg4: 00000000

Debugging Details:
------------------

*** WARNING: Unable to verify timestamp for USER32.dll
*** ERROR: Module load completed but symbols could not be loaded for USER32.dll
*** WARNING: Unable to verify timestamp for COMCTL32.DLL
*** ERROR: Module load completed but symbols could not be loaded for COMCTL32.DLL
*** WARNING: Unable to verify timestamp for Explorer.EXE
*** ERROR: Module load completed but symbols could not be loaded for Explorer.EXE
*** WARNING: Unable to verify timestamp for KERNEL32.dll
*** ERROR: Module load completed but symbols could not be loaded for KERNEL32.dll

PROCESSNAE:  explorer.exe

FAULTING_IP: 
win32k!HmgDecrementShareReferenceCount+c
a0002b44 8b06             mov     eax,[esi]

EXCEPTION_RECORD:  ffffffff -- (.exr ffffffffffffffff)
ExceptionAddress: a0002b44 (win32k!HmgDecrementShareReferenceCount+0x0000000c)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 00000000
Attempt to read from address 00000000

ERROR_CODE: (NTSTATUS) 0xc0000005 - (...)

READ_ADDRESS:  00000000 

BUGCHECK_STR:  ACCESS_VIOLATION

DEFAULT_BUCKET_ID:  INTEL_CPU_MICROCODE_ZERO

LAST_CONTROL_TRANSFER:  from a0001eaf to a0002b44

STACK_TEXT:  
be805ce8 a0001eaf 00004000 e27d9688 a02b14dc win32k!HmgDecrementShareReferenceCount+0xc
be805d18 a0002109 e29716c8 be805d64 a00034ca win32k!XDCOBJ::bCleanDC+0x16d
be805d24 a00034ca 01010277 00000029 0006fc28 win32k!GreCleanDC+0x21
be805d38 a00032d2 01010277 00000000 a0005331 win32k!ReleaseCacheDC+0x69
be805d44 a0005331 01010277 be805d64 0006fc28 win32k!_ReleaseDC+0xb
be805d54 80465014 01010277 00000029 00000000 win32k!NtUserCallOneParam+0x20
be805d54 77e415b5 01010277 00000029 00000000 nt!KiSystemService+0xc4
WARNING: Stack unwind information not available. Following frames may be wrong.
0006fc80 7175f039 00000e50 000949a0 00092990 USER32+0x315b5
0006fce0 7175f2a0 00098888 00000113 00098888 COMCTL32+0x4f039
0006fe18 77e4158f 0001005a 00000113 00000001 COMCTL32+0x4f2a0
0006fe38 77e41dc9 717138d8 0001005a 00000113 USER32+0x3158f
0006fec4 77e41e7e 0006fee0 00000000 7cf9aaf9 USER32+0x31dc9
0006fefc 7cfa9f9b 7945edd2 000954d8 00000001 USER32+0x31e7e
0006ff1c 7cfa9aed 00000000 004084c4 000954d8 SHELL32!CDesktopBrowser::_MessageLoop+0x14
0006ff24 004084c4 000954d8 00000000 000205be SHELL32!SHDesktopMessageLoop+0x20
0006ff60 00408201 0000005c 00000000 000205be Explorer+0x84c4
0006ffc0 79478989 00000000 00000000 7ffdf000 Explorer+0x8201
0006fff0 00000000 00408188 00000000 000000c8 KERNEL32+0x28989


FOLLOWUP_IP: 
win32k!HmgDecrementShareReferenceCount+c
a0002b44 8b06             mov     eax,[esi]

SYMBOL_STACK_INDEX:  0

FOLLOWUPNAE:  MachineOwner

SYMBOLNAE:  win32k!HmgDecrementShareReferenceCount+c

MODULENAE:  win32k

IMAGENAE:  win32k.sys

DEBUG_FLR_IMAGE_TIMESTAMP:  4344ef76

STACK_COMMAND:  kb

FAILURE_BUCKET_ID:  ACCESS_VIOLATION_win32k!HmgDecrementShareReferenceCount+c

BUCKET_ID:  ACCESS_VIOLATION_win32k!HmgDecrementShareReferenceCount+c

Followup: MachineOwner

kd> !cpuinfo
CP F/M/S Manufacturer  MHz Update Signature Features
 0 15,6,8 GenuineIntel 2799 0000000000000000 00002fff

win32k!HmgDecrementShareReferenceCount:
a0002b38 55               push    ebp
a0002b39 8bec             mov     ebp,esp
a0002b3b 83ec10           sub     esp,0x10
a0002b3e 56               push    esi
a0002b3f 8bf1             mov     esi,ecx
a0002b41 57               push    edi
a0002b42 33ff             xor     edi,edi
a0002b44 8b06             mov     eax,[esi]         ds:0023:00000000=????????  <-- null ptr dereference
a0002b46 57               push    edi
a0002b47 25ffff0000       and     eax,0xffff
a0002b4c 8d4df0           lea     ecx,[ebp-0x10]
a0002b4f c1e004           shl     eax,0x4
a0002b52 0305587f17a0     add     eax,[win32k!gpentHmgr (a0177f58)]
a0002b58 50               push    eax