|
以下是 QMCreatePrivateQueue的调用
loc_6B2255C3: ; int push [ebp+arg_1C] mov ecx, offset ?g_QPrivate@@3VCQPrivate@@A ; CQPrivate g_QPrivate push [ebp+arg_18] ; int push [ebp+arg_14] ; int push [ebp+arg_10] ; int push [ebp+arg_C] ; int push [ebp+Str] ; Str call ?QMCreatePrivateQueue@CQPrivate@@QAEJPBGKPAXKQAKQAUtagPROPVARIANT@@H@Z ; CQPrivate::QMCreatePrivateQueue(ushort const *,ulong,void *,ulong,ulong * const,tagPROPVARIANT * const,int) 实际上,我们在后面可以看到,漏洞是由于QMCreatePrivateQueue的第一个参数,也就是_QMCreateObjectInternal的第二个参数所造成的。
进入QMCreatePrivateQueue 之后,我们要调用到 ReplaceDNSNameWithNetBiosName. 以下是代码片段
.text:6B2178A9 mov eax, offset sub_6B25BE64 .text:6B2178AE call __EH_prolog .text:6B2178B3 sub esp, 138h .text:6B2178B9 push ebx .text:6B2178BA push esi .text:6B2178BB mov esi, [ebp+8] .text:6B2178BE lea eax, [ebp-1Ch] .text:6B2178C1 push edi .text:6B2178C2 push eax ; int .text:6B2178C3 mov [ebp-18h], ecx .text:6B2178C6 push esi ; Source .text:6B2178C7 call ?IsPathnameForLocalMachine@@YAHPBGPAH@Z ; IsPathnameForLocalMachine(ushort const *,int *) .text:6B2178CC xor ebx, ebx ; ebx 清0 .text:6B2178CE pop ecx .text:6B2178CF cmp eax, ebx ; 比较ispath函数的返回值 .text:6B2178D1 pop ecx .text:6B2178D2 jnz short loc_6B2178EC ; 这里有个判断
.text:6B2178EC cmp [ebp-1Ch], ebx ; 这里有个判断 .text:6B2178EF jz short loc_6B217906 .text:6B2178F1 lea eax, [ebp-144h] ; 在栈上 .text:6B2178F7 push eax ; Dest .text:6B2178F8 push esi ; Str 我们传入的参数 .text:6B2178F9 call ?ReplaceDNSNameWithNetBiosName@@YAXPBGPAG@Z ; ReplaceDNSNameWithNetBiosName(ushort const *,ushort *) ========== 这是聪明的分割线 ============
要走到 ReplaceDNSNameWithNetBiosName ,就需要先绕过 IsPathnameForLocalMachine 这个函数。 我在绕过这个函数上走了很多弯路,花了许多功夫。
看看IsPathnameForLocalMachine函数:
中间分析过程很多,这里我就拿重要的说
mov eax, offset sub_6B25D54C call __EH_prolog sub esp, 204h push ebx push esi lea eax, [ebp+String1] push edi push eax ; Dest push [ebp+Source] ; Source call ?ExtractMachineName@@YAXPBGPAG@Z ; ExtractMachineName(ushort const *,ushort *) mov eax, [ebp+arg_4] pop ecx pop ecx mov esi, ds:__imp__CompareStringW@24 ; CompareStringW(x,x,x,x,x,x) and dword ptr [eax], 0 push 0FFFFFFFFh ; cchCount2 push ?g_szMachineName@@3PAGA ; lpString2 lea eax, [ebp+String1] mov edi, 800h push 0FFFFFFFFh ; cchCount1 push eax ; lpString1 push 1 ; dwCmpFlags push edi ; Locale call esi ; CompareStringW(x,x,x,x,x,x) ; CompareStringW(x,x,x,x,x,x) dec eax dec eax jnz short loc_6B2344E9 ExtractMachineName(ushort const *,ushort *) 这个函数把\x5c 就是斜杠前的名字,就是机器名拷贝到某处,所以我们的传入参数里要有斜杠。
然后CompareStringW(x,x,x,x,x,x) 函数,把我们传入的斜杠前的那部分和 机器名比较,这里机器名是通过 push ?g_szMachineName@@3PAGA ; lpString2 取得的,所以是一个定值。
对比完后,我们要让返回值不能为2,因为要跳转到下面的地方:
loc_6B2344E9: lea eax, [ebp+String1] push 2Eh ; Ch push eax ; Str call ds:__imp__wcschr pop ecx test eax, eax pop ecx jz loc_6B2345DD 这里会把刚才斜杠前的那部分拿来比较,看中间有没有点,我们要让跳转条件非真,所以我们的传入参数中要带一个“.” 就是\x2e
然后我们控制流程来到
push ?g_szMachineName@@3PAGA ; Str mov ebx, ds:__imp__wcslen call ebx ; __imp__wcslen pop ecx push eax ; cchCount2 mov eax, ?g_szMachineName@@3PAGA ; ushort * g_szMachineName push eax ; lpString2 push eax ; Str call ebx ; __imp__wcslen pop ecx push eax ; cchCount1 lea eax, [ebp+String1] push eax ; lpString1 push 1 ; dwCmpFlags push edi ; Locale call esi ; CompareStringW(x,x,x,x,x,x) ; CompareStringW(x,x,x,x,x,x) dec eax dec eax jnz loc_6B2345DD
这里再次把机器名和我们传入的参数比较了一次, 这时候要让跳转条件不成立
上一页 [1] [2] [3] [4] [5] [6] 下一页 |