摘要

本報告根據一項全面的安全評估 [1],提出了對 Uhale 驅動的數位相框生態系統中所識別的安全漏洞進行的技術分析。調查揭示了一系列關鍵缺陷,主要源於不安全的軟體開發實作,包括在憑證驗證方面使用了 不安全的信任管理員 (insecure trust manager) 和在更新程序期間進行了 未淨化的 shell 執行 (unsanitized shell execution)。這些漏洞使裝置能夠被完整地遠端入侵 (remote compromise),允許具備 root 權限的遠端程式碼執行 (Remote Code Execution, RCE) 和惡意軟體 (malware) 交付的潛力。本分析著重於促成這些高嚴重性攻擊的底層程式邏輯和架構弱點。

Android AOSP 設備通病?低成本物聯網裝置為何成為 Root 權限破口? | 資訊安全新聞

1. 簡介

低成本、專用消費性電子產品的普及,通常運行著被重新利用的 Android 開源專案 (Android Open Source Project, AOSP) 韌體,帶來了重大的安全風險。以 Uhale 數位相框為例,這些裝置由於成本限制和長期支援不足,經常缺乏安全規範 [1]。儘管它們的功能有限,但其持續的網路連線使其成為有吸引力的漏洞利用目標,有可能作為網路內部橫向移動的樞紐點。本研究剖析了兩個主要的 RCE 漏洞,說明了有缺陷的應用程式邏輯如何導致完整的系統入侵。

2. 透過不安全的信任管理員進行遠端程式碼執行 (RCE) (CVE-2025-58392, CVE-2025-58397)

Uhale 應用程式 (版本 4.2.0) 包含一個服務組件 com.zeasn.frame/com.zeasn.cook.CookService ,負責發起對遠端伺服器 ( dcsdkos.dc16888888.com ) 的網路請求,以擷取有關 JAR 或 APK 檔案的資訊用於動態執行 [1]。關鍵漏洞在於應用程式未能正確驗證這些 HTTPS 連線的 SSL/TLS 憑證,使得通訊容易受到 中間人攻擊 (Man-in-the-Middle (MITM) attack) 的影響。

2.1. 不安全信任管理員的技術細節分析 (Breakdown)

根本原因是一個內部類別 com.nasa.memory.tool.l$f ,它實作了 javax.net.ssl.X509TrustManager 介面,但為關鍵的憑證驗證方法提供了空的實作。

  1. // Java: class: com.nasa.memory.tool.l$f
  2. // Description: Insecure implementation of X509TrustManager
  3. public static class f implements X509TrustManager {
  4. @Override // javax.net.ssl.X509TrustManager
  5. public void checkClientTrusted(X509Certificate[] x509CertificateArr, String str) {
  6. // COMMENT: No validation performed for client certificates.
  7. }
  8. @Override // javax.net.ssl.X509TrustManager
  9. public void checkServerTrusted(X509Certificate[] x509CertificateArr, String str) {
  10. // COMMENT: CRITICAL FLAW: No validation performed for server certificates.
  11. // An attacker can present any self-signed certificate.
  12. }
  13. @Override // javax.net.ssl.X509TrustManager
  14. public X509Certificate[] getAcceptedIssuers() {
  15. return null;
  16. }
  17. }

透過攔截流量,攻擊者可以出示一個自簽署憑證 (self-signed certificate),解密通訊,並注入一個偽造的 JSON 回應。這個回應使用 hardcoded 的 AES key 進行加密,指示應用程式從攻擊者控制的 URL 下載一個 malicious payload 的 DEX Payload。

2.2. 動態程式碼載入機制

應用程式的設計包含一個用於對下載的 Payload 進行 動態程式碼載入 的機制。 com.nasa.memory.tool.n.b(android.content.Context) 方法使用 Java Reflection 來實例化一個 dalvik.system.DexClassLoader ,它從裝置的檔案系統 ( /data/data/com.zeasn.frame/files/.honor/1628853355.jar ) 載入注入的 JAR 檔案 (包含 DEX Payload)。

  1. // Java: Snippet from com.nasa.memory.tool.n.b(Context)
  2. // Description: Dynamic loading of the DEX payload via DexClassLoader and Reflection.
  3. Class cls = Class.forName(g.r); // g.r = "dalvik.system.DexClassLoader"
  4. Constructor constructor = cls.getConstructor(String.class, String.class,
  5. String.class, Class.forName(g.x)); // g.x = "java.lang.ClassLoader"
  6. // ...
  7. Object newInstance = constructor.newInstance(c2, b2, null, invoke);
  8. Method a4 = a(cls, g.s, String.class); // g.s = "loadClass"
  9. if (a4 != null) {
  10. a4.setAccessible(true);
  11. Class cls2 = (Class) a4.invoke(
  12. newInstance, g.t); // g.t = "com.sun.galaxy.lib.OceanInit"
  13. // ...
  14. }

接著會以反射方式呼叫預定義的進入點方法 void com.sun.galaxy.lib.OceanInit.init(Context context, String str) ,從而使攻擊者獲得對 Uhale 應用程式權限的即時 RCE。鑑於這些有漏洞的裝置通常以 SELinux 關閉狀態運行並預設為 root ,此 RCE 可以輕鬆升級為 root 級別的 存取 權限 [1]。

2.3. 攻擊工作流程圖

下圖說明了透過不安全信任管理員漏洞進行 RCE 的攻擊流程。

graph LR A["



Smart Picture Frame
(Uhale App 4.2.0)



"] -->|"HTTPS POST to
/sdkbin


" | B("


dcsdkos.dc16888888.com


"); B -->|

Encrypted
JSON Response| A; subgraph Attack Scenario C["Attacker
(MITM)"] A -->|Intercepts Traffic| C; C -->|Presents Self-Signed Cert| A; C -->|Injects Forged Encrypted JSON| A; end A -->|"Decrypts JSON,
Downloads Payload




"| D(

cdn.webtencent.com/
sdkfile/
malicious.jar); D -->|Malicious
DEX Payload| A; A -->|Dynamically
Loads DEX| E["

RCE with Root Privileges

"]; style C fill:#f9f,stroke:#333,stroke-width:2px style E fill:#f99,stroke:#333,stroke-width:2px

3. 透過未淨化的 shell 執行進行遠端程式碼執行 (RCE) (CVE-2025-58388)

在 Uhale 應用程式的舊版本 (版本 3.7.3 和 4.0.3) 於其自我更新程序期間,發現了第二個、不同的 RCE 漏洞。此缺陷是 命令注入 (command injection) 的一個經典例子,源於在將使用者可控制的輸入傳遞給系統 shell 之前未能淨化 [2]。

3.1. 命令注入的技術細節分析 (Breakdown)

應用程式透過查詢 https://photo.saas.zeasn.tv/sp/api/device/v1/clientUpg 等進入點來檢查更新。可用的更新由包含新 APK 的 downloadUrl 欄位的 JSON 回應發出信號。應用程式從該 URL 中擷取檔名,並將其直接傳遞給 shell 命令進行安裝。

com.zeasn.frame.base.utils.StringUtil.getFileNameAndExtension(String file) 方法擷取 URL 中最後一個斜線 ( / ) 之後的子字串。然後,這個擷取的字串被串接到一個 shell 命令中,而沒有進行任何淨化。

  1. // Java: Snippet from com.zeasn.frame.base.board.IBoard$-CC.installApkWithShell
  2. // Description: Unsanitized input (apkPath) is passed directly to the shell.
  3. public static boolean installApkWithShell(Context context, String apkPath) {
  4. // ...
  5. try {
  6. Process process = Runtime.getRuntime().exec("sh");
  7. DataOutputStream dataOutputStream = new DataOutputStream(process.getOutputStream());
  8. String command = "pm install -r " + apkPath + "\n"; // apkPath is unsanitized input
  9. dataOutputStream.write(command.getBytes(Charset.forName("utf-8")));
  10. // ...
  11. }
  12. // ...
  13. }

Threat actor 可以透過將 shell metacharacter 注入到偽造 JSON 回應的 downloadUrl 欄位中來利用此漏洞。舉例來說,透過將 downloadUrl 設定為一個經過處理後會產生包含命令分隔符號 (例如 ; & ) 後接著任意命令的 apkPath 的字串,攻擊者就可以實現 RCE。此技術是命令注入漏洞中常見的模式 [2]。

一個 malicious downloadUrl 可以被精心設計,使其包含一個 Payload,該 Payload 終止 pm install 命令並執行一個任意命令,例如:

// Malicious downloadUrl payload (URL-encoded for transport)
// .../signed7/malicious.apk; id > /data/local/tmp/pwned.txt; #

當應用程式建構 shell 命令時,產生的字串將會是:

pm install -r malicious.apk; id > /data/local/tmp/pwned.txt; #

shell 執行 pm install 命令 (這很可能會失敗,但被分號終止),接著執行注入的 id > /data/local/tmp/pwned.txt 命令,最後,雜湊符號 ( # ) 將原始命令行的其餘部分註釋掉,防止語法錯誤 [2]。

3.2. 攻擊工作流程圖

下圖說明了命令注入攻擊流程。

%% Mermaid Diagram: Command Injection Workflow graph TD     A["Smart Picture Frame
(Uhale App 3.7.3/4.0.3)"] -->|HTTPS Request
for Update| B(saas.zeasn.tv/clientUpg);     subgraph Attack Scenario         C["Attacker (MITM)"]         B -->|Intercepts Traffic| C;         C -->|Presents
Self-Signed Cert| A;         C -->|Injects Forged JSON
with Malicious downloadUrl| A;     end     A -->|Extracts
Unsanitized Filename| D(Malicious Filename +
Shell Command);     D -->|Concatenated into
Shell Command| E["Runtime.
getRuntime().
exec(''sh'')"];     E -->|Arbitrary
Command Execution| F[RCE with
Root Privileges];     style C fill:#f9f,stroke:#333,stroke-width:2px     style F fill:#f99,stroke:#333,stroke-width:2px

4. 其他關鍵安全弱點

除了 RCE 缺陷之外,評估還強調了導致該裝置安全性不佳的其他幾個關鍵安全弱點 [1]。

弱點 (Weakness) CVE 技術影響 (Technical Implication)
缺乏系統完整性 CVE-2025-58394 裝置運行過時的 Android 版本 (6),SELinux 被關閉,預設為 root ,並使用公共 AOSP 測試 key 進行簽署。這顯著降低了提升權限和系統入侵的門檻。
任意檔案寫入/刪除 CVE-2025-58396 Uhale 應用程式透過 TCP socket Port 17802 接受未經身份驗證的檔案上傳。缺乏 更新 (path) 遍歷防護 (path traversal protection) 使得 local 網路上的攻擊者能夠將任意內容寫入裝置上的任何 更新
SQL Injection CVE-2025-58395 應用程式包含 Code site,其中原始字串被串接並在 SQL 語句中執行,這表明存在 SQL Injection 攻擊的漏洞。
不安全的 WebView 設定 CVE-2025-58390 WebViews 被設定為忽略 SSL/TLS 錯誤,將 HTTPS 連線暴露給 MITM 攻擊。

這些缺陷的組合創造了一個高度脆弱的平台。例如,任意檔案寫入漏洞可以與 缺乏系統完整性 串聯起來,無需依賴複雜的 RCE 漏洞利用即可實現持久的 root 存取

5. 結論

對 Uhale 數位相框的安全評估揭示了其應用程式開發中嚴重缺乏基本的安全實務。 不安全的信任管理員 未淨化的 shell 執行 漏洞是教科書般的例子,說明了忽視輸入驗證和安全通訊協議如何導致災難性的 RCE 缺陷。動態程式碼載入機制雖然旨在用於更新,但與不安全的信任管理員配對時,卻成為惡意軟體交付的強大媒介。多個高嚴重性漏洞 (包括命令注入和 SQL Injection) 的存在,凸顯了嵌入式裝置開發中進行嚴格安全審計和轉向安全設計原則 (secure-by-design principles) 的必要性。