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

攻擊Windows平臺NVIDIA驅動程序

安全 黑客攻防 網站安全
NVIDIA為每一個逃逸都單獨實現了其私有數據(DXGKARG_ESCAPE 結構體中的pPrivateDriverData),格式為“頭部+數據”。

[[184593]]

前言

現代圖形驅動程序是十分復雜的,它提供了大量有希望被利用的攻擊面,可以使用具有訪問GPU權限的進程(比如Chrome的GPU進程)進行提權和沙箱逃逸。在這篇文章中,你們將看到如何攻擊NVIDIA內核模式的Windows驅動程序,以及在此期間我發現的一些bug。我的這項研究是Project Zero的一個20%項目的一部分,在此期間我總共發現了16個漏洞。

內核WDDM接口

圖形驅動程序的內核模式組件被稱為顯示微端口驅動程序。微軟的官方文檔為我們提供了一個很好的結構圖,總結了各個組件之間的關系:

在顯示微端口驅動程序 的DriverEntry()函數中,DRIVER_INITIALIZATION_DATA結構被由廠商實現的函數(實際上與硬件進行交互)的回調進行填充,該函數通過DxgkInitialize()傳遞給dxgkrnl.sys(DirectX的子系統)。這些回調要么由DirectX內核子系統調用,要么在某些情況下直接從用戶模式代碼調用。

DxgkDdiEscape

一個眾所周知的潛在漏洞的入口點是 DxgkDdiEscape 接口。它可以直接在用戶模式下被調用,并且可以接受任意數據,該數據以廠商指定的方式(本質上是IOCTL)解析和處理。在后文中,我們將使用術語“逃逸”來表示由DxgkDdiEscape 函數支持的特定命令。

截止寫作時,NVIDIA有著數量驚人的400多個逃逸,所以這里也是我花費了絕大部分時間的地方(這些逃逸中的絕大多數是否有必要處在內核空間中是一個問題):

  1. // (這些結構體的名稱是我命名的) 
  2. // 表示一組逃逸代碼 
  3. struct NvEscapeRecord { 
  4.   DWORD action_num; 
  5.   DWORD expected_magic; 
  6.   void *handler_func; 
  7.   NvEscapeRecordInfo *info; 
  8.   _QWORD num_codes; 
  9. }; 
  10.    
  11. // 有關特定逃逸代碼的信息 
  12. struct NvEscapeCodeInfo { 
  13.   DWORD code; 
  14.   DWORD unknown; 
  15.   _QWORD expected_size; 
  16.   WORD unknown_1; 
  17. }; 

NVIDIA為每一個逃逸都單獨實現了其私有數據(DXGKARG_ESCAPE 結構體中的pPrivateDriverData),格式為“頭部+數據”。頭部格式如下:

  1. struct NvEscapeHeader { 
  2.   DWORD magic; 
  3.   WORD unknown_4; 
  4.   WORD unknown_6; 
  5.   DWORD size
  6.   DWORD magic2; 
  7.   DWORD code; 
  8.   DWORD unknown[7]; 
  9. }; 

這些逃逸由32位代碼(上面NvEscapeCodeInfo結構體的第一個成員)標識,并根據它們的最高有效字節進行分組(從1到9)。

在處理每個逃逸代碼之前都會做一些驗證。具體來說,每個 NvEscapeCodeInfo 應當包含頭部后面的逃逸數據的預期大小。這將根據NvEscapeHeader中的大小來驗證,NvEscapeHeader自身又通過傳遞給 DxgkDdiEscape的PrivateDriverDataSize字段進行驗證。但是,預期大小有時可能為0(通常當逃逸數據為可變大小時),這意味著逃逸處理程序負責進行自身的驗證。這將導致一些bug(1,2)。

在逃逸處理程序中發現的大多數漏洞(總共13個)都是些非常基本的bug,例如盲目地向用戶提供的指針進行寫入操作,向用戶模式公開未初始化的內核內存以及不正確的邊界檢查。還有許多我發現的問題(例如OOB讀取)沒有報告出去,因為它們似乎沒有可以利用的地方。

DxgkDdiSubmitBufferVirtual

另一個有趣的入口點是DxgkDdiSubmitBufferVirtual函數,它首次在Windows 10和WDDM 2.0中被引入,主要用來支持GPU虛擬內存(而舊的 DxgkDdiSubmitBuffer / DxgkDdiRender 函數已被棄用)。這個函數相當復雜,并且還接受來自用戶模式驅動程序提交的每一個由廠商特定的數據。我在這里找到了一個bug。

其他

還有一些其他WDDM函數接受廠商特定的數據,但快速瀏覽后沒有發現任何有趣的東西。

暴露的設備

NVIDIA暴露了可由任何用戶打開的一些其他設備:

  1. \\.\ NvAdminDevice 

似乎用于 NVAPI。很多ioctl處理程序似乎都會調用DxgkDdiEscape。

  1. \\.\ UVMLite {Controller,Process *} 

可能與NVIDIA的“統一內存”相關。在這里找到1個bug。

  1. \\.\ NvStreamKms 

作為GeForce Experience的一部分默認選擇安裝,但也可以在安裝期間選擇停用。不是很明白為什么這個驅動程序是必要的。在這里也發現了1個bug。

更多有趣的Bug

我發現的大多數bug是通過手動逆向和分析得到的,并且使用了一些自定義的IDA腳本。我還寫了一個模糊工具。最終結果成功得有點令人驚訝,這也說明了這些bug的簡單性。

雖然大多數bug相當無聊(缺乏驗證之類的簡單案例),但也有一些比較有意思。

NvStreamKms

此驅動程序使用 PsSetCreateProcessNotifyRoutineEx 函數注冊進程創建通知回調。該回調檢查系統上創建的新進程是否和先前通過發送IOCTL設置的映像名稱相匹配。

這個創建通知的例程包含一個bug:

(簡化的反編譯輸出)

  1. wchar_t Dst[BUF_SIZE]; 
  2.    
  3. ... 
  4.    
  5. if ( cur->image_names_count > 0 ) { 
  6.   // info_是傳遞給例程的PPS_CREATE_NOTIFY_INFO 
  7.   image_filename = info_->ImageFileName; 
  8.   buf = image_filename->Buffer; 
  9.   if ( buf ) { 
  10.     filename_length = 0i64; 
  11.     num_chars = image_filename->Length / 2; 
  12.     // 通過掃描反斜杠來查找文件名 
  13.     if ( num_chars ) { 
  14.       while ( buf[num_chars - filename_length - 1] != '\\' ) { 
  15.         ++filename_length; 
  16.         if ( filename_length >= num_chars ) 
  17.           goto DO_COPY; 
  18.       } 
  19.       buf += num_chars - filename_length; 
  20.     } 
  21. DO_COPY: 
  22.     wcscpy_s(Dst, filename_length, buf); 
  23.     Dst[filename_length] = 0; 
  24.     wcslwr(Dst); 

此例程通過向后搜索反斜杠('\')的方法從PS_CREATE_NOTIFY_INFO的ImageFileName 成員中提取映像名稱,然后使用 wcscpy_s 將其復制到堆棧緩沖區(Dst),但傳遞的長度是計算出的名稱長度,而不是目標緩沖區的長度。

即使 Dst 是大小固定的緩沖區,這也不能被視為一個直接溢出。因為它的大小大于255個wchar長度,并且對于大多數Windows文件系統路徑組件來說其不能超過255個字符。而因為ImageFileName 是規范化的路徑,所以掃描反斜杠在大多數情況下也是有效的。

然而,上述規則可以通過如下方式繞過:對于一個符合通用命名規約(UNC)的路徑,其規范化后保持以正斜杠('/')作為路徑分隔符(感謝James Forshaw向我指出這一點)。這便意味著我們可以得到一個“aaa / bbb / ccc / ...”形式的文件名從而引發溢出。

例如:

  1. CreateProcessW(L"\\\\?\\UNC\\127.0.0.1@8000\\DavWWWRoot\\aaaa/bbbb/cccc/blah.exe", …) 

另一個有趣的關注點是,跟隨受損副本的wcslwr實際上并不限制溢出的內容(唯一的要求是有效的UTF-16編碼)。因為計算的filename_length不包含null終止符,所以wcscpy_s 會認為目的地太小,然后以在開始處寫入null字節的方式來清除目的地字符串(發生在內容復制到 filename_length 字節之后,因此溢出仍然發生)。這意味著 wcslwr是無用的,因為對 wcscpy_s的調用和一部分的代碼從來沒有工作過。

利用這個漏洞就不那么復雜了,因為驅動程序沒有使用堆棧cookie編譯過。在以前的漏洞中附加過一個本地特權提升漏洞利用程序,它配置了一個偽造的WebDAV服務器來利用漏洞(ROP,從主堆棧到用戶緩沖區,再次ROP來分配 讀寫執行內存,用來存放shellcode并跳轉進去)。

UVMLiteController中錯誤的驗證

NVIDIA的驅動程序還在 \\.\ UVMLiteController路徑中暴露了一個可以由任何用戶打開的設備(包括從沙箱中的Chrome GPU進程)。該設備的IOCTL處理程序直接將結果寫入Irp->UserBuffer中,作為將要傳遞給 DeviceIoControl 的輸出指針 (微軟的文檔中指出不要這樣做)。IO控制代碼指定使用METHOD_BUFFERED,這意味著在Windows內核檢查地址提供的范圍并將其傳遞給驅動器之前,用戶具有寫操作的權限。

然而,這些處理程序還缺少對輸出緩沖區的邊界檢查,這意味著用戶模式上下文可以通過任何任意地址傳遞值為0的長度(可以繞過ProbeForWrite的檢查), 這樣做的結果是創造出一個受限的Write-what-where情景(這里的“what“僅限于一些特定的值:包括32位0xffff,32位0x1f,32位0和8位0)。

在原始問題中附加了簡單的提權漏洞利用 。

遠程攻擊途徑?

考慮到已發現的bug數量如此之眾,我做了一個調查,是否可以在不必首先破壞沙盒進程的前提下,完全從遠程環境中訪問其中任意一個bug(例如通過瀏覽器中的WebGL或通過視頻加速)。

幸運的是結果似乎并非如此。但這并不令人驚訝,因為這里的易受攻擊的API是非常底層的,只有經過許多層才能訪問得到(對于Chrome而言,需要經歷libANGLE -> Direct3D運行時和用戶模式驅動程序 ->內核模式驅動程序),并且通常需要在用戶模式驅動程序中構造有效的參數才能調用。

NVIDIA的回應

發現的bug的性質表明NVIDIA仍有很多工作要做。他們的驅動程序包含的很多可能不必出現在內核中的代碼,而發現的大多數錯誤是非常基本的錯誤。事到如今,他們的驅動程序(NvStreamKms.sys)仍然缺乏非常基本的緩解措施(堆棧cookie)。

不過,他們的反應倒是快速且積極的。大多數bug在截止日期之前已經修復好了,并且他們自己內部也在做一些尋找bug的工作。他們還表示,他們一直在努力重構他們內核驅動程序的安全性,但還沒有準備好分享任何具體的細節。

時間線

補丁間隔

NVIDIA的第一個補丁,其中包括我報告的6個bug的修復,但是沒有在公告中詳細說明(發布說明稱作“安全更新“)。他們原本計劃在補丁發布后一個月再公布詳細信息。我們注意到了這一點并告訴他們這樣做并不恰當,因為黑客可以通過逆向補丁來找到之前的漏洞,而當大眾意識到這些漏洞細節的時候已經晚了。

雖然前6個bug修復后在30多天內都沒有發布修復的詳細信息,但剩余的8個bug的修復補丁發布后5天內就發布了細節公告。看上去NVIDIA也一直在嘗試減少這種差距,但是就最近的公告來看兩者的發布仍有很大的不一致性。

結論

鑒于內核中的圖形驅動程序所暴露出來的巨大攻擊面,以及第三方廠商的低質量代碼,它似乎是挖掘沙箱逃逸和特權提升漏洞的一個非常豐富的目標。GPU廠商應該盡快將其驅動代碼從內核中轉移出去,從而縮小攻擊面使得這種情況得以限制。

責任編輯:武曉燕 來源: googleprojectzero.blogspot.tw
相關推薦

2021-07-22 23:24:44

Windows 11Windows微軟

2022-05-13 09:14:47

NVidia開源Linux

2022-05-19 08:33:53

漏洞惡意軟件

2019-10-22 15:40:34

Windows 10驅動程序Windows

2015-12-01 10:54:44

Ubuntu 15.1NVIDIA 358.Linux

2022-05-23 13:17:32

Linux開源NVIDIA

2009-07-03 16:48:05

Windows CE

2019-03-27 13:20:31

Windows 10更新驅動程序

2018-11-19 10:15:26

Windows 10WiFi驅動程序

2009-07-06 18:17:46

JDBC驅動程序

2009-03-09 18:48:26

Windows 7驅動開發

2019-03-11 15:51:25

NVIDIAKepler筆記本

2023-09-26 19:20:09

微軟開源windows

2020-12-20 09:52:44

Windows10操作系統Windows

2022-01-10 07:17:02

安全工具CFB模糊測試

2018-07-18 16:35:06

Windows 10Windows驅動程序

2015-09-10 14:42:37

自動更新UpdateWindows 10

2012-11-22 13:49:52

Windows 7

2018-09-03 15:45:48

Windows 10Windows驅動程序

2010-01-07 13:27:22

Linux驅動程序
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91视频一88av | 亚洲在线一区二区 | 91电影在线 | 天天澡天天狠天天天做 | 午夜免费电影院 | 成人在线视频免费看 | 久久综合一区二区三区 | 亚洲成人福利在线观看 | 日韩在线观看网站 | 欧美日韩一区精品 | 国产精品3区 | 久久精品一级 | 亚洲91 | 九九热精品在线 | 久久精品视频在线播放 | 九九色九九 | 欧洲精品一区 | 激情六月丁香婷婷 | 欧美成人免费在线 | 成在线人视频免费视频 | 午夜a级理论片915影院 | 天天操天天射天天舔 | 亚洲精品自在在线观看 | 免费的色网站 | 国户精品久久久久久久久久久不卡 | 久久一区二区视频 | www.日本在线播放 | 成人av影院| 久久国产精品一区二区三区 | 色.com| 精品国产伦一区二区三区观看方式 | 成人一级黄色毛片 | 亚洲精品v | 热re99久久精品国99热观看 | 91在线一区| 影视一区| 自拍视频网站 | 中文字幕国产日韩 | 在线小视频 | 最近中文字幕第一页 | 精品久久香蕉国产线看观看亚洲 |