成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

驗證Windows內核漏洞的框架

安全 漏洞
在內核級的漏洞(操作系統本身或者硬件驅動)中,有一項就是我們常說的’任意寫(write-what-where)’[1]。 為便于分析, 很有必要寫個基本的框架,對給定的’任意寫(write-what-where)’漏洞進行封裝,并驗證其對操作系統的利用。要把任意的寫操作轉換為攻擊利用,需要三個基本的步驟。

Pwn2Own大賽之后,HP的0day防御計劃(Zero Day Initiative, ZDI) 并不要求研究者給我們提供相關攻擊利用。ZDI的分析師對每個提交的案例進行評估,可能也會挑選一些進行全面的攻擊利用。

[[114008]]

在內核級的漏洞(操作系統本身或者硬件驅動)中,有一項就是我們常說的’任意寫(write-what-where)’[1]。 為便于分析, 很有必要寫個基本的框架,對給定的’任意寫(write-what-where)’漏洞進行封裝,并驗證其對操作系統的利用。

要把任意的寫操作轉換為攻擊利用,需要三個基本的步驟, 我們將來逐一介紹。

禁用Windows訪問權限檢查的負載

Windows訪問控制系統的核心是nt!SeAccessCheck函數。它決定著我們是否有權訪問操作系統中的對象(文件,進程等等)。

我們將采用的手法,于1992年由Greg Hoglund[2]首次提及, 2006年由John Heasman改進使用[3]。 這里將采用后者作為我們的起點。 

original 01 

關鍵點在于高亮標注的內容。 如果是出于對用戶態進程的檢查,那么操作系統就會檢查確認是否具有正確的權限。 但如果是內核態的,就會永遠成功。 那么我們的目標,就是對Windows內核進行動態補丁,使其根據設置的AccessMode認為該訪問檢查調用是針對內核的。

在Windows XP上,這是非常簡單的。 如果我們在IDA里檢查內核(這里,我們處理的是ntkrnlpa.exe), 在SeAccessCheck實現中發現如下的代碼:

PAGE:005107BC xor ebx, ebx
PAGE:005107BE cmp [ebp+AccessMode], bl
PAGE:005107C1 jnz short loc_5107EC

由于在wdm.h中KernelMode被定義為0,我們只需將比較語句之后的條件跳轉Nop掉,這樣所有的訪問權限檢查就能順利通過了。

在XP之后的版本中,情況變得有點復雜了。Nt!SeAccessCheck函數調用了nt!SeAccessCheckWithHint, 后者正是我們要處理的。在后面我們收集用于攻擊的信息時,就會看到這如何使得問題復雜化了。在Windows8.1中,會看到沒有跳轉到內核函數,而是這樣的分支:

.text:00494613 loc_494613:
.text:00494613 cmp [ebp+AccessMode], al
.text:00494616 jz loc_494B28

僅需將條件跳轉替換為無條件跳轉,即可使得對SeAccessCheck的調用好像來自內核一樣。

現在目標清楚了,但還有一個小問題要解決。 我們要改寫的內存地址在只讀頁中。 我們可以更改頁的屬性設置,但有個更簡單的解決方法。在x86和x64處理器上,在控制寄存器0 (Control Register 0)上有個標志決定著管態下的代碼(即Ring 0代碼,我們的攻擊利用代碼)是否在乎內存的只讀狀態。 引用Barnaby Jack[4]的話:

禁用CR0中的寫保護位。

執行代碼和內存改寫。

再恢復寫保護位。

到這里,我們實際的攻擊利用核心代碼如下所示: 

original 02 

我們對寫保護位的處理還有一個問題。我們要將攻擊利用和處理器進行關聯,確保我們始終處于設定的處理器的核心上。 我們對寫保護位的處理似乎是非必須的, 但在更復雜的,要求我們禁用SMEP(稍后介紹)的攻擊利用中,這著實是個事。 無論哪種方式,都可以的,我們要做的,就是一個簡單的調用:

1SetProcessAffinityMask(GetCurrentProcess(), (DWORD_PTR)1);

此時,你會注意到在攻擊代碼中,我們實際上并不知道具體的補丁信息。該攻擊代碼僅是獲取我們提供的信息,然后應用它。我們將在實際的漏洞研究中提供這些信息。#p#

攻擊:將控制轉給攻擊代碼

我們有了讓代碼在Ring 0運行的條件了。 現在需要兩件事來使其運行:關于操作系統配置的信息,以及當處理器運行在管態時如何將控制權轉移給我們的代碼。

由于最初是想處理’任意寫(write-what-where)’問題, 這里我們將改寫HalDispatchTable中的一個函數。 該方法,在2007年由Ruben Santamarta[5]提及, 允許我們將執行流轉向我們的攻擊利用代碼。

我們將攔截處理的是hal!HalQuerySystemInformation函數。該函數由未文檔化的NtQueryIntervalProfile[5][6]函數調用,而且調用函數也不常用。 要理解它為啥很重要,我們就需要詳細的談下windows中的內存布局。

Windows將內存劃分為兩個大區間:內核態的內存空間在MmUserProbeAddress之上, 其下是用戶態的內存空間。 內核態的內存是所有進程共用的(雖然進程代碼無法訪問這些空間),而用戶態的內存空間是因進程而異的。由于我們的攻擊利用代碼要運行在用戶進程空間中,而我們卻在掛鉤一個內核函數指針, 如果其他進程調用了NtQueryIntervalProfile,很可能就會導致操作系統的崩潰。 因此,我們攻擊利用的第一步就是恢復原始的函數指針。 

original 03 

在我們之前的代碼里,你可以看到我們依賴額外的信息來確定函數指針入口所在,以及原始值。

現在,我們實際的攻擊利用觸發函數如下所示: 

original 04 

為了靈活性,我們的WriteWhatWhere()函數原型也包括了地址的原始值。最后一步就是找到利用點和攻擊利用掛鉤的地址。#p#

研究:確定操作系統的配置

這里,我們假設進行本地提權。我們可以在系統上以某用戶權限執行任意代碼, 最終的目標是取得對系統的完全控制權。 在對內核漏洞的遠程攻擊中,確定操作系統的配置會更復雜。

已經確定需要知道如下的信息:

1) nt!HalDispatchTable的地址

2) hal!HaliQuerySystemInformation的地址

3) nt!SeAccessCheck 或者相關函數中要打補丁的代碼的地址

4) 要補丁的值

此外,我們也需要查找原始的值,以便我們恢復原始函數功能,進行不同的利用。畢竟,一旦我們完成了所需做的,干嘛還把門敞著呢?

我們需要知道兩個內核模塊的基址——硬件抽象層(HAL)和NT內核自身。為了獲取這些,我們還需要一個未文檔化的函數——NtQuerySystemInformation[6][7]。 因為我們需要知道兩個函數,我們將提前創建函數原型,并從NTDLL中直接加載它們: 

original 05 

下一步就是確定所使用模塊的版本信息,以及它們在內存中的實際位置。利用NtQuerySystemInformation獲取加載的模塊,然后遍歷查詢所需的模塊名稱。 

original 06 

下一步,在大多數情況是很壞的主意,但在這里不是。使用LoadLibraryEx已經過時的特性, 加載我們找到的模塊的拷貝(duplicate copies)。 

original 07 

設置了這個標志, 我們就不會加載任何引用的模塊, 不執行任何的代碼, 但仍然可以使用GetProcAddress()來搜尋模塊。這正是我們想要的, 因為我們要把這些加載的模塊當作我們的源碼,來查詢在實際運行的內核代碼中所需的。

此時,我們已經具備了查找偏移所需的一切。有了拷貝的內核模塊的基址,系統的實際基址, 所以我們可以將拷貝中的相對虛擬地址(RVA)轉換為實際的系統地址。同時我們又擁有對拷貝代碼的讀取權,所以可以掃描代碼查詢所需的函數。 所剩的最后一件事,就是一個windows調用,用GetVersionEx()來決定運行的windows的版本。

有些很容易, 因為地址已經導出了: 

original 08 

但我們所需的大部分,還是要通過搜索獲取。要搜索的兩個函數,其中hal!HaliQuerySystemInformation沒有導出符號, 另一個是nt!SeAccessCheck或者它直接調用的函數。

再看最后一個例子,來看看是如何處理導出函數和那些完全私有函數的。首先是nt!SeAccessCheck: 

original 09 

然后看一下將要進行補丁處理的nt!SeAccessCheckWithHint: 

original 10 

這里,兩個函數看上去是相鄰的, 但我們還是要使用公開的函數來跟蹤對這些內部函數的引用,然后據此確定我們的補丁位置。 代碼如下所示: 

original 11 

這里的PatternScan函數是一個簡單的輔助處理,根據給定的指針、掃描的大小范圍,要掃描的模式及其大小,來查找模式匹配的起始點(如果沒有找到就是NULL)。

在上面的代碼中,首先搜索到nt!SeAccessCheckWithHint的相對跳轉,并獲取到偏移。

將其用于計算我們的拷貝模塊中nt!SeAccessCheckWithHint的實際起始位置,然后掃描查找我們要替換的條件分支的模式部分。 一旦定位成功, 就可以確定它的實際地址——首先將其轉換為相對虛擬地址(RVA),然后根據實際加載的內核映像進行重定位。最后,相應的替換值還是依賴于具體的操作系統版本的。這里對JZ(0x0f 0×84)的替換是NOP(0×90)和JMP(0xe9)。

通過從拷貝的系統模塊中收集所需信息,對多個不同版本的Windows操作系統的處理都可以放在同一個框架下進行。 通過在目標函數中搜索有關模式, 只要不是我們要查找的函數發生了變化,其他的我們都可以有效的應對。#p#

最后的麻煩

目前我們所做的一切都可以正常運行,直到Windows 8, 更確切的說,是NT6.2內核。為方便起見,我們將實際的攻擊利用代碼運行在用戶態中。

在Ivy-Bridge架構中,Intel引入了一種叫做管態執行保護(Supervisor Mode Execute Protection, SMEP)[9]的功能。如果開啟了此項功能,當處理器在管態模式下,我們試圖執行用戶態地址空間中的指令時,處理器就會出錯。這樣將控制權從內核中攔截的函數指針轉換給我們的代碼時,就會發生異常。Windows在Windows8/Server 2012中支持SMEP,而且在支持的處理器中是默認開啟的。要解決這個問題,我們要么把攻擊利用代碼移到內核空間中(這在NT6.2中也比較難), 要么就是禁用SMEP[11][12]。

最后存在的問題出現在Windows 8.1中。 要獲取Windows 8.1的真正版本號, 需要額外的處理,根據MSDN[13]: 

original 12 

包含了這個,就能正確的檢測Windows 8.1了,在確定偏移時適當的調整一下我們的搜索參數即可。

結束語

當然了,這里有缺少的部分。利用框架來驗證攻擊利用是很有幫助的,我們還需要一個‘任意寫(write-what-where)’的案例來對對此進行驗證。

我們內部就是在使用該框架在驗證那些漏洞,如果你有啥新的發現,可以通過http://www.zerodayinitiative.com/提交給我們(有沒有攻擊負載都可以)。期待你的消息。

原文:http://h30499.www3.hp.com/t5/HP-Security-Research-Blog/Verifying-Windows-Kernel-Vulnerabilities/ba-p/6252649#.UyZi2T-Sy0f

注解

[1] 我對此能找到的最早使用是在Gerardo Richarte的論文“About Exploits Writing(GCON 1, 2002)”他將其劃分為“將任意的內容寫到某處”(write-anything-somewhere)和“將任意的內容寫到任意地方”(write-anything-anywhere)。這里,我們的“任意寫”(write-what-where)是指“將任意內容寫到任意地方”(write-anything-anywhere)。

[2] Greg Hoglund, “A *REAL* NT Rootkit, patching the NT Kernel” (Phrack 55, 1999)

[3] John Heasman, “Implementing and Detecting an ACPI BIOS Rootkit” (Black Hat Europe, 2006)

[4] Barnaby Jack, “Remote Windows Kernel Exploitation – Step In To the Ring 0” (Black Hat USA, 2005) [White Paper]

[5] Ruben Santamarta, “Exploiting Common Flaws in Drivers” (2007)

[6] Windows NT/2000 Natvie API Reference (Gary Nebbett, 2000) 雖然沒有囊括較新的Windows 操作系統版本,但它對內部Windows API函數和結構仍然是一份很棒的參考

[7] Alex Ionescu, “I Got 99 Problems But a Kernel Pointer Ain’t One” (RECon, 2013)

[8] Raymond Chen, “LoadLibraryEx(DONT_RESOLVE_DLL_REFERENCES) is fundamentally flawed” (The Old New Thing)

[9] Varghese George, Tom Piazza, and Hong Jiang, “Intel Next Generation Microarchitecture Codename Ivy Bridge” (IDF, 2011)

[10] Ken Johnson and Matt Miller, “Exploit Mitigation Improvements in Windows 8” (Black Hat USA, 2012)

[11] Artem Shishkin, “Intel SMEP overview and partial bypass on Windows 8” (Positive Research Center)

[12] Artem Shisken and Ilya Smit, “Bypassing Intel SMEP on Windows 8 x64 using Return-oriented Programming” (Positive Research Center)

[13] MSDN, “Operating system version changes in Windows 8.1 and Windows Server 2012 R2”

參考讀物

Enrico Perla and Massimiliano Oldani, A Guide to Kernel Exploitation: Attacking the Core, (Syngress, 2010)

bugcheck and skape, “Kernel-mode Payloads on Windows”, (Uninformed Volume 3, 2006)

skape and Skywing, “A Catalog of Windows Local Kernel-mode Backdoor Techniques”, (Uninformed Volume 8, 2007)

mxatone, “Analyzing local privilege escalations in win32k”, (Uninformed Volume 10, 2008)

 

責任編輯:藍雨淚 來源: IDF實驗室
相關推薦

2024-12-17 16:09:36

2017-03-10 20:26:27

2013-05-23 10:48:14

EPATHOBJ 0d0day漏洞

2021-07-19 10:10:15

身份驗證漏洞Windows Hel

2009-08-13 16:28:07

windows2008密碼驗證

2010-11-29 14:05:29

2023-09-11 06:59:59

2009-10-21 14:31:15

漏洞補丁

2010-08-09 09:09:18

2009-03-18 10:55:50

2017-01-15 23:46:37

2021-02-20 06:08:07

LinuxWindows內核

2022-12-01 14:28:38

2019-06-18 07:12:25

驗證碼漏洞加密

2020-10-12 09:43:41

iOS 14漏洞蘋果

2013-05-13 09:52:52

Windows內核Linux內核

2024-12-13 15:40:54

2012-01-04 13:08:30

2011-03-23 14:54:34

2022-05-06 14:40:32

漏洞補丁Android
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精产嫩模国品一二三区 | 免费看黄色小视频 | 国产成人高清成人av片在线看 | 欧美日本久久 | 成人精品在线观看 | 日韩av一二三区 | 中文字幕日韩av | 成人亚洲性情网站www在线观看 | 伊人久久综合 | 中文字幕在线看人 | 欧美精品一区二区三区四区五区 | 中文字幕免费观看 | 日韩精品 电影一区 亚洲 | 国产一区二区在线免费 | 国产精品久久久久久久久免费桃花 | 欧美区在线 | 精品久久影院 | 国内av在线 | av免费在线播放 | 亚洲国产精品美女 | 浮生影院免费观看中文版 | 久久久久国产一区二区三区四区 | 6080亚洲精品一区二区 | 丁香五月网久久综合 | 久久久久久一区 | 久久久蜜桃一区二区人 | 巨大黑人极品videos精品 | 九九伦理电影 | 亚洲精品视频免费观看 | 玖玖综合在线 | 亚洲大片一区 | 欧美成人a | 亚洲一区二区免费 | 久久久精品一区二区三区 | 老牛嫩草一区二区三区av | 97精品一区二区 | 国产一级淫片a直接免费看 免费a网站 | 国产精品777一区二区 | 精品美女视频在免费观看 | 日韩中文在线 | 黄色视频a级毛片 |