📚 네트워크 · 패킷 분석 › 01. TCP/IP 구조 이해 — 43편
이전 글: 42. TCP 상태 전이 — LISTEN부터 TIME_WAIT까지 · 다음 글: 44. SYN, SYN/ACK, ACK
TCP Flag(Control Bits)는 TCP 헤더 안의 1비트짜리 스위치 8개로, 이 Segment가 연결에 대해 무엇을 하려는지를 나타냅니다. "연결을 시작하자(SYN)", "받았다(ACK)", "그만 보낸다(FIN)", "당장 끊는다(RST)" 같은 신호입니다.
각 비트의 이름과 위치는 40. TCP와 UDP 헤더 비교 — 신뢰성과 속도의 차이에서 표로 정리했습니다. 이 글은 한 걸음 더 나아가 Flag를 조합으로 읽는 법, 그리고 여러 도구가 같은 Flag를 어떻게 다르게 표기하는지에 집중합니다.
Flag는 헤더의 오프셋 13바이트에 모여 있어서, 8개 비트를 합친 16진수 한 바이트로 표현할 수 있습니다.
비트: CWR ECE URG ACK PSH RST SYN FIN
값: 0x80 0x40 0x20 0x10 0x08 0x04 0x02 0x01
예) SYN + ACK = 0x02 + 0x10 = 0x12
PSH + ACK = 0x08 + 0x10 = 0x18
FIN + ACK = 0x01 + 0x10 = 0x11
Flag는 양쪽 호스트의 연결 상태(State)를 바꾸는 계기입니다. 상태 전체는 42. TCP 상태 전이 — LISTEN부터 TIME_WAIT까지에서 다뤘고, 여기서는 "어떤 Flag가 어떤 단계에 등장하는가"만 흐름으로 봅니다.
[연결 수립] SYN ──→ ←── SYN+ACK ──→ ACK (44편, 41편)
│
↓
[데이터 전송] PSH+ACK (데이터 포함) ⇄ ACK (확인만) (46편)
│ ※ 수립 이후 거의 모든 Segment에 ACK가 켜져 있음
↓
[정상 종료] FIN+ACK ──→ ←── ACK, ←── FIN+ACK ──→ ACK (42편)
│
[강제 중단] RST 또는 RST+ACK (어느 단계에서든) (45편)
[혼잡 알림(ECN)] SYN에 ECE+CWR로 지원 여부 협상 → 이후 ECE/CWR로 혼잡 통지
이 흐름에서 나오는 판단 규칙이 있습니다.
정상 통신에서 자주 보는 조합입니다.
| 조합 | 16진수 | 등장 위치 | 의미 |
|---|---|---|---|
| SYN | 0x02 | 연결 시작 | 연결 요청 |
| SYN+ACK | 0x12 | 연결 시작 응답 | 요청 수락 |
| ACK | 0x10 | 전 구간 | 확인 응답(데이터 없을 수 있음) |
| PSH+ACK | 0x18 | 데이터 전송 | 데이터를 바로 전달 |
| FIN+ACK | 0x11 | 종료 | 더 보낼 데이터 없음 |
| RST | 0x04 | 거부·중단 | 즉시 끊음 |
| RST+ACK | 0x14 | 닫힌 포트 응답 등 | 받은 Segment를 확인하며 거부 |
| SYN+ECE+CWR | 0xC2 | 연결 시작 | ECN 지원 협상 (정상) |
정상 흐름에 없는 조합과 그 해석입니다. 이런 패킷은 대개 사람이 만든(Crafted) 패킷이며 스캔 도구의 흔적으로 알려져 있습니다.
| 조합 | 16진수 | 흔히 불리는 이름 | 해석 |
|---|---|---|---|
| Flag 없음 | 0x00 | NULL | 정상 TCP에는 없음 → 스캔·조작 패킷 가능성 |
| FIN만 (ACK 없음) | 0x01 | FIN 스캔 | 연결이 없는데 종료 신호 |
| FIN+PSH+URG | 0x29 | Xmas 스캔 | 여러 비트를 "켜 둔" 조작 패킷 |
| SYN+FIN | 0x03 | — | 시작과 종료 동시. 필터 우회·OS 식별 시도 가능성 |
| SYN+RST | 0x06 | — | 정상 흐름에 없음 |
| ACK만 (연결 없음) | 0x10 | ACK 스캔 | 방화벽이 상태 기반인지 확인하려는 시도일 수 있음 |
이러한 스캔 기법별 흔적은 05. 네트워크 스캔 징후 분석 영역(219. Null Scan, 220. XMAS Scan, 221. FIN Scan, 222. ACK Scan)에서 다룹니다.
같은 Flag를 도구마다 다르게 표기하므로, 로그를 오갈 때 변환할 수 있어야 합니다. 아래 표기는 형식 예시(값은 환경마다 다름)입니다.
| 도구 | SYN+ACK 표기 예 | 비고 |
|---|---|---|
| tcpdump | Flags [S.] | .이 ACK. S SYN, F FIN, R RST, P PSH, U URG, E ECE, W CWR |
| Wireshark Info 열 | [SYN, ACK] | 필터는 tcp.flags == 0x012 (예약 비트까지 3자리로 표시) |
| Snort·Suricata 룰 | flags:SA; | 룰 키워드. 추가 비트 허용 여부를 수식어로 지정 |
| 플로우 로그(Suricata flow 등) | "tcp_flags": "12" 형태 | 세션 전체 Flag를 OR로 누적한 값인 경우가 많음 |
실습 예시 — 본인 소유 Linux VM(Rocky/Ubuntu 공통)에서 Flag 조건으로 캡처합니다. 인터페이스 ens33은 예시입니다.
# SYN만 켜진 패킷 (ACK 없음) = 연결 요청
sudo tcpdump -nn -i ens33 'tcp[tcpflags] == tcp-syn'
# Flag 바이트 값으로 직접 비교: PSH+ACK(0x18)
sudo tcpdump -nn -i ens33 'tcp[13] == 0x18'
# 비정상 조합 감시: NULL(0x00) 또는 SYN+FIN이 함께 켜진 패킷
sudo tcpdump -nn -i ens33 'tcp[13] == 0 or tcp[13] & 0x03 == 0x03'
tcpdump 출력 형식 예시:
IP 192.168.10.10.51000 > 192.168.10.20.80: Flags [S], seq 1000, win 64240, length 0
IP 192.168.10.20.80 > 192.168.10.10.51000: Flags [S.], seq 5000, ack 1001, win 65160, length 0
IP 192.168.10.10.51000 > 192.168.10.20.80: Flags [P.], seq 1:78, ack 1, win 502, length 77
IP 192.168.10.10.51000 > 192.168.10.20.80: Flags [F.], seq 78, ack 300, win 501, length 0
플로우 로그의 누적 Flag는 세션 요약에 유용합니다. 예를 들어 누적값이 0x02(SYN만)이면 응답 없는 시도, 0x1b(FIN+SYN+PSH+ACK)이면 데이터가 오간 뒤 정상 종료된 세션일 가능성이 큽니다. Wireshark에서 Flag를 필드 단위로 분석하는 방법은 03. Wireshark 패킷 분석 영역 128. TCP Flag 분석에서 다룹니다.
| 흔적 위치 | 확인할 수 있는 것 |
|---|---|
| 패킷 캡처 | 패킷별 Flag 바이트, 조합의 정상 여부 |
| IDS/IPS | flags 조건 시그니처(NULL·Xmas·SYN+FIN 등), 스트림 이상 이벤트 |
| 방화벽 로그 | 상태 불일치(invalid, out-of-state) 차단 이벤트 — 명칭은 장비마다 다름 |
| 플로우 로그 | 세션 누적 Flag로 성립·종료 방식 요약 |
관제자가 확인할 질문
오탐 주의: ECN 협상(SYN+ECE+CWR)은 정상입니다. 세션 타임아웃 이후 늦게 도착한 ACK·FIN, 비대칭 경로로 한쪽 방향만 보이는 센서 위치에서는 정상 트래픽도 "연결 없는 ACK"나 out-of-state로 기록될 수 있습니다. 조합 하나보다 반복 패턴으로 판단합니다.
[S.]), Wireshark(0x012), IDS 룰(flags:SA), 플로우 로그(누적 16진수) 표기를 서로 변환할 수 있어야 합니다.