摘要

這份報告針對 CVE-2025-54957 這個嚴重的 Zero-click 漏洞,提供詳細技術分析。漏洞位於 Dolby Unified Decoder (UDC) 元件中,具體出現在處理 Dolby Digital Plus (DD+) 音訊串流內的 Extensible Metadata Delivery Format (EMDF) Payload 時,因自訂堆積上的記憶體配置發生錯誤的整數溢位檢查所致。分析聚焦於核心漏洞利用基本技術——可控制的堆積緩衝區溢位以及記憶體洩漏能力,並詳細說明為了在媒體編解碼器環境中達成任意程式碼執行,所建構的複雜多階段漏洞攻擊鏈。討論內容強調堆積操控、函數指標劫持,以及透過 /proc/self/mem 進行 shellcode 注入的技術細節,凸顯媒體解碼器漏洞在現代運算環境中的嚴重安全影響。

隱形威脅:為何簡訊音訊檔能成為 Android 手機的 0-click 破口? | 資訊安全新聞

1. 簡介

現代行動作業系統日益複雜,尤其整合自動語音轉文字等功能,無意間擴大了 Zero-click 攻擊面 [1]。音訊解碼器能在無使用者互動的情況下處理傳入媒體,已成為遠端漏洞利用的主要目標。這份報告檢視 Dolby Unified Decoder (UDC) 中的特定漏洞 CVE-2025-54957,該程式庫負責處理 Dolby Digital (DD) 與 Dolby Digital Plus (DD+) 音訊格式 [1]。UDC 被廣泛整合於各平台(包含 Android),通常以 binary blob 形式提供,增加內部分析難度。漏洞利用可讓攻擊者在沙箱化的媒體編解碼器程序中取得任意程式碼執行,這是完整漏洞攻擊鏈中的關鍵步驟 [1]。

此類漏洞的利用通常需要進階技術來繞過現代安全防護。例如,Android 安全環境常需處理 zero-day 與 kernel 層級漏洞 [3],而軟體開發實務中的缺陷(如不安全的信任管理器或未過濾的 shell 執行)可能導致遠端程式碼執行 (RCE) 與權限提升 [2]。UDC 漏洞提供一個極具代表性的案例,展示如何利用看似微小的算術缺陷,達成對關鍵元件的完整控制。

2. 漏洞分析 (CVE-2025-54957)

CVE-2025-54957 的根本原因在於 UDC 處理 EMDF container 結構中的 emdf_payload_size 欄位。此數值透過 variable_bits(8) 函數讀取,沒有對結果數值設限 [1]。接著 UDC 使用 ddp_udc_int_evo_malloc 函數,在自訂的單一 slab「evo」堆積上配置記憶體,而該函數存在嚴重缺陷。

2.1. ddp_udc_int_evo_malloc 中的整數溢位

ddp_udc_int_evo_malloc 函數負責在「evo」堆積上配置記憶體。函數會計算配置所需的 total_size (包含 extra 長度),然後將大小對齊到 8 位元組邊界。配置邏輯的 pseudocode 如下 [1]:

  1. void ddp_udc_int_evo_malloc(heap *h, size_t alloc_size, size_t extra)
  2. {
  3. size_t total_size;
  4. unsigned __int8 *mem;
  5. total_size = alloc_size + extra;
  6. // ... (Initial check for simple overflow: alloc_size + extra < alloc_size)
  7. // VULNERABILITY: Flawed alignment logic
  8. // If total_size is close to SIZE_MAX, this calculation can wrap around.
  9. if ( total_size % 8 )
  10. total_size += (8 - total_size) % total_size;
  11. // ... (Check against remaining heap size)
  12. if ( total_size > heap->remaining )
  13. return 0;
  14. // ... (Update heap pointers)
  15. }

當由攻擊者控制的 emdf_payload_size 衍生出一個介於 0xFFFFFFFFFFFFFFF9 0xFFFFFFFFFFFFFFFF 之間的極大值(在 64 位元系統上),對齊計算 (8 - total_size) % total_size 會導致 total_size 回繞,產生極小的配置大小(例如 0 或很小的正數)[1]。然而,後續複製 EMDF Payload 的程式碼仍使用原始的大型 payload_length 作為邊界,造成可控制的大規模堆積緩衝區溢位,溢入「evo」堆積。

2.2. 漏洞利用基本技術

整數溢位提供了主要漏洞利用基本技術: Buffer Overrun Capability 。攻擊者可透過操控 EMDF container 長度與 Payload 資料,控制寫入的範圍與內容,實現任意 out-of-bounds 寫入 [1]。寫入範圍受 skip buffer 大小限制(每個音訊區塊約 0x1FF 位元組,最多 6 個區塊)[1]。

另一個關鍵基本技術是 Leak Capability 。這源於 skip buffer 的寫入邊界由 skipl 限制,但解析 EMDF container 的 bit reader 長度卻由 emdf_container_length 決定 [1]。將 emdf_container_length 設為大於 skipl ,解碼器即可讀取已初始化 skip buffer 之外的資料,有效洩漏鄰近記憶體內容。此洩漏對於繞過 Address Space Layout Randomization (ASLR) 及定位關鍵指標極為重要 [1]。

3. 漏洞攻擊鏈建構

漏洞攻擊鏈為多階段流程,透過一系列特殊製作的 DD+ syncframe 實現。每個 syncframe 負責特定動作,逐步累積必要的基本技術,最終達成任意程式碼執行 (Arbitrary Code Execution, ACE)。整體流程可視為針對媒體編解碼器程序的一連串步驟:

graph TD A["DD+ Bitstream"] --> B{Syncframe 1:
Initial Setup}; B --> C[Trigger Integer Overflow
in evo_malloc]; C --> D[Heap Overflow
Primitive Unlocked]; D --> E[WRITE STATIC Primitive:
Overwrite Function Pointers]; E --> F[Leak Primitive:
Obtain GOT Pointers]; F --> G[WRITE DYNAMIC Primitive:
Regain Control over Heap]; G --> H[ROP Chain Construction:
Set up pwrite Call]; H --> I["Execute pwrite to
/proc/self/mem"]; I --> J[Trigger
Overwritten Function]; J --> K["Arbitrary Code Execution
(ACE)"]; style A fill:#f9f,stroke:#333,stroke-width:2px style K fill:#ccf,stroke:#333,stroke-width:2px

圖 1:CVE-2025-54957 漏洞攻擊鏈架構

3.1. 堆積操控與基本技術建立

初始 syncframe 用於觸發整數溢位並建立可靠的寫入基本技術。透過將 emdf_payload_size 設為導致回繞的值,產生小型配置。後續 Payload 寫入即溢出小型緩衝區,讓攻擊者覆寫「evo」堆積的內部指標,尤其是 skip_pointer [1]。這建立了 WRITE STATIC 基本技術,能夠寫入堆積結構中固定且反覆被解碼器主處理函數 DLB_CLqmf_analysisL 存取的位置 [1]。

3.2. 函數指標劫持與 ROP

DLB_CLqmf_analysisL 函數的記憶體配置包含數個可透過 WRITE STATIC 基本技術直接存取的函數指標與參數(暫存器 X0 至 X3)[1]。漏洞利用流程如下:

  1. 劫持直接呼叫指標: 將直接函數呼叫指標覆寫為 ret gadget,避免在設定其他參數時發生 Crash [1]。
  2. 建立洩漏: 利用 Leak Capability 取得類似 strstr 的 Global Offset Table (GOT) 位址。透過洩漏基本技術將 GOT 指標複製到受控記憶體位置(例如 direct_call_X1 )[1]。
  3. 呼叫 fopen 暫時將間接函數指標設為 fopen 。小心使用 WRITE STATIC 基本技術設定參數(X0 為 "/proc/self/mem" ,X1 為 "wb" ),多次開啟記憶體檔案描述符進行「Spray」,使其位置可預測 [1]。

3.3. 透過 /proc/self/mem 進行 shellcode 注入

最後階段利用已開啟的檔案描述符,將 shellcode 寫入程序記憶體。透過設定呼叫 pwrite 函數實現。漏洞攻擊鏈包含:

  1. 重新取得 WRITE DYNAMIC: 暫時重建 WRITE DYNAMIC 基本技術,以便在動態緩衝區可靠設定指標 [1]。
  2. 設定 pwrite 操縱函數指標指向 pwrite 。參數設定如下:
    • X0 (檔案描述符): 猜測的 /proc/self/mem 檔案處理(例如 40)[1]。
    • X1 (緩衝區): 動態緩衝區中 shellcode Payload 的指標 [1]。
    • X2 (計數): shellcode 長度 [1]。
    • X3 (位移): 要覆寫的函數位址,例如 __stack_chk_fail ,此函數在正常操作中很少被呼叫 [1]。
  3. 執行: 觸發 pwrite 呼叫,將 shellcode 覆寫至目標函數的 GOT 項目。接著觸發已被覆寫的函數(例如 __stack_chk_fail ),執行 shellcode 並達成 ACE [1]。

以下概念性 pseudocode 展示以受控位址覆寫函數指標的流程,為漏洞攻擊鏈的最後步驟 [1]:

  1. // Target function to overwrite (e.g., __stack_chk_fail GOT entry)
  2. target_address = get_got_entry("__stack_chk_fail");
  3. // Shellcode payload
  4. shellcode_buffer = dynamic_buffer + SHELLCODE_OFFSET;
  5. // Prepare pwrite parameters using WRITE STATIC primitive
  6. set_register_x0(file_handle_proc_self_mem); // e.g., 40
  7. set_register_x1(shellcode_buffer); // Pointer to shellcode
  8. set_register_x2(shellcode_length); // Length of shellcode
  9. set_register_x3(target_address); // Offset (address to write to)
  10. // Set direct function pointer to pwrite gadget
  11. set_direct_call_fptr(pwrite_gadget_address);
  12. // Trigger pwrite call (writes shellcode to target_address)
  13. // Trigger the overwritten function to execute shellcode
  14. call_function(__stack_chk_fail);

4. 結論

成功建構 CVE-2025-54957 的 0-click 漏洞攻擊鏈,顯示媒體解碼器漏洞的嚴重性,因為這些元件越來越常暴露於未經驗證的遠端資料。漏洞利用充分展現堆積漏洞利用的高超技巧,利用客製化記憶體配置器中的細微整數溢位,取得強大的讀寫基本技術。多階段方法包含精確 Heap spraying、函數指標劫持,以及創新使用 /proc/self/mem 進行 shellcode 注入,突顯資安研究人員在高度沙箱化環境中達成任意程式碼執行的進階技術。這項研究提醒開發人員必須嚴格審查所有程式碼路徑,尤其是處理外部未受信任輸入的部分,檢查整數溢位等基本缺陷;同時也呼籲業界持續強化媒體處理元件的防護,以對抗 0-click 攻擊。