패킷의 세계 — OSI 7계층과 3-way Handshake 기반 장애 격리 및 네트워크 보안 진단
Wireshark 패킷 캡처와 헤더 역공학, 계층적 네트워크 장애 사다리 진단, SYN Flooding 탐지 및 로컬 포트 공격 표면 점검
- Date
- Status
- published
- Tags
1. 개요 및 학습 개념 요약
보안 관제 자동화 1과목에서는 파이썬 고수준 라이브러리를 활용해 로그를 파싱하고 웹훅을 호출하는 LLM 판단 파이프라인을 구축했다. 하지만 애플리케이션 레벨의 단순한 네트워크 호출 한 줄 이면에는 물리 회선과 라우터, 스위치를 거치는 복잡한 패킷 캡슐화와 프로토콜 핸드셰이크가 맞물려 돌아간다.
상위 애플리케이션 로그에만 의존하는 관제 체계로는 네트워크 하위 계층에서 일어나는 통신 두절이나 패킷 손실, 비정상 세션 연결 시도를 온전히 식별하기 어렵다.
애플리케이션의 단순한 네트워크 호출 이면에는 물리 계층부터 전송 계층까지 이어지는 복잡한 캡슐화와 프로토콜 핸드셰이크가 맞물려 돌아간다.
실무 관제 현장에서 빈번하게 접하는 “네트워크 접속 불가” 증상은 단순한 단일 문장이지만, 물리선 단선부터 로컬 게이트웨이 병목, 외부 라우팅 장애, DNS 해석 오류에 이르기까지 원인 후보가 광범위하다. 이를 체계적으로 진단하기 위해 OSI 7계층 모델을 기준으로 문제를 최하위 물리 계층부터 상위 애플리케이션 계층까지 단계적으로 좁혀가는 장애 격리 사다리를 구축했다.
Wireshark를 활용해 실제 네트워크 카드로 송수신되는 로우 레벨 패킷을 직접 캡처하고, 3계층 IP 헤더와 4계층 TCP 헤더의 필드를 역공학하여 연결 수립과 종료 메커니즘을 규명했다. 클라이언트와 서버가 연결을 맺는 3-way Handshake와 연결을 종료하는 4-way Teardown의 패킷 흐름을 분석하고, 자동화 스크립트로 패킷 헤더 보고서를 생성하는 파이프라인을 구축했다. 로컬 환경의 개방 포트를 점검하여 잠재적 공격 표면을 식별하고, 비암호화 통신의 취약성을 검증했다.
- 계층적 장애 격리 사다리: 물리 링크, 로컬 게이트웨이, 외부 통신망, DNS 질의 단계로 이어지는 Bottom-up 진단 로직을 구현하여 장애 지점을 특정 계층으로 신속히 수렴시켰다.
- TCP 핸드셰이크와 세션 라이프사이클 분석: SYN, SYN-ACK, ACK로 이어지는 3-way Handshake와 FIN 세그먼트 기반의 4-way Teardown을 캡처하고, TIME_WAIT 소켓 상태가 네트워크 안정성에 미치는 영향을 분석했다.
- 패킷 헤더 파싱과 마크다운 보고서 자동화: 캡처된 패킷 데이터 딕셔너리를 순회하여 보고서용 마크다운 표를 자동 출력하는 생성 스크립트를 구현했다.
- 네트워크 보안 공격 표면 식별: 응답 없는 연속 SYN 패킷을 카운팅하여 SYN Flooding 공격 징후를 감지하는 필터를 설계하고, netstat 점검을 통해 로컬 환경의 SMB 445 포트 노출 위험과 평문 통신의 스니핑 위험을 확인했다.
2. 전체 산출물 및 계층별 진단 체계
물리 계층 점검부터 상위 애플리케이션 진단까지, 당일 실습에서 다룬 계층별 데이터와 진단 도구 체계는 다음과 같다.
| 계층 | 대상 프로토콜 및 데이터 | 진단 도구 및 명령어 | 점검 목적 및 실패 시 현상 |
|---|---|---|---|
| L1/L2 (물리·데이터링크) | 이더넷 케이블, Wi-Fi 신호, MAC 주소, ARP | ipconfig /all, arp -a | 케이블 탈락, 무선 연결 끊김, 게이트웨이 MAC 미해결 |
| L3 (네트워크) | IPv4/IPv6, ICMP, 서브넷 마스크, TTL | ping 192.168.1.1, ping 8.8.8.8 | 로컬 공유기 통신 장애, 외부 게이트웨이 라우팅 단절 |
| L4 (전송) | TCP, UDP, 포트 번호, 제어 플래그 | netstat -ano, Wireshark 필터 | 방화벽 포트 차단, 3-way Handshake 실패, 세션 고갈 |
| L7 (응용) | DNS, HTTP, TLS, SMB | nslookup, curl, 브라우저 | 도메인 이름 풀이 실패, 평문 자격증명 노출, 취약 서비스 개방 |
3. 기존 체계의 한계와 도전 과제
상위 계층 모니터링의 한계와 장애 전파의 사각지대
애플리케이션 계층에서 HTTP 상태 코드가 반환되지 않거나 타임아웃이 발생할 때, 기존 로그만으로는 원인을 파악하기 어렵다. 통신 실패의 실제 원인은 L1/L2 무선 링크 단절, L3 게이트웨이 라우팅 테이블 누락, L4 방화벽의 패킷 폐기, L7 DNS 서버 응답 불능 등 하위 계층 전반에 걸쳐 분산되어 있다.
하위 계층부터 상위 계층으로 체계적으로 점검하는 절차적 가드레일이 없으면 모든 네트워크 장애를 무차별적으로 서버 프로세스 장애로 오판하게 된다.
단순 문자열 기반 식별자 검증의 한계와 주소 스푸핑 공격 표면
네트워크 식별자인 IP와 MAC 주소를 단순 문자열 분리(split)로만 검증하는 방식은 형식적 결함뿐만 아니라 하드웨어 비트 레벨의 정책 우회에 취약하다. 옥텟 분할만으로는 16진수 포맷 무결성을 보장하기 어렵고, 첫 번째 옥텟의 I/G 비트(유니캐스트/멀티캐스트)나 U/L 비트, 그리고 브로드캐스트·널 주소 같은 프로토콜 예약 주소를 걸러내지 못한다.
네트워크 접근 제어(NAC)나 방화벽 화이트리스트 정책에서 주소 체계의 비트 제약을 엄격히 검증하지 않으면 스푸핑 트래픽을 신뢰 통신으로 오인할 위험이 존재한다.
프로토콜 비대칭성과 자원 고갈 위협
TCP 연결 수립과 해제는 상태 머신 상에서 서로 다른 대칭 구조를 가진다. 연결 수립은 SYN과 ACK를 묶어 3개 패킷으로 완료되지만, 연결 해제는 양방향 통신의 잔여 데이터 송신을 보장하기 위해 4-way Teardown으로 전개된다.
이 과정에서 한쪽 호스트가 일방적으로 SYN 패킷만 대량 전송할 경우 백로그 큐가 가득 차는 SYN Flooding 공격에 취약해진다. 정상 종료 후에도 세션이 TIME_WAIT 상태로 소켓을 점유하므로, 이에 대한 정확한 상태 이해와 포트 관리가 선행되어야 시스템 자원 고갈을 방지할 수 있다.
3-way 연결 수립은 SYN과 ACK를 결합해 신속히 완료되지만, 4-way 연결 해제는 양방향 잔여 데이터 보장을 위해 비대칭적으로 분리 전개된다.
4. 엔지니어링 의사결정 및 리팩터링
4.1. 계층적 장애 진단 사다리와 ICMP·DNS 핑 자동화 (diagnose.py, ping_check.py)
네트워크 장애가 발생했을 때 상위 애플리케이션부터 접근하면 수많은 종속성으로 인해 원인 격리가 지연된다. 최하위 물리 계층부터 최상위 애플리케이션 계층으로 진단 영역을 순차적으로 좁혀가는 장애 사다리 패턴을 설계했다.
1차 구현 코드인 diagnose.py에서는 검사항목 딕셔너리를 입력받아 가장 낮은 계층의 결함부터 즉시 반환하는 가드 클로즈 방식을 채택했다.
def diagnose(checks):
if checks["wifi"] == False:
return "1~2층 문제 — 케이블·Wi-Fi 연결부터 확인"
if checks["gateway"] == False:
return "내 방 문제 — 공유기를 확인"
if checks["internet"] == False:
return "외부 회선 문제 — 통신사 쪽 확인"
if checks["dns"] == False:
return "이름 풀이 문제 — DNS 설정 확인"
return "정상"
이 조건 분기는 네트워크 계층 모델의 의존성을 그대로 반영한다. Wi-Fi 또는 물리 케이블이 단선되면 게이트웨이나 인터넷 통신은 검사할 필요도 없이 실패한다. 로컬 게이트웨이 통신이 성공한 뒤에야 외부 ISP 회선을 검증하고, 외부 IP 통신이 성공한 뒤에야 L7 DNS 이름 풀이를 검증한다.
운영 환경에서 이러한 진단 절차를 자동화하기 위해, ping_check.py의 로직을 운영체제에 독립적인 네트워크 도달성 검증 함수로 표준화했다.
# 운영체제 독립적 ICMP 핑 도달성 검증 함수
import subprocess
import platform
def check_reachability(target: str, timeout_ms: int = 1000) -> bool:
count_flag = "-n" if platform.system().lower() == "windows" else "-c"
timeout_flag = "-w" if platform.system().lower() == "windows" else "-W"
proc = subprocess.run(
["ping", count_flag, "1", timeout_flag, str(timeout_ms), target],
capture_output=True,
text=True
)
return proc.returncode == 0
4.2. 정규표현식 기반 식별자 검증과 MAC 주소 하드웨어 비트 제약 분석 (ip_address.py)
네트워크 인터페이스 카드와 패킷 전달 경로에서 IP와 MAC 주소는 통신 주체를 식별하는 핵심 요소다. 단순한 구분자 분리(split)만으로는 형식적 오류를 온전히 방어하기 어려우므로, 정규표현식을 도입하여 표준 하이픈 표기법과 16진수 범위를 엄격하게 제한했다.
# 정규표현식 기반 MAC 주소 포맷 검증 (ip_address.py)
MAC_HYPHEN_PATTERN = re.compile(r"^([0-9A-Fa-f]{2}-){5}[0-9A-Fa-f]{2}$")
def is_mac(address):
parts = address.split("-")
if len(parts) != 6:
return False
return bool(MAC_HYPHEN_PATTERN.fullmatch(address.strip()))
코드 인라인 주석 리서치를 통해 정규식 유효성 통과 이후에도 보안 관점에서 추가 고려해야 할 MAC 주소의 하드웨어 비트 제약을 분석했다.
- I/G 비트 제약: 첫 번째 옥텟의 최하위 0번 비트는 유니캐스트 0과 멀티캐스트 1을 결정한다. 단일 엔드포인트 단말의 MAC 주소는 0번 비트가 0이어야 한다.
- U/L 비트 제약: 첫 번째 옥텟의 두 번째 최하위 1번 비트는 IEEE 등록 벤더 고유 주소인 UAA 0과 관리자 수동 생성 주소인 LAA 1을 구분한다.
- 특수 목적 및 예약 주소 배제: 전체 비트가 1인 브로드캐스트 주소(
FF-FF-FF-FF-FF-FF) 및 전체 비트가 0인 널 주소(00-00-00-00-00-00)는 단말 할당이 불가능하므로 화이트리스트 검증에서 배제해야 한다. - OUI 기반 제조사 식별: 상위 3바이트(24비트)를 IEEE 공인 OUI 데이터베이스와 대조하여, 인가된 장비만 네트워크에 접속시키는 제로트러스트 엔드포인트 통제에 활용할 수 있다.
4.3. TCP 핸드셰이크 상태 머신 추적과 SYN Flooding 이상 탐지 (mini_packet_filter.py, netstat.py)
TCP 통신은 신뢰성 확보를 위해 양방향 시퀀스 번호를 동기화하는 핸드셰이크 과정을 거친다. 패킷 흐름 상에서 비정상적인 플래그 조합을 분별하고 세션 자원을 고갈시키는 공격을 모니터링하는 로직을 분석했다.
mini_packet_filter.py에서는 수신된 패킷 배열에서 순수 SYN 플래그만을 추출하여 특정 출발지 IP의 누적 횟수를 집계했다.
# SYN Flooding 탐지 로직 (mini_packet_filter.py)
counts = {}
for p in packets:
if "SYN" in p["flags"] and "ACK" not in p["flags"]:
src = p["src"]
if src not in counts:
counts[src] = 0
counts[src] = counts[src] + 1
for ip in counts:
if counts[ip] >= 3:
print(f"[의심] {ip} — 답장 없는 SYN {counts[ip]}개")
else:
print(f"[정상] {ip} — 답장 없는 SYN {counts[ip]}개")
SYN 플래그는 연결 요청을 의미하므로 정상적인 경우 서버가 SYN-ACK를 반환하고 클라이언트가 최종 ACK를 전송해야 한다. 만약 ACK 플래그가 동반되지 않은 순수 SYN 패킷만 단시간에 특정 IP(10.0.0.99)로부터 연속 유입된다면, 이는 TCP 백로그 큐를 점유하여 서비스 거부를 유발하는 SYN Flooding 공격 패턴으로 규정할 수 있다.
또한 netstat.py를 통해 로컬 시스템의 활성 네트워크 연결을 조사하고, 소켓 종료 상태를 분석했다.
# 소켓 외부 포트 추출 및 통계 집계 (netstat.py)
LINES = """TCP 192.168.0.15:51234 93.184.216.34:443 ESTABLISHED
TCP 192.168.0.15:51240 172.217.161.238:443 ESTABLISHED
TCP 192.168.0.15:51255 13.107.42.16:443 ESTABLISHED
TCP 192.168.0.15:51261 23.76.153.112:80 ESTABLISHED
TCP 192.168.0.15:51288 20.42.65.92:443 ESTABLISHED"""
PORTS = {80: "HTTP", 443: "HTTPS", 53: "DNS", 22: "SSH"}
실습 보고서(day01_packet_analysis.md)에 기록된 실제 소켓 상태 TIME_WAIT에 대해 아키텍처 관점의 상태 분석을 도출했다. 연결 종료 시 4-way Teardown을 수행할 때, 마지막 ACK를 전송한 액티브 클로즈 측은 즉시 소켓을 파기하지 않고 일정 시간 동안 TIME_WAIT 상태를 유지한다.
이는 네트워크 지연으로 인해 뒤늦게 도착할 수 있는 이전 연결의 잔여 세그먼트가 신규 연결 세그먼트와 뒤섞이는 데이터 오염을 방지하고, 마지막 전송 ACK가 손실되었을 때 상대방의 FIN 재전송에 응답하기 위한 필수 보호 장치다.
TIME_WAIT는 단순한 종료 지연이 아니라, 네트워크 지연 패킷에 의한 세션 데이터 오염을 차단하고 FIN 재전송에 응답하기 위한 프로토콜 보호 장치다.
4.4. 패킷 헤더 자동 구조화와 로컬 공격 표면 점검 (packet_capture.py, day01_packet_analysis.md)
수집된 Wireshark 패킷 캡처 데이터를 문서화하고 공유하는 작업은 수동 복사 시 휴먼 에러가 빈번하다. 파이썬 자료구조로부터 마크다운 표 서식을 결정론적으로 생성하는 packet_capture.py를 작성하여 보고서 작성 파이프라인을 자동화했다.
# 마크다운 표 생성 파이프라인 (packet_capture.py)
packets = [
{"src": "192.168.100.249", "dst": "104.20.23.154", "info": "[SYN]"},
{"src": "104.20.23.154", "dst": "192.168.100.249", "info": "[SYN, ACK]"},
{"src": "192.168.100.249", "dst": "104.20.23.154", "info": "[ACK]"},
]
headers = [
{"item": "출발지 IP", "value": "192.168.100.249", "where": "IP 헤더 (3층)"},
{"item": "목적지 IP", "value": "104.20.23.154", "where": "IP 헤더 (3층)"},
{"item": "TTL", "value": "128", "where": "IP 헤더 (3층)"},
{"item": "출발지 포트", "value": "51234", "where": "TCP 헤더 (4층)"},
{"item": "목적지 포트", "value": "443", "where": "TCP 헤더 (4층)"},
{"item": "플래그", "value": "SYN", "where": "TCP 헤더 (4층)"},
]
print("| 순서 | Source | Destination | Info |")
print("|---|---|---|---|")
for i, packet in enumerate(packets):
print(f"| {i} | {packet['src']} | {packet['dst']} | {packet['info']} |")
이 자동화 코드를 통해 생성된 마크다운 표는 day01_packet_analysis.md 보고서의 2섹션과 3섹션에 오차 없이 반영되었다.
보고서 분석 과정에서 드러난 실체적 보안 취약점 두 가지를 식별했다.
첫째, 로컬 시스템에서 LISTENING 상태로 개방된 9개 포트 중 SMB 서비스인 445 포트가 열려 있음을 확인했다. SMB 445 포트는 사내망 및 인터넷 환경에서 원격 코드 실행 및 랜섬웨어 전파의 주요 진입로로 악용되는 고위험 포트다. 인가되지 않은 외부 접근을 차단하기 위해 호스트 방화벽 정책 수립이 필수적이다.
둘째, Wireshark의 Follow TCP Stream 기능을 통해 HTTP 평문 통신과 TLS 암호화 통신을 대조 분석했다. HTTP 통신에서는 클라이언트가 전송한 GET 요청 경로, 호스트 도메인, 브라우저 User-Agent 문자열이 평문으로 완전 노출되었다.
동일 로컬 네트워크에 위치한 공격자가 ARP 스푸핑 등으로 트래픽을 가로챌 경우 세션 쿠키와 자격증명이 그대로 탈취될 수 있음을 확인하고, 전송 계층 암호화(TLS)의 필수성을 실증했다.
동일 네트워크 환경에서 평문 HTTP 통신은 스니핑에 무방비로 노출되므로, 전송 계층 암호화(TLS)와 호스트 방화벽 정책이 병행되어야 한다.
5. 검증 및 회고
실제 산출물 데이터 기반 동작 검증
day01_packet_analysis.md에 기록된 캡처 데이터와 파이썬 진단 스크립트 실행 결과를 대조하여 시스템 동작을 정량적으로 검증했다.
- 실습 캡처 환경: 로컬 호스트 IPv4
192.168.100.249, MACD8-BB-C1-40-36-CA, 기본 게이트웨이192.168.1.1(MAC00-10-f3-a3-fc-96), DNS 서버168.126.63.1(KT DNS) 정상 식별 완료. - 3-way Handshake 완결: 클라이언트 포트
51234에서 목적지 웹서버104.20.23.154:443으로 SYN 전송 후 SYN-ACK 수신 및 최종 ACK 송신까지 3단계 패킷이 누락 없이 캡처되었다. - 헤더 필드 역공학: IP 헤더의 TTL 값
128(윈도우 기본값)과 TCP 헤더의 목적지 포트443(HTTPS) 매핑을 확인했다. - 소켓 상태 분석:
chrome.exe(PID17728) 프로세스가 생성한192.168.100.249:60315 -> 104.17.24.14:443세션의TIME_WAIT상태를 확인하여 소켓 회수 지연 메커니즘을 규명했다. - 이상 탐지 필터 동작:
mini_packet_filter.py실행 결과, 응답 없는 SYN 패킷 3개를 전송한10.0.0.99에 대해 정확히[의심]판정이 출력되었다.
현실적 회고 및 교훈
컴퓨터공학 전공 과정에서 이론으로 접했던 OSI 7계층과 TCP 3-way Handshake 모델을 실제 Wireshark 덤프와 호스트 소켓 데이터로 직접 확인하면서 패킷 통신의 실체를 체감했다.
추상적으로만 이해했던 계층 모델이 실제 장애 격리 현장에서 “물리 링크 확인 -> 게이트웨이 핑 -> 외부 IP 핑 -> DNS 이름 풀이”라는 구체적이고 결정론적인 디버깅 순서로 체계화되는 과정을 확인했다.
단순 파싱 규칙에 의존하는 간이 진단 도구는 예외적인 패킷 포맷이나 프로토콜 경계값을 잘못 판단하여 정상 트래픽을 공격으로 오판하거나 비정상 트래픽을 누락시키는 보안 홀이 될 수 있음을 확인했다. 자동화 도구일수록 엄격한 정규표현식과 프로토콜 비트 제약에 기반한 방어적 검증이 선행되어야 함을 절감했다.
로컬 환경 점검 과정에서 의도치 않게 개방되어 있던 445 포트와 평문 HTTP 패킷의 적나라한 노출을 직접 관찰하면서, 애플리케이션 보안뿐만 아니라 호스트 엔드포인트 방화벽과 네트워크 암호화가 복합적으로 구축되어야만 완전한 보안 태세를 갖출 수 있음을 확인했다.