作者:維一零
原文鏈接:https://weiyiling.cn/one/firefox_0day_case_analysis
RCE部分
在渲染進程通過一個JS腳本利用XSL對象解析的UAF漏洞執行遠程ShellCode。
漏洞原理
利用程序首先定義一些XML,內部包含多個XSL對象。

隨后調用transformToDocument方法導致Convert函數被調用。

Convert函數的調用堆棧如下,txMozillaXSLTProcessor::TransformToDocument經過多層調用執行了Convert函數。

Convert函數取參數時使用了JS::ToString,導致用戶自定義的回調函數調用。

用戶回調函數中,攻擊者調用removeParameter釋放了參數本身導致UAF。

漏洞利用
通過XSL對象的UAF漏洞,攻擊者構造2個數組對象用于實現任意內存讀寫。

借助這2個數組對象分別實現任意內存地址讀寫原語和JS對象地址函數。

接著通過一個函數對象獲取JIT代碼的地址,通過多次調用該函數使其轉變為編譯熱代碼,并通過內存讀寫原語獲取其引用位置。

待執行的ShellCode事先通過一個DataView對象存儲,來源為遠程的二進制資源 “s97.bin”。

最終通過構造一段ROP代碼調用VirtualProtect函數修改ShellCode的內存屬性并成功執行,調用的方式是通過修改JIT代碼引用指針進行代碼劫持。

EOP部分
通過RCE部分的ShellCode二進制代碼“s97.bin”進行提權,最終由低權限的渲染進程向中權限的WebGPU進程實施代碼劫持,利用的是WebGPU由于某RPC接口函數暴露問題引起的UAF漏洞。
漏洞原理
FireFox的WebGPU對象有父端和子端的角色區分,通常父端進程位于一個專門的WebGPU進程,具有較高的權限。漏洞發生位置是WebGPU對象定義的Shutdown接口函數,該函數用于相關對象的關閉和清理工作,但是由于定義此接口時使用父子端IPDL通信協議,故存在配套的SendShutdown函數和RecvShutdown函數。以下為PWebGPUChild子端對象的SendShutdown函數,該函數發送一個IPDL消息“PWebGPU::Msg_Shutdown”請求父端對象進行關閉操作,此操作通常僅在渲染進程清理時由內部CompositorBridgeChild對象的Destroy函數進行調用。

父端對象WebGPUParent對應的接收處理函數RecvShutdown如下,其內部調用wgpu_server_delete函數直接釋放一個WGPUGlobal類型的對象mContext。

漏洞產生的根源在于SendShutdown函數接口的意外暴露導致攻擊者可以直接調用該函數釋放WGPUGlobal對象,形成UAF漏洞。如下是利用程序創建一個webgpu實例對象后直接調用PWebGPUChild::SendShutdown接口來形成UAF的方式。

漏洞利用
利用該UAF漏洞攻擊者通過向WebGPU父端進程發送一些顯示數據進行占位,此數據為經過特殊構造的ROP_GADGET片段,同時將最終待執行的payload也一起發送給父端進程。

構造的ROP_GADGET片段如下,主要包含對占位對象內部字段的劫持指針和用于payload調用任務ROP代碼。

占位成功后,調用2次SendShaderModuleDestroy函數觸發代碼劫持,第一次調用利用GetClientSetRequestHeaders函數實現一個任意地址寫的功能,用于修改第二次調用時利用_cairo_win32_device_flush函數內部的GdiFlush函數指針。

接著由劫持的GdiFlush函數指針調用ROP代碼,該代碼主要功能即調用VirtualProtect修改一段ShellCode的內存屬性并執行。

該ShellCode的代碼主要負責查找位于顯示數據區域的payload并調用VirtualProtect修改其內存屬性和最終執行,而payload代碼則是一段簡單的downloader,負責從 hxxps://xxx.xxx.xxx.xxx/public_api/get64 下載遠程msf惡意模塊。

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