摘要

本報告詳細技術分析了在 Microsoft Windows Cloud Files MiniFilter ( cldflt.sys ) 中發現的 Time-of-Check to Time-of-Use (TOCTOU) Race Condition 弱點。此缺陷已於 October 2025 修補,並被指派為 CVE-2025-55680,它允許攻擊者藉由在任意、特權位置建立檔案或目錄來實現權限提升 (Privilege Escalation)。此弱點發生在 HsmpOpCreatePlaceholders() 函式處理 CfCreatePlaceholders() 請求的過程中。我們檢視了 Race Condition 的機制、Cloud Files MiniFilter 驅動程序的角色、涉及多執行緒 (multithreading) 和連接點 (junction points) 的漏洞攻擊方法,以及隨後的透過 DLL 側載 (DLL side-loading) 進行權限提升的過程。本報告強調了此弱點及其漏洞攻擊的技術複雜性。

繞過檔案驗證!詳解 Cloud Files 如何遭 TOCTOU 攻擊導致系統高權限存取 | 資訊安全新聞

1. 簡介

權限提升弱點是資安缺陷中的關鍵類別,它允許攻擊者在系統中取得更高的存取權限。本報告調查了一個重大的 Time-of-Check to Time-of-Use (TOCTOU) Race Condition 弱點,CVE-2025-55680,它存在於 Microsoft Windows Cloud Files MiniFilter ( cldflt.sys ) 中。這個弱點在 March 2024 被發現,並在 October 2025 獲得修補,它允許攻擊者繞過檔案名稱驗證檢查,並在受保護的系統位置建立任意檔案或目錄,最終導致權限提升 [1]。本分析深入探討了此弱點的技術細節、底層的 Windows Cloud Files 架構、漏洞攻擊步驟,以及用來實現更高權限的方法。

2. Microsoft Windows Cloud Files MiniFilter 概觀

Microsoft Cloud API 促進了檔案和目錄在本地主機與遠端雲端服務(例如 OneDrive)之間的同步。此功能依賴於 cldapi.dll 函式庫,而該函式庫由 Cloud Files MiniFilter 驅動程序 ( cldflt.sys ) 所支援。 cldflt.sys 驅動程序是一個檔案系統篩選 (filter) 驅動程序,它向篩選管理器 (Filter Manager) 註冊,並透過各種 I/O 控制 (IOCTL) 碼和主要函式類型向雲端應用程序公開檔案系統功能 [1]。

2.1. Cloud Files 概念

Cloud Files 生態系統中的關鍵概念包括:

  • 同步根目錄 (Sync Root Directory): 一個已註冊的資料夾,其中的檔案和目錄會進行同步。
  • Placeholder Files: 檔案雖然在本地存在,但其內容儲存在雲端。當被存取時,它們會被補充水分 (hydrated)(下載內容)。
  • 補充水分政策 (Hydration Policy): 定義了檔案內容何時從雲端下載。
  • 填充政策 (Population Policy): 定義了目錄如何從雲端內容填充。

同步提供者 (sync providers) 使用 CfRegisterSyncRoot() API 將目錄註冊為同步根,指定管理同步行為的各種政策 [1]。

2.2. Cloud Files MiniFilter 驅動程序互動

cldflt.sys 驅動程序透過為主要函式碼(例如 IRP_MJ_CREATE IRP_MJ_READ IRP_MJ_FILE_SYSTEM_CONTROL )註冊的 Callback Function 來攔截各種 I/O 請求程序包 (IRPs)。對於 NtDeviceIoControlFile() NtFsControlFile() 使用者空間 (user-space) APIs,驅動程序定義了 HsmFltPreFILE_SYSTEM_CONTROL() HsmFltPostFILE_SYSTEM_CONTROL() Callback Function,它們分別在實際操作之前和之後執行 [1]。

此弱點特別針對一個客製化的 IOCTL, 0x903BC ,它被 cldapi.dll 用於像 CfCreatePlaceholders() 這樣的操作。當發出帶有 0x903BC 控制碼、Tag 0x9000001A OpType 0xC0000001 的 IOCTL 時,表示它是一個 CfCreatePlaceholders 請求 [1]。

CfCreatePlaceholders() API 接受一個 BaseDirectoryPath 和一個 CF_PLACEHOLDER_CREATE_INFO 結構的陣列。 CF_PLACEHOLDER_CREATE_INFO 結構包含一個 RelativeFileName ( LPCWSTR )、檔案 metadata 和身分識別資訊 [1]。

0x903BC IOCTL 的輸入緩衝區遵循 ioctl_0x903BC 資料結構,其中包含一個 placeholder_payload ,它指向一個 create_placeholder_t 結構的陣列。 create_placeholder_t 結構儲存了相對檔案名稱 ( relName ) 和檔案身分識別 ( fileid ) 的位移 (offsets) 和長度 (lengths),以及檔案屬性 (attributes) [1]。

3. 弱點分析 (CVE-2025-55680)

TOCTOU 弱點位於 cldflt.sys 中實作的 HsmpOpCreatePlaceholders() 函式中,用於處理 CfCreatePlaceholders() 請求。關鍵缺陷在於檔案名稱驗證與實際檔案建立之間存在一個 Race Condition [1]。

3.1. HsmpOpCreatePlaceholders() 函式流程

HsmpOpCreatePlaceholders() 函式透過以下步驟處理請求:

  1. 使用 IoAllocateMdl() 為使用者空間緩衝區 ( placeholderPayload ) 分配一個 MDL (Memory Descriptor List)。
  2. 使用 MmMapLockedPagesSpecifyCache() 將使用者空間緩衝區對映 (Mapping) 到 Kernel 空間。這會建立一個共享實體頁面 (shared physical page) 來支援使用者空間和 Kernel 對映的緩衝區,這表示在使用者空間中的修改會反映在 Kernel 對映的區域 [1]。
  3. 解析 placeholderPayload 緩衝區並將其資料複製到堆疊變數 (stack variable) placeholderPayload_stack 中。
  4. 驗證包含在 relName 欄位中的檔案名稱。此驗證會檢查是否存在 \ : 字元。此檢查是作為 CVE-2020-17136 的更新程式引入的 [1]。
  5. 如果檔案名稱被視為有效,則使用目錄 Handle 和檔案名稱(指向 Kernel 對映的使用者空間緩衝區)準備 ObjectAttributes
  6. 呼叫 FltCreateFileEx2() 來建立檔案或目錄 [1]。

3.2. Race Condition

此弱點源於檔案名稱驗證(步驟 4)與透過 FltCreateFileEx2() 建立實際檔案(步驟 6)之間的時間窗口。由於使用者空間緩衝區被對映到 Kernel 空間,並且在驗證後未受到修改保護,攻擊者可以在此窗口期間更改對映記憶體中的 relName 字串。具體來說,攻擊者可以在檔案名稱通過驗證後、但在 FltCreateFileEx2() 被呼叫之前,將一個 \ 字元 插入到檔案名稱中 [1]。

FltCreateFileEx2() 函式在呼叫時如果沒有特定的旗標來處理符號連結 (symlinks)/junctions,它將會跟隨 junction point。這允許攻擊者最初將 relName 設定為類似 JUSTASTRINGDnewfile.dll 的內容。如果攻擊者贏得 Race Condition ,他們可以將其更改為 JUSTASTRING\newfile.dll 。如果 JUSTASTRING 是一個指向不可寫入系統目錄(例如 C:\Windows\System32 )的 junction,那麼 FltCreateFileEx2() 將會在該特權位置建立 newfile.dll [1]。

下圖說明了 TOCTOU Race Condition

graph TD             A["User calls CfCreatePlaceholders()"] --> B{"HsmpOpCreatePlaceholders() invoked"}             B --> C["IoAllocateMdl() & MmMapLockedPagesSpecifyCache()"]             C --> D[Copy payload to placeholderPayload_stack]             D --> E{"Validate relName (no \ or :)"}             E -- Valid --> F["Prepare ObjectAttributes (ObjectName points to mmapped_userspace_region.relName)"]             E -- Invalid --> G[Return Error]             F -- Race Window --> H[Attacker modifies mmapped_userspace_region.relName to include \]             H --> I["FltCreateFileEx2() called with modified relName"]             I -- Follows Junction --> J[File created in arbitrary privileged location]             I -- No Junction / Valid Path --> K[File created in expected location]

圖 1:HsmpOpCreatePlaceholders() 中的 TOCTOU Race Condition

3.3. 程式碼片段分析

HsmpOpCreatePlaceholders() 內部的相關程式碼區段,如文章中所述,Highlight了驗證和檔案建立步驟:

  1. __int64 __fastcall HsmpOpCreatePlaceholders(
  2. PFLT_INSTANCE *a1,
  3. __int128 *DirHandle,
  4. int syncPolicy,
  5. create_placeholder_t *placeholderPayload,
  6. ULONG placeholderPayload_size,
  7. int *out)
  8. {
  9. // ... (initializations and other code)
  10. // [4] Allocation and mapping of user-space buffer into kernel space
  11. MemoryDescriptorList = IoAllocateMdl(placeholderPayload, placeholderPayload_size, 0, 0, 0i64);
  12. // ... (error handling)
  13. MmProbeAndLockPages(MemoryDescriptorList, 1, IoReadAccess);
  14. // ... (mapping to MappedSystemVa)
  15. mmapped_userspace_region = MappedSystemVa;
  16. while ( 1 )
  17. {
  18. // [7] Copying payload info to stack variable
  19. memset(&placeholderPayload_stack, 0, sizeof(placeholderPayload_stack));
  20. v16 = (create_placeholder_t *)((char *)mmapped_userspace_region + v53);
  21. // ... (copying specific fields)
  22. // [8] Filename validation loop
  23. v21 = (int)v51;
  24. v22 = 0;
  25. if ( HIWORD(relName_sz) >> 1 )
  26. {
  27. while ( 1 )
  28. {
  29. v23 = *(_WORD *)((char *)v51 + 2 * v22 + relName_offset);
  30. if ( v23 == '\\' || v23 == ':' ) // Check for '\' or ':'
  31. break; // Validation fails if forbidden characters are found
  32. if ( ++v22 >= (unsigned __int16)(HIWORD(relName_sz) >> 1) )
  33. goto LABEL_51;
  34. }
  35. // ... (error handling and return)
  36. }
  37. // [9] Preparing ObjectAttributes with ObjectName pointing to mmapped_userspace_region.relName
  38. *((_QWORD *)&v65 + 1) = (char *)v51 + placeholderPayload_stack.relativeName_offset;
  39. LOWORD(v65) = placeholderPayload_stack.relativeName_len;
  40. WORD1(v65) = placeholderPayload_stack.relativeName_len;
  41. ObjectAttributes.Length = 48;
  42. ObjectAttributes.RootDirectory = dirHandle_cp;
  43. ObjectAttributes.Attributes = 576;
  44. ObjectAttributes.ObjectName = (PUNICODE_STRING)&v65 // Pointer to the mapped user-space buffer
  45. // ... (other ObjectAttributes fields)
  46. // [10] File creation call
  47. LODWORD(v24) = FltCreateFileEx2(
  48. Filter,
  49. Instance,
  50. &FileHandle,
  51. &FileObject,
  52. 0x100180u,
  53. &ObjectAttributes,
  54. &IoStatusBlock,
  55. &AllocationSize,
  56. FileAttributes,
  57. 0,
  58. 2u,
  59. CreateOptions,
  60. 0i64,
  61. 0,
  62. 0x800u,
  63. &DriverContext);
  64. // ... (loop continuation or exit)
  65. }
  66. }

關鍵的觀察結果是,指定 FltCreateFileEx2() 檔案 Path 的 ObjectAttributes.ObjectName 直接指向 mmapped_userspace_region.relName 。這意味著在驗證迴圈 ( [8] ) 完成之後和 FltCreateFileEx2() ( [10] ) 被呼叫之前,使用者模式應用程序對原始 relName 緩衝區所做的任何更改都會反映在 Kernel 中,從而繞過檢查 [1]。

4. 漏洞攻擊方法

利用這個 TOCTOU Race Condition 需要一個精心策劃的攻擊,涉及多個執行緒 (threads) 和 Windows junction point 的策略性使用 [1]。

4.1. 漏洞攻擊步驟

漏洞攻擊過程可以分解為三個主要步驟:

  1. 設定環境: 使用 CfRegisterSyncRoot() 註冊一個同步根目錄。在此同步根中,建立一個目錄(例如 JUSTASTRING )並將其設定為指向不可寫入系統目錄(例如 C:\Windows\System32 )的 junction point [1]。
  2. 觸發弱點 (Race Condition): 此步驟涉及多個執行緒並行 (concurrently) 運行以利用 TOCTOU 窗口 [1]:
    • 監控執行緒 (Monitor Thread): 持續檢查目標 malicious payload 檔案(例如 C:\Windows\System32\newfile.dll )是否已建立。一旦偵測到,它就會停止 Race Condition 並進入下一個階段。
    • 建立 Placeholder 執行緒 (Create Placeholder Threads): 這些執行緒持續呼叫 CfCreatePlaceholders() ,目標是同步根目錄。輸入緩衝區中的 relName 最初設定為一個良性 (benign) 字串,例如 JUSTASTRINGDnewfile.dll ,並且 fileAttributes 設定為 FILE_ATTRIBUTE_NORMAL
    • 檔案名稱更改執行緒 (Filename Changer Threads): 這些執行緒重複修改使用者空間的 relName 緩衝區。具體來說,它們會將一個 字元 (例如 JUSTASTRINGDnewfile.dll 中的 'D')在其原始值和反斜線 (backslash) ( \ ) 之間切換,並帶有微小的延遲 (delay)。這旨在擊中驗證已通過,但 FltCreateFileEx2() 呼叫尚未發生的 Race Condition 窗口。

    如果檔案名稱更改執行緒在驗證之後成功插入一個 \ relName 就會變成 JUSTASTRING\newfile.dll 。由於 JUSTASTRING 是指向 C:\Windows\System32 junction FltCreateFileEx2() 將會跟隨此 junction 並在 C:\Windows\System32 內建立 newfile.dll [1]。

  3. 權限提升: 一旦 malicious payload DLL(例如 newfile.dll )在特權系統目錄中建立,攻擊者就可以利用 DLL 側載 (DLL side-loading) 技術。這涉及放置一個特殊製作的 DLL,該 DLL 將被一個以更高權限運行的合法系統程序所載入,從而以系統級權限執行任意程式碼。檔案建立後,監控執行緒就可以將 malicious payload 內容寫入其中。

5. 結論

Microsoft Windows Cloud Files MiniFilter TOCTOU 權限提升 (CVE-2025-55680) 突顯了確保複雜作業系統元件安全方面持續存在的挑戰,特別是那些涉及使用者 Kernel 互動和檔案系統操作的元件。 HsmpOpCreatePlaceholders() 內部的 Race Condition 證明了一個看似穩健 (robust) 的檔案名稱驗證如何因其實作中的時間性弱點而被繞過。漏洞攻擊方法結合了多執行緒攻擊、 junction point 和 DLL 側載,突顯了攻擊者用來實現權限提升的複雜技術。這個弱點對開發人員來說是一個重要的提醒,要仔細考慮安全敏感程式碼路徑中的 Time-of-Check to Time-of-Use 情境,同時也提醒系統管理員要迅速安裝更新程式以緩解此類風險。