Adobe Reader型別混淆導致程式碼執行漏洞分析(CVE-2018-12794)
概述
我們發現,在ZDI漏洞專案中提交的漏洞中,最常見的就是影響PDF文件的漏洞,而在這些漏洞中,大多數都涉及到Adobe Reader。因此,我們挑選了這些Adobe Reader中最有代表性的漏洞,進行詳細地分析。在Adobe Reader 2018年7月釋出的更新中,包含CVE-2018-12794/ZDI-18-682的補丁。這一漏洞由Sebastian Apelt發現,並且提交了一份質量非常高的漏洞詳情。
漏洞成因
產生這一漏洞的根本原因是型別混淆條件(Type Confusion Condition)。通過構建XML資料包(XML Data Package,XDP)模版,並對XML表單體系結構(XML Forms Architecture,XFA)物件執行某些JavaScript操作,攻擊者就可以強制Adobe Reader從模版物件的邊界引用資料。成功之後,將會在沙盒渲染器程序中實現程式碼執行。
漏洞詳情
觸發此漏洞所需的XDP模版非常簡單:
該漏洞由兩條JavaScript指令觸發。通過將一個子表單附加到另一個子表單,我們可以觸發底層Template物件的越界(Out-Of-Bounds)讀取錯誤。在這種情況下,當一個子表單由xfa.template引用,一個由xfa.form引用,隨後呼叫calling <object>.presence = “inactive”;時,就會產生漏洞。
啟用頁堆(Page Heap)後,在讀取Template物件過程中發生越界讀取時,就會在CMP指令的位置發生崩潰。雖然該物件的大小似乎只有0x140位元組,但我們在偏移量0x1d0處取消引用的資料超出了緩衝區的邊界。
深入分析
根據崩潰情況,我們唯一能夠知道的是物件型別為0x7c00。通過檢視Solaris 9.4.1中acroform.api的符號化版本,我們可以看到這個特定的型別id屬於XFATemplateModelImpl物件,它只是來自底層XDP的“Template”物件:
回到非符號化的Windows版本的acroform.api,我們可以確認Template物件的大小為0x140位元組,這也是從上面引用的越界物件的大小。我們只需要幾個步驟,就能夠找到它的大小:
1、在Acroform.api中找到靜態變數0x7c00並查詢XFATemplateModelImpl::Type方法。
2、通過前後參照,我們得到XFATemplateModelImpl虛擬函式表(Vtable)。
3、對虛擬函式表進行前後參照(Xref),得到建構函式。
4、對建構函式進行前後參照,並向上滾動幾行,將會展示出物件的大小,即0x140位元組:
由於我們導致Template物件的越界讀取,因此可以推測,程式碼正在期望一個更大的物件,而不是Template物件。同時,這一點也說明了在這裡發生了型別混淆的問題。最有可能的情況就是,型別混淆的問題發生在xfa.template和xfa.form物件之間。儘管xfa.template的大小為0x140位元組,但xfa.form物件的大小為0x270位元組。
漏洞利用
我們無法在Template物件例項化之前去執行JavaScript程式碼,因此控制其崩潰並非一件容易的事。為了實現這一點,在XDP解析發生之前,需要在PDF解析過程中或其他受控制的資料處理期間,利用漏洞進行可以控制的分配和釋放。控制崩潰發生的另一種方法,是構建一個PDF,其中包含能觸發漏洞的附加PDF。Feng shui這個堆必須發生在外部PDF中,並觸發內部(附加的)PDF中的漏洞。在這裡,要使其以執行JavaScript程式碼的方式開啟附加的PDF,還需要對許可權進行提升。因此,該方法可能對大多數使用者都無效。
實際上,也可以在沒有頁堆的情況下,執行poc.pdf來觀察可以控制崩潰發生的情況。由於讀取了Unicode字元的一部分,並將其用作指標,最終會導致其發生崩潰。以下是不使用頁堆情況下的崩潰輸出:
結論
如果大家想要自行測試這一漏洞,PoC位於: https://github.com/thezdi/PoC/tree/master/CVE-2018-12794 。該漏洞應該適用於2018.011.20040版本之前的Adobe Reader。
縱觀我們今年釋出的通告,我們發現其中有許多與PDF相關的漏洞。Adobe Reader可能是漏洞數量最多的PDF瀏覽器,同時Foxit中也存在大量漏洞。由於Adobe Reader被很多作業系統作為預設PDF渲染器使用,因此也不難解釋,為什麼眾多調查人員都在針對Adobe Reader尋找漏洞。
在之後,我們還將持續關注其安全性,請大家繼續跟隨我們瞭解最新的漏洞利用技術和安全補丁情況。