日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

触发一个断点_一个补丁引发的RCE: 对CVE20191208的深入分析

發(fā)布時(shí)間:2025/4/16 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 触发一个断点_一个补丁引发的RCE: 对CVE20191208的深入分析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

CVE-2019-1208是趨勢科技的@elli0tn0phacker在今年6月發(fā)現(xiàn)的一個(gè)vbscript漏洞,報(bào)告中提到這個(gè)漏洞是通過補(bǔ)丁比對發(fā)現(xiàn)的,這引起了筆者的興趣。最近,筆者花了一些時(shí)間對該漏洞進(jìn)行了比較詳細(xì)的研究。在這篇文章中,筆者將從漏洞成因、修復(fù)方案、利用編寫三個(gè)方面對該漏洞進(jìn)行介紹。

讀者將會(huì)看到,代碼開發(fā)者是如何在修復(fù)舊漏洞時(shí)不經(jīng)意間引入新漏洞。在這個(gè)例子中,引入的還是一個(gè)非常嚴(yán)重的遠(yuǎn)程代碼執(zhí)行漏洞。通過這個(gè)例子讀者也會(huì)發(fā)現(xiàn),有時(shí)候通過補(bǔ)丁比對就可以發(fā)現(xiàn)新漏洞。

該漏洞從2019年6月更新被引入,到2019年9月更新被修復(fù),只存活了短短3個(gè)月,因此編寫這個(gè)漏洞的利用并無價(jià)值,筆者寫這個(gè)漏洞的利用只是為了概念驗(yàn)證。

盡管微軟已經(jīng)在2019年8月的IE更新中全面禁用了vbscript,但出于安全性考慮,完整利用代碼不予公開。

漏洞成因

這是一個(gè)vbscript的UAF(Use After Free)漏洞,漏洞成因還要從微軟今年6月的補(bǔ)丁說起。

漏洞成因

微軟在2019年6月的vbscript更新中引入了下面幾個(gè)函數(shù):

?SafeArrayAddRef

?SafeArrayReleaseData

?SafeArrayReleaseDescriptor

引入SafeArrayAddRef的作用是為SafeArray提供一種類似引用計(jì)數(shù)的機(jī)制。

源碼中通過使用STL的 map將一些對象/數(shù)據(jù)指針(如pSafeArray和pvData)與一個(gè)int型的計(jì)數(shù)器進(jìn)行綁定。

在VbsFilter和VbsJoin這兩個(gè)函數(shù)中,在調(diào)用實(shí)際的rtJoin和rtFilter前,會(huì)調(diào)用SafeArrayAddRef對相關(guān)指針的引用計(jì)數(shù)+1。調(diào)用完畢后,再調(diào)用SafeArrayReleaseData和SafeArrayReleaseDescriptor在map中將指針對應(yīng)的計(jì)數(shù)-1,并將指針?biāo)鶎?yīng)的key從map中刪除。

開發(fā)者應(yīng)該是用這種方式修復(fù)了一些UAF問題。但修復(fù)方案中沒有考慮到當(dāng)Join/Filter傳入的數(shù)組中有類對象時(shí),在Public Default Property Get這一潛在的回調(diào)中可以對數(shù)組進(jìn)行操作(比如ReDim)。這樣,當(dāng)調(diào)用完 rtJoin/rtFilter后返回VbsJoin/VbsFilter時(shí),對應(yīng)的pSafeArray/pvData指針已被更新,原先的設(shè)計(jì)是將之前已在Map中“注冊”的指針傳入后續(xù)的SafeArrayReleaseData/SafeArrayReleaseDescriptor進(jìn)行引用計(jì)數(shù)減操作,但現(xiàn)在傳入SafeArrayReleaseData/SafeArrayReleaseDescriptor的指針均不在map中(因?yàn)楸恢匦聞?chuàng)建了)。這導(dǎo)致在調(diào)用RefCountMap::Decrement函數(shù)時(shí),find方法找不到對應(yīng)的key,函數(shù)直接返回0。這個(gè)返回結(jié)果被SafeArrayReleaseData/SafeArrayReleaseDescriptor理解為對應(yīng)的指針的引用計(jì)數(shù)為0,從而將對應(yīng)的SafeArray對象和數(shù)據(jù)銷毀。

具體地,開發(fā)者借助RefCountMap類實(shí)現(xiàn)了一個(gè)“偽引用計(jì)數(shù)機(jī)制”,通過一個(gè)map將所關(guān)心的SafeArray指針與一個(gè)int型計(jì)數(shù)器綁定起來,計(jì)數(shù)值只有0、1、不存在,三種情況。

相關(guān)操作函數(shù)的聲明如下:

RefCountMap::Decrement函數(shù)的偽代碼如下:

了解了這些知識后,回過頭去理解@elli0tn0phacker報(bào)告中的Figure 5就會(huì)容易多了。

PoC分析

@elli0tn0phacker給出的poc大致如下:

由于漏洞的存在,我們知道arr(0) = 1語句執(zhí)行前arr已被釋放,而且從代碼中可以看到arr是在回調(diào)中被ReDim的。那么arr到底存在哪里?為什么arr(0) = 1索引的是ReDim后被釋放的SafeArray,而不是Redim前的SafeArray?

這就涉及到 vbscript虛擬機(jī)的相關(guān)知識。

卡巴斯基實(shí)驗(yàn)室的Boris Larin曾寫過一篇關(guān)于vbscript虛擬機(jī)的文章,并且開源了相關(guān)的調(diào)試插件。

在文章中,作者對vbscript虛擬機(jī)進(jìn)行了比較細(xì)致的介紹。vbscript的所有代碼都會(huì)先被編譯為P-Code,隨后通過CScriptRuntime::RunNoEH對所有P-Code進(jìn)行解釋執(zhí)行,CScriptRuntime對象的成員變量中存儲(chǔ)著解釋所需的許多信息,比較重要的幾個(gè)如下:

借助調(diào)試插件,我們可以得到 PoC代碼編譯后的P-Code:?

?以下是上述用到的部分指令對應(yīng)的字節(jié)碼(全部指令請參考Boris的插件源碼):?

從P-Code中可以看出, arr(0) = 1這句對應(yīng)的指令索引的是本地變量棧(OP_CallLclSt, 0x25),Call Join(arr)這句對應(yīng)的指令索引的也是本地變量棧(OP_LocalAdr, 0x19),從兩個(gè)指令名稱中我們可以猜測arr被存儲(chǔ)在本地變量棧上。?

在IDA Pro中對vbscript!CScriptRuntime::RunNoEH進(jìn)行逆向,我們來看一下上述兩個(gè)指令解釋分支的匯編代碼:?

上述兩個(gè)分支都調(diào)用了CScriptRuntime::PvarLocal方法,再來看一下CScriptRuntime::PvarLocal方法的實(shí)現(xiàn):

可以看到CScriptRuntime::PvarLocal接收一個(gè)索引,并且基于CScriptRuntime對象+0x28或0x2C處的值進(jìn)行偏移運(yùn)算。調(diào)試時(shí)發(fā)現(xiàn)PoC兩處對arr的操作索引均為1,所以存儲(chǔ)arr的地址為:

poi(pCScriptRuntime + 0x28) - 0x10*1? ?

上述分析驗(yàn)證了上面對于指令作用的猜想,PoC中每次使用arr變量時(shí),都會(huì)傳入對應(yīng)的索引去本地變量棧中進(jìn)行訪問。

明白了arr的存取原理后,我們可以清晰地在調(diào)試器中觀察arr的變化過程,從而理解整個(gè)UAF的過程。

筆者在開啟頁堆后對PoC進(jìn)行了調(diào)試。我們先將斷點(diǎn)下到OP_LocalAdr指令的解釋分支,可以看到Join(arr)執(zhí)行時(shí)訪問到的arr,命中斷點(diǎn)時(shí)ebx即為CScriptRuntime,調(diào)試時(shí)arr從本地變量棧(ebx+0x28)進(jìn)行索引,讀者請留意下圖中藍(lán)色高亮的指針,ReDim語句執(zhí)行后它會(huì)發(fā)生變化。

我們對上圖中高亮數(shù)據(jù)(SafeArray指針)所在的內(nèi)存下一個(gè)寫入斷點(diǎn),觀察這個(gè)位置上數(shù)據(jù)的幾次變化過程。

第一次是在ReDim(OP_ArrNamReDim)執(zhí)行時(shí),對之前arr的清理階段(OP_ArrNamReDim指令的解釋流程在后面“修復(fù)方案”一節(jié)中會(huì)進(jìn)一步說明。):

第二次是在OP_ArrNamReDim執(zhí)行時(shí),將新創(chuàng)建的arr復(fù)制到本地變量棧的對應(yīng)內(nèi)存處,可以看到藍(lán)色高亮處的指針已經(jīng)發(fā)生變化,此時(shí)的SafeArray已經(jīng)變?yōu)閯倓倓?chuàng)建的二維數(shù)組。

最后,我們將斷點(diǎn)下到OP_CallLclSt的解釋分支,目的是斷在arr(0) = 1這句對arr的訪問過程,由于“漏洞成因”所描述的設(shè)計(jì)上的問題,此時(shí)本地變量棧上的arr已經(jīng)被釋放:

追蹤到的釋放棧回溯如下圖,讀者可以看到,這個(gè)不當(dāng)?shù)尼尫耪怯捎赟afeArrayReleaseDescriptor傳入了未在map注冊的指針?biāo)鶎?dǎo)致。

通過以上調(diào)試,讀者應(yīng)該可以清晰感受到整個(gè)Use After Free過程。

修復(fù)方案

清楚漏洞成因后,我們來看一下微軟在9月更新中是如何修復(fù)該漏洞的。筆者用Bidiff工具比對了8月更新和9月更新兩個(gè)vbscript.dll,發(fā)現(xiàn)在rtJoin(rtFilter均類似,下面只以rtJoin進(jìn)行說明)函數(shù)中,在對數(shù)組內(nèi)的元素進(jìn)行操作前后,加了一對SafeArrayLock/SafeArrayUnlock函數(shù):?

微軟采用對SafeArray加鎖的方式來修補(bǔ)這個(gè)由之前的補(bǔ)丁引入的問題。SafeArrayLock會(huì)令pSafeArr->cLocks的值+1。這樣,當(dāng)在安裝9月補(bǔ)丁后再次打開PoC。由于前面的+1操作,就可以令ReDim指令無法得到正常執(zhí)行,我們來看一下具體的邏輯。

這里再引述一下上面提到的P-Code,可以看到ReDim arr(1, 1)這句語句對應(yīng)的P-Code如下:?

筆者在調(diào)試器中跟了一遍OP_ArrNamReDim指令(0x0A) 的執(zhí)行邏輯,發(fā)現(xiàn)有如下幾個(gè)關(guān)鍵點(diǎn):

有意思的是,調(diào)試前筆者以為這里的ReDim最終會(huì)調(diào)用oleaut32!SafeArrayRedim函數(shù),結(jié)果并沒有。

結(jié)合上述邏輯,當(dāng)補(bǔ)丁中在操作Join傳入的數(shù)組前,SafeArrayLock令pSafeArr->cLocks從0變?yōu)?,從而在執(zhí)行ReDim arr(1, 1)對應(yīng)的指令時(shí),無法通過3.1.1這一步,新數(shù)組無法被創(chuàng)建,Join函數(shù)執(zhí)行完后本地變量棧中的數(shù)組指針不會(huì)得到更新,之前的UAF問題也就無從談起了。Filter函數(shù)的修復(fù)方案同上。

以下為上述過程中涉及到的函數(shù)調(diào)用及說明:

這個(gè)修復(fù)方案和CVE-2016-0189的修復(fù)方案思路一致。

利用編寫

@elli0tn0phacker在他的報(bào)告中已經(jīng)給出了這個(gè)漏洞的exploit編寫思路,但沒有公布完整代碼。作為概念驗(yàn)證,筆者親手編寫了對應(yīng)的exploit,以下對部分細(xì)節(jié)進(jìn)行說明。

偽造超長數(shù)組

通過觸發(fā)漏洞,可以得到一塊大小為0x30的空閑內(nèi)存。借助堆的特性,如果在Join函數(shù)執(zhí)行完后立即申請一些字符串長度為(0x30 - 4)的BSTR對象,就可以實(shí)現(xiàn)對被釋放內(nèi)存的占位。減4是因?yàn)锽STR的字符串前面還有4字節(jié)的長度域,會(huì)一并申請。

實(shí)踐證明這里的操作還是比較簡單的,并不需要過多的堆風(fēng)水技巧,下面是一個(gè)可以成功占位的代碼示例:

占位后,因?yàn)楣P者已經(jīng)在字符串中構(gòu)造了假的超長數(shù)組,當(dāng)下次訪問arr時(shí),成功占位的字符串會(huì)被解釋為SafeArray結(jié)構(gòu)體,從而得到一個(gè)基地址為0,元素個(gè)數(shù)為0x7fffffff,元素大小為1的超長數(shù)組。

任意地址讀取

這部分,以及如何構(gòu)造一塊可讀寫內(nèi)存的步驟請參考@elli0tn0phacker的報(bào)告,相關(guān)步驟實(shí)現(xiàn)起來非常簡單,這里不再重復(fù)敘述。

Bypass ASLR

在前面的基礎(chǔ)上,就可以泄露一個(gè)指針對象以繞過ASLR,這里筆者采用的方法和和CVE-2019-0752一樣,泄露一個(gè)Scripting.Dictionary對象的虛表指針,具體操作如下:

虛函數(shù)劫持

若PoC要在windows 10上執(zhí)行,必須要繞過CFG。筆者最終采用了@elli0tn0phacker在他報(bào)告中提到的方法,即對CVE-2019-0752的利用方式稍作改動(dòng):

1.借助BSTR復(fù)制并偽造一個(gè)假的Dictionary虛表(fake_vtable),并改寫Dictionary.Exists函數(shù)指針為kernel32!WinExec,由于kernel32!WinExec是系統(tǒng)自帶函數(shù),因此可以繞過CFG檢測

2.借助BSTR復(fù)制并偽造一個(gè)假的Dictionary對象(fake_dict),將虛表替換為上述的假虛表,將WinExec的命令行參數(shù)寫入虛表指針后4字節(jié)開始的地址

3.將假的Dictionary對象所對應(yīng)BSTR的type設(shè)為0x09,使之成為一個(gè)對象(VT_DISPATCH)

4.調(diào)用fake_dict.Exists,使控制流導(dǎo)向WinExec函數(shù),命令行參數(shù)在步驟2中已經(jīng)構(gòu)造好

這個(gè)過程的示例代碼如下:

利用約束

這個(gè)漏洞利用在任意地址寫上有一些受限條件,@elli0tn0phacker已在他的報(bào)告中提到,這里也不再重復(fù)敘述。

這里提一個(gè)筆者編寫利用時(shí)遇到的問題,筆者一開始是在windows7 sp1 x86環(huán)境下寫的利用,代碼全部寫完后發(fā)現(xiàn)計(jì)算器無法彈出,一番調(diào)試后發(fā)現(xiàn),傳入WinExec函數(shù)的命令行參數(shù)無法得到正常解釋,原因也很簡單,來看一下某次win7調(diào)試時(shí)最終傳給WinExec的參數(shù):

出于利用構(gòu)造的約束條件,命令行參數(shù)的前4個(gè)字符是由前面?zhèn)卧斓奶摫淼牡刂方忉尪鴣?#xff0c;這種情況下很容易造成前4個(gè)字符里面有多余字符,因此WinExec也就不能按預(yù)期執(zhí)行后續(xù)的命令行。筆者一開始想到的將虛表偽造到0x20202020這個(gè)地址,這樣命令行參數(shù)的前4個(gè)字符可以被解釋為空格,不會(huì)影響整個(gè)命令行的解釋。但該漏洞中對指定地址的連續(xù)寫是受限的,筆者最終放棄了這個(gè)思路。

后來筆者將未加修改的exploit在win10環(huán)境試了一下,發(fā)現(xiàn)計(jì)算器可以成功彈出,以下為某次在win10下調(diào)試得到的參數(shù)及偽造的虛函數(shù)表:

筆者推測win10和win7下進(jìn)程創(chuàng)建相關(guān)函數(shù)對命令行參數(shù)的處理存在一些差異,win10上的容錯(cuò)性更高一點(diǎn)。

代碼執(zhí)行

最終,筆者成功在windows 10 1709 x86系統(tǒng)的2019年8月全補(bǔ)丁環(huán)境上彈出一個(gè)計(jì)算器:

參考資料

《Delving deep into VBScript》

《From BinDiff to Zero-Day: A Proof of Concept Exploiting CVE-2019-1208 in Internet Explorer》

《RCE WITHOUT NATIVE CODE: EXPLOITATION OF A WRITE-WHAT-WHERE IN INTERNET EXPLORER》

聲明

本文僅限技術(shù)研究與討論,嚴(yán)禁用于非法用途。由于傳播、利用此文所提供的信息而造成的任何直接或者間接的后果及損失,均由使用者本人負(fù)責(zé),安恒信息以及文章作者不為此承擔(dān)任何責(zé)任。安恒信息擁有對此文章的修改和解釋權(quán),未經(jīng)允許不得修改、增減內(nèi)容,不得以任何方式將其用于商業(yè)目的。

團(tuán)隊(duì)簡介

獵影威脅分析團(tuán)隊(duì)是安恒安全研究院一只專注于攻防技術(shù)研究的團(tuán)隊(duì),團(tuán)隊(duì)由一只擅長攻防技術(shù)研究、APT分析、二進(jìn)制研究的年輕隊(duì)伍組成。歡迎有志于安全檢測、二進(jìn)制研究和攻防技術(shù)研究的小伙伴加入我們團(tuán)隊(duì)。

招聘二進(jìn)制安全研究員

職位描述:

1、在日常可疑文件分析的基礎(chǔ),進(jìn)行數(shù)據(jù)挖掘,尋找APT攻擊事件;

2、分析客戶反饋的可疑文件,編寫分析報(bào)告,提供解決方案等;

3、負(fù)責(zé)熱門安全事件、最新漏洞的分析,編寫分析報(bào)告或poc代碼等

4、研究新的檢測方法,維護(hù)和完善APT檢測等產(chǎn)品策略

5、協(xié)助內(nèi)部威脅分析平臺建設(shè)等

職位要求:

1、熟悉windows、Linux上調(diào)試手段,能夠熟練使用常用逆向分析工具(IDA、WinDbg、OD等);

2、熟悉C/C++、匯編語言,至少熟悉一門腳本編程語言,能快速完成POC代碼編寫;

3、熟悉病毒、木馬通信原理和常用技術(shù)以及常見加密算法等;

4、熟悉安全漏洞原理,有獨(dú)立文檔漏洞分析能力;

5、至少1年以上逆向分析、安全研究相關(guān)工作經(jīng)驗(yàn),能力優(yōu)先不受工作年限限制;

6、具備大數(shù)據(jù)挖掘能力,對數(shù)據(jù)極度敏感,能夠快速對數(shù)據(jù)進(jìn)行關(guān)聯(lián)分析;

7、思路清晰,善于主動(dòng)思考,有創(chuàng)新、能獨(dú)立分析和解決問題,具有良好的溝通能力和團(tuán)隊(duì)合作精神;

8、有漏洞分析、病毒木馬分析、Web攻防、威脅情報(bào)挖掘、反APT攻擊、機(jī)器學(xué)習(xí)相關(guān)、IOT、ICS等工作經(jīng)驗(yàn)的優(yōu)先。

往期精選

圍觀

安全牛Matrix:安恒信息WAF技術(shù)創(chuàng)新、規(guī)模及影響力第一

熱文

魔芋行動(dòng)(Operation Ninikachu )針對韓國某大型集團(tuán)的定向攻擊

熱文

成功登陸科創(chuàng)板,安恒信息開啟2.0時(shí)代

總結(jié)

以上是生活随笔為你收集整理的触发一个断点_一个补丁引发的RCE: 对CVE20191208的深入分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。