CVE-2014-4113漏洞利用过程分析

0x00 简介


通过VMware和Windbg搭建32位内核调试环境,系统为xp sp2,执行漏洞利用程序win32.exe calc.exe,弹出了一个SYSTEM权限的calc。

enter image description here

通过IDA分析win32.exe,可以看到signed int __cdecl sub_4010F2()函数通过调用ZwQuerySystemInformation泄露内核模块ntkrnlpa.exe基址,最终得到PsLookupProcessByProcessId函数地址,该函数用于漏洞利用代码。

enter image description here

sub_401830函数是漏洞利用代码,完成权限提升操作。

enter image description here

0x01 调试过程


通过在函数上设置断点,可以得到漏洞利用触发位置。

enter image description here

可见是由TrackPopupMenu最终触发了漏洞,调用点为call dwordptr[esi+20],此时esi的值为0xfffffffb。 通过函数调用栈,对esi值的来源进行反向跟踪,可以知道在Menu的消息处理函数signed int __stdcall xxxHandleMenuMessages(int a1, int a2, int a3)中调用int __stdcall xxxMNFindWindowFromPoint(int a1, int a2, unsigned int a3)时返回了异常的值,最终触发了漏洞。

enter image description here

通过对xxxMNFindWindowFromPoint的调用过程进行分析,找到异常的返回值是在int __stdcall SfnOUTDWORDINDWORD(int a1, int a2, int a3, int a4, int a5, int a6, char a7, int a8)中得到的。异常的值最终是由KeUserModeCallback函数通过v28指向的值返回。其中KeUserModeCallback函数的原型如下:

 

enter image description here

内核态的KeUserModeCallback函数最终会调用ntdll中的KiUserCallbackDispatcher函数来调用用户态回调函数,通过对KeUserModeCallbackKiUserCallbackDispatcher设置断点,可以看到第一次处理0x1EB(MN_FINDWINDOWFROMPOINT)消息是通过xxxSendMessageTimeout中调用的xxxCallHook来调用用户注册的钩子函数,在用户空间里函数调用了USER32中的__fnOUTDWORDINDWORD函数,最终调用sub_401475(pfnFilterProc)函数。

enter image description here

enter image description here

enter image description here

程序在pfnFilterProc中通过SetWindowLongA设置PopupMenu的窗口消息处理函数,那么当xxxCallHook函数返回后,图中的!(*(_BYTE *)(a1 + 22) & 4)条件成立,将执行xxxSendMessageToClient,该函数内将执行KeUserModeCallback,最终调用用户态函数sub_4013F3

enter image description here

enter image description here

sub_4013F3函数尾部返回了0xFFFFFFFB。与KeUserModeCallback函数通过v28返回的值相等。为了进一步确认,修改sub_4013F3函数返回值为0xFFFFFFFF。可以看到v28指向的值变成了0xFFFFFFF

enter image description here

enter image description here

通过修改win32.exe中的指令,将0x40146D处的push 0FFFFFFFBh修改为push 0FFFFFFFFh,执行之后发现提权失败。进一步确定由于内核的使用了异常的函数返回值,最终导致了权限提升。

enter image description here

可见在PopupMenu的窗口消息处理函数处理0x1EB的消息时,没有判断消息函数的返回值,最终导致了权限提升。 所以漏洞触发的完整过程如下:通过模仿点击事件,CreatePopupMenu创建的PopupMenu会收到0x1EB类型的消息,因为无法拿到PopupMenu的窗口句柄,程序并没有办法直接设置PopupMenu的窗口消息处理函数,因此首先通过SetWindowsHookExA注册钩子函数,在钩子函数中得到PopupMenu的窗口句柄,再通过SetWindowLongA设置PopupMenu的窗口消息处理函数,注册之后,xxxSendMessageToClient将调用新的窗口消息处理函数,接收并处理0x1EB的消息。 在新的窗口消息处理函数中,对于消息号为0x1EB的消息,函数返回了0xFFFFFFFB,最终触发了漏洞。

enter image description here

0x02 触发代码


通过上面的分析,根据win32.exe中代码,稍加简化,可以得到如下的漏洞触发代码。

编译执行之后,可以看到触发了异常。

enter image description here