Nebula漏洞利用包CVE-2016-0189漏洞利用分析
*原創作者:蘭雲科技銀河實驗室,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載
n1.t引言
n
在最近的一年裡, 漏洞利用工具包(EK/Exploit Kit)市場風雲變幻。2016年六月初,曾經極為猖獗的Angler EK 銷聲匿跡,Neutrino EK 迅速填補了空白。隨後短短不到3個月時間,Neutrino EK 又轉為地下,RIG EK繼而成為最流行的漏洞利用工具包。今年3月初,RIG又淡出視線,而迎來了新的Nebula EK。
nNebula EK包中對CVE-2016-0189的漏洞利用,比其它漏洞利用包的漏洞利用方有了一定改進,這裡進行一下深入分析。
n所用工具:
n
?tIE11(調試Javascript)
n?twindbg
n
n
Nebula EK 的首頁,如下圖所示。
不難看出,頁面里包含了混淆過的Javascript代碼。進一步分析,這些代碼是否有種似曾相識的感覺?對了,代碼的混淆方法跟落日漏洞利用工具包(Sundown EK)極為相似。
n頁面中共有2段Javascript代碼, 混淆方法相同。第一段Javascript代碼,去掉混淆後,代碼如下, 不難看出,這段代碼就是CVE-2016-0189的漏洞利用。
nnn關於CVE-2016-0189,網上已有一些分析報告,比如Theori的分析[1]。 然而這些分析報告,並未提供在內存層面的技術細節,使得讀者總有種知其然,不知其所以然的感覺。本文試圖利用windbg來分析漏洞利用時的內存布局,使得讀者對該漏洞利用有更深刻的理解。
n2.tCVE-2016-0189的關鍵知識點
n
CVE-2016-0189是個關於VBScript的漏洞。VBScript 腳本引擎代碼在vbscript.dll 中。
n2.1.tVBScript的變數
n
VBScript 的內存變數佔用0×10個位元組, 前兩個位元組定了變數類型VARTYPE。常見類型定義如下表所示[2]。
nnn我們可以在VBScript代碼中插入IsEmpty()函數,然後在windbg的vbscript!IsEmpty() 函數上設置斷點來觀察內存[3]。
nnn
圖1 調試用VBScript代碼
nnn這裡,0a560198就是str對象,這裡 0008兩個位元組表示的是VARTYPE,根據表可知,值恰好為vbString(VT_BSTR = 8) 而偏移0×8處存放的就是字元串地址,
nnn這裡還可以看出,字元串是Unicode存放的。
n2.2.tVBScript的數組
n
VBScript 的數組的定義如下
nnn當訪問數組元素時,VBScript引擎會調用 AccessArray 函數來計算元素的存放地址。
n試著用windbg 調試如下代碼, 在vbscript!AccessArray處下斷點:
nnnnn堆棧中0ab04380即為數組A地址
nnn數組元素存放在 pvData (0x7dfd130) 起始的地方
n在 vbscript!AccessArray+0x9d: 指令處停下 (不同版本這個偏移值可能會有出入)
nnn這條指令非常關鍵,它計算元素A(1,2) 的地址。 這裡esi 就是SAFEARRAY的地址,而esi+0c是pvData的地址。eax值就是元素相對於pvData的偏移。查看eax值
nnn
為什麼A(1,2)的偏移會是0×50呢。 VBScript的數組內存布局和C語言有些不太一樣。A數組的內存布局為 A(0,0) A(1,0) A(0, 1), A(1,1), A(0, 2), A(1,2), 而每個元素大小為0×10位元組(cbElements)。因此 A(1,2) 的偏移為0×50。
n2.3.tCVE-2016-0189 漏洞原理初探
n
CVE-2016-0189 的漏洞在AccessArray 函數代碼中。我們看一下這個函數的邏輯:
nnn這個函數在根據索引計算偏移時,如果索引是VT_I2 或者VT_I4時,直接使用它的值。而如果是其它類型時候,將會調用rtVariantChangeTypeEx 函數來計算索引值。如果索引是JavaScript對象的話,將會調用索引對象的valueOf函數來獲取索引的值。
n這似乎並沒有太大問題,然而我們看一下漏洞利用腳本的valueOf函數
nnn除了返回值」1」因為, 它調用了SumggleFag函數
n查看該函數的代碼可以發現:它調用了ZeroineL函數,而該函數將數組重新定義成了Cod(1,1) (k1=1)
nnnn到這裡,我們明白了該漏洞的原理了,在AccessArray中計算索引值的時候,索引如果是個JavaScript對象,可以通過函數valueof來重新修改該數組的大小! 當數組的大小變小時,將會導致訪問越界。
n3.tCVE-2016-0189 漏洞利用深入分析
n
Nebula EK的漏洞利用在越界訪問的基礎上實現了:
n1.t泄漏VBScript對象的地址
n2.t讀取任意地址
n
3.t寫入任意地址(受限)
n
n
這3種手段在實現原理上都是類似的。通過將數組定義 Cod從(1,2000), 縮小到(1,1),從而在AccessArray 函數中實現了越界訪問。同時,立即使用大量y(i) 對釋放掉的內存重新進行佔位。由於y(i)是可控的,如果越界訪問到y(i)的內存區,即可控制對內存的訪問。
n下面我們利用windbg對內存進行觀察,分析1.泄露VBScript對象地址的情形。
n需要注意的是,由於腳本中有大量數組操作,如果我們在AccessArray函數上下斷點,可能會斷下很多次。這裡介紹一個小技巧:先將斷點用bd命令禁掉,在想斷下的VBScript 腳本前加入MsgBox函數,當MsgBox彈出後,我們再把斷點用be命令恢復。這樣就可以確保斷在我們想斷的地方。
n為清晰起見,我們將在腳本中將aw.Cod(0,0)設成0×11223344。
n利用該技巧,我們在vbscript!AccessArray+0x9d斷在
naw.Cod(arg1, 2) = st// arg1.valueOf() == 1 , s 是我們試圖泄露的對象地址
n這行越界訪問(寫入)處。
n斷下時,
nnn0x2a659d0 就是 aw.Cod數組的pvData 地址,03 00 兩個位元組是vbLong (VT_I4), 而 44 33 22 11恰好為我們賦的值。
n
前面已經分析過aw.Cod(arg1,2), 即 aw.Cod(1,2), 該元素相對pvData的偏移就是0×50, 由於aw.Cod現在被重新設定為(1,1),所以 大小為2*2*0×10=0×40, 也就是說 awCod(arg1,2) 越界了0×10個位元組。
naw.Cod(1,2) 的地址為 2a659d0 + 0×50 = 0x2a65a20。而從地址0x2a65a1c起(標為綠色的部分)是某個成功佔位y(i) 的值。內存布局如下圖所示:
nnn由上圖可知,Aw.cod(1,2) 正好與y(i)的第四個位元組開始的部分重疊。
nnn了解了這點。上面這段代碼就不難理解了–遍歷 y的所有元素,找到與Aw.cod(1,2) 重疊的那個y(i). 由於s 被寫入了Aw.cod(1,2), 即 yi(i) 的第四個位元組開始的部分。那麼Mid(y(i), 3, 1)
n正好是第四個位元組開始的2個位元組(注意Mid函數下表是從 1 開始的),它存放的是對象的類型的值。 4個位元組之後,則是對象的地址。這樣,只須讀取y(i)的內容,就可以獲取對象的地址了。
n概括起來,Aw.cod 和 某個y(i) 重疊,我們可以通過Aw.cod的越界操作來將數據寫入可控的y(i)里。
n下面討論情形2 讀取任意地址
nnn這次我們在佔位的內存中,成功構造如下數據:
nnnAw.cod(1,2) 將越界訪問到 我們構造的佔位內存 地址0x2f72878。
n08 00 為vbString類型VT_BSTR, 而48 c2 1b 01 四個位元組則為試圖讀取的地址。
n
當執行 o = aw.Cod(arg1,2)時, VBScript引擎將會把地址0x2f72878作為一個vbString對象來處理。而48 c2 1b 01 四個位元組則作為字元串內容的地址來處理。
n讀取該字元串的內容則獲取了 48 c2 1b 01 地址里存放的內容。
n最後我們看一下寫入任意地址(受限)的情形。
nnn寫入與讀取原理大致一樣。這裡只是將CSng(0) 賦值給了 aw.Cod(1,2),從而導致 CSng 的類型值 4(VT_R4) 被寫入了指定地址。這裡腳本並未實現任意值的寫入,然而並不影響漏洞的利用。
n最後我們看一下,整個漏洞利用是如何工作的:
n1)t首先,創建一個 對象,通過上述的方法(1) 泄露該對象的地址;
n2)t 在該對象偏移為8的地方,利用方法(2)讀取內存獲取CSession對象指針;
n3)t然後在CSession對象偏移為4的地方,獲取COleScript 對象;
n4)t而COleScript 對象0×174的地方則存放了SafetyOption,也就是所謂的上帝模式(GodMode)標記。利用上述方法(3)將其值修改為4,從而成功開啟上帝模式。
n
n
4.t一個有趣的DLL劫持技巧
n
分析本來到這裡可以結束了,然而我們在Nebula的漏洞利用包里發現了一個有趣的DLL劫持技巧。儘管在前面,上帝模式已經成功開啟了,當IE的保護模式開啟時(默認是開啟的),Vista以後的版本在執行Shell.Applicaion對象的ShellExecute 函數時, 會彈出一個如下的對話框(除非被載入的程序在ElevationPolicy中定義了靜默載入,比如notepad.exe),向用戶詢問是否允許。正是由於這個原因,一些漏洞利用包選擇了僅在XP系統上對CVE-2016-0189 進行利用。
nnn
Nebula EK採用了一個BlackHat 2014[2]上 公布的技巧來規避這個問題。IE瀏覽器在創建Shell.Application 對象時,會載入%systemroot%system32shell32.dll。通常情況下%systemroot%為c:windows目錄。然而,攻擊者可以通過如下方式進行DLL劫持攻擊。
n1)t在%temp% 目錄下創建system32目錄
n2)t在上面創建的目錄下生成一個假的shell32.dll文件,用來載入需要載入的程序。Nebula EK 在VBScript腳本中會生成一個3K左右的文件。
n3)t在腳本創建Shell.Application對象之前,利用WScript.Shell 來 修改 %system32%環境變數,指向1)創建的目錄
n4)t創建Shell.Application 對象,從而自動載入 假的shell32.dll文件,達到執行文件的目的。
n
n
相應的代碼片段如下。
nnn需要指出的是,通過這種方式載入的進程是低完整性(Low Integrity)的。通常被載入的程序還需要通過本地漏洞來進一步提權。
n5.t總結
n
Nebula EK 通過CVE-2016-0189的一個漏洞,實現了對任意內存的讀寫,從而開啟了上帝模式。並且配合一個DLL劫持技巧,達到了繞過IE保護模式,靜默執行任何文件的目的。
n6.t參考文獻
n
[1]tPATCH ANALYSIS OF CVE-2016-0189. Patch Analysis of CVE-2016-0189
n[2]tVarType Function(v=vs.60).aspx
n
[3]t 啟明星辰CVE-2014-6332分析報告。http://www.venustech.com.cn/UserFiles/20141210_%E6%97%A0%E9%9C%80%E6%8B%85%E5%BF%83%E6%BD%9C%E8%97%8F%E4%BA%8618%E5%B9%B4%E7%9A%84%E5%BE%AE%E8%BD%AF%E6%B5%8F%E8%A7%88%E5%99%A8%E8%BF%9C%E7%A8%8B%E4%BB%A3%20%E7%A0%81%E6%89%A7%E8%A1%8C%E6%BC%8F%E6%B4%9E.pdf
n[4]tWrite Once, Pwn Anywhere.
nhttps://www.blackhat.com/docs/us-14/materials/us-14-Yu-Write-Once-Pwn-Anywhere.pdf
n*原創作者:蘭雲科技銀河實驗室,本文屬FreeBuf原創獎勵計劃,未經許可禁止轉載
推薦閱讀:
※可擴展的有狀態服務
※Windows 黑科技工具推薦 #多媒體
※譯文: iPhone X的AR引擎對於設計師意味著什麼?
※諸葛錦囊 | 以分答為例,數據化的用戶研究應該這樣做
TAG:互联网 |