您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關在野樣本中如何利用RPC繞過CFG緩解技術的CVE-2021-26411研究,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
瀏覽器渲染進程漏洞利用的一般思路是:在利用漏洞獲得用戶態任意地址讀寫權限后,通過篡改DOM、js等對象的虛表函數指針劫持程序執行流,通過ROP鏈調用VirtualProtect等Win32 API,修改保存shellcode buffer的內存屬性為PAGE_EXECUTE_READWRITE,最終由ROP鏈跳轉到shellcode執行。Windows 8.1后,Microsoft引入了CFG(Control Flow Guard)緩解技術[1],對間接調用的函數指針進行驗證,從而緩解了通過篡改虛表函數指針劫持程序執行流這種利用技術。
然而對抗不會因此終止,隨后出現了一些繞過CFG緩解技術的新方法,比如chakra/jscript9中通過篡改棧上函數返回地址劫持程序執行流[2],v8中利用具有可執行內存屬性的WebAssembly對象執行shellcode[3]等。 2020年12月,Microsoft在Windows 10 20H1中基于Intel Tiger Lake CPU加入了CET緩解技術[4],防護了通過篡改棧上函數返回地址劫持程序執行流的利用方法。因此,如何在有CET防護的環境中繞過CFG再次成為漏洞利用的難題。
在分析CVE-2021-26411在野利用樣本時[5],我們發現了一種利用Windows RPC(Remote Procedure Call)[5]繞過CFG的新方法,這種方法無需依賴ROP鏈,通過構造RPC_MESSAGE并調用rpcrt4!NdrServerCall2即可實現任意代碼執行。
《IE瀏覽器在野0day:CVE-2021-26411分析》[5] 一文中介紹了該漏洞的根因:removeAttributeNode()觸發屬性對象nodeValue的valueOf回調,回調期間手動調用clearAttributes(),導致nodeValue保存的BSTR被提前釋放。回調返回后,沒有檢查nodeValue是否存在繼續使用該對象,最終導致UAF。
3月份Windows補丁中該漏洞的修復方法為,在CAttrArray::Destroy函數中刪除對象操作前增加索引檢查:
對于這樣一個大小可控的UAF漏洞,利用思路為:利用兩個不同類型的指針(BSTR和Dictionary.items)指向該空洞內存,通過類型混淆實現指針泄露和指針解引用:
Windows RPC用來解決分布式客戶端/服務端函數調用問題。基于RPC,客戶端可以像調用本地函數一樣調用服務端函數,RPC基本架構如下圖:
客戶端/服務端程序將調用參數/返回值等傳給下層Stub函數,Stub函數負責封裝數據成NDR(Network Data Representation)格式,最后通過rpcrt4.dll提供的runtime庫進行通信。
下面給出一示例idl:
當客戶端調用add函數后,服務端由rpcrt4.dll接受處理請求并調用rpcrt4!NdrServerCall2:
rpcrt4!NdrServerCall2只有一個參數PRPC_MESSAGE,其中包含了客戶端調用的函數索引、傳參等重要數據,服務端RPC_MESSAGE結構及主要子數據結構如下圖(32位):
如上圖所示,RPC_MESSAGE結構中,函數調用關鍵的兩個變量為Buffer和RpcInterfaceInformation。其中Buffer存放了函數的傳參,RpcInterfaceInformation指向RPC_SERVER_INTERFACE結構。RPC_SERVER_INTERFACE結構保存了服務端程序接口信息,其中+0x2c DispatchTable保存了runtime庫和Stub函數的接口函數指針,+0x3c InterpreterInfo指向MIDL_SERVER_INFO結構。MIDL_SERVER_INFO結構保存了服務端IDL接口信息,其中DispatchTable保存了服務端提供的遠程調用例程的函數指針數組。
下面以一個實例介紹RPC_MESSAGE的結構:
根據上面給出的idl,當客戶端調用add(0x111, 0x222),服務端程序斷在rpcrt4!NdrServerCall2:
可以看到,動態調試的內存dump與RPC_MESSAGE結構分析一致,其中add函數就存放在MIDL_SERVER_INFO. DispatchTable中。
接下來分析rpcrt4!NdrServerCall2是如何根據RPC_MESSAGE調用add函數的:
rpcrt4!NdrServerCall2內部調用rpcrt4!NdrStubCall2,rpcrt4!NdrStubCall2內部根據MIDL_SERVER_INFO. DispatchTable的基地址和RPC_MESSAGE. ProcNum計算調用的函數指針地址,將函數指針、函數參數和參數長度傳給rpcrt4!Invoke:
rpcrt4!Invoke內部最終調用服務端例程函數:
通過上面的分析可以知道,在獲得任意地址讀寫權限后,可以構造一個RPC_MESSAGE數據結構,傳入想要調用的函數指針和函數參數,最后手動調用rpcrt4!NdrServerCall2,即可實現任意函數執行。
接下來需要解決兩個問題:
1)如何通過js腳本調用rpcrt4! NdrServerCall2
2)觀察rpcrt4!Invoke最后的服務端例程函數調用:
可以看到這里是一處間接調用,且有CFG檢查。因此需要考慮替換MIDL_SERVER_INFO. DispatchTable函數指針后如何繞過這里的CFG防護。
首先解決問題1: 如何通過js腳本調用rpcrt4! NdrServerCall2
這里可以復用替換DOM對象虛表函數指針劫持程序執行流的方法,因為rpcrt4!NdrServerCall2是記錄在CFGBitmap里的合法指針,所以替換后依然可以通過CFG檢查。樣本里通過篡改MSHTML!CAttribute::normalize,最終由“xyz.normalize()”調用rpcrt4!NdrServerCall2。
接著解決問題2: 如何繞過rpcrt4!NdrServerCall2中的CFG防護
樣本里的思路是:
1) 利用偽造的RPC_MESSAGE和rpcrt4!NdrServerCall2調用VirtualProtect修改RPCRT4!__guard_check_icall_fptr內存屬性為PAGE_EXECUTE_READWRITE
2)替換rpcrt4!__guard_check_icall_fptr里保存的指針ntdll!LdrpValidateUserCallTarget為ntdll!KiFastSystemCallRet,從而關閉rpcrt4的CFG檢查
3) 恢復RPCRT4!__guard_check_icall_fptr內存屬性
解決了問題1,2后,后續即可利用偽造的RPC_MESSAGE實現任意函數的調用。樣本中將shellcode寫入msi.dll + 0x5000的位置,最終通過rpcrt4!NdrServerCall2調用shellcode:
最終完整的利用演示:
CVE-2021-26411在野樣本中出現了利用RPC繞過CFG緩解技術的這一創新方法。這種利用方法無需構造ROP鏈,直接通過偽造RPC_MESSAGE即可實現任意代碼執行,利用簡單且穩定,有理由相信該方法會成為繞過CFG緩解措施的一種新的有效利用技術。
上述就是小編為大家分享的在野樣本中如何利用RPC繞過CFG緩解技術的CVE-2021-26411研究了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。