Numen 獨家:微軟 0day 漏洞可系統+物理層面掀掉 Web3 牌局

2023-06-10 00:06:14

引言:

在上個月微軟的安全補丁中,包含一個在野利用的 win32k 提權漏洞。該漏洞似乎不能在 win11 的系統版本上觸發,僅存在於早期系統。

這類漏洞的利用來源已久,此次,我們希望分析這類在當前新緩解措施不斷改善的背景下,攻擊組織是可能如何繼續利用這個漏洞。

我們在 server2016 下完成整個分析過程。

背景補充:

0day 漏洞,即零日漏洞,指未被披露和修補的漏洞,時間概念上類比於 Web3 更為人熟知的概念,是 T+0 交易。0day 漏洞被發現後可以在未被察覺的情況惡意利用,這類攻擊往往具備極大的破壞性。

Numen Cyber 本次發現的 0day 漏洞是微軟 Windows 系統層面的漏洞,通過該漏洞,黑客可獲取 Windows 的完全控制權。

被黑客控制所有權的後果,包括不限於個人信息竊取、系統崩潰數據丟失、財務損失、惡意軟件植入等,小範圍說,你的私鑰可以被竊取,以及數字資產被轉移。大範圍說,這個漏洞能掀掉基於 Web2 基礎設施運行的 Web3 牌局(可查看今日次條獲取更多文章)。

圖標僅為示意

補丁分析

分析補丁,我們似乎並不能太直觀看出是什么問題,這裏僅僅似乎是一個對象的引用計數被多處理了一次:

但因為win32k是比較古老的代碼,我們能找到一些早期的源碼注釋:

這樣就非常好理解了,這裏說明以前的代碼只是鎖定了窗口對象,沒有鎖定窗口對象中的菜單對象,這裏菜單對象可能被錯誤引用。

實現 poc

https://github.com/numencyber/Vulnerability_PoC/blob/main/CVE-2023-29336/poc.cpp

如何錯誤的引用這個窗口中的菜單對象呢?

分析漏洞函數上下文,我們發現一個問題,傳入到 xxxEnableMenuItem()的菜單,通常已經在上一層函數被鎖定,那這裏到底是要保護哪一個菜單對象呢?

繼續分析 xxxEnableMenuItem 中,對菜單對象的可能處理過程,我們終於發現 xxxEnableMenuItem 中的 MenuItemState 函數返回的菜單有兩種可能,一種就是窗口中的主菜單,但也有可能是菜單中的子菜單,甚至子子菜單。

poc 中,我們構造一個特殊的菜單(這裏是三層,四個菜單):

上面相鄰的菜單都是父子關系,如 菜單D 是 菜單C 的子菜單。

並且這些菜單有以下一些特點(這些特徵都是為了通過 xxxEnableMenuItem 函數中的檢測和判斷,因為這和該漏洞產生原理有關):

  1. 菜單D 中,必須其 ID 類型必須為系統菜單類型的一種,如:0xf060(關閉菜單).

  2. 菜單A 也必須是系統菜單,為了在後續的菜單遍歷過程中在 菜單C 中的子菜單中尋找到我們指定的系統菜單類型 0xf060(菜單A 中如果包含我們要找的系統菜單類型,會提前結束菜單查找過程)。我們需要刪除 菜單A 中的對應系統菜單類型 0xf060。

  3. 刪除掉 菜單C 在 菜單B 中的引用,才能在返回用戶層的過程中徹底釋放 菜單C。

  4. 為什么需要 菜單B,這裏我們並不確認這是否是必須以及原理,但如果沒有 菜單B 這一層,似乎 菜單C 的釋放仍有一些不順利。

在 xxxRedrawTitle 返回用戶層的時候,刪除 菜單C 和 菜單B 的引用關系,然後成功釋放該 菜單C。

最後,回到內核中的 xxxEnableMenuItem 函數的 xxxRedrawTitle 函數返回點時,後面即將引用的 菜單C 對象已經無效。

實現 exp

A. 整體思路

在確定使用哪種利用思路之前,我們通常希望做一些理論上的前期判斷,以避免一些不能繞過關鍵問題的方案會浪費大量嘗試時間。這也是在分析其他漏洞 poc 或者 exp 的一個常規過程。

本次漏洞 exp 構造前,我們主要有以下兩種考量方向:

執行 shellcode 代碼:

這個思路參考早期的 CVE-2017-0263 和 CVE-2016-0167。這種方式我們並沒有嘗試,因為在該漏洞的這個方案下,執行 shellcode 的入口點以及一些例如 SMEP 的安全機制問題在高版本 windows 中,可能並沒有一些方便且已經公开的解決方式。

利用讀寫原語修改 token 地址:

即使在最近的兩年,依然已經有公开的 exp 可以參考。其中對於桌面堆內存布局以及桌面堆中的讀寫原語具有長久的通用性。我們現在唯一需要花更多時間完成的只是分析出 UAF 內存被重用時,如何第一次控制 cbwndextra 為一個特別大的值。

所以,這裏我們將整個 exp 利用拆分為兩個問題。一個是如何利用 UAF 漏洞控制 cbwndextra 的值,另一個則是控制 cbwndextra 值後,穩定的讀寫原語方式。

B. 如何寫入第一次數據

當我們最开始觸發漏洞時,系統並不總會 crash。因為我們的漏洞觸發方式裏,我們已經去掉了被重用漏洞在系統中所有的其他關聯。

系統可能錯誤使用這個被我們控制內存的窗口對象數據基本只有 xxxEnableMenuItem 函數中的 MNGetPopupFromMenu() 和xxxMNUpdateShownMenu()。

我們使用窗口類 WNDClass 中的窗口名稱對象來佔用漏洞觸發中我們釋放的菜單對象。

我們能夠實現第一次的數據寫入時機也在這其中。

我們需要做的只有一件事,就是找到一個可以由我們構建的地址結構中,能夠被任意寫入數據的地方。哪怕僅僅一個字節(我們可以將這個字節寫入到 cbwndextra 的高位)。

此過程如在迷宮中尋找一條出路,不再贅述。

最終我們有 xxxRedrawWindow 函數中的兩個預備的方案。

如果使用 GreCreateRectRgnIndirect,交換相鄰內存數據的方式有兩個困難。

一是 cbwndextra 的前一個8位是一個非常不易控制的參數,並且似乎只能在有限的條件下短暫為1.另外使用這種方式時,cbwndextra 的其他相對偏移會定位到前一個對象(無論任何對象,因為這裏只和窗口對象 cbwndextra 偏移本身大小有關)的最後8位,這是一個堆鏈表尾的安全字節,其不易受控。

所以我們使用了第二個地址寫入點,即依靠一個標志位的 AND 2 操作。但同樣,由於上述的堆鏈表尾的安全字節不易受控的原因,我們變換以下思路:

我們並不寫入窗口對象的 cb-extra,而是寫入 HWNDClass 的 cb-extra。這是因為後者的 cb-extra 偏移相對於前者的 cb-extra 偏移更小,我們可以通過布局內存,控制前一個對象的內存數據來當作通過 xxxRedrawWindow 函數中,對對象標志判斷的參數。

C. 穩定的內存布局

我們設計內存至少是連續三個 0x250 字節的 HWND 對象。釋放掉中間那一個,構造一個 0x250 字節的 HWNDClass 對象去佔用釋放掉的 HWND 對象。

前一個 HWND 對象其尾部數據作為通過 xxxRedrawWindow 中標志檢驗的參數。後一個 HWND 對象其菜單對象和其 HWNDClass 對象作為最終讀寫原語的媒介。

我們盡量控制窗口對象和我們的的 HWNDClass 對象盡量大小一致,窗口對象的擴展數據大小也要足夠大,以通過前面提到的修改第一個窗口 class 對象的額外數據大小參數。

我們通過堆內存中的泄露的內核句柄地址來精確判斷(計算按順序排列的相鄰對象的間距)我們申請的窗口對象是否按照我們預期的順序排列。

D. 讀寫原語的一些修改

任意讀原語我們仍然使用 GetMenuBarInfo();

任意寫原語我們則使用 SetClassLongPtr();

除了替換 TOKEN 的寫入操作是依賴第二個窗口的 class 對象,其他寫入都是利用第一個窗口對象的 class 對象使用偏移來寫入。

EXP 鏈接

https://github.com/numencyber/Vulnerability_PoC/tree/main/CVE-2023-29336

總結

A. win32k 現狀

win32k 漏洞歷史衆所周知。但在最新的 windows11 預覽版中,微軟已經在嘗試使用 Rust 重構該部分內核代碼。未來該類型的漏洞在新系統可能被杜絕。

B. 漏洞利用過程基本不太困難

唯有如何使用釋放內存重新佔用的數據去控制第一次寫入的方法需要比較細心的嘗試外,基本不要需要使用到任何新的利用技術,該類漏洞嚴重依賴桌面堆句柄地址的泄露。

雖然其較以往有改動,但如果不徹底解決這個問題,對於老舊系統始終是一個不安全的隱患。

C. 漏洞的發現

分析該漏洞,我們擅自猜測該漏洞的發現可能依賴於更加完善的代碼覆蓋率檢測。一旦系統 API 在目標函數的執行路徑能夠到達最深處的漏洞點,並且目前窗口對象本身也是一個多重嵌套引用狀態,這個漏洞就可能被 fuzz 發現。

D. 其他發現途徑

對於漏洞利用檢測來說,除了對於漏洞觸發函數的關鍵點的檢測,對於這類不常見的對內存布局以及對窗口或者窗口類額外數據的異常偏移讀寫的針對檢測將是發現此類型同種漏洞的可能途徑之一。

參考

1.https://github.com/0x5bfa/NT5.1/blob/1b390dddff9fe017e9c11a7845c67a887c3483dc/Source/XPSP1/NT/windows/core/ntuser/kernel/mnsys.c#L511

2.https://github.com/L4ys/CVE-2022-21882/blob/main/CVE-2022-21882.cpp

3.https://github.com/KaLendsi/CVE-2022-21882/blob/main/ExploitTest.cpp

4.https://www.zerodayinitiative.com/blog/2023/5/8/the-may-2023-security-update-review

5.https://www.real-sec.com/2022/01/technical-analysis-of-cve-2021-1732/

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播信息之目的,不構成任何投資建議,如有侵權行為,請第一時間聯絡我們修改或刪除,多謝。

推薦文章

btc日內再次下跌 短线應當如何處理?

盡管以太坊現貨ETF獲批是個好消息,但市場反應卻不如預期。在消息公布後,以太坊價格出現了小幅下跌,...

加密蓮
134 3個月前

7月23日、BTC(合約)ETH(合約)行情分析及操作策略

昨日收益還是不錯的,日內給出的現價空單分別止盈我們目標點位,恭喜跟上的朋友喫肉。時間一晃到月底了,...

倪老師
134 3個月前

幣圈院士:血與淚的教訓!交易者為何總是撞死在同一棵樹上?

幣圈院士談。交易市場中的幾種“死法” 在幣圈市場鱗次櫛比的海洋,風起雲湧,時常讓人感到驚手不及。在...

幣圈院士
139 3個月前

7月23:Mt. Gox 比特幣錢包在市場緊縮的情況下轉移了價值 28.2 億美元的 BTC

7月23:Mt. Gox 比特幣錢包在市場緊縮的情況下轉移了價值 28.2 億美元的 BTC一個引...

168超神
131 3個月前

悅盈:比特幣68000的空完美落地反彈繼續看跌 以太坊破前高看回撤

一個人的自律中,藏着無限的可能性,你自律的程度,決定着你人生的高度。 人生沒有近路可走,但你走的每...

我是周悅盈
111 3個月前

btc完美盈利 晚間波動較大注意

昨日btc空單完美給到,最大化走出一千七百點空間~ btc: 日內开盤下跌繼續測試66000一线,...

加密蓮
121 3個月前