
摘要
本報告提供對 CVE-2025-24076 及 CVE-2025-24994 兩個在 Windows 11 中發現的漏洞的技術分析,這兩個漏洞允許低權限使用者取得本機系統權限。主要漏洞 CVE-2025-24076 利用 Dynamic-link Library (DLL) hijacking 技術結合 API hooking,以可靠地覆寫使用者可修改的 DLL 檔案,該檔案隨後由高權限程序載入 。CVE-2025-24994 被描述為因缺乏足夠的 DLL 簽章驗證而導致的相關使用者對使用者攻擊。本報告詳細說明了發現過程、攻擊過程中遇到的技術挑戰,以及克服這些挑戰的方法,包括使用 Microsoft Detours 進行 API 攔截和創建代理 DLL 以維持程式功能。

1. 簡介
在一次滲透測試任務中,於客戶的 Windows 11 筆記型電腦上發現了一個有漏洞的設定,最初被視為精簡客戶端。自動化掃描工具(特別是 PrivescCheck)標記了一個與 COM 伺服器映像檔權限相關的潛在問題,顯示目前使用者對與 COM 伺服器相關的檔案具有修改權限。進一步調查顯示,此發現與 Windows 11 的「行動裝置」功能有關,該功能允許連結行動電話以實現諸如將手機攝影機用作網路攝影機的功能 。此功能涉及載入特定的 DLL(CrossDevice.Streaming.Source.dll),首先由一般使用者程序載入,隨後由高權限程序載入 。關鍵漏洞在於該 DLL 位於使用者可修改的目錄(%PROGRAMDATA%\CrossDevice\)中,且更重要的是,載入該 DLL 的程序未驗證其數位簽章,儘管該 DLL 由 Microsoft 簽署 。這種組合允許低權限使用者以惡意 DLL 取代合法 DLL,進而以提升的權限執行。
2. 漏洞描述
漏洞的核心在於不安全地載入 CrossDevice.Streaming.Source.dll 檔案 。該 DLL 儲存於 C:\ProgramData\CrossDevice\,這是一個標準使用者通常可修改的位置 。一般使用者程序(CrossDeviceService.exe)和高權限系統程序均會載入此 DLL。系統程序在未進行簽章驗證的情況下載入使用者可修改的 DLL,構成關鍵的提權漏洞 CVE-2025-24076。相關漏洞 CVE-2025-24994 涉及使用者程序未驗證 DLL,可能導致使用者對使用者的危害。透過以惡意 Payload 取代合法 DLL,攻擊者可實現以載入程序權限執行的程式碼。由於系統程序載入此 DLL,這允許本機提權至 NT AUTHORITY\SYSTEM。
3. 攻擊挑戰與解決方案
可靠地利用此漏洞面臨兩個主要挑戰:
- 時間窗口: 將合法 DLL 檔案替換為惡意檔案的機會最初被觀察到是一個非常狹窄的時間窗口,約為 300 毫秒,介於使用者程序使用檔案與高權限程序載入檔案之間。雖然在慢速虛擬機器上手動計時嘗試成功,但需要可靠的自動化方法。最初的想法是使用 Opportunistic Locks (OpLocks) 在檔案被存取時暫停執行,但此方法面臨第二個挑戰。
- 檔案鎖定: 一個重大障礙是無法在 CrossDeviceService.exe 程序使用 CrossDevice.Streaming.Source.dll 檔案時覆寫該檔案 。這是 Windows 的標準限制,取決於檔案 Handle 的 ShareMode。確定該檔案被鎖定在允許讀取但禁止修改或覆寫的模式。當程序呼叫諸如 GetFileVersionInfoExW 的函數以取得檔案資訊時,檔案 Handle 會被持有。
為克服這些挑戰並將 Race Condition 轉化為可靠的攻擊,以下技術被採用:
- 使用 Detours 進行 API Hooking: 不依賴精確的計時,該攻擊方法攔截使用者程序(CrossDeviceService.exe)中的特定 Windows API 呼叫 。選擇 Microsoft Detours 函式庫是因為其在攔截 WinAPI 呼叫方面的有效性。策略是將惡意 DLL 注入 CrossDeviceService.exe 程序並 Hook GetFileVersionInfoExW 函數。此函數在程序存取目標 DLL 時被呼叫。Hook 允許惡意程式碼在程式嘗試讀取檔案版本資訊之前獲得控制,但關鍵的是,惡意程式碼會等待直到程序使用完檔案並釋放檔案 Handle,使檔案可寫入 。一旦可寫入,Hook 程序會以惡意 DLL 覆寫合法 DLL 。
- DLL Proxying: 在以執行 Payload(例如取得管理員權限)的惡意 DLL 覆寫原始 DLL 後,CrossDeviceService.exe 程序仍期望原始 DLL 的匯出函數可用。僅以僅含 Payload 的版本取代 DLL 會導致程式 Crash。為避免此情況,惡意 DLL 被設計為代理。它匯出與原始 DLL 相同的函數(DllCanUnloadNow 和 DllGetClassObject),並在執行惡意 Payload 後,將這些函數呼叫轉發至原始合法 DLL 的實作 。
4. 技術分析:程式碼與實作
可靠的攻擊依賴於三個主要組件:注入使用者程序的 Hooking DLL、惡意 Payload DLL 以及代理的定義檔案。
4.1. Hooking DLL
提供的 C++ 程式碼片段展示了使用 Microsoft Detours 的 Hooking DLL 。此 DLL 被載入 CrossDeviceService.exe 程序 。
DllMain 函數是 DLL 的入口點。當 DLL 附加到 CrossDeviceService.exe 程序(dwReason == DLL_PROCESS_ATTACH)時,它執行 Hooking 。DetourRestoreAfterWith() 通常在 DLL 透過 detours.exe /wdll 注入時使用,以確保正確狀態 。DetourFindFunction("kernelbase.dll", "GetFileVersionInfoExW") 動態尋找 kernelbase.dll 中合法 GetFileVersionInfoExW 函數的記憶體位址 。此位址儲存於 OriginalGetFileVersionInfoExW。DetourTransactionBegin()、DetourAttach() 和 DetourTransactionCommit() 是用於應用 Hook 的 Detours 函數 。DetourAttach(&(PVOID&)OriginalGetFileVersionInfoExW, DetouredGetFileVersionInfoExW) 將目標函數的位址替換為客制化的 DetouredGetFileVersionInfoExW 函數的位址 。後續對 GetFileVersionInfoExW 的呼叫將被重新導向至我們的函數。
每當 CrossDeviceService.exe 呼叫 GetFileVersionInfoExW 時,DetouredGetFileVersionInfoExW 函數會被執行 。它檢查函數呼叫是否針對特定目標 DLL(C:\\ProgramData\\CrossDevice\\CrossDevice.Streaming.Source.dll) 。如果是,它首先呼叫原始的 GetFileVersionInfoExW 函數 。在檔案可存取時(或可能在檔案可存取的時間點),它呼叫 CopyFileExW 將惡意 DLL(C:\\ProgramData\\CrossDevice\\poc.dll)複製到合法 DLL 上 。CopyFileExW 是用於檔案複製的標準 Windows API。透過攔截存取目標 DLL 的函數呼叫並在 Hook 內執行覆寫,該攻擊確保在高權限程序嘗試載入時,惡意 DLL 已就位。
4.2. 惡意 Payload DLL
惡意 DLL(poc.dll)被設計為一個簡單的 Payload,展示成功的提權。
此 DLL 的 DllMain 函數在 DLL 被載入程序時被呼叫。當 ul_reason_for_call 為 DLL_PROCESS_ATTACH 時,表示 DLL 正在被映射到程序的位址空間。此時,程式碼執行命令 system("whoami >> C:\\poc_only_admin_can_write_to_c.txt")。system() 函數在子殼層(subshell)中執行命令。whoami 列印目前使用者的身份,>> C:\\poc_only_admin_can_write_to_c.txt 將輸出附加到位於 C:\ 磁碟根目錄的 poc_only_admin_can_write_to_c.txt 檔案。直接寫入系統磁碟根目錄(C:\)通常需要管理員權限 。因此,如果此檔案成功建立並包含 whoami 的輸出,則證明載入此惡意 DLL 的程序具有提升的權限(在 CVE-2025-24076 的情況下為 NT AUTHORITY\SYSTEM 使用者) 。
4.3. 代理定義檔案
為防止合法程序在載入惡意 DLL 後 Crash,惡意 DLL 必須匯出原始 DLL 提供的函數 。原始 DLL(CrossDevice.Streaming.Source.dll)匯出 DllCanUnloadNow 和 DllGetClassObject 。在編譯惡意 DLL(poc.dll)時使用定義檔案(.def)來指定這些匯出並將呼叫重新導向至原始 DLL 的實作 。
此 .def 檔案指定編譯的 DLL(poc.dll)匯出兩個函數:DllCanUnloadNow 和 DllGetClassObject。語法 FunctionName=target_original.FunctionName @Ordinal 表示惡意 DLL 中的 FunctionName 呼叫應轉發至名為 target_original 的函式庫中的 FunctionName,該函式庫在特定序號匯出。target_original 指的是重新命名的合法 CrossDevice.Streaming.Source.dll 檔案,代理 DLL 會動態載入。這允許依賴這些 COM 相關函數的合法程式流程在惡意程式碼於 DllMain 執行後繼續不受干擾 。
5. 攻擊流程
結合這些技術的整體攻擊流程如下所述 :
- 觸發功能: 以低權限使用者身份,啟動 Windows 設定中的「行動裝置」網路攝影機功能的安裝或使用 。此動作涉及 CrossDeviceService.exe 程序,並隨後觸發高權限程序載入 CrossDevice.Streaming.Source.dll 。
- 注入與 Hook: 透過某種方式將使用 Detours 的 Hooking DLL 注入低權限的 CrossDeviceService.exe 程序。此 Hooking DLL 攔截針對目標 DLL 檔案的 GetFileVersionInfoExW 呼叫 。
- 等待與覆寫: 當針對 CrossDevice.Streaming.Source.dll 的 GetFileVersionInfoExW Hook 被觸發時,Hooking 程式碼等待直到 CrossDeviceService.exe(或其他阻止寫入的程序)持有的檔案 Handle 釋放,使檔案可寫入 。一旦可寫入,惡意代理 DLL(poc.dll,之前放置於 %PROGRAMDATA%\CrossDevice\ 目錄)被複製到原始 CrossDevice.Streaming.Source.dll 上 。
- 提權: 高權限系統程序隨後嘗試載入(現已被替換的)CrossDevice.Streaming.Source.dll 。它反而載入惡意代理 DLL。由於該程序未驗證 DLL 簽章,它繼續載入惡意程式碼 。
- 執行 Payload: 在高權限程序中的 DLL_PROCESS_ATTACH 時,惡意 DLL 的 DllMain 執行命令 system("whoami >> C:\\poc_only_admin_can_write_to_c.txt")。
- 驗證: 建立包含系統使用者身份的檔案 C:\poc_only_admin_can_write_to_c.txt,確認以 NT AUTHORITY\SYSTEM 權限實現程式碼執行 。
6. 緩解措施
漏洞 CVE-2025-24076 已通報 Microsoft 並修補 。主要緩解措施是應用 Microsoft 發布的相關 Windows 更新。保持作業系統最新至關重要。此外,採用 Endpoint Detection and Response (EDR) 解決方案有助於檢測與利用嘗試相關的異常行為,甚至可能在修補程式應用前識別 Threat actor。
7. 結論
CVE-2025-24076 突顯了 DLL hijacking 漏洞的持續風險,特別是當結合不充分的簽章驗證和使用者可修改的檔案路徑時 。該攻擊展示了如何使用 Detours 等進階技術進行 API Hooking,以克服典型的檔案鎖定機制和 Race Condition,將難以定時的漏洞轉化為可靠的本機提權方法 。使用代理 DLL 對於在執行惡意 Payload 後維持程式穩定性至關重要 。此發現強調了對載入二進位檔案的安全檔案權限和強大的簽章驗證在特權程序中的重要性。及時安裝安全更新是對此特定漏洞最有效的防禦措施。