91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析

發布時間:2021-11-25 13:51:27 來源:億速云 閱讀:137 作者:柒染 欄目:編程語言

本篇文章為大家展示了如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

背景

2018年5月15日,ESET發布文章“A tale of two zero-days”,該文章披露了今年3月ESET在惡意軟件掃描引擎(VirusTotal)上捕獲了一個用于攻擊測試的 PDF文檔。該PDF文檔樣本包含兩枚0-day漏洞(CVE-2018-4990,CVE-2018-8120)以實現針對Adobe Acrobat/Reader PDF閱讀器的任意代碼執行。其中CVE-2018-4990為Adobe PDF閱讀器的代碼執行漏洞,而CVE-2018-8120則是Windows操作系統Win32k的內核提權漏洞,在獲取代碼執行權限后通過內核提權漏洞繞過Adobe PDF閱讀器的沙盒保護,實現任意代碼執行。

漏洞利用回溯分析

360威脅情報中心分析確認披露的漏洞可被利用,我們試圖通過公開的POC樣本中針對Adobe Acrobat/Reader代碼執行的漏洞(CVE-2018-4990)利用過程進行詳細分析,并記錄整個分析過程。如有分析不當之處敬請諒解。

分析環境

操作系統:Windows 7 SP1

AdobeReader DC:1700920044

樣本MD5:bd23ad33accef14684d42c32769092a0

Payload功能解析

使用PDFStream打開漏洞樣本,在尾部可以發現使用了JavaScript來觸發利用漏洞:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析    

通過分析可知,JavaScript中的前部分為PDF閱讀器漏洞觸發后加載運行的載荷,主要用于提權并執行惡意代碼。而之后的JavaScript代碼中則通過兩個Array實例sprayarr及a1來實現內存Spray布局,這里需要注意的是a1對Array中奇數下標的element進行了釋放,這是UAF類漏洞利用中常見的一種內存布局手法:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析    

內存部署成功之后,接著在myfun1,myfun2中調用了兩次觸發double free的腳本,該腳本代碼觸發了double free,從而導致后來的代碼執行,觸發double free的腳本:

varf1 = this.getField("Button1");

最后對array實例sprayarr2進行賦值,每個element為一個長度為0x20000-0x24的ArrayBuffer,接著遍歷sprayarr可以發現其對應的某一個sprayarr的element長度被修改為了0x20000-0x24(默認的長度為0x10000-0x24),此時通過超長的sprayarr[i1]即可修改相鄰的sprayarr[i1+1]對象的len長度屬性,從腳本代碼中可以看到長度被修改為了0x66666666,最終通過該超長的sprayarr[i1+1]即可實現全內存的讀寫:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析        

為此攻擊者編寫了專門的利用超長sprayarr對象實現全內存讀寫的函數:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

獲取全內存讀寫能力后,POC中通過偽造bookmarkRoot的對象實現代碼執行:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

POC運行之后會導致崩潰:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

崩潰的原因為objecscript地址為硬編碼,其中0x23A59BA4-0x23800000的地址并不適配測試的Adobe Reader版本,從而導致崩潰:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

通過對POC中的Payload功能解析,我們確定了POC中的幾個需要分析的要點,這也是搞清楚整個漏洞利用的關鍵:

l sprayarr,a1在進行內存spray時的內存結構

l 觸發double free的代碼具體分析(var f1 = this.getField("Button1");)

l sprayarr2初始化時的內存狀態,其初始每個element長度正好是sprayarr中超長element的長度,這不禁讓我們懷疑sprayarr2和某個sprayarr重合了(或許是第二點中的代碼將sprayarr中的某個element釋放了?然后被sprayarr2重用?)

腳本分析及調試

帶著Payload功能解析中得出了漏洞利用關鍵點我們開始逐一進行調試分析。

如何分析相關內存結構

樣本中具體的漏洞觸發/利用部分都是JavaScript腳本,因此調試的時候我們可以依賴對應的三角函數實現具體的中斷。為了獲取對應的內存結構,我們可以直接修改對應POC,比如在POC中創建一個Array的實例myContent,將該Array中第0個element賦值為0x1a2c3d4f,以便于內存搜索,之后分別將我們感興趣的變量賦值到該Array中即可很方便的定位內存 進行分析:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

通過上述的三角函數斷下后,此時通過搜索0x1a2c3d4f即可找到對應的myContent結構,如下所示地址0x062035f8開始的數據則為對應的tag(標記為0x1a2c3d4f),之后的四字節值0xffffff81標記該element的type類型,再往后依次為我們賦值的element,由于都是Array,所以type均為0xffffff87:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

而為了獲取sprayarr和a1的內存狀態,我們可以在下圖位置下三角函數斷點來方便調試:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

sprayarr

有了分析腳本中內存結構的方法,我們通過上述的辦法定位到sprayarr的內存結構,可以看到element個數為0x1000,偏移c的位置包含指向具體內存element的指針0x07e94718:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

進一步可以看到對應的每一個element對象的地址,由于sprayarr的element為ArrayBuffer,所以其對應的type為0xffffff87,從下標1開始全部都是type為0xffffff87的ArrayBuffer:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

查看下標為1的element對象的內存結構如下所示,大的紅框分別對應的sprayarr[1]和sprayarr[2]中的Arraybuffer對象,其內存為連續布局。每個Arraybuffer對象偏移+c的位置為具體的內存空間,下圖中每個Arraybuffer對象的實際內存空間也是連續分布,而內存中的兩個值相減則正好為Arraybuffer初始化時的長度(0x88dc760 - 0x88cc760=10000):

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

進入到具體的Arraybuffer內存空間查看(0x88cc760),實際內存長度為ffe8(和分配的0x10000-0x24一致):

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

而sprayarr連續布局的內存空間一直到延伸到地址0x18ce0038:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析

al

繼續使用分析相關內存結構的方法查看此時的al array,同理偏移+c的地方指向了具體的element:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析由于a1中的奇數下標的element在此時已經被釋放,因此右側element的內存都為0,此處選擇al[2]進行查看,可以看到0x074926d8處保存了對應的長度,之后0x74926E0處指向腳本代碼中對應的Uint32Array,起偏移+0xC的位置包含了指向具體內存的指針,而0x063008a0處即為對應的Uint32Array(252),其長度為252*4=1008=0x3f0,而a1中有所Uint32Array最后都指向連續布局的內存空間:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析對應的JavaScript腳本,其中a1i1,a1i1的值在此時分別為0x0d0e0048和0x0d0f0048:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析Uint32Array(252)對應的內存布局(0x063008a0):

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析釋放的al[3]對象內存布局:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析Uint32Array最終的內存布局(從0x06300890開始到0x88be180):

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析

sprayarr2

對sprayarr2的內存布局分析同樣通過三角函數在sprayarr長度修改后斷下:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析sprayarr2的內存結構不過多展示,和sprayarr大致相同,此時sprayarr[i1]的長度已經被修改為0x1ffe8:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析其后相鄰element的len也被修改為0x66666666:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析整個sprayarr的起始地址對應的內存數據:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析檢查sprayarr2內存,發現sprayarr中被修改的element和sprayarr2中的某個element指向同一片內存:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

而sprayarr2中除了和sprayarr中一致的0x0d0e0058外可以發現,正常情況下,sprayarr2的element內存地址是從0x18d4a0d8開始的一片連續內存,而此處0x0d0e0058更像是漏洞利用中占坑的結果,這也肯定了我們之前的猜測,sprayarr中的內存被釋放然后被sprayarr2占據,由于正好占據的長度為spayarr element大小的兩倍,因此可以猜測釋放了兩次,每次釋放一個sprayarr element:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

這里值得注意的是重用的內存地址0x0d0e0058似乎和POC中a1i1和a1i1的值非常接近,難道是通過這個地方控制的釋放?

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

釋放函數定位

為了驗證到底是否是var f1 = this.getField("Button1");相關代碼導致了對應的a1i1和a1i1中的精確地址釋放,通過以下windbg斷點進行驗證:

buMSVCR120!free ".if poi(esp+4)=0x0d0e0048{}.else{gc}"

由于該函數在程序運行中會被大量調用,直接下斷點會導致程序卡死,而且此處我們是為了驗證var f1 = this.getField("Button1");相關代碼是否導致了sprayarr中的element被釋放,因此可以在該代碼前后加log函數,log被斷下后再下對應的free斷點并運行:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析                    

再次運行,調試器斷下,可以看到此時正在釋放地址0x0d0e0048中的內存,可以看到是JP2KLib!JP2kCopyRect+0xbae6調用了free釋放函數:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

查看JP2KLib!JP2kCopyRect+0xbae6即可定位到漏洞觸發點(釋放函數):

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

動態調試分析可以發現漏洞函數運行到該loop前,其循環遍歷的地址為eax,而eax的值為0x08AA2820(通過poi(poi(esi+0x48)+0x0c)獲取):

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

而0x08aa2820正好為腳本中的a1中某個釋放的hole,即其大小為0x3f0:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

而循環的校驗值為0xff,0xfe*4 = 0x3f8,即可以訪問到之后的a1i1和a1i1(0x0d0e0048,0x0d0f0048):

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

之后繼續訪問并讀取地址0x0d0e0048中的數據,并通過eax傳入函數sub_10066FEA。

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

sub_10066FEA最終會調用MSVCR120!free釋放該內存:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

精準的內存釋放過程

動態調試得知第一次調用var f1 = this.getField("Button1");相關函數將導致0x0d0e0048對應的0x10000長度的內存被釋放:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

繼續循環執行后,漏洞函數讀取之后的地址0x0d0f0048中的數據,并釋放對應大小為0x10000的內存,此時兩次釋放了總共0x20000長度的內存(兩次釋放由myfun1函數中的getField相關代碼完成,myfun2中的getField刪除不影響利用):

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

通過對比hole被占據成buffer后的內存結構和正常a1的element就可以發現,該結構中尋址的起始地址要比之前的element低16個字節,因此獲取a1i1和a1i1 element時的尋址編號分別是0xfd和0xfe:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

最后通過sprayarra2賦值搶占該0x20000的內存,一旦分配成功,即變相的將sprayarr中0x0d0f0048位置的element的長度從0xffe8修改為0x11fe8:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

漏洞觸發原理分析            

分析到這還剩最后兩個疑問。

1. poi(poi(esi+0x48)+0x0c)這個被遍歷的地址是如何被分配的?

2. poi(poi(esi+0x48)+0x04)處的0xff來自何處?

第一個問題

通過調試回溯,我們找到了具體的jp2h解析函數,如下所示:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

其對應的參數如下:

參數1:getField("Button1")獲取的圖片的實際大小

參數2:poi(poi(esi+0x48)+0x0c)

參數3:圖片的對象,可以看到包含的具體圖片內容

函數調用前,poi(poi(esi+0x48)+0x0c)這個地址初始化為零:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

繼續跟蹤調試可以看到,給poi(poi(esi+0x48)+0x0c)分配的內存地址大小為0x3f4,即一個a1中的hole:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

而圖片的實際大小則是0x3f4,正好用于填補a1的hole:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

poi(poi(esi+0x48)+0x0c)為pg2h解析時分配,其實際大小和圖片大小一致(0x3f4),正好填補a1中的hole,而在loop邏輯處理poi(poi(esi+0x48)+0x0c)時,由于長度為0xfe(0xfe*4 = 0x3f8),所以越界8字節剛好讀到hole中殘留的攻擊者部署地址!

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

至此,可以清楚的知道漏洞觸發的原因:越界讀取,而我們也可以將漏洞觸發的代碼注釋修改成越界讀了:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

0xff控制字

其中控制loop循環次數的0xff,實際在poi(poi(esi+0x48)+0x4)的位置。

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

通過回溯分析,發現該值同樣來自pg2h函數中的解析。

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

調試知道,其賦值來自于pg2h第三個參數,圖片對象+10的位置。

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

067f4700這個變量主要用于標記解析圖片時的指針,當解析圖片時,該指針從圖片的開始一直遞加,直到圖片尾部,如下圖所示為掃描到圖片中間時的值。

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

掃描完之后發現該指針指向后面的一片fffffff的內容,如下所示:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

此時通過該指針給poi(poi(esi+0x48)+0x4)賦值時即為對應的0xff,從而導致之后的越界讀(這個地方感覺應該是pclr后面應該還有字段,突然截斷了導致了一個錯誤的殘留指針)。

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

而打過補丁之后,poi(poi(esi+0x48)+0x0c)處的buffer被設置為零,不再指向之前a1中的某一個hole地址,從而無法通過釋放函數前的校驗:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

遺留問題

腳本函數myfun1中 array2的賦值會導致部分a1里hole偏移249處,地址為0x0d0e0048的4字節數據被置空(因為其Uint32Array的大小為250,所以正好可以將偏移249的地址為0x0d0e0048處的4字節數據置空)。

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

如下所示,部分被填掉的a1 hole,可以看到對應的長度由0x3f0變成了0x3e8:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析            

而直接刪除后會影響漏洞觸發,如下所示可以看到崩潰的原因在于漏洞函數釋放的地址不合法導致,其遍歷的buffer并不是我們分配的任何一個a1的element對象,因此猜測針對array2的循環遍歷主要是用于將部分符合大小的臟 hole給填補上,這樣var f1 = this.getField("Button1");相關代碼調用的時候就能確保該buffer分配到我們指定的a1 hole中。通過調整array2的大小后發現,將大小值從0x200一直減少到0x70都能保證漏洞的穩定觸發,但是低于0x70則會降低觸發運行漏洞函數的幾率,此處可以進一步研究:

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析                

整個漏洞利用過程

通過以上的分析過程可知漏洞函數JP2KLib!JP2kCopyRect+0xbae6中對訪問的buffer檢驗有誤,導致可以越界讀取之后8字節的內容(0xff的獲取有可能是pclr突然中斷導致),所以該8字節的內容為攻擊者可控,并在之后用于精確釋放內存,最終通過精確釋放,并重用該釋放的地址,獲取一個超長element,以實現全局內存讀寫,最終導致任意代碼執行。

整個漏洞利用過程總結如下(編號和內存布局圖中的編號對應):

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析                    

1、 通過heap spray a1布置大量比buffer稍大的Uint32Array,將Uint32Array中249,250位置的element設置為需要釋放的地址,之后將a1中奇數elemnt釋放(以便于之后JP2KLib中解析圖片時被分配到)。

2、 heap spray sprayarr布置之后需要釋放的內存對象(即sprayarr)

3、 通過加載指定大小的jp2k圖片,導致解析jp2k圖片時分配的內存為之前某一個a1中的hole,之后運行到JP2KLib!JP2kCopyRect+0xbae6,漏洞觸發越界讀取249,250偏移處(即sprayarr中兩個相連的elment)的內存并釋放(合計0x20000),轉化為類UAF的利用

4、 同上

5、 通過sprayarr2的賦值搶占釋放的0x20000內存,一旦搶占成功,sprayarr中之前被釋放的elment的長度就會被修改為0x20000

如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析                    

6、 最終通過精確釋放,并重用該釋放地址,獲取一個超長element,以實現全局內存讀寫,再通過全局內存讀寫,偽造bookmarkRoot的對象實現任意代碼執行!

上述內容就是如何進行CVE-2018-4990 Adobe Reader代碼執行漏洞利用分析,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

龙海市| 延边| 南郑县| 瑞昌市| 麻城市| 嘉黎县| 深水埗区| 大连市| 大港区| 饶阳县| 斗六市| 水城县| 池州市| 额尔古纳市| 台东县| 乐清市| 达尔| 郎溪县| 仁布县| 阜阳市| 桃园市| 宝鸡市| 武安市| 柳林县| 潜江市| 江陵县| 丹棱县| 西畴县| 平江县| 阳信县| 三台县| 阳东县| 惠州市| 分宜县| 禄劝| 临夏市| 台北县| 兴宁市| 梧州市| 铜陵市| 乌兰浩特市|