91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

win32k.sys中怎么實現漏洞挖掘

發布時間:2021-08-05 16:55:28 來源:億速云 閱讀:173 作者:Leah 欄目:編程語言

這篇文章給大家介紹win32k.sys中怎么實現漏洞挖掘,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

1研究背景

4月1日,以色列安全研究員Gil Dabah在博客上發布了一篇關于win32k漏洞研究文章,描述了如何通過內核對象的Destroy函數和win32k user-mode callback緩解措施的特性來尋找UAF漏洞的新思路。

為此,啟明星辰ADLab對win32k相關內核機制進行研究分析,并對這類漏洞的挖掘思路進行詳細解讀分析。

2 win32k漏洞緩解與對抗

2.1 win32k user-mode callback漏洞

由于設計原因,win32k驅動需要處理很多用戶層的回調,這些回調給win32k模塊的安全帶來了非常大的隱患,并在過去10年時間貢獻了大量的漏洞。

為了便于漏洞描述,以如下偽代碼進行舉例分析。

 上述代碼執行效果如下圖所示,用戶層執行的某函數通過syscall傳入內核層,當內核層代碼執行到somecallback這一句時,用戶層可以在用戶定義的callback函數中獲得代碼執行的機會,如果用戶在callback函數調用了DestroyWindow函數銷毀窗口p,內核層的相應銷毀代碼將會被執行,p的相應內存被釋放,回調執行完畢,NtUserSysCall函數繼續執行,當執行到xxxSetWindowStyle(p)一句時,由于p的內存已經被釋放從而導致UAF漏洞的產生。

win32k.sys中怎么實現漏洞挖掘

2.2 user-mode callback漏洞緩解機制

為了防止上述問題的產生,微軟在對象中引入了一個引用計數(對象+0x8處),對象分配時引用計數為1,當執行對象的Destroy函數時引用計數減1,當引用計數為0時對象會被真正釋放。微軟通過鎖的概念為對象添加和減少引用計數,在win32k中為對象管理引用計數的鎖有兩種分別是臨時鎖(相應函數為ThreadLock/ ThreadUnlock)和永久鎖(相應函數為HMAssignmentLock/ HMAssignmentUnlock)。經過加固之后代碼表現為如下形式:

通過上述代碼,可以保證即使callback被執行,p在xxxSetWindowStyle函數執行的時候也不會被釋放。

2.3緩解機制的對抗技術

上一節提到了對象的引用計數,如果對象的引用計數為正,即使執行對象的destroy函數,對象沒有真正被釋放,仍舊存留在內存中,這種對象被微軟開發者稱為僵尸(Zombie)對象。一旦僵尸對象的引用計數減少到0它將會消失,但是在此之前它仍舊存在內存中,只是用戶層無法訪問該對象。

同時為了防止僵尸對象繼續存留在內存中,鎖的釋放函數(ThreadUnlock/ HMAssignmentUnlock)一般會包含對象的釋放環節。

對象的Destroy函數還有一個特性就是在釋放對象的同時,Destroy函數也會釋放對象的子資源,其過程可以簡要描述如下。

DestroyWindow在第一次調用時釋放子資源,一旦窗口不再被引用,句柄管理器就會再次完全銷毀它,一般情況下,第二次銷毀Destroy函數不會在去處理子資源,因為第一次已經釋放了所有的子資源。

但是事情往往不是這么簡單,事實上即使是一個已經調用過相應Destroy函數釋放的僵尸對象,仍然有機會對其本身進行一些更改(回調之后內核代碼仍會對對象進行一些操作),我們把這種情況叫做Zombie Reload,當該僵尸對象由于引用計數為0而被真正釋放時,之前的更改操作將會給內核帶來一些隱患。

對于如下代碼片段:

我們在用戶層回調中對pwnd執行了Destroy函數,然后通過InternalSetTimer為之設置了一個計時器,當ThreadUnlock將pwnd真正釋放的時候,計時器也將被釋放,那么接下來對計時器的操作將會導致UAF漏洞的產生。

3 案例分析

上一節我們討論了對象的引用計數和鎖給對象帶來的新的安全隱患,但是真正的挑戰在于我們如何確定一段代碼中存在漏洞,關鍵點是確保在unlock函數中釋放的對象在運行到有問題的代碼時其引用計數應該為1,只有這樣我們才能在用戶層回調調用其Destroy函數,并通過unlock函數將這個對象真正釋放掉(上鎖的時候會做+1處理),這也是我們接下來需要討論的。下面我們通過一個案例來分析漏洞挖掘思路。

3.1漏洞成因

下圖是xxxMnOpenHierarchy函數的代碼片段。

win32k.sys中怎么實現漏洞挖掘

圖中通過xxxCreateWindowEx可以獲得一個返回用戶層執行callback函數的機會,xxxCreateWindowEx創建的窗口將作為父窗口*(structtagWND **)(**v3 + 8)(上圖紅框)的子窗口,如果我們可以通過ThreadUnlock釋放父窗口,那么子窗口v32也會被釋放,所以當后續的safe_cast_fnid_to_PMENUWND函數將v32作為參數執行時就會產生問題,值得注意的是通過回調釋放v32是行不通的,如果這樣xxxCreateWindowEx將會返回0,無法通過if判斷。

這里的問題就在于如何保證父窗口在ThreadUnlock函數執行的時候引用計數為1,因為要執行xxxMnOpenHierarchy函數需要將父窗口關聯到一個menu窗口上,此時父窗口和menu窗口將會被一個永久鎖鎖住,下面我們介紹如何繞過永久鎖。

3.2 漏洞挖掘思路

首先我們創建了g_hMenuOwner和g_hNewOwner兩個窗口,其中g_hMenuOwner的菜單句柄為hMenu,它也是g_hNewOwner的所有者。

win32k.sys中怎么實現漏洞挖掘

在上述創建過程中內核通過LockPopuMenu函數分別為hMenu和g_hMenuOwner添加了永久鎖,為了達成釋放目的,這個永久鎖需要被繞過。

win32k.sys中怎么實現漏洞挖掘win32k.sys中怎么實現漏洞挖掘

此時鎖和所有者的關系是這樣的:

win32k.sys中怎么實現漏洞挖掘

接下來我們通過SetWindowsHookEx給窗口添加了WH_CBT鉤子,并讓窗口進入消息循環中。

win32k.sys中怎么實現漏洞挖掘

SendMessage操作為g_hMenuOwner添加一個臨時鎖,由于后續的所有攻擊都是在message的回調中進行,所以對于g_hMenuOwner來說這個臨時鎖是無法釋放的,如果想要構造一個漏洞利用環境首先需要用一些方法來繞過它。

win32k.sys中怎么實現漏洞挖掘

現在的情況變成了下圖所示:

win32k.sys中怎么實現漏洞挖掘

當消息為HCBT_CREATEWND時,我們第一次到達xxxMNOpenHierarchy函數內部的xxxCreateWindowEx。

win32k.sys中怎么實現漏洞挖掘

這里可以通過定義關于HCBT_CREATEWND消息的處理得到執行用戶層回調代碼的機會,這一步的主要目的是為了獲取Menu的Wnd。

win32k.sys中怎么實現漏洞挖掘

當接收到的消息為WM_ENTERIDLE時,我們在窗口的消息回調中通過PostMessage下發消息。

win32k.sys中怎么實現漏洞挖掘

發送消息后,驅動程序來到了xxxMNKeyDown函數內部調用xxxSendMessage處。

win32k.sys中怎么實現漏洞挖掘

通過WM_NEXTMENU消息的回調函數開始為LPARAM賦值,賦值操作是為了修改hMenu的Owner,這樣就可以將Owner的臨時鎖繞過。

win32k.sys中怎么實現漏洞挖掘

此時內核會接到銷毀menu的消息,通過用戶層的回調函數返回1阻止menu的銷毀。

win32k.sys中怎么實現漏洞挖掘xxxMNKeyDown函數通過UnlockPopupMenu將g_hMenuOwner身上的永久鎖被去掉。

win32k.sys中怎么實現漏洞挖掘

取而代之的是g_hNewOwner加上了一個鎖,hMenu的Owner也從g_hMenuOwner變成了g_hNewOwner。

win32k.sys中怎么實現漏洞挖掘

這時,鎖的關系變成了:

win32k.sys中怎么實現漏洞挖掘

接下來程序第二次進入到xxxMNOpenHierarchy函數并通過xxxSendMessage發送了消息。

win32k.sys中怎么實現漏洞挖掘

此時通過設置WM_INITMENUPOPUP回調來獲得用戶層執行的機會,WM_INITMENUPOPUP回調函數通過SetWindowsHookEx函數設置了一個新的hook,目的是為了在xxxMnOpenHierarchy函數創建子窗口的時候獲得用戶層執行權限。

win32k.sys中怎么實現漏洞挖掘

xxxMnOpenHierarchy函數繼續向下執行,再次來到xxxCreateWindowEx處。

win32k.sys中怎么實現漏洞挖掘

xxxCreateWindowEx調用了剛剛設置的回調函數childMenuHookProc。

win32k.sys中怎么實現漏洞挖掘

在回調函數childMenuHookProc中,SendMessage發送了WM_NEXTMENU消息,通過該定義該消息的回調函數再次修改參數LPARAM,這是為了去掉g_hNewOwner身上的永久鎖。

win32k.sys中怎么實現漏洞挖掘

Menu的Owner關系再次被改變,xxxMNKeyDown通過函數UnlockPopMenu去掉g_hNewOwner身上的永久鎖。并將這個鎖重新加在了g_hMenuOwner上。

win32k.sys中怎么實現漏洞挖掘win32k.sys中怎么實現漏洞挖掘

這個時候,所有的鎖都已經轉移到了g_hMenuOwner身上,而由于WH_CBT鉤子已經被移除,menu將被棄用,g_hNewOwner將把新創建的窗口link到自己身上。這個時候情況變成了下面的樣子,g_hNewOwner身上已經沒有需要繞過的鎖了。

win32k.sys中怎么實現漏洞挖掘

接著childMenuHookProc通過SetWindowsHookEx函數又一次設置了回調函數并通過SetWindowLongPtr函數來調用它,回調函數銷毀了g_hNewOwner和xxxCreateWindowEx生成的新窗口。

win32k.sys中怎么實現漏洞挖掘

xxxCreateWindowEx返回的值為ffff871b80239130,這就是xxxCreateWindowEx創建的子窗口。

win32k.sys中怎么實現漏洞挖掘

接下來就可以通過ThreadUnlock來銷毀g_hNewOwner和其新創建的子窗口來得到一個UAF漏洞。

win32k.sys中怎么實現漏洞挖掘

關于win32k.sys中怎么實現漏洞挖掘就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

周口市| 新余市| 洞头县| 勃利县| 来凤县| 南宁市| 界首市| 河南省| 洞头县| 高雄县| 阳信县| 广德县| 彰化县| 德庆县| 无极县| 色达县| 黑山县| 达日县| 乌拉特后旗| 巫溪县| 揭东县| 印江| 贺州市| 南开区| 吴川市| 玛曲县| 启东市| 政和县| 津市市| 韶山市| 会理县| 剑河县| 民乐县| 普洱| 赤城县| 瓦房店市| 彭泽县| 利川市| 南江县| 永寿县| 德阳市|