作者:成都應急響應中心-360核心安全
博客:http://blogs.#/post/RootCause_CVE-2019-0808_CH.html

2019年3月微軟發布的補丁修復了兩個在野Windows零日漏洞,其中CVE-2019-0808是由谷歌威脅分析小組發現并向微軟提交。 據微軟稱,這個影響Win32k組件的漏洞允許攻擊者提升權限并在內核模式下執行任意代碼。谷歌表示,該漏洞只影響Windows 7和Windows Server 2008,由于微軟在最新版本的操作系統中引入了漏洞利用緩解措施,因此Windows 10不會受到影響。但是Windows 7仍然占有一定數量的用戶比例,同時該漏洞結合Chrome RCE(CVE-2019-5786)已經被用于真實的APT攻擊,因此極有可能被利用來執行大規模的攻擊并構成現實的威脅,因此360核心安全技術中心通過編寫代碼構造出POC,對漏洞觸發過程進行了一些還原,以便安全廠商可以增加相應的防護措施。

1. 漏洞成因

xxxMNFindWindowFromPoint函數在接收到窗口過程函數返回的菜單窗口對象后,未有效檢驗其成員tagPOPUPMENU的有效性,造成后續MNGetpItemFromIndex函數觸發零指針解引用漏洞。

2. 漏洞觸發流程

image.png

下面對主要流程進行解釋。 第一步:首先需要設置全局的消息鉤子函數用于攔截xxxMNFindWindowFromPoint發出的MN_FINDMENUWINDOWFROMPOINT消息。

image.png

第二步:創建擁有拖拽功能的菜單項,以及一個特殊的窗口句柄hpwn留作備用。

image.png

image.png

第三步:通過拖拽菜單或直接調用相關系統調用,使程序流程進入NtUserMNDragOver函數。

image.png

第四步:調用關系如下NtUserMNDragOver -> xxxMNMouseMove -> xxxMNFindWindowFromPoint,xxxMNFindWindowFromPoint會向窗口發送MN_FINDMENUWINDOWFROMPOINT消息并接收返回的窗口句柄。由于設置了全局消息鉤子函數,執行流程又回到了用戶層。

image.png

第五步:由于前面替換了菜單窗口的窗口過程函數,全局消息鉤子函數執行完后即會進入FakeWindowProc函數,這里直接返回先前備用的窗口句柄hpwn。

image.png

第六步: xxxMNFindWindowFromPoint函數獲得窗口句柄后,直接將其對應的窗口對象返回并傳入xxxMNUpdateDraggingInfo函數。需要注意的是,這里得到的窗口對象即是之前偽造的hpwn窗口對象,其內部成員tagPOPUPMENU沒有設置完全,多數成員都為0!

image.png

第七步:xxxMNUpdateDraggingInfo函數獲得窗口對象后,會通過MNGetpItem函數訪問其成員tagPOPUPMENU對象。

image.png

MNGetpItem函數又會繼續訪問tagPOPUPMENU對象的spmenu成員,從而造成零指針解引用漏洞。

image.png

image.png

3. 漏洞補丁

在3月份的Windows7補丁當中,微軟修復了窗口類型混淆(不是MENU類型則返回NULL),并且檢查popupMenu對象的狀態,代碼對比如下

補丁前:

image.png

補丁后:

image.png

4. 結論

通過構造出的POC,發現漏洞成因是在特定情況下調用NtUserMNDragOver函數時,會造成 win32k!MNGetpItemFromIndex 中的零指針解引用。該漏洞利用Windows內核驅動模塊win32k.sys可以執行本地提權,提權成功后可以突破普通用戶權限的限制,用作安全沙箱逃逸,完全控制用戶計算機系統。


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