當前位置:
首頁 > 新聞 > 如何繞過Windows 10的CFG機制

如何繞過Windows 10的CFG機制

前言


本文來源於我在2016年7月的研究結論,由於各種原因現在才能發布。2016年6月,Theori曾發表了一篇關於MS16-063中修補了的IE漏洞分析,文中發布的exploit則僅是針對Windows7上的IE 11版本,此外由於Windows 10採用了CFG機制所以無法對Windows 10機器進行利用。

而本文就描述了我是如何在Windows 10下繞過CFG並進行利用的。事實上我還發現了另一種方法,會在接下來的一篇文章中提到。


了解CFG


控制流保護(Control Flow Guard,CFG)是微軟在Windows 8.1 update 3和Windows 10下實現的一個保護機制,用以保護在彙編層下的直接調用。趨勢科技分享的一篇Windows 10如何實現CFG的分析文章很不錯。雖說目前已有數種公開的CFG繞過方法,但是這些方法大多是針對CFG的實現演算法,而我想從功能的薄弱點入手。


Theori在其博文中講到由於CFG機制,無法成功在Windows 7上成功利用,接下來就讓我們來細究一二,然後嘗試繞過它。

Theori分享的利用代碼在Windows 10的IE下執行,直到調用虛函數表後被重寫。所以剩下的問題便是,我們如何利用任意讀寫來繞過CFG。


根據趨勢科技的研究,函數LdrValidateUserCallTarget調用CFG驗證函數是否有效使用了間接調用,如下圖所示:



載入到EDX中的指針是驗證bitmap的基本指針,在本例為:


之後經過驗證的函數將其地址載入到ECX,以kernel32!VirtualProtectStub作為例子,那麼地址則為:



接著地址向右偏移8位,用以載入存儲著驗證位(validation bit)的DWORD值:



函數地址右移3位,然後執行位測試,實質上對偏移地址進行0×20模操作。然後利用驗證的bitmap對DWORD進行檢測:


所以相關的位都在偏移地址0×14:



這也就是說它是有效的,VirtualProtect存在有效調用地址,然而它的參數也必須由攻擊者提供,所以我們還得再接再厲。通常情況是在ROP鏈中完成,但所有不是從函數開始的位元組都是無效的,因此解決方案是找到一個在被調用參數是可以控制的函數,且函數的功能可以給攻擊者提供便利。

在Windows 10中利用


Theori提供的exploit,代碼執行是以stack pivot重寫TypedArray的虛函數表。由於排除掉其他可能性,細究TypedArray提供的函數還是很不錯的,以下兩個函數就比較有趣:




偏移地址分別為0x7c和0×188,他們能從javascript代碼中直接調用,而且HasItem有個可以控制的參數,與此同時Subarray存在兩個用戶可控制的參數,然而問題是它們都不返回除布爾值之外的任何數據。之後的問題便是,我們該選擇哪個函數來進行覆蓋。


此外選擇的函數必須提供相同數量的參數,否則在返回時會導致堆棧不平衡而引發異常。我要找的API應該是可以向堆棧載入一個指針用以覆蓋返回地址,從而繞過CFG。


我找到的API為RtlCaptureContext,在kernel32.dll、kernelbase.dll和ntdll.dll中都有調用,這個API有一個指向CONTEXT結構的參數:



CONTEXT結構保存了轉儲的包含ESP的所有寄存器,此外輸入值僅僅為一個可容納數據的指向緩衝區的指針。如下為TypedArray對象的布局:



第一個DWORD值是虛函數表指針,其能夠被覆蓋偏移地址0x7c處的API RtlCaptureContext的地址,然後創建一個假的虛函數表。同時偏移地址0×20下的DWORD是TypedArray用以指向實際數據的指針:



由於它依舊可能泄漏緩衝區地址,我們就將其充當為RtlCaptureContext的參數。為了構造假的虛函數表,必須在偏移地址0x7c處創建一個指針指向ntdll!RtlCaptureContext,這意味著泄漏了RtlCaptureContext地址,也即ntdll.dll的地址也泄漏了。執行的默認路徑需要使用一個指向jscript9.dll的指針的虛表地址:



從該指針向上迭代0×1000個位元組搜索MZ頭,之後查找到指向kernelbase.dll的導入表。然後使用同樣的方法找到kernelbase.dll的基址,接著找到ntdll.dll的導入表指針並再次獲得其基址,最後從導出函數中找到RtlCaptureContext。


儘管這個方法是有效的但是有個缺陷,如果系統中裝了EMET,會觸發來自jscript9.dll的代碼崩潰,因為從PE頭或導出表讀取數據是不被允許的,為了繞過EMET我使用了另外的技術。


記住CFG會保護所有的間接調用,由於jscript9.dll的函數被CFG保護了,所以不能調用直接指向ntdll的函數。偏移地址0×10下就有一個這樣的函數:



使用讀操作,能通過以下函數找到指向ntdll.dll的指針:



通過一個指向ntdll.dll的指針得到RtlCaptureContext的地址,這一步可以不通過查找導出表而是通過搜索簽名或者hash完成。RtlCaptureContext內容如下:



前0×30位元組保持不變且看來相當的獨特。如下所示當把他們整合在一起時,將其作為不受限制的哈希碰撞:



函數可以使用指向ntdll.dll的指針作為參數。


接著將其全都整合到一起:



緩衝區偏移地址0×200包含了來自RtlCaptureContext返回的結果:



從上面可以清楚地看出堆棧指針被泄漏,現在我們需要找到一個能執行控制的地址用以進行重寫。注意堆棧頂部:



這就是當前函數的返回地址。運氣不要太好,該偏移地址與其他簡單函數將是相同的,所以可以進行寫入並使其覆蓋其返回地址,從而繞過CFG。


利用補充如下:



運行時顯示EIP控制:



此外在偏移地址0×40和0×44的寫入現在位於棧頂,其允許創建stack pivot於是獲得ROP鏈,接下來就是使用POP EAX gadget,隨後使用XCHG EAX,ESP gadget。


解決方案


然而微軟表示,通過損壞堆棧上的返回地址以繞過CFG是一個已知的設計限制,因此無法領取任何種類的賞金,如下所示:



說了這麼多,微軟做了兩個事情來解決這個問題,首先在Windows 10即將到來的版本中,將引進RFG機制(Return Flow Guard),防止通過損壞堆棧以獲取執行控制的方式。其次便是在Windows 10的周年版發布中引入敏感的API的介紹,它僅保護微軟Edge。雖然對於本例來說沒有什麼幫助,但是他能限制微軟Edge中的RtlCaptureContext API。


Poc代碼可以在這找到:https://github.com/MortenSchenk/RtlCaptureContext-CFG-Bypass


*參考來源:improsec,FB小編鳶尾編譯,轉載請註明來自FreeBuf.COM


您的贊是小編持續努力的最大動力,動動手指贊一下吧!


本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 FreeBuf 的精彩文章:

美國國防部DARPA想要創建安全數據共享技術
圖解Meterpreter實現網路穿透的方法

TAG:FreeBuf |

您可能感興趣

如何使用SilentCleanup繞過UAC?
如何利用sdclt.exe繞過UAC?
繞過AppLocker系列之CreateRestrictedToken的利用
如何在32位系統中使用ROP+Return-to-dl來繞過ASLR+DEP
攻擊者現可繞過MicrosoftEdge、Google Chrome和Safari的內容安全策略
Windows Shellcode學習筆記——利用VirtualAlloc繞過DEP
【FB TV】一周「BUF大事件」:黑客泄露竊取的900Gb Cellebrite數據;Netgear路由器存在密碼繞過漏洞
繞過AppLocker系列之MSBuild的利用
利用忘記密碼功能繞過Windows auth & BitLocker
繞過AppLocker系列之MSIEXEC的利用
Chrome XSS審計之SVG標籤繞過
利用 API 實現對 Windwos 日誌監控的繞過
通過APC實現Dll注入——繞過Sysmon監控
無法繞過的Helga Testorf—安德魯.懷斯
如何繞過sop執行XSS盜取cookie並發送推文?
如何利用sdclt磁碟備份工具繞過UAC
蘋果電腦小心!攻擊者可繞過macOS 10.13中的SKEL安全保護
竊取 OAuth 令牌繞過 Airbnb 身份驗證
滲透技巧——Windows日誌的刪除與繞過