1、虛擬機添加一個串行端口
2、設置命名管道的名字
\.\pipe\aiyou
3、啟動虛擬機
4、添加一個bat文件,內容為
bcdedit /copy {current} /d "win10 x64 debug for windbg"
pause
5、以管理員身份運行
6、通過msconfig打開系統配置
7、設置調試端口并重啟,選擇win10 x64 debug for windbg啟動系統
8、真機啟動windbg
9、中通過菜單選擇Kernel Debug或者快捷鍵ctrl+k
10、重啟虛擬機,鏈接成功
11、打開上節課寫的驅動保護文件,進行相關操作,可以正常調試
Windows 10 1809內核ASLR繞過技術的演變
在內核地址空間布局隨機化(KASLR)保護機制得以正確實現的情況下,直接獲取內核驅動程序的基地址是不現實的,這給Windows內核的漏洞利用帶來了極大的困難。為了繞過該防御機制,研究人員過去的研究重點通常都放在以下幾種途徑上面:通過內核地址泄漏來檢索這些地址,或者通過特定的內核內存泄漏漏洞,或者使用通過池溢出(pool overflow)或write-what-where之類的內核漏洞來創建內核模式讀取原語。不過,本文的重點則是使用內核模式讀取原語繞過KASLR,因為這種類型的方法更加通用。
實際上,在KASLR安全機制的繞過與反繞過方面,一直是個貓鼠游戲:
在撰寫本文時,已經有一年時間沒見過新型的通用Windows內核利用技術問世了,這意味著Windows10的當前版本中的KASLR已經非常強大了。
從表面上看,這似乎是一件好事,但當我開始著手準備一個新的安全課程時,卻讓我有點為難:既然是新課程,如果還在介紹一年前就開始使用的、針對老版操作系統的老技術的話,好像有點說不過去。
所以,我開始在當前版本的Windows 10(代號為Redstone 5)上挖掘新型的KASLR繞過方法。功夫不負有心人,經過一番折騰,我終于找到了一個。
在這篇文章中,我將向您介紹在挖掘這種繞過技術過程中的一些關鍵步驟,正是借助于這些步驟,才幫我發現了尚未公布的KASLR繞過技術。
踏上征程
首先,請注意,通過使用眾所周知的EnumDeviceDrivers和NtQuerySystemInformation API,攻擊者能夠以中等完整性級別來發動攻擊,從而輕易繞過KASLR。因此,對于本文的其余部分,將假設執行的上下文是在低完整性水平下,或是在應用程序沙箱中進行的。
在以前版本的Windows 10中,可以使用多種通用方法來強制內核指針泄漏,包括使用來自線程環境塊(TEB)的Win32ThreadInfo指針,泄漏兼容位圖或利用桌面堆(Desktop heap)。對于這里介紹的繞過方法來說,我們將專注于使用桌面堆。
在Windows 10的Redstone 2版本中,微軟刪除了存放在桌面堆上分配內存的所有對象的內核模式地址的UserHandleTable,但幸運的是,桌面堆本身仍然是以用戶模式映射的,使得我們仍然可以對其進行搜索并查找特定的對象。另外,由于像tagWnd這樣的桌面堆對象通常包含一個頭部,我們可以借助特定的dereference鏈,通過這個頭部來獲取一個KTHREAD結構,因此,我們可以設法觸發內核模式指針地址泄漏,進而繞過KASLR。下面的清單1給出了相應的代碼:
清單1:適用于Windows 10 Redstone 2版本的KASLR繞過技術
為了在Windows 10 Redstone5版本下進行測試,我們通過CreateWindowEx API創建了一個窗口,從TEB中的偏移0x828處獲取用戶模式映射桌面堆的地址,然后通過暴力搜索,在用戶模式映射的桌面堆上查找Window句柄,以獲取相應的偏移量——這實際上就是我在2017年的Black Hat USA大會上展示的一種技術。
圖1:用戶模式映射的桌面堆中的窗口句柄和位置
在Redstone 5之前,圖1中的地址tagWnd將指向tagWnd內核對象的直接副本,該對象包含tagWnd對象的直接副本,該對象包含所有相關的內核模式指針,包括threadInfo指針。但是,如清單2所示,實際結果相去甚遠:
清單2:用戶模式映射桌面堆內的Windows對象
在Redstone 2版本中,清單2中突出顯示的值將包含窗口對象名稱的UNICODE_STRING結構。這意味著映射到上面突出顯示的值的值通常包含窗口名稱的UNICODE_STRING結構,該結構位于偏移量8處,即映射到地址0x20a177ab800的值通常包含指向該UNICODE字符串的內核模式指針。但事實并非如此。很明顯,微軟已經徹底修改了用戶模式映射的桌面堆。
此時,為了更好地理解具體發生了什么變化,我不得不在內核空間中執行一些交叉檢查。為此,我嘗試查找桌面堆內核模式的基地址。在Redstone 5之前的版本,我們可以在桌面堆頭部的偏移量0x28處找到該指針,并且,該指針可以從用戶模式映射的桌面堆中讀取。因此,我嘗試通過調試器從TEB中偏移量0x828處手動獲取該地址:
清單3:用戶模式映射的桌面堆的頭部
從上面的列表中我可以看到,現在用戶模式映射桌面堆中偏移量為0x28處的QWORD的值為NULL。不過,我們可以在偏移量0x80處得到桌面堆的內核基地址,所以,我繼續使用該偏移量進行分析。
清單4:桌面堆和Window內核模式地址的Delta值
由于用戶模式映射的桌面堆是由SYSTEM線程進行更新的,所以,我預計內核空間中桌面堆的內容會與用戶空間中顯示的內容略有不同。但是,在檢查兩個桌面堆的內存(見清單3)時,WinDBG顯示了完全相同(未經過濾)的內容!這意味著Microsoft對Desktop堆和相關API進行了徹底的修改。
更多的堆
為了弄清楚微軟具體做了哪些修改,并確定攻擊向量是否可行,我需要了解更多關于內核模式API如何在修改后的桌面堆上操作的相關信息。由于窗口名稱(作為Unicode字符串存儲在tagWnd對象中)通常比較容易識別(并且是用戶可控的),因此,我調用了NTUserDefSetText API,試圖更新該名稱,并獲得其實際的內核模式地址。為了跟蹤執行情況,我在Win32KFull.sys中的NTUserDefSetText上設置了一個斷點:
清單5:在NtUserDefSetText的prologue中看到的ValidateHwnd
在這里,我注意到了對ValidateHwnd的調用,它使用窗口句柄來定位內核模式tagWnd對象的地址。通常情況下,ValidateHwnd將返回內核桌面堆上的tagWnd的內存地址,但這又帶來了另一個驚喜:
清單6:包含tagWnd對象的第二個桌面堆
如清單6所示,從ValidateHwnd接收的內核模式地址指向一個句柄為0x30502的對象,該對象與更新后的POC在用戶空間中返回的Window句柄完全一致。所以,該對象包含的是內核模式指針,偏移量0x28處包含的是指向具有單獨內存空間的指針,該內存空間也包含相同的窗口句柄。
由此得出的結論是,微軟已經創建了多個桌面堆,并將對象內容存放到多個堆中,同時,只將內核模式指針的free版本映射到用戶模式。這是一種非常好的方法,可以緩解用戶模式中內核模式對象的濫用,從而加固KASLR。好了,這方面的內容就不多講了,畢竟本文的主題是KASLR繞過技術。
與ASLR繞過所有方法一樣,這里的關鍵也是要弄清楚在進程重啟過程中隨機化了哪些內容。在完成這些調查的過程中,我發現了一些重要的信息。首先,映射到用戶模式的桌面堆的基地址始終以0x1400000結尾,重新啟動后,只對高36位的內容進行了隨機化處理。
其次,包含內核模式對象指針的桌面堆的地址也只是高36位(如清單7中的綠色所示)進行了隨機化處理,這與映射到用戶模式的桌面堆的地址的處理方式是一致的。之后的4 bit的內容始終等于0x4或0x6(見紅色部分),而低24位則進行了隨機化(以藍色顯示),這樣就無法預測對象的僅內核模式桌面堆(kernel-mode only Desktop heap)的地址了:
清單7:僅內核模式桌面堆中的tagWnd對象的頭部
這種區分似乎是合理的,只有內核模式的桌面堆包含指向用戶模式桌面堆的指針。
固定值的使用似乎非常值得關注,因為它表明隨機化是不徹底的。幸運的是,我在重新啟動時發現了一個更加重要的線索。清單7中顯示的tagWnd對象的僅內核模式的桌面堆部分表明偏移0x50處的指針指向另一個僅內核模式桌面堆,其內容是未知對象:
清單8:單獨的桌面堆中的未知對象
這個對象讓人感興趣的是,低28位在重新啟動時是一個固定值,即0x08308c0(以藍色顯示),而高36位是與用戶模式共享的桌面堆(以綠色顯示)。實際上,我們可以泄漏并計算包含內核模式指針的對象的絕對地址!
更有價值的是,從該對象的開頭偏移0x10處的值是指向threadInfo結構的指針,這使我們可以使用原來的tagWnd KASLR繞過技術。threadInfo結構的偏移量0x0處包含指向KTHREAD的指針,其在偏移量02A8處包含指向ntoskrnl的指針。Dereference過程如清單9所示:
清單9:從未知對象指向ntoskrnl的指針
小結
在Windows10發布的Redstone 5版本中,微軟完成了一項令人印象深刻的工程任務:將桌面堆分割成多個堆,并只允許用戶模式查看與內核無關的內容。但是,它的隨機化在實現方面存在使用靜態值的缺陷,所以,如果攻擊者能夠讀取任意內核模式內存的話,仍然能夠繞過KASLR安全機制。
該KASLR繞過技術之所以能夠得逞,是因為攻擊者可以泄露內核模式對象地址中已經隨機化處理后的36位,而低28位是靜態的。與內核模式讀取原語一起使用的內核模式對象的位置將指針泄漏給NTOSKRNL。
盡管原理比較復雜,但是要想繞過Windows 10 的Redstone 5版本中的KASLR防御機制,只要一條命令就行了:
清單10:利用一條WinDBG命令繞過KASLR
由于這種類型的安全問題與任何MicrosoftBug報告程序或指南都不匹配,因此,我尚未報告該問題。但是,我已經確認,由于某些設計的更改,這個問題在即將發布的19H1版本中將得到修復。
本文由白帽匯整理并翻譯,不代表白帽匯任何觀點和立場
來源:https://nosec.org/home/detail/2381.html
原文:https://www.offensive-security.com/vulndev/development-of-a-new-windows-10-kaslr-bypass-in-one-windbg-command/
白帽匯從事信息安全,專注于安全大數據、企業威脅情報。
公司產品:FOFA-網絡空間安全搜索引擎、FOEYE-網絡空間檢索系統、NOSEC-安全訊息平臺。
為您提供:網絡空間測繪、企業資產收集、企業威脅情報、應急響應服務。