作者:ze0r@360 A-TEAM
來源:https://mp.weixin.qq.com/s/F2N04exaW8QO1IeHRZgmfg

本篇文章,360 A-TEAM 將為大家介紹FLASH 0day(CVE-2018-4878)如何從POC到利用。

聲明:本文由ze0r@360 A-Team原創,僅用于技術研究,不恰當使用會造成危害,嚴禁違法使用,否則后果自負。

0×00 前言

這篇文章沒有前言,簡單粗暴,干貨滿滿~下面我們就開始吧~

0×01 在野EXP

一開始我們下載到了當時在野的EXP,用FFDEC查看AS腳本,關鍵觸發點如下:

從反編譯的腳本中,可發現除了布局內存外就是這兩個方法,主要就是以一個§\x05§為參數初始化了一個drmManager對象,之后就將§\x05§賦值為NULL,而§\x05§為:

之后在github上發現已經有人發布了POC,而代碼完全一致,只不過把亂變量名變得有意義了,而且也可以直接編譯生成。故分析依照此POC進行。

前面已經說過,除了布局內存的代碼外,就是初始化并賦值后建立了一個監聽器。在POC中exploit方法中只留下這段代碼,編譯運行:

打開稍等片刻就會崩潰到調試器,查看:

可見直接使用ecx傳遞了一個對象,在IDA中也確認這是一次虛函數調用。

根據匯編代碼可斷定,ECX偏移0x0c處為某對象指針,而此對象已經全是0,造成了懸掛指針。再看AS3腳本中,把一個MyListener(實現了DRMOperationCompleteListener接口)類型對象賦值null。所以可猜測ecx->0x0c為MyListener對象。下斷此時ecx這個對象的構造過程:

大致可判斷此對象共5個方法,triggerVul即面觸發崩潰的方法。查看引用共有2處:

反匯編確認賦值方法為1037a150:

windbg中下斷,單步幾次后查看對象內存:

確認此對象0x0c處為DRMOperationCompleteListener實例指針,即DRMOperationCompleteListener實例在被置null之后被垃圾回收,而在對象中還留存著實例指針造成懸掛指針問題。

0×02 POC利用

而在POC的利用中,則是利用雙重釋放內存來利用此漏洞。如下:

由于在代碼中,在出現異常后又new了一個新的MyListener對象,由于同是Mylistener對象大小相同,所以內存管理器會仍然分配這塊原來MyListener對象所在內存給新對象(只要沒被占用)。而之后代碼drmManager從未被使用,所以垃圾回收會釋放drmManager對象,同樣,也會把drmManager對象成員釋放(減少引用計數),于是0x068c0100會再次被清除回收:

在清除完成后,AS3中的danglingpointer變量仍然指向這塊區域,所以在POC中,也是定時查看danglingpointer的成員變量是否被改變來判斷是否已經完成內存釋放。而之后大量申請內存以再次被內存管理器分配此內存完成占用。在偏移0x70處下寫入斷點(因為重啟了調試器,故下面截圖中地址并不完全相同):

可以看到Mem_Arr已經成功占位,正在寫入變量默認值。完成后可得內存布局:

可見Mem_arr的數據區域為0x054a815c-0x054a819c(position=0x31)。其中0x38383838為改寫的Modify對象標記,即:

AS3代碼中,PwnBuffer主要設置成員o1的成員變量值,下寫入斷點得到布局:

從POC注釋中我們知道danglingpointer.a14為m_buffer地址,而a31為o1對象,而查看上面的布局,發現有明顯的故意錯誤(0x54a818c已經被錯誤的改寫為0xfffffff0),修正后:“this.danglingpointer.a30 =this.danglingpointer.a14 - 0x10;”。修正后布局:

正確改寫o1指針后,調用 PwnBuffer則更改了arr[0]屬性,之后可成功讀取內存:

此時由于arr[0]長度已經被設置成0xffffffff,故可讀寫進程任意地址內存:


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/536/