Skip to content

Latest commit

 

History

History
948 lines (746 loc) · 36 KB

File metadata and controls

948 lines (746 loc) · 36 KB

네트워크 보안 게임 - TCP 패킷 분석 실습 플랫폼

Docker 기반 웹 애플리케이션으로 구현된 멀티플레이어 네트워크 패킷 분석 게임

목차

  1. 프로젝트 개요
  2. 시스템 아키텍처
  3. 게임 규칙 (간략)
  4. 네트워크 통신 계층
  5. 게임 흐름 구조
  6. 모듈 설명
  7. 서버와 클라이언트 정의
  8. 웹 기반 통신과 패킷 분석
  9. 설치 및 실행
  10. Wireshark 사용법

프로젝트 개요

본 프로젝트는 TCP/IP 네트워크 보안을 학습하기 위한 교육용 멀티플레이어 게임입니다. 플레이어들은 Docker 컨테이너 환경에서 웹 브라우저를 통해 게임에 참여하며, Wireshark를 사용하여 실시간 네트워크 패킷을 분석하여 자신을 향한 공격을 탐지합니다.

핵심 특징

  • Docker 기반 격리 환경: 각 플레이어는 독립된 컨테이너에서 실행
  • 웹 기반 인터페이스: Flask + Socket.IO를 사용한 실시간 웹 애플리케이션
  • P2P 직접 통신: 공격 패킷은 플레이어 간 직접 전송 (실제 IP 노출)
  • 실시간 패킷 분석: Wireshark로 TCP 스트림 분석 및 공격자 IP 식별
  • 라운드 기반 난이도 증가: 5라운드에 걸쳐 점진적으로 증가하는 복잡도

시스템 아키텍처

전체 시스템 구조도

┌─────────────────────────────────────────────────────────────────┐
│                     Docker Network (172.20.0.0/16)               │
│                                                                   │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │  게임 서버 (172.20.0.10:9999)                            │   │
│  │  ┌────────────────────────────────────────────────────┐  │   │
│  │  │ Flask 웹 서버 (8000)                              │  │   │
│  │  │  - 웹 GUI 제공                                     │  │   │
│  │  │  - Socket.IO (실시간 통신)                        │  │   │
│  │  └────────────────────────────────────────────────────┘  │   │
│  │  ┌────────────────────────────────────────────────────┐  │   │
│  │  │ TCP 게임 서버 (9999)                              │  │   │
│  │  │  - 클라이언트 연결 관리                           │  │   │
│  │  │  - 게임 상태 관리 (GameManager)                   │  │   │
│  │  │  - 더미/노이즈/가짜공격 생성                      │  │   │
│  │  │  - 점수 계산 및 라운드 진행                       │  │   │
│  │  └────────────────────────────────────────────────────┘  │   │
│  └──────────────────────────────────────────────────────────┘   │
│                           │                                       │
│                           │ (서버-클라이언트 통신)               │
│                           │                                       │
│  ┌────────────────┐   ┌────────────────┐   ┌────────────────┐  │
│  │ Player1        │   │ Player2        │   │ Player3        │  │
│  │ (172.20.0.11)  │   │ (172.20.0.12)  │   │ (172.20.0.13)  │  │
│  │                │   │                │   │                │  │
│  │ Flask (5000)   │   │ Flask (5000)   │   │ Flask (5000)   │  │
│  │ - 웹 UI        │   │ - 웹 UI        │   │ - 웹 UI        │  │
│  │                │   │                │   │                │  │
│  │ P2P (10001)    │◄─┼►│ P2P (10002)    │◄─┼►│ P2P (10003)    │  │
│  │ - 공격 수신    │   │ - 공격 수신    │   │ - 공격 수신    │  │
│  └────────────────┘   └────────────────┘   └────────────────┘  │
│         ▲                     ▲                     ▲           │
│         └─────────────────────┴─────────────────────┘           │
│                  P2P 공격 패킷 (직접 통신)                       │
└─────────────────────────────────────────────────────────────────┘
                           │
                           ▼
                    ┌──────────────┐
                    │  Wireshark   │
                    │ 패킷 캡처 및  │
                    │    분석      │
                    └──────────────┘

아키텍처 핵심 개념

1. 이중 통신 구조

  • 서버-클라이언트 통신 (172.20.0.10:9999)

    • 게임 상태, 더미 패킷, 점수 정보 등
    • 서버가 중앙 집중식으로 관리
  • P2P 직접 통신 (플레이어 간)

    • 실제 공격 패킷만 P2P로 직접 전송
    • 공격자의 실제 IP가 패킷에 노출 (학습 목적)

2. 가상 IP 시스템

  • 컨테이너 실제 IP: 172.20.0.x (네트워크 계층)
  • 게임 가상 IP: 172.20.1.x (애플리케이션 계층)
  • 서버가 가상 IP를 할당하여 게임 메시지에 사용

3. 웹 기반 인터페이스

  • Flask: 웹 페이지 제공
  • Socket.IO: 실시간 양방향 통신 (게임 상태 업데이트)
  • TCP 소켓: 게임 패킷 송수신

게임 규칙 (간략)

목표

Wireshark로 네트워크 패킷을 분석하여 자신을 공격한 플레이어의 IP를 찾아 방어

진행 방식

  1. 5라운드 진행 (각 라운드 90초)
  2. 플레이어는 다른 플레이어에게 공격 패킷 전송 가능 (라운드당 제한 있음)
  3. 서버는 주기적으로 더미 패킷 전송 (라운드마다 빈도 증가)
  4. R3부터 노이즈 트래픽 추가, R5에는 가짜 공격 추가
  5. 라운드 종료 후 방어 페이즈(20초): 공격자 IP 제출
  6. 점수 계산: 정답(+점수), 오답(-점수), 놓친 공격(-점수, HP 감소)

난이도 구성

  • R1-R2: 기본 IP 탐지 학습
  • R3-R4: 노이즈 트래픽 추가
  • R5: 가짜 공격 10개 추가 (최고 난이도)

네트워크 통신 계층

패킷 전송 계층 구분

본 프로젝트의 모든 통신은 TCP/IP 프로토콜을 사용합니다. 통신은 두 가지 계층에서 이루어집니다:

1. 네트워크 계층 (Transport Layer - TCP)

실제 패킷 전송이 이루어지는 계층:

  • 프로토콜: TCP
  • 포트:
    • 게임 서버: 9999
    • P2P 공격: 10001, 10002, 10003 ...
    • 웹 서버: 8000 (서버), 5000 (클라이언트)
  • IP 주소: Docker 컨테이너의 실제 IP (172.20.0.x)
  • Wireshark 캡처 대상: 이 계층의 TCP 패킷

특징:

  • Wireshark에서 보이는 Source IP / Destination IP는 실제 컨테이너 IP
  • TCP 스트림으로 패킷의 출발지와 목적지 확인 가능
  • SSL/TLS 없이 평문 JSON 전송 (교육 목적)

2. 애플리케이션 계층 (Application Layer)

게임 로직이 동작하는 계층:

  • 프로토콜: 커스텀 JSON 메시지
  • 가상 IP: 172.20.1.x (게임 내부에서만 사용)
  • 메시지 타입: ATTACK, DUMMY, DEFENSE, SCORE 등
  • 페이로드: Base64 인코딩 (Wireshark에서 평문 안 보임)

특징:

  • JSON 메시지 내부에 from_ip, to_ip 필드로 가상 IP 사용
  • 서버가 플레이어에게 가상 IP 할당 (예: Player1 → 172.20.1.1)
  • 게임 메시지는 애플리케이션 레벨에서 해석

계층 비교표

구분 네트워크 계층 (TCP) 애플리케이션 계층
프로토콜 TCP/IP 커스텀 JSON
IP 주소 172.20.0.x (실제) 172.20.1.x (가상)
패킷 분석 Wireshark로 캡처 JSON 파싱
공격 탐지 방법 Source IP 확인 메시지 내 from_ip 확인
암호화 없음 (평문) Base64 인코딩 (난독화)

게임 흐름 구조

┌─────────────────────────────────────────────────────────────────┐
│                          게임 시작                                │
│                    (2명 이상 접속 시)                            │
└────────────────────────┬────────────────────────────────────────┘
                         │
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│                   라운드 루프 (R1~R5)                            │
│                                                                   │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │ 1. 라운드 시작 (ROUND_START)                            │    │
│  │    - 난이도 설정 (더미 간격, 공격 제한 등)             │    │
│  │    - 플레이어 상태 초기화                               │    │
│  └────────────┬────────────────────────────────────────────┘    │
│               │                                                   │
│               ▼                                                   │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │ 2. 게임 페이즈 (PLAYING) - 90초                         │    │
│  │                                                           │    │
│  │  [서버 동작]                                             │    │
│  │  - 더미 패킷 주기적 브로드캐스트                       │    │
│  │  - 노이즈 트래픽 생성 (R3+)                            │    │
│  │  - 가짜 공격 생성 (R5)                                 │    │
│  │                                                           │    │
│  │  [플레이어 동작]                                         │    │
│  │  ① 공격 요청 → 서버                                    │    │
│  │  ② 서버 승인 → 공격자에게 타겟 정보 제공              │    │
│  │  ③ 공격자 → 타겟에게 P2P 직접 공격                    │    │
│  │  ④ 양쪽이 서버에 확인 메시지 전송                      │    │
│  │  ⑤ 서버가 실제 공격으로 기록                           │    │
│  │                                                           │    │
│  │  [Wireshark]                                             │    │
│  │  - 플레이어가 실시간으로 패킷 캡처 및 분석            │    │
│  │  - 자신을 향한 공격 패킷의 Source IP 기록              │    │
│  └────────────┬────────────────────────────────────────────┘    │
│               │                                                   │
│               ▼                                                   │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │ 3. 방어 페이즈 (DEFENSE_PHASE) - 20초                  │    │
│  │    - 플레이어가 공격자 IP 목록 제출                    │    │
│  │    - 중복 제출 시 누적 (여러 번 제출 가능)            │    │
│  └────────────┬────────────────────────────────────────────┘    │
│               │                                                   │
│               ▼                                                   │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │ 4. 점수 계산 (ROUND_END)                                │    │
│  │    - 정답: 해당 IP의 공격 중 1개만 방어 (+점수)       │    │
│  │    - 오답: 실제 공격하지 않은 IP (-점수)               │    │
│  │    - 놓친 공격: 제출하지 않은 IP의 모든 공격          │    │
│  │                (-점수, HP 감소)                         │    │
│  │    - 플레이어 목록 실시간 업데이트 (Score, HP)        │    │
│  └────────────┬────────────────────────────────────────────┘    │
│               │                                                   │
│               ▼                                                   │
│         다음 라운드 or 게임 종료                                 │
└───────────────┬───────────────────────────────────────────────┬─┘
                │                                               │
                ▼                                               ▼
        다음 라운드 진행                           ┌────────────────┐
        (R1→R2→...→R5)                             │  게임 종료      │
                                                    │  최종 점수 집계 │
                                                    └────────────────┘

공격 승인 및 P2P 통신 흐름 (v2.0)

Player1 (공격자)                 Server                    Player2 (타겟)
      │                             │                             │
      │ ① ATTACK_REQUEST            │                             │
      ├────────────────────────────►│                             │
      │                             │ - 공격 가능 여부 검증      │
      │                             │ - 타겟 IP/포트 조회        │
      │                             │ - attack_id 생성           │
      │                             │                             │
      │ ② ATTACK_APPROVED           │ ③ INCOMING_ATTACK_WARNING   │
      │◄────────────────────────────┤────────────────────────────►│
      │ (타겟 IP: 172.20.0.12)      │   (공격자 IP: 172.20.1.1)  │
      │ (타겟 포트: 10002)           │                             │
      │                             │                             │
      │ ④ P2P 직접 연결 및 공격 패킷 전송                          │
      ├────────────────────────────────────────────────────────►│
      │   (TCP: 172.20.0.11 → 172.20.0.12:10002)                 │
      │   Wireshark에서 이 패킷의 Source IP를 봐야 함!           │
      │                             │                             │
      │ ⑤ ATTACK_CONFIRM (SENT)     │                             │
      ├────────────────────────────►│                             │
      │                             │                             │
      │                             │ ⑥ ATTACK_CONFIRM (RECEIVED) │
      │                             │◄────────────────────────────┤
      │                             │                             │
      │                             │ ⑦ 양쪽 확인 완료            │
      │                             │   → real_attacks에 기록    │
      │                             │   → 점수 계산에 반영        │

모듈 설명

프로젝트 구조

ComNetProject/
├── common/                  # 공통 모듈 (서버/클라이언트 공유)
│   ├── constants.py         # 게임 설정 상수
│   ├── message_types.py     # JSON 메시지 클래스
│   └── protocol.py          # TCP 통신 프로토콜
│
├── server/                  # 서버 모듈
│   ├── web_server_gui.py    # 웹 서버 메인 (Flask + Socket.IO)
│   ├── game_manager.py      # 게임 로직 관리자
│   ├── player_manager.py    # 플레이어 정보 관리
│   ├── dummy_generator.py   # 더미 패킷 생성기
│   ├── noise_generator.py   # 노이즈 트래픽 생성기
│   └── decoy_generator.py   # 가짜 공격 생성기 (R5)
│
├── client/                  # 클라이언트 모듈
│   ├── web_client.py        # 웹 클라이언트 (Flask + Socket.IO)
│   └── templates/           # HTML 템플릿
│       └── client.html
│
├── docs/                    # 문서
│   ├── protocol.md          # 통신 프로토콜 명세
│   ├── wireshark_guide.md   # Wireshark 사용 가이드
│   └── docker_guide.md      # Docker 설정 가이드
│
├── Dockerfile               # Docker 이미지 빌드 파일
├── docker-compose.yml       # 멀티 컨테이너 구성
└── requirements.txt         # Python 의존성

모듈 상세 설명

1. common/ - 공통 모듈

서버와 클라이언트가 공유하는 핵심 라이브러리:

  • constants.py

    • 역할: 게임 설정 값 관리
    • 주요 내용:
      • 네트워크 설정 (포트, 버퍼 크기)
      • 게임 설정 (라운드 수, 시간 제한, HP)
      • 라운드별 난이도 (DIFFICULTY_BY_ROUND)
      • 점수 배점 (SCORE_*)
    • 특징: 모든 설정을 한 곳에서 관리하여 일관성 유지
  • message_types.py

    • 역할: 네트워크 메시지 구조체 정의
    • 주요 클래스:
      • Message: 기본 메시지 (type, timestamp)
      • AttackMessage: 공격 패킷 (from_ip, to_ip, payload, attack_id)
      • DefenseMessage: 방어 제출 (player_id, attacker_ips)
      • ScoreMessage: 점수 업데이트
    • 특징: Base64 인코딩으로 페이로드 난독화
  • protocol.py

    • 역할: TCP 메시지 송수신 프로토콜
    • 주요 기능:
      • 메시지 길이 헤더 추가 (4바이트)
      • JSON 직렬화/역직렬화
      • 네트워크 바이트 순서 처리
    • 특징: 신뢰성 있는 메시지 전송 보장

2. server/ - 서버 모듈

게임 서버의 핵심 구성 요소:

  • web_server_gui.py (메인 서버)

    • 역할: 웹 서버 및 게임 서버 통합
    • 구성:
      • Flask: 웹 GUI 제공 (포트 8000)
      • Socket.IO: 실시간 양방향 통신
      • TCP 서버: 게임 패킷 처리 (포트 9999)
    • 기능:
      • 클라이언트 연결 수락 및 관리
      • 게임 시작/중지 제어
      • 플레이어 목록 실시간 브로드캐스트
      • 서버 로그 웹 UI 출력
  • game_manager.py (게임 로직 관리자)

    • 역할: 게임 상태 및 진행 관리
    • 주요 기능:
      • 게임 상태 관리 (WAITING, PLAYING, DEFENSE_PHASE 등)
      • 라운드 진행 및 타이머 관리
      • 공격 승인 시스템 (P2P 중개)
      • 점수 계산 및 HP 관리
      • 난이도 조정 (라운드별)
    • 특징:
      • 스레드 안전성 보장 (Lock 사용)
      • 공격 타임아웃 처리
      • 실시간 플레이어 목록 업데이트
  • player_manager.py (플레이어 정보 관리)

    • 역할: 플레이어 상태 관리
    • 주요 기능:
      • 플레이어 추가/제거
      • 가상 IP 할당 (172.20.1.x 풀)
      • 점수 및 HP 업데이트
      • 공격 기록 관리 (attacks_received)
    • 특징:
      • 연결 순서 기반 인덱스 (P2P 포트 할당용)
      • 스레드 안전성 보장
  • dummy_generator.py (더미 패킷 생성기)

    • 역할: 주기적으로 더미 패킷 전송
    • 특징:
      • 라운드별 전송 간격 조정 (R1: 2초 → R5: 0.5초)
      • 페이로드: "DUMMY_" + 랜덤 문자열
      • 백그라운드 스레드로 동작
  • noise_generator.py (노이즈 트래픽 생성기)

    • 역할: 플레이어 간 배경 트래픽 생성 (R3+)
    • 특징:
      • 랜덤하게 플레이어 쌍 선택
      • 페이로드: "NOISE_" + 랜덤 데이터
      • 실제 공격처럼 보이지만 게임에 영향 없음
  • decoy_generator.py (가짜 공격 생성기)

    • 역할: 서버가 생성한 가짜 공격 (R5 only)
    • 특징:
      • 10개의 가짜 공격 생성
      • 플레이어 IP를 사칭하여 전송
      • 제출 시 오답 처리

3. client/ - 클라이언트 모듈

플레이어 웹 애플리케이션:

  • web_client.py (웹 클라이언트)

    • 역할: 플레이어 인터페이스
    • 구성:
      • Flask: 웹 UI 제공 (포트 5000)
      • Socket.IO: 실시간 게임 상태 수신
      • TCP 클라이언트: 게임 서버 통신
      • P2P 서버: 공격 패킷 수신 (포트 10001+)
    • 기능:
      • 서버 연결 및 게임 참여
      • 공격 요청 및 전송
      • 방어 답안 제출
      • 게임 상태 실시간 표시
  • templates/client.html (웹 UI)

    • HTML, CSS, JavaScript로 구성
    • Socket.IO 클라이언트로 실시간 업데이트

서버와 클라이언트 정의

서버 (Server) 정의

역할: 게임의 중앙 관리자 및 중재자

주요 책임:

  1. 연결 관리

    • 플레이어 접속 수락
    • 가상 IP 할당 (172.20.1.x)
    • 플레이어 목록 관리
  2. 게임 진행 관리

    • 게임 시작/중지 제어
    • 라운드 타이머 관리
    • 게임 상태 전환 (WAITING → PLAYING → DEFENSE → ROUND_END)
  3. 공격 중재 (v2.0 핵심)

    • 공격 요청 승인/거부
    • P2P 연결 정보 제공 (타겟 IP/포트)
    • 공격 완료 확인 (양방향)
    • 실제 공격 기록 (real_attacks)
  4. 컨텐츠 생성

    • 더미 패킷 브로드캐스트
    • 노이즈 트래픽 생성 (R3+)
    • 가짜 공격 생성 (R5)
  5. 점수 계산

    • 방어 답안 검증
    • 점수 및 HP 업데이트
    • 결과 브로드캐스트

통신 포트:

  • TCP 9999: 게임 통신
  • HTTP 8000: 웹 GUI

특징:

  • 단일 인스턴스 (Docker 컨테이너 1개)
  • 모든 게임 상태의 신뢰 소스 (Single Source of Truth)
  • 플레이어는 직접 공격하지 않고 서버를 통해 승인 받음

클라이언트 (Client) 정의

역할: 플레이어의 게임 참여 인터페이스

주요 책임:

  1. 서버 통신

    • 서버에 연결 및 인증
    • 게임 상태 메시지 수신
    • 방어 답안 제출
  2. P2P 공격 (v2.0 핵심)

    • 공격 요청 전송 (서버에)
    • 승인 받은 후 타겟에게 직접 연결
    • 공격 패킷 송신 및 확인
  3. P2P 방어

    • P2P 포트에서 공격 패킷 수신
    • 서버에 수신 확인 전송
  4. 사용자 인터페이스

    • 웹 브라우저로 게임 상태 표시
    • 공격 및 방어 입력 받음
    • Wireshark 연동 (사용자가 직접)

통신 포트:

  • TCP 9999: 서버 통신
  • HTTP 5000: 웹 UI
  • TCP 10001+: P2P 공격 수신

특징:

  • 다중 인스턴스 (Docker 컨테이너 N개, 2-4개)
  • 각 플레이어는 독립된 컨테이너
  • 웹 브라우저로 접근 (localhost:8081, 8082, 8083...)

서버-클라이언트 상호작용 요약

기능 서버 역할 클라이언트 역할
연결 수락 및 가상 IP 할당 연결 요청
게임 진행 타이머 및 상태 관리 상태 수신 및 표시
더미/노이즈 생성 및 전송 수신 (무시)
공격 승인 및 중재 요청 → P2P 직접 전송
방어 답안 검증 및 점수 계산 IP 제출
패킷 분석 (없음) Wireshark로 분석

웹 기반 통신과 패킷 분석

웹 기반 아키텍처의 특징

본 프로젝트는 Flask 웹 프레임워크를 사용하지만, 게임 패킷 통신은 일반 TCP 소켓으로 이루어집니다.

통신 구분

  1. 웹 인터페이스 (Flask + Socket.IO)

    • 역할: 사용자 UI 제공 및 실시간 상태 업데이트
    • 프로토콜: HTTP/WebSocket
    • 포트: 8000 (서버), 5000 (클라이언트)
    • 특징: 브라우저에서 접근 가능
  2. 게임 패킷 통신 (Python Socket)

    • 역할: 게임 메시지 및 공격 패킷 전송
    • 프로토콜: TCP (평문)
    • 포트: 9999 (서버), 10001+ (P2P)
    • 특징: Wireshark로 캡처 가능

SSL/TLS와 패킷 캡처

Q: 웹 기반인데 HTTPS(SSL/TLS)를 사용하나요?

A: 아니오. 본 프로젝트는 SSL/TLS를 사용하지 않습니다.

이유:

  1. 교육 목적: Wireshark로 패킷을 분석해야 하므로 평문 통신 필요
  2. 로컬 네트워크: Docker 내부 네트워크로 외부 노출 없음
  3. Flask 개발 서버: 프로덕션 환경 아님 (학습용)

웹 통신 vs 게임 통신

구분 웹 인터페이스 게임 패킷
프로토콜 HTTP / WebSocket TCP (평문)
암호화 없음 (HTTP) 없음
용도 UI 제공, 실시간 업데이트 게임 메시지 전송
Wireshark 캡처 가능 (분석 불필요) 가능 (분석 필수)
SSL/TLS 영향 없음 없음

Wireshark 캡처 영향

결론: SSL/TLS가 없으므로 Wireshark로 모든 패킷을 평문으로 볼 수 있습니다.

  • ✅ TCP 스트림의 Source IP / Destination IP 확인 가능
  • ✅ JSON 메시지의 type 필드 확인 가능
  • ✅ Base64 인코딩된 페이로드는 수동으로 디코딩 가능 (선택 사항)

만약 SSL/TLS를 사용했다면:

  • ❌ Wireshark에서 암호화된 데이터만 보임
  • ❌ Source IP는 보이지만 메시지 내용 분석 불가
  • ❌ 교육 목적 달성 불가

패킷 분석 방법

Wireshark에서 캡처한 패킷은 다음과 같이 보입니다:

Frame 42: 120 bytes on wire
Ethernet II, Src: 02:42:ac:14:00:0b, Dst: 02:42:ac:14:00:0c
Internet Protocol, Src: 172.20.0.11, Dst: 172.20.0.12
Transmission Control Protocol, Src Port: 45678, Dst Port: 10002

Data (JSON 평문):
{
  "type": "ATTACK",
  "timestamp": 1730000000.123,
  "from_ip": "172.20.1.1",
  "to_ip": "172.20.1.2",
  "from_player": "Player1",
  "to_player": "Player2",
  "payload": "QVRUQUNLX1RBUkdFVF9QbGF5ZXIy",
  "attack_id": "Player1→Player2_1730000000_1"
}

분석 포인트:

  1. IP 계층: Src IP = 172.20.0.11 (공격자의 실제 IP) ← 이것을 기록!
  2. JSON 메시지: type = "ATTACK" (공격 패킷 확인)
  3. 페이로드: Base64 디코딩 → "ATTACK_TARGET_Player2"

설치 및 실행

시스템 요구사항

  • 운영체제: Windows 10/11, macOS, Linux
  • Docker: Docker Engine 20.10 이상
  • Docker Compose: v2.0 이상
  • Wireshark: 3.0 이상
  • 웹 브라우저: Chrome, Firefox, Edge 등

1. 프로젝트 다운로드

# Git Clone
git clone https://github.com/Hyunwoo2267/ComNetProject.git
cd ComNetProject

2. Docker 설치

Windows

  1. Docker Desktop for Windows 다운로드
  2. 설치 후 재부팅
  3. Docker Desktop 실행 확인

macOS

brew install --cask docker

Linux

# Ubuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER

Docker 설치 확인:

docker --version
docker-compose --version

3. Wireshark 설치

Windows

  1. Wireshark 다운로드
  2. 설치 시 "Npcap" 옵션 선택 (필수)

macOS

brew install --cask wireshark

Linux

sudo apt install wireshark
sudo usermod -aG wireshark $USER

4. 게임 실행

4.1. Docker 컨테이너 시작

# 전체 시스템 빌드 및 시작
docker-compose up -d --build

# 실행 확인
docker ps

예상 출력:

CONTAINER ID   IMAGE                    PORTS                    NAMES
abc123         comnetproject-server     0.0.0.0:8000->8000/tcp   game_server
def456         comnetproject-player1    0.0.0.0:8081->5000/tcp   game_player1
ghi789         comnetproject-player2    0.0.0.0:8082->5000/tcp   game_player2
jkl012         comnetproject-player3    0.0.0.0:8083->5000/tcp   game_player3

4.2. 웹 인터페이스 접속

서버 관리 페이지 (게임 시작/중지):

http://localhost:8000

플레이어 클라이언트:

  • Player1: http://localhost:8081
  • Player2: http://localhost:8082
  • Player3: http://localhost:8083

4.3. 게임 시작 순서

  1. 각 플레이어가 웹 브라우저로 자신의 URL 접속
  2. "서버에 연결" 버튼 클릭
  3. 최소 2명 접속 시 게임 자동 시작
  4. Wireshark에서 패킷 캡처 시작 (아래 참조)

5. Wireshark 설정 및 캡처

5.1. Wireshark 실행

# Windows
# 시작 메뉴에서 "Wireshark" 실행

# macOS/Linux
sudo wireshark

5.2. 캡처 인터페이스 선택

  1. Wireshark 시작 화면에서 네트워크 인터페이스 선택:

    • Windows: "Ethernet" 또는 "Wi-Fi"
    • macOS: "en0" (Wi-Fi) 또는 "en1" (Ethernet)
    • Linux: "eth0" 또는 "docker0"
  2. Docker 네트워크 캡처 (권장):

    • Linux: "docker0" 인터페이스 선택
    • Windows/macOS: "Loopback" 또는 "lo0" 선택

5.3. 캡처 필터 설정

옵션 1: 게임 포트만 캡처 (권장)

tcp port 9999 or tcp portrange 10001-10010

옵션 2: 게임 서버 IP 캡처

host 172.20.0.10

옵션 3: 모든 Docker 트래픽

net 172.20.0.0/16

5.4. 캡처 시작

  1. 인터페이스 선택 후 파란색 상어 지느러미 버튼 클릭
  2. 패킷이 캡처되기 시작함

6. 시스템 종료

# 모든 컨테이너 정지 및 제거
docker-compose down

# 이미지도 함께 제거
docker-compose down --rmi all

# 볼륨도 함께 제거
docker-compose down -v

7. 로그 확인

# 서버 로그 실시간 확인
docker logs -f game_server

# 특정 플레이어 로그
docker logs -f game_player1

# 모든 로그 확인
docker-compose logs -f

Wireshark 사용법

패킷 필터링

기본 필터

게임 트래픽만 표시:

tcp.port == 9999 or tcp.port >= 10001

고급 필터

특정 플레이어가 보낸 패킷:

ip.src == 172.20.0.11

특정 플레이어가 받은 패킷:

ip.dst == 172.20.0.12

공격 패킷만 보기 (P2P 포트):

tcp.port >= 10001 and tcp.port <= 10010

더미 패킷 제외:

ip.src != 172.20.0.10

패킷 분석 방법

1. Source IP 확인

공격자를 찾는 가장 중요한 정보:

  1. 패킷 선택
  2. 중간 패널에서 Internet Protocol 확장
  3. Source Address 확인
  4. 이 IP가 공격자!

예시:

Source: 172.20.0.11  ← Player1이 보낸 패킷
Destination: 172.20.0.12  ← Player2가 받는 패킷

2. TCP Stream 추적

하나의 연결에서 주고받은 모든 패킷 보기:

  1. 패킷 우클릭
  2. FollowTCP Stream
  3. 전체 대화 내용 확인 (JSON 메시지)

3. Statistics 활용

IP별 통신량 확인:

  1. 메뉴: StatisticsConversations
  2. IPv4 탭 선택
  3. "Address A" 열 정렬 → 누가 얼마나 많이 보냈는지 확인

시간대별 패킷 분석:

  1. 메뉴: StatisticsIO Graph
  2. Y축: 패킷 수
  3. X축: 시간

공격 패킷 식별 가이드

방법 1: Source IP로 판단 (권장)

공식:

  • Source IP가 다른 플레이어 컨테이너 IP (172.20.0.11~13) → 공격 가능성
  • Source IP가 서버 IP (172.20.0.10) → 더미 또는 노이즈

절차:

  1. Wireshark 필터: ip.dst == [내 IP]
  2. Source IP 목록 작성
  3. 서버 IP(172.20.0.10) 제외
  4. 남은 IP를 방어 답안으로 제출

방법 2: TCP 포트로 판단

  • Destination Port가 10001~10003 → P2P 공격 패킷
  • Destination Port가 9999 → 서버 통신 (더미 등)

방법 3: 페이로드 디코딩 (고급)

Base64 페이로드 디코딩:

Python:

import base64

payload = "QVRUQUNLX1RBUkdFVF9QbGF5ZXIy"
decoded = base64.b64decode(payload).decode('utf-8')
print(decoded)  # "ATTACK_TARGET_Player2"

Linux/macOS:

echo "QVRUQUNLX1RBUkdFVF9QbGF5ZXIy" | base64 -d

Windows PowerShell:

[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String("QVRUQUNLX1RBUkdFVF9QbGF5ZXIy"))

R5 라운드 팁: 가짜 공격 구별

문제: 서버가 생성한 가짜 공격 10개가 섞여 있음

전략:

  1. 타이밍 분석: 같은 IP에서 연속으로 빠르게 오는 패킷은 의심
  2. 패턴 분석: 실제 플레이어는 수동으로 공격 (불규칙), 서버는 자동 생성 (규칙적)
  3. 확률 활용: 의심스러운 IP는 제출하지 않기 (오답 -10점 손해)

문제 해결

1. Docker 관련

컨테이너가 시작되지 않음:

# 로그 확인
docker-compose logs

# 재시작
docker-compose restart

포트 충돌 (이미 사용 중):

# docker-compose.yml 수정
ports:
  - "8000:8000"  # 8000을 다른 포트로 변경

2. 네트워크 관련

클라이언트가 서버에 연결 안 됨:

# 서버 컨테이너 IP 확인
docker inspect game_server | grep IPAddress

# 네트워크 확인
docker network inspect comnetproject_game_network

3. Wireshark 관련

패킷이 캡처되지 않음:

  • 올바른 인터페이스 선택 확인
  • Docker 네트워크 인터페이스 선택 (docker0, lo0 등)
  • 관리자 권한으로 실행

패킷이 너무 많음:

  • 필터 사용: tcp.port == 9999
  • 다른 프로그램의 네트워크 사용 중지

참고 자료


라이센스

본 프로젝트는 교육 목적으로 제작되었습니다.