作者:gaoya,yyjb
原文鏈接:http://noahblog.#/cve-2020-0796_improvement/

在此前跟進CVE-2020-0796的過程中,我們發現公開代碼的利用穩定性比較差,經常出現藍屏的情況,通過研究,本文分享了CVE-2020-0796漏洞實現在realworld使用過程中遇到的一些問題以及相應的解決方法。

Takeaways

  • 我們分析了exp導致系統藍屏的原因,并嘗試對其進行了改進;
  • 相對于重構前exp,重構后的exp執行效率與穩定性都有顯著提高;
  • 關于漏洞原理闡述,Ricerca Security在2020年4月份發布的一篇blog中已非常清晰,有興趣的讀者可以移步閱讀,本文不再贅述。

初步選擇和測試公開exp可用性

測試環境:VMWare,Win10專業版1903,2G內存,2處理核心

為了測試和說明方便,我們可以將exp的執行分為3個階段:

  1. 漏洞利用到內核shellcode代碼開始執行
  2. 內核shellcode代碼執行
  3. 用戶層shellcode執行

根據實際情況,我們測試了chompie1337ZecOps的漏洞利用代碼。根據各自項目的說明文檔,兩份代碼初步情況如下:

  • ZecOps

ZecOps的利用代碼是在單個處理器的目標計算機系統上測試的;在后續的實際測試中,發現其代碼對多處理器系統的支持不足,雖然在測試環境中進行了多次測試中,系統不會產生BSOD,但漏洞無法成功利用(即exp執行第一階段失敗)。

  • chompie1337

chompie1337的代碼在漏洞利用階段則表現得十分穩定,但在內核shellcode執行時會造成系統崩潰。

因此,我們決定將chompie1337的利用代碼作為主要測試對象。

內核shellcode問題定位

我們在win10 1903中測試了chompie1337的exp代碼,絕大部分的崩潰原因是在漏洞利用成功后、內核shellcode代碼執行(即exp執行的第二階段)時,申請用戶空間內存的API zwAllocateVirtualMemory調用失敗。在我們的多次測試中,崩潰現場主要包括以下兩種:

imgCrash_A backtrace

imgCrash_B backtrace

對比exp正常執行時的流程和崩潰現場,我們發現無論是哪種崩潰現場,根本原因都是在內核態申請用戶態內存時,調用MiFastLockLeafPageTable時(crash_A是在MiMakeHyperRangeAccessible中調用MiFastLockLeafPageTable,crash_B在MiGetNextPageTable中調用MiFastLockLeafPageTable)函數內部出現錯誤,導致系統崩潰。

在遇到crash_B時,我們起初認為這是在內核態申請用戶態讀寫權限內存時,系統復制CFG Bitmap出現的異常。CFG(Control Flow Guard,控制流防護)會檢查內存申請等關鍵API調用者是否有效,以避免出現安全問題。

隨后,我們嘗試了一些CFG繞過的方法,包括替換內存申請API間接調用地址,強制修改進程CFG啟動標志等,這些方法無一例外都失敗了。但在嘗試過程中,ZecOps在他的漏洞分析利用文章中提到的一篇文章給了我們啟發。zerosum0x0這篇文章分析了cve-2019-0708漏洞內核shellcode不能穩定利用的原因,其中提到了微軟針對Intel CPU漏洞的緩解措施,KVA Shadow。

我們再次詳細分析了導致MiFastLockLeafPageTable調用失敗的原因,發現MiFastLockLeafPageTable函數中的分頁表地址(即下圖中的v12)可能會無效。

img

我們根據KVA Shadow緩解措施原理,猜測這是本次測試exp崩潰的根本原因。內核shellcode在調用API申請用戶層內存時,由于KVA Shadow對于用戶層和內核層的系統服務調用陷阱,如果IRQL等級不是PASSIVE_LEVEL,無法獲取到正確的用戶層映射地址。

解決問題

通過參考zerosum0x0文章中修正CVE-2019-0708 payload來繞過KVA Shadow的代碼,但出于時間以及系統穩定性等多方面因素,我們暫時放棄了這種方法,轉而嘗試通過一種更簡單和容易的方式來解決這個問題。

顯而易見地,如果我們能夠在內核shellcode中降低系統調用中的IRQL,將其調整為PASSIVE_LEVEL,就能夠解決后續shellcode執行時由于用戶態內存分配出現崩潰的問題。但在公開資料的查找過程中,我們并沒有找到針對win10系統的IRQL修改方法。

于是,我們從崩潰本身出發,試圖對這種情況進行改進。由于內核shellcode是從DISPATCH_LEVEL的IRQL開始執行的,調用內存分配等API時,可能因為分頁內存的異常訪問導致崩潰,于是我們嘗試避免系統訪問可能崩潰的分頁內存。

在重新比對分析crash_B和成功執行的利用代碼時,我們發現MiCommitVadCfgBits函數中會檢查進程的CFG禁用標志是否開啟(下圖中的MiIsProcessCfgEnabled函數)。如果能夠跳過CFG的處理機制,那么就可以避免系統在內存申請過程中處理CFG位圖時對可能存在問題的分頁內存的訪問。

img

進一步對MiIsProcessCfgEnabled進行分析,該標志位在進程TEB中,可以通過GS寄存器訪問和修改。

img

我們在內核shellcode調用zwAllocateVirtualMemory API之前修改CFG標志,就可以避免大部分崩潰情況(即B類型),順利完成用戶態內存的分配。需要一提的是,win10在內存申請時,大部分系統處理過程都是針對CFG的相關處理,導致B類型崩潰產生的次數在實際測試中占比達80%以上,所以我們沒有考慮A類型崩潰的情況。

參考Google Researcher Bruce Dawson有關windows創建進程性能分析的文章

實際修改shellcode遇到的問題

在修改CFG標志位解決大部分內核shellcode崩潰的問題后,我們在實際測試中又發現,該exp無法執行用戶層shellcode(即exp執行第三階段)。經過分析發現,這是由于用戶層shellcode會被用戶層CFG檢查機制阻斷(參考:https://ricercasecurity.blogspot.com/2020/04/ill-ask-your-body-smbghost-pre-auth-rce.html )。CFG阻斷可以分為兩種情況:一是對用戶層APC起始地址代碼的調用;二是用戶層shellcode中對創建線程API的調用。下圖的代碼就是針對第二種情況的阻斷機制:只有當線程地址通過CFG檢查時,才會跳轉到指定的shellcode執行。

img

這里我們采用了zerosum0x0文章中的方式:在內核shellcode中,patch CFG檢查函數(ldrpvalidateusercalltarget和ldrpdispatchusercalltarget),跳過CFG檢查過程來達到目的。需要注意的是,在內核態修改用戶態代碼前,要修改cr0寄存器來關閉代碼讀寫保護。

另外,在patch CFG檢查函數時,使用相對偏移查找相應的函數地址。由于CVE-2020-0796只影響win10 1903和1909版本,因此這種方法是可行的。但如果是其他更通用的漏洞,還需要考慮一種更加合理的方式來尋找函數地址。

最終測試

我們在win10 1903(專業版/企業版)和win10 1909(專業版/企業版)中測試了代碼。經過測試,修改后的exp代碼執行成功率從不到20%上升到了80%以上。但我們的修改仍然是不完美的:

  1. 本文并沒有解決漏洞利用階段可能出現的問題。盡管chompie1337的漏洞利用階段代碼已經非常完善,但仍不是100%成功。考慮到漏洞利用階段出現崩潰的概率非常低(在我們的實際測試中,出現概率低于10%),如果系統處于流暢運行,這種概率會更小,我們的exp仍然使用了chompie1337在漏洞利用階段的代碼。
  2. 在本文中,我們嘗試解決了由CFG處理機制導致的崩潰情形(即類型B的情況),沒有從根本上解決內核shellcode執行階段的崩潰。在這個階段,shellcode仍然可能導致系統崩潰出現藍屏,但這種概率比較低,在我們的測試中沒有超過20%。
  3. 在使用本文的方式成功執行用戶態shellcode之后,系統處于一種不穩定狀態。如果系統中有其他重要進程頻繁進行API調用,系統大概率會崩潰;如果僅通過反彈的后臺shell執行命令,系統會處在一種相對穩定的狀態。我們認為,對滲透測試來說,改進后的exp已經基本能夠滿足需求。

其他方案

除本文討論的內容外,還可以通過內核shellcode直接寫文件到啟動項的方式來執行用戶態代碼。從理論上講,這種方式能夠避免內核shellcode在申請用戶層內存時產生崩潰的問題,但對于滲透測試場景而言,該方法需要等待目標重啟主機,實時性并不高,本文不在此進行具體討論。

總結

針對網絡公開的CVE-2020-0796 exp在實際使用過程中會產生崩潰的問題,本文分享了一些方法來解決這些問題,以便滿足實際在滲透測試等應用場景中的需求。盡管本文的方法不盡完美,但我們希望我們的研究工作能夠為諸位安全同僚提供一些思路。我們也會在后續的工作當中,持續對此進行研究,力圖找到一種更簡單、通用的方式解決問題。


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