最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

[翻譯] 星期二補丁- 星期三利用:24 小時內(nèi)破解 WinSock (afd.sys) 的 Windows 輔助功

2023-07-03 13:44 作者:半條命-拉瑪  | 我要投稿

原文地址:https://securityintelligence.com/posts/patch-tuesday-exploit-wednesday-pwning-windows-ancillary-function-driver-winsock/


“星期二補丁,星期三利用” 是一句古老的黑客格言,指的是每月安全補丁公開后的第二天,漏洞就被武器化。隨著安全性的提高和漏洞緩解措施變得更加復(fù)雜,制作武器化漏洞所需的研究和開發(fā)量也隨之增加。這與內(nèi)存損壞漏洞尤其相關(guān)。


補丁差異和根本原因分析

根據(jù)微軟安全響應(yīng)中心(MSRC)發(fā)布的CVE-2023-21768的詳細信息,該漏洞存在于輔助功能驅(qū)動程序(AFD)中,其二進制文件名為?afd.sys。AFD 模塊是?Winsock API?的內(nèi)核入口點。利用這些信息,我們分析了 2022 年 12 月的驅(qū)動程序版本,并將其與 2023 年 1 月新發(fā)布的版本進行了比較。這些樣本可以從?Winbindex?單獨獲取,無需從 Microsoft 補丁中提取更改的耗時過程。分析的兩個版本如下所示。

  • AFD.sys / Windows 11 22H2 / 10.0.22621.608 (December 2022)

  • AFD.sys / Windows 11 22H2 / 10.0.22621.1105 (January 2023)

Ghidra?用于為這兩個文件創(chuàng)建二進制導(dǎo)出,以便可以在?BinDiff?中對它們進行比較。匹配功能的概述如下所示。

Figure 2 — Binary comparison of AFD.sys

似乎只有一個函數(shù)發(fā)生了變化,afd!AfdNotifyRemoveIoCompletion。這大大加快了我們對漏洞的分析速度。然后我們比較了這兩個功能。下面的屏幕截圖顯示了在?Binary Ninja?中查看反編譯代碼時修補前后代碼的變化。

Pre-patch,?afd.sys version 10.0.22621.608.

Figure 3 — afd!AfdNotifyRemoveIoCompletion pre-patch

Post-patch,?afd.sys version 10.0.22621.1105.

Figure 4 — afd!AfdNotifyRemoveIoCompletion post-patch

上面顯示的此更改是對已識別功能的唯一更新。一些快速分析表明,正在根據(jù)以下內(nèi)容執(zhí)行檢查

PreviousMode?。 如果?PreviousMode?為 0 (表明調(diào)用源自內(nèi)核),則將值寫入由未知結(jié)構(gòu)中的字段指定的指針。另一方面,如果 PreviousMode 不為零,則?ProbeForWrite函數(shù)被調(diào)用確保該字段中設(shè)置的指針是駐留在用戶模式中的有效地址。

補丁前版本的驅(qū)動程序中缺少此檢查。由于該函數(shù)有一個針對?PreviousMode?的特定 switch 語句,因此假設(shè)開發(fā)人員打算添加此檢查但忘記了(我們有時都缺咖啡??。?。

從這次更新中,我們可以推斷攻擊者可以通過未知結(jié)構(gòu)的?field_0x18?處的受控值到達此代碼路徑。如果攻擊者能夠使用內(nèi)核地址填充此字段,則可以創(chuàng)建任意內(nèi)核 Write-Where 原語。此時,尚不清楚正在寫入什么值,但任何值都可能用于本地權(quán)限升級原語。

函數(shù)原型本身包含?PreviousMode?值和指向未知結(jié)構(gòu)的指針,分別作為第一個和第三個參數(shù)。

Figure 5 — afd!AfdNotifyRemoveIoCompletion function prototype

逆向工程

我們現(xiàn)在知道漏洞的位置,但不知道如何觸發(fā)有漏洞的代碼路徑的執(zhí)行。在開始進行概念驗證 (PoC) 之前,我們將進行一些逆向工程。

首先,交叉引用易受攻擊的函數(shù)以了解其使用地點和方式。

在?afd!AfdNotifySock?中對易受攻擊的函數(shù)進行了一次調(diào)用。

我們重復(fù)該過程,尋找對?AfdNotifySock?的交叉引用。我們發(fā)現(xiàn)沒有對該函數(shù)的直接調(diào)用,但其地址出現(xiàn)在名為?AfdIrpCallDispatch?的函數(shù)指針表上方。

Figure 7 — afd!AfdIrpCallDispatch

該表包含 AFD 驅(qū)動程序的調(diào)度例程。調(diào)度例程用于通過調(diào)用來處理來自 Win32 應(yīng)用程序的請求?DeviceIoControl. 每個函數(shù)的控制代碼可在?AfdIoctlTable?中找到。

然而,上面的指針并不像我們預(yù)期的那樣位于?AfdIrpCallDispatch?表中。從 Steven Vittitoe 的?Recon?談話幻燈片中,我們發(fā)現(xiàn) AFD 實際上有兩個調(diào)度表。第二個是?AfdImmediateCallDispatch?。通過計算該表的開頭與存儲 AfdNotifySock 的指針之間的距離,我們可以計算 AfdIoctlTable 的索引,該索引顯示該函數(shù)的控制代碼是?0x12127

Figure 8 — afd!AfdIoctlTable

值得注意的是,它是表中最后一個輸入/輸出控制(IOCTL)代碼,表明?AfdNotifySock?很可能是最近添加到 AFD 驅(qū)動程序中的新調(diào)度函數(shù)。

此時,我們有幾個選擇。我們可以在用戶空間對相應(yīng)的?Winsock API?進行逆向工程,以更好地了解底層內(nèi)核函數(shù)是如何調(diào)用的,或者對內(nèi)核代碼進行逆向工程并直接調(diào)用它。我們實際上并不知道哪個 Winsock 函數(shù)對應(yīng)于?AfdNotifySock?,因此我們選擇了后者。

我們發(fā)現(xiàn)?x86matthew?發(fā)布的一些代碼通過直接調(diào)用 AFD 驅(qū)動程序來執(zhí)行套接字操作,放棄了 Winsock 庫。從隱秘的角度來看,這很有趣,但就我們的目的而言,它是一個很好的模板,可以創(chuàng)建 TCP 套接字的句柄以向 AFD 驅(qū)動程序發(fā)出 IOCTL 請求。從那里,我們能夠到達目標(biāo)函數(shù),正如在內(nèi)核調(diào)試時到達?WinDbg?中設(shè)置的斷點所證明的那樣。

Figure 9 — afd!AfdNotifySock breakpoint

現(xiàn)在,回顧一下?DeviceIoControl?的函數(shù)原型,通過它我們從用戶空間調(diào)用 AFD 驅(qū)動程序。參數(shù)之一 lpInBuffer 是用戶模式緩沖區(qū)。如上一節(jié)所述,該漏洞的發(fā)生是因為用戶能夠在未知數(shù)據(jù)結(jié)構(gòu)中將未經(jīng)驗證的指針傳遞給驅(qū)動程序。該結(jié)構(gòu)是通過?lpInBuffer?參數(shù)直接從我們的用戶模式應(yīng)用程序傳入的。它作為第四個參數(shù)傳遞到 AfdNotifySock 中,并作為第三個參數(shù)傳遞到?AfdNotifyRemoveIoCompletion?中。

此時,我們不知道如何填充?lpInBuffer?中的數(shù)據(jù)(我們將其稱為?AFD_NOTIFYSOCK_STRUCT?),以便通過到達?AfdNotifyRemoveIoCompletion?中易受攻擊的代碼路徑所需的檢查。我們逆向工程過程的其余部分包括遵循執(zhí)行流程并檢查如何訪問易受攻擊的代碼。

讓我們逐一檢查一下。

我們遇到的第一個檢查是在?AfdNotifySock?的開頭:


Figure 10 — afd!AfdNotifySock size check

此檢查告訴我們?AFD_NOTIFYSOCK_STRUCT?的大小應(yīng)等于 0x30 字節(jié),否則函數(shù)會失敗并顯示?STATUS_INFO_LENGTH_MISMATCH?。

下一個檢查驗證結(jié)構(gòu)中各個字段中的值:

Figure 11 — afd!AfdNotifySock structure validation

當(dāng)時我們不知道這些字段對應(yīng)什么,所以我們傳入一個?0x30?字節(jié)數(shù)組,其中填充了?0x41?字節(jié)(AAAAAAAAA...)。

我們遇到的下一個檢查是在調(diào)用之后?ObReferenceObjectByHandle. 該函數(shù)將輸入結(jié)構(gòu)的第一個字段作為其第一個參數(shù)。

該調(diào)用必須返回成功才能繼續(xù)到正確的代碼執(zhí)行路徑,這意味著我們必須將有效的句柄傳遞給?IoCompletionObject?。沒有正式記錄的方法可以通過 Win32 API 創(chuàng)建該類型的對象。然而,經(jīng)過一番搜索,我們發(fā)現(xiàn)了一個未記錄的 NT 函數(shù)?NtCreateIoCompletion?之后,我們到達一個循環(huán),其計數(shù)器是結(jié)構(gòu)中的值之一:

Figure 13 — afd!AfdNotifySock loop

該循環(huán)檢查結(jié)構(gòu)中的一個字段,以驗證它包含有效的用戶模式指針并將數(shù)據(jù)復(fù)制到其中。每次循環(huán)迭代后指針都會遞增。我們用有效地址填充了指針,并將計數(shù)器設(shè)置為 1。從這里,我們最終能夠到達存在漏洞的函數(shù)?AfdNotifyRemoveIoCompletion?

Figure 14 — afd!AfdNotifyRemoveIoCompletion call

進入?AfdNotifyRemoveIoCompletion?后,第一個檢查是結(jié)構(gòu)中的另一個字段。它必須是非零的。然后將其乘以 0x20,并與結(jié)構(gòu)體中的另一個字段一起作為指針參數(shù)傳遞到?ProbeForWrite?。從這里,我們可以使用有效的用戶模式指針 (pData2) 和字段?dwLen = 1?進一步填充結(jié)構(gòu)(以便傳遞給?ProbeForWrite?的總大小等于?0x20?),并且檢查通過。

Figure 15 — afd! Afd!AfdNotifyRemoveIoCompletion field check

最后,在到達目標(biāo)代碼之前要通過的最后一個檢查是對?IoRemoveCompletion?的調(diào)用,它必須返回 0 (STATUS_SUCCESS)。

該函數(shù)將阻塞,直到:

  • 完成記錄可用于?IoCompletionObject?參數(shù)

  • 超時到期,作為函數(shù)的參數(shù)傳入

我們通過結(jié)構(gòu)控制超時值,但簡單地將超時設(shè)置為 0 不足以讓函數(shù)返回成功。為了使該函數(shù)無錯誤地返回,必須至少有一個可用的完成記錄。經(jīng)過一番研究,我們發(fā)現(xiàn)了未記錄的功能?NtSetIoCompletion?它手動增加?IoCompletionObject?上的 I/O 掛起計數(shù)器。在我們之前創(chuàng)建的?IoCompletionObject?上調(diào)用此函數(shù)可確保對?IoRemoveCompletion?的調(diào)用返回?STATUS_SUCCESS?。

Figure 16 — afd!AfdNotifyRemoveIoCompletion check return nt!IoRemoveIoCompletion

觸發(fā)任意寫位置

現(xiàn)在我們可以到達易受攻擊的代碼,我們可以用任意要寫入的地址填充結(jié)構(gòu)中的適當(dāng)字段。我們寫入該地址的值來自一個整數(shù),該整數(shù)的指針被傳遞到對?IoRemoveIoCompletion?的調(diào)用中。?IoRemoveIoCompletion?將此整數(shù)的值設(shè)置為調(diào)用?KeRemoveQueueEx?的返回值。

Figure 17 — nt!KeRemoveQueueEx return value
Figure 18 — nt!KeRemoveQueueEx return use

在我們的概念驗證中,該寫入值始終等于 0x1。我們推測?KeRemoveQueueEx?的返回值是從隊列中刪除的項目數(shù),但沒有進一步調(diào)查。此時,我們已經(jīng)有了所需的原語,并繼續(xù)完成漏洞利用鏈。我們后來證實了這個猜測是正確的,并且可以通過對?IoCompletionObject?上的?NtSetIoCompletion?進行額外調(diào)用來任意增加寫入值。

LPE with IORING


由于能夠在任意內(nèi)核地址寫入固定值 (0x1),我們繼續(xù)將其轉(zhuǎn)換為完整的任意內(nèi)核讀/寫。由于此漏洞影響最新版本的 Windows 11(22H2),因此我們選擇利用?Windows I/O?環(huán)對象損壞來創(chuàng)建我們的原語。Yarden Shafir?撰寫了許多關(guān)于 Windows I/O 環(huán)的優(yōu)秀文章,并且還開發(fā)并披露了我們在漏洞利用鏈中利用的原語。據(jù)我們所知,這是該原語首次被用于公共漏洞利用。?當(dāng)用戶初始化 I/O 環(huán)時,會創(chuàng)建兩個獨立的結(jié)構(gòu),一個在用戶空間,一個在內(nèi)核空間。?這些結(jié)構(gòu)如下所示。

內(nèi)核對象映射到?nt!_IORING_OBJECT,如下所示。

Figure 19 — nt!_IORING_OBJECT initialization

請注意,內(nèi)核對象有兩個字段:RegBuffersCount?和?RegBuffers,它們在初始化時被清零。該計數(shù)指示有多少 I/O 操作可以在 I/O 環(huán)中排隊。另一個參數(shù)是指向當(dāng)前排隊操作列表的指針。

在用戶空間端,調(diào)用?kernelbase!CreateIoRing時,如果成功,您將返回一個 I/O 環(huán)句柄。該句柄是指向未記錄結(jié)構(gòu) (HIORING) 的指針。我們對這種結(jié)構(gòu)的定義是從 Yarden Shafir 所做的研究中獲得的。

如果某個漏洞(例如本博文中提到的漏洞)允許您更新?RegBuffersCount?和?RegBuffers?字段,則可以使用標(biāo)準(zhǔn) I/O Ring API 來讀取和寫入內(nèi)核內(nèi)存。

正如我們在上面看到的,我們可以利用該漏洞在我們喜歡的任何內(nèi)核地址寫入?0x1。要設(shè)置 I/O 環(huán)原語,我們只需觸發(fā)該漏洞兩次即可。

Figure 20 — nt!_IORING_OBJECT first time triggering the bug

在第二個觸發(fā)器中,我們將?RegBuffers?設(shè)置為可以在用戶空間中分配的地址(例如?0x0000000100000000)。

Figure 21 — nt!_IORING_OBJECT second time triggering the bug

備注:?需要驗證兩次的原因就是?RegBuffersCount?和?RegBuffers?分別驗證是否能通過帶有缺陷的驅(qū)動寫入。

Figure 22 — Setting up user space for I/O Ring kernel R/W primitive

下面的屏幕截圖顯示了這樣一個?nt!_IOP_MC_BUFFER_ENTRY?。請注意,操作的目標(biāo)是內(nèi)核地址 (0xfffff8052831da20),并且在本例中操作的大小為?0x8?字節(jié)。從結(jié)構(gòu)中無法判斷這是讀操作還是寫操作。操作的方向取決于使用哪個 API 對 I/O 請求進行排隊。利用?kernelbase!BuildIoRingReadFile?導(dǎo)致任意內(nèi)核寫入,kernelbase!BuildIoRingWriteFile?導(dǎo)致任意內(nèi)核讀取。

Figure 23 — Example faked I/O Ring operation

為了執(zhí)行任意寫入,I/O 操作的任務(wù)是從文件句柄讀取數(shù)據(jù)并將該數(shù)據(jù)寫入內(nèi)核地址。


Figure 24 — I/O Ring arbitrary write

相反,為了執(zhí)行任意讀取,I/O 操作的任務(wù)是讀取內(nèi)核地址處的數(shù)據(jù)并將該數(shù)據(jù)寫入文件句柄。


Figure 25 – I/O Ring arbitrary read

Demo

設(shè)置原語后,剩下的就是使用一些標(biāo)準(zhǔn)內(nèi)核后利用技術(shù)來泄漏系統(tǒng)(PID 4)等提升進程的令牌并覆蓋不同進程的令牌。

視頻地址:https://youtu.be/M3IPsKAsxvQ


在野利用


在我們的漏洞代碼公開后,來自360 Icesword Lab的Xiaoliang Liu(@flame36987044)首次公開披露,他們在今年早些時候發(fā)現(xiàn)了利用該漏洞的樣本(ITW)。 ITW 樣本使用的技術(shù)與我們的不同。攻擊者使用相應(yīng)的 Winsock API 函數(shù)?ProcessSocketNotifications?觸發(fā)漏洞,而不是像我們的漏洞利用那樣直接調(diào)用 afd.sys 驅(qū)動程序。

360冰劍實驗室官方聲明如下:

“360冰劍實驗室專注于APT檢測與防御?;谖覀兊?day漏洞雷達系統(tǒng),今年1月份我們在野外發(fā)現(xiàn)了CVE-2023-21768的利用樣本,該樣本與?@chompie1337?和?@FuzzySec?公布的利用樣本不同,它是通過系統(tǒng)機制和漏洞特征進行利用的。該漏洞與?NtSetIoCompletion?和?ProcessSocketNotifications?有關(guān),?ProcessSocketNotifications?獲取調(diào)用?NtSetIoCompletion?的次數(shù),因此我們使用它來更改權(quán)限計數(shù)。”

結(jié)論和最終反思

您可能會注意到,在逆向工程的某些部分,我們的分析是膚淺的。有時,僅觀察一些相關(guān)的狀態(tài)變化并將程序的某些部分視為黑匣子是有幫助的,以避免陷入不相關(guān)的兔子洞。這使我們能夠快速扭轉(zhuǎn)漏洞,盡管最大化完成速度不是我們的目標(biāo)。此外,我們對 afd.sys 中所有報告的漏洞進行了補丁差異審查,這些漏洞被標(biāo)記為“利用可能性更大”。我們的審查顯示,除了兩個漏洞之外,所有漏洞都是由于對從用戶模式傳入的指針驗證不當(dāng)造成的。這表明,了解過去的漏洞(尤其是特定目標(biāo)內(nèi)的漏洞)的歷史知識,對于發(fā)現(xiàn)新漏洞可能會卓有成效。當(dāng)代碼庫擴展時,同樣的錯誤很可能會重復(fù)。請記住,新的 C 代碼 == 新的 bug ??。正如發(fā)現(xiàn)上述漏洞在野外被利用所證明的那樣,可以肯定地說,攻擊者也在密切監(jiān)視新的代碼庫添加。

Windows 內(nèi)核中缺乏對管理員模式訪問保護 (SMAP) 的支持,這給我們提供了豐富的選項來構(gòu)建新的純數(shù)據(jù)利用原語。這些原語在支持 SMAP 的其他操作系統(tǒng)中不可行。例如,考慮 CVE-2021-41073,這是 Linux 的 I/O 環(huán)預(yù)注冊緩沖區(qū)實現(xiàn)中的一個漏洞(我們在 Windows 中濫用相同的功能用于 R/W 原語)。此漏洞可以允許覆蓋已注冊緩沖區(qū)的內(nèi)核指針,但不能用于構(gòu)造任意 R/W 原語,因為如果該指針被替換為用戶指針,并且內(nèi)核嘗試在那里讀取或?qū)懭?,系統(tǒng)將崩潰。

盡管微軟盡了最大努力來消除人們喜愛的漏洞利用原語,但肯定會發(fā)現(xiàn)新的原語來取代它們。我們能夠利用最新版本的 Windows 11 22H2,而不會遇到?HVCI(內(nèi)存完整性和基于虛擬化的安全性)?等基于虛擬化的安全功能的任何緩解或限制。

引用

1. MSRC (CVE-2023-21768)?(https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2023-21768)

2. I/O Rings – When One I/O Operation is Not Enough ?(@yarden_shafir)?(https://windows-internals.com/i-o-rings-when-one-i-o-operation-is-not-enough/)

3. IoRing vs. io_uring: a comparison of Windows and Linux implementations ?(@yarden_shafir) https://windows-internals.com/ioring-vs-io_uring-a-comparison-of-windows-and-linux-implementations/)

4. One Year to I/O Ring: What Changed? (@yarden_shafir) (https://windows-internals.com/one-year-to-i-o-ring-what-changed/)

5. One I/O Ring to Rule Them All: A Full Read/Write Exploit Primitive on Windows 11 (@yarden_shafir) (https://windows-internals.com/one-i-o-ring-to-rule-them-all-a-full-read-write-exploit-primitive-on-windows-11/)

6. Arbitrary Kernel RW using IORING’s (@FuzzySec)? (https://knifecoat.com/Posts/Arbitrary+Kernel+RW+using+IORING's)

7. NTSockets – Downloading a file via HTTP using the NtCreateFile and NtDeviceIoControlFile syscalls (@x86matthew) (https://www.x86matthew.com/view_post?id=ntsockets)

8. Reverse Engineering AFD.sys (@bool101) (https://recon.cx/2015/slides/recon2015-20-steven-vittitoe-Reverse-Engineering-Windows-AFD-sys.pdf)

9. Microsoft Windows Ancillary Function Driver for WinSock privilege escalation CVE-2023-21768 Vulnerability Report (https://exchange.xforce.ibmcloud.com/vulnerabilities/243235)




[翻譯] 星期二補丁- 星期三利用:24 小時內(nèi)破解 WinSock (afd.sys) 的 Windows 輔助功的評論 (共 條)

分享到微博請遵守國家法律
阳山县| 疏勒县| 武乡县| 炎陵县| 华池县| 柳江县| 佛冈县| 彰武县| 新建县| 景洪市| 台中县| 连云港市| 日照市| 盱眙县| 新干县| 望江县| 忻城县| 徐汇区| 武胜县| 青神县| 昔阳县| 大余县| 衡南县| 阿城市| 东海县| 托里县| 西畴县| 锡林郭勒盟| 南宫市| 南川市| 桂平市| 日照市| 沙雅县| 泌阳县| 项城市| 延长县| 华安县| 镇康县| 思茅市| 荔浦县| 资兴市|