Windows VBScript引擎遠端執行程式碼漏洞 之CVE-2018-8373分析與復現
一、漏洞簡介
VBScript引擎處理記憶體中物件的方式中存在一個遠端執行程式碼漏洞。該漏洞可能以一種攻擊者可以在當前使用者的上下文中執行任意程式碼的方式來破壞記憶體。成功利用此漏洞的攻擊者可以獲得與當前使用者相同的使用者許可權。如果當前使用者使用管理使用者許可權登入,則成功利用此漏洞的攻擊者可以控制受影響的系統。然後攻擊者可以安裝程式; 檢視,更改或刪除資料; 或建立具有完全使用者許可權的新帳戶。
在基於Web的攻擊情形中,攻擊者能通過Internet Explorer利用此漏洞的特定網站,然後誘使使用者檢視該網站。攻擊者還可以在承載IE呈現引擎的應用程式或Microsoft Office文件中嵌入標記為“安全初始化”的ActiveX控制元件。攻擊者還可以利用受到破壞的網站和接受或託管使用者提供的內容或廣告的網站。這些網站可能包含可能利用此漏洞的特製內容。
2018年8月14日,微軟釋出了安全補丁,影響流行的大部分系統版本。
漏洞基本資訊 |
|
漏洞ID |
CVE-2018-8373 |
漏洞名稱 |
Microsoft VBScript引擎遠端執行程式碼漏洞 |
漏洞型別 |
遠端程式碼執行 |
威脅型別 |
UAF |
影響系統版本 |
IE9 WS 2008 32/64、IE10 Windows Server2012、IE11大部分版本 |
二、漏洞測試
系統環境 |
Win7 32/64 |
IE版本 |
IE10 |
EXP |
https://github.com/B1eed/VulRec/blob/master/CVE-2018-8373 |
三、漏洞原理
由於樣本混淆嚴重,部分程式碼見圖1,這裡採用簡化POC進行分析,程式碼見圖2。
圖1 樣本採用了嚴重混淆
圖2 Crash Poc
Crash PoC定義了MyClass類、一個array的成員變數和兩個成員函式:Class_Initialize 與Default Property Get P。Class_Initialize 是一種被棄用的方法,現在已經被新的過程所替代。當物件初始化的時候,會被自動喚醒。在PoC中,Class_Initialize 是過載的,當呼叫 VBScriptClass::InitializeClass時,處理的是過載的函式。
MyClass:通過new進行建立並賦值給指定變數cls,該操作首先會觸發類的建立以及初始化,建立類的函式由vbscript!VBScriptClass::Create函式完成;
建立類成功後則會呼叫vbscript!VBScriptClass::InitializeClass函式對class的內容進行初始化;
在vbscript!VAR::IsFunction函式中獲取class指標;
隨後呼叫class的虛擬函式vbscript!CScriptEntryPoint::Call 進行初始化,最終的呼叫棧如下:
vbscript!CScriptRunTime::RunNoEH負責對編譯後的vbs程式碼進行解釋執行。這裡執行類的初始化操作,主要包含了array陣列的定義以及Class_Initialize函式的執行。
vbscript中建立陣列的函式為vbscript!MakeArray,如下:
ReDim array(2):會呼叫vbscript!MakeArray來建立元素數是3的陣列,如下圖
cls.array(2):呼叫vbscript!Accessarray來獲取陣列元素的地址。在vbscript!Accessarray 中,首先會檢查陣列元素的索引是否越界,然後計算元素的地址,儲存到棧中。
將元素的地址儲存到堆疊上,儲存array(2)= 0x12ae6ff0地址到棧上cls.array(2)=cls:呼叫vbscript!AssignVar來設定MyClass的預設屬性值為 cls.array(2)。獲取MyClass的預設屬性值後,會呼叫Public Default Property Get P並執行Public Default Property Get P中的ReDim array(1),釋放了原來的pvData。
ReDim Preserve array(1):重置array記憶體的操作實際通過函式RedimPreserveArray實現,最終會呼叫SafeArrayRedim可以看到array物件的pvData已經被修改為0x0818afe0,之前的pvData(0x12ae6fd0)的記憶體地址已經被釋放,包括之前儲存在棧上的0x12ae6ff0。
array(2)的地址仍然儲存在棧中, Public Default Property Get P 的返回值會訪問釋放的記憶體,最終導致UAF漏洞。
四、EXP除錯分析
除錯方法同Crash PoC,跟蹤分析如何將二維陣列修改長度為0x0FFFFFFF,如何實現任意記憶體讀寫以及如何偽造CONTEXT結構來執行Shellcode/">Shellcode。
漏洞定義了兩個陣列,array1和array2。array1就是前面PoC中描述的陣列,array2是一個二維陣列,其中每個元素的值都是3。然後使用腳本回調函式DefaultPropertyGet釋放原來的array1.pvData,設定array2為新的array1.pvData。因為原來array1.pvData的大小和array2.SAFEARRAY結構是相同的,在記憶體中是0x30位元組。array2.SAFEARRAY結構將重用原始array1.pvData中釋放的記憶體。同時,DefaultPropertyGet的返回值0x0FFFFFFFF會覆蓋array2.SAFEARRAY的結構SAFEARRAYBOUND,並修改二維陣列的長度為0x0FFFFFFF。
修改二維陣列的長度為0x0FFFFFFF
將array(index_vul)(index_a, 0)設定為“AAAA”,使下個array2的Data域就變成了8,因為string的VarType型別為8,這樣就得到了一組可以混淆的 array(index_vul)(index_a+n, 0)和array(index_b)(0, n),通過將array(index_vul)(index_a, 0)處的variant 轉化為長整型,令array(index_vul)(index_a, 0)處的variant轉化為陣列,從而得到了一段洩露的記憶體util_mem,即可讀寫記憶體指定區域。
執行rw_primit後,指定位置已被覆蓋成0x200C,有了一塊洩露的記憶體 util_mem,能夠實現 32 位下使用者態任意地址讀寫的一維陣列
執行Shellcode方法與8174相同,這裡不再詳細分析。
在Windows7環境下能夠成功利用,以彈出calc為例。
參考:https://blog.trendmicro.com/trendlabs-security-intelligence/use-after-free-uaf-vulnerability-cve-2018-8373-in-vbscript-engine-affects-internet-explorer-to-run-shellcode/
原創文章轉載請註明作者:四維創智