隨著云存儲(chǔ)的普及,各種操作系統(tǒng)都添加了支持此類存儲(chǔ)的服務(wù)和功能?,F(xiàn)在可以在云端同步本地存儲(chǔ),同時(shí)也可以在系統(tǒng)上檢索到問(wèn)題。在 Windows 上,這種功能是通過(guò)Cloud Sync Engines云同步引擎完成的。該組件公開(kāi)了一個(gè) Cloud Filter API 的本機(jī) API。該API實(shí)現(xiàn)可在 Cloud Files Mini Filter Driver 或 cldflt.sys 中找到。本文介紹了有關(guān)此驅(qū)動(dòng)程序中的整數(shù)下溢漏洞的一些詳細(xì)信息,該漏洞的編號(hào)為CVE-2021-31969 / ZDI-21-797,它可以被利用來(lái)溢出內(nèi)核緩沖區(qū)并通過(guò)權(quán)限提升實(shí)現(xiàn)代碼執(zhí)行。
一、Cloud Sync Engines
Windows 中的Cloud Filter API 啟用是從 Windows 10 版本的 1709 開(kāi)始。它提供對(duì)Cloud Sync Engines云同步引擎的支持并處理創(chuàng)建和管理占位符文件和目錄之類的任務(wù)。Cloud Sync Engines云同步引擎是一種在遠(yuǎn)程主機(jī)和本地客戶端之間同步文件的服務(wù),它允許本地用戶通過(guò) Windows 文件系統(tǒng)和文件資源管理器訪問(wèn)云托管的文件和目錄。在這種情況下,文件本身駐留在云端,而在你的本地文件系統(tǒng)上,該文件的表示稱為“占位符”。在云中的文件可能很大,但占位符文件可能只消耗存儲(chǔ)標(biāo)頭所需的幾個(gè)字節(jié)。當(dāng)你訪問(wèn)占位符文件時(shí),Windows 通過(guò)同步使關(guān)聯(lián)的云文件顯示出來(lái)。
二、漏洞利用方法
以下是PoC中關(guān)鍵步驟的描述:
1:首先執(zhí)行同步注冊(cè)。然后啟動(dòng)同步提供程序和同步過(guò)濾器 API 之間的通信:
2:獲取目標(biāo)目錄的句柄并通過(guò)FSCTL_GET_REPARSE_POINT控制代碼檢索重解析數(shù)據(jù):
3:修改檢索到的重解析數(shù)據(jù),將長(zhǎng)度設(shè)置為零。然后通過(guò)FSCTL_SET_REPARSE_POINT_EX控制代碼將其設(shè)置回原位(標(biāo)簽設(shè)置為 0x9000301A,即IO_REPARSE_TAG_CLOUD_3)。最后,設(shè)置參數(shù)以code= 0xC0000003通過(guò)cloud filter FSCTL ( 0x903BC)請(qǐng)求占位符更新。
三、內(nèi)核漏洞
內(nèi)核驅(qū)動(dòng)程序cldflt.sys負(fù)責(zé)處理cloud filter FSCTL。函數(shù)中用了大量 switch 語(yǔ)句來(lái)完成工作,這個(gè)函數(shù)被命名為HsmFltProcessHSMControl:
圖 1 - HsmFltProcessHSMControl 函數(shù)
對(duì)0xC0000003的操作,最終會(huì)調(diào)用HsmFltProcessUpdatePlaceholder:
圖 2 - 調(diào)用 HsmFltProcessUpdatePlaceholder
經(jīng)過(guò)一些處理,執(zhí)行流程將達(dá)到HsmpRpReadBuffer。首先分配一個(gè)緩沖區(qū),然后通過(guò)發(fā)出一個(gè)FSCTL_GET_REPARSE_POINT控制指令來(lái)檢索重解析數(shù)據(jù)。檢索到的數(shù)據(jù)可能已被攻擊者修改,之后調(diào)用HsmpRpiDecompressBuffer:
圖 3 - 調(diào)用 HsmpRpiDecompressBuffer
在HsmpRpiDecompressBuffer內(nèi)部,提供的長(zhǎng)度(攻擊者已設(shè)置為零)被檢索并增加 8。它保存在局部變量 length 中,然后用于分配內(nèi)核緩沖區(qū)。之后,代碼通過(guò)調(diào)用RtlDecompressBuffer使用分配的緩沖區(qū)作為未壓縮數(shù)據(jù)的目標(biāo)緩沖區(qū)繼續(xù)解壓縮數(shù)據(jù)。但是,它傳遞給RtlDecompressBuffer的指針不是已分配緩沖區(qū)的開(kāi)始。而是已分配緩沖區(qū)開(kāi)始前的 12 個(gè)字節(jié),以便為某些元數(shù)據(jù)騰出空間。相應(yīng)地,它傳遞給RtlDecompressBuffer的緩沖區(qū)大小是length-12。在下面的反匯編代碼中,減法被優(yōu)化為ADD。在我們的例子中,這個(gè)減法產(chǎn)生了一個(gè)整數(shù)下溢,因此一個(gè)巨大的緩沖區(qū)長(zhǎng)度值 0xFFFFFFF4 被傳遞給RtlDecompressBuffer,這會(huì)導(dǎo)致內(nèi)核緩沖區(qū)溢出。
圖 4 - 整數(shù)下溢漏洞
四、補(bǔ)丁分析
Microsoft 通過(guò)添加檢查以確保檢索到的長(zhǎng)度不小于 4 來(lái)修復(fù)此漏洞,這使得無(wú)法觸發(fā)整數(shù)下溢。
圖 5 - 來(lái)自 Microsoft 的補(bǔ)丁