📚 네트워크 · 패킷 분석 › 03. Wireshark 패킷 분석 — 125편
이전 글: 124. SYN/ACK Packet 분석 · 다음 글: 126. FIN Packet 분석

1. 개념

TCP 연결이 성립한 뒤에는 첫 SYN을 제외한 거의 모든 패킷에 ACK 비트가 켜져 있습니다. 그래서 "ACK 패킷"은 한 종류가 아니라, ACK 비트 외에 어떤 조건이 붙었는지로 역할이 나뉩니다. 이 글은 ACK 비트가 켜진 패킷을 Wireshark에서 역할별로 구분하는 방법을 다룹니다. ACK 번호 값의 계산과 검증은 130. ACK Number 분석, 중복 ACK는 132. Duplicate ACK에서 자세히 봅니다.

역할구분 조건Wireshark 표시
Handshake 세 번째 ACKSYN/ACK 직후, tcp.len == 0, 상대 seq 1·ack 1[ACK]
순수 ACK (수신 확인만)tcp.flags == 0x010 && tcp.len == 0[ACK]
데이터 동반 ACKtcp.len > 0 (흔히 PSH 포함 0x018)[PSH, ACK] 또는 [ACK] + 데이터
FIN 확인 ACK상대 FIN 직후, ack = FIN seq + 1[ACK]
Keep-Aliveseq가 다음 seq보다 1 작고 len 0 또는 1[TCP Keep-Alive]
Keep-Alive 응답Keep-Alive에 대한 ACK[TCP Keep-Alive ACK]
Window Update데이터 없이 Window 값만 바뀜[TCP Window Update]
중복 ACK같은 ack 번호 반복[TCP Dup ACK N#M]

2. 동작 원리

Wireshark가 ACK 패킷에 분석 정보를 붙이는 과정입니다.

ACK 비트가 켜진 패킷 도착
   ↓
tcp.ack가 가리키는 바이트까지 확인된 상대 세그먼트 찾기
   ↓ 찾으면
[This is an ACK to the segment in frame: N]   → tcp.analysis.acks_frame
[The RTT to ACK the segment was: 0.0402 s]   → tcp.analysis.ack_rtt
   ↓ 이전 상태와 비교
len 0이고 ack·window 같음      → Dup ACK
len 0이고 window만 커짐        → Window Update
seq = 다음 seq − 1 (len 0/1)   → Keep-Alive
   ↓
해당 없으면 일반 ACK
  • tcp.analysis.ack_rtt는 데이터를 보낸 쪽에서 본 왕복 시간입니다. 수신 측의 지연 ACK(Delayed ACK) 때문에 순수 ACK는 데이터 도착 후 수십~수백 ms 늦게 나갈 수 있습니다(대기 시간은 OS마다 다름).
  • 순수 ACK는 데이터가 없으므로 tcp.seq가 증가하지 않습니다. 같은 seq의 ACK가 이어지는 것은 정상입니다.

3. 주요 특징

ACK 관련 필터 모음

목적Display Filter
순수 ACKtcp.flags == 0x010 && tcp.len == 0
데이터가 실린 패킷tcp.len > 0
Keep-Alive와 응답tcp.analysis.keep_alive or tcp.analysis.keep_alive_ack
Window Updatetcp.analysis.window_update
ACK 왕복 시간이 큰 것tcp.analysis.ack_rtt > 0.2
캡처가 보지 못한 데이터를 확인한 ACKtcp.analysis.ack_lost_segment

연결 상태와 맞지 않는 ACK

보이는 모습해석비고
SYN 없이 ACK만, 대상이 RST 응답대상에 연결이 없음 → ACK 스캔 또는 오래된 세션222편
ACK만, 대상 응답 없음상태 기반 방화벽이 버림방화벽의 invalid 차단 로그
[TCP ACKed unseen segment]ACK가 가리키는 데이터를 캡처가 보지 못함캡처 누락·비대칭 경로
매우 짧은 간격의 ACK 반복ACK storm, 양쪽 seq 불일치중간 장비의 세션 동기화 문제

4. 예시

실습 예시 — 본인 VM에서 파일을 내려받으며 ACK 종류를 분류합니다. 명령과 출력은 예시(값은 환경마다 다름)입니다.

# 서버(192.168.10.30): 테스트 파일과 간이 웹 서버 (실습 후 종료)
head -c 5M /dev/urandom > /tmp/test.bin && cd /tmp && python3 -m http.server 8080

# 클라이언트: 캡처 후 다운로드
sudo tshark -i ens33 -f "tcp port 8080" -w /tmp/ack.pcapng &
curl -s -o /dev/null http://192.168.10.30:8080/test.bin
sudo pkill -INT tshark

# ACK 비트 패킷을 역할별로 집계
tshark -r /tmp/ack.pcapng -Y 'tcp.flags.ack == 1' -T fields -e tcp.len -e _ws.col.Info \
  | awk '{ if ($0 ~ /Keep-Alive/) k="keepalive"; else if ($0 ~ /Window Update/) k="win_update";
          else if ($0 ~ /Dup ACK/) k="dup_ack"; else if ($1 > 0) k="data"; else k="pure_ack";
          c[k]++ } END {for (k in c) print k, c[k]}'

# 순수 ACK가 확인한 프레임과 RTT
tshark -r /tmp/ack.pcapng -Y 'tcp.flags == 0x010 && tcp.len == 0' -T fields -E header=y \
  -e frame.number -e ip.src -e tcp.ack -e tcp.analysis.acks_frame -e tcp.analysis.ack_rtt | head

firewalld(Rocky)나 ufw(Ubuntu)가 켜져 있다면 8080/tcp를 실습 동안만 허용하고 끝나면 제거합니다. 집계 결과 형식 예시입니다.

data        3620
pure_ack    1790
win_update  3
확인 포인트읽는 법
data가 pure_ack의 약 2배수신 측이 세그먼트 두 개마다 ACK 하나를 보내는 일반적 패턴
pure_ack의 출발지가 거의 클라이언트다운로드 방향의 반대로 ACK가 흐름
Window Update 소수수신 버퍼 여유가 생겨 알린 것, 정상

📷 [실습 화면 삽입 위치] 순수 ACK 패킷 Details의 [SEQ/ACK analysis]에서 [This is an ACK to the segment in frame]과 [The RTT to ACK the segment was]가 보이는 화면


5. 보안 관점

관찰가능한 해석확인할 것
한 출발지가 여러 포트로 ACK만 전송, 대상은 RSTACK 스캔으로 방화벽 상태 확인 시도응답 유무를 포트별로 정리
긴 연결에서 데이터 없이 Keep-Alive만 주기적으로유휴 세션 유지, 원격 접속 도구 가능성목적지, 주기, 세션 시작 시점
데이터 없는 ACK 대량 유입ACK Flood 가능성pps, 출발지 수
ACK의 ack 번호가 상대가 보낸 적 없는 범위조작 패킷, 세션 하이재킹 시도 가능성[TCP ACKed unseen segment], 캡처 누락 여부

6. SOC 관점

흔적 위치확인할 수 있는 것
패킷 캡처ACK 역할, acks_frame·ack_rtt, 비정상 표시
방화벽 로그세션 없는 ACK 차단(invalid, out-of-state 등 장비별 명칭)
IDS/IPSACK 스캔, 스트림 이상 이벤트
NetFlow패킷 수 대비 바이트가 매우 작은 흐름

관제자가 확인할 질문

  • 이 ACK는 성립된 연결에 속하는가(같은 tcp.stream에 SYN이 있는가)?
  • 연결 없는 ACK였다면 대상은 RST로 응답했는가, 무응답이었는가?
  • 데이터 없이 유지되는 연결이 서비스 특성상 정상인가?

오탐 주의: 캡처 시작 전에 열린 연결은 SYN 없이 ACK부터 보입니다. 또 [TCP ACKed unseen segment]는 대부분 캡처 누락 때문이므로 공격 판단 전에 센서의 드롭 통계를 확인합니다.


7. 핵심 정리

  • 연결 성립 후 거의 모든 패킷에 ACK 비트가 켜지므로, ACK 패킷은 데이터 유무·Wireshark 분석 표시로 역할을 나눕니다.
  • 순수 ACK는 tcp.flags == 0x010 && tcp.len == 0, 데이터 동반은 tcp.len > 0으로 구분합니다.
  • tcp.analysis.acks_frame과 ack_rtt로 어떤 세그먼트를 얼마 만에 확인했는지 봅니다.
  • Keep-Alive·Window Update·Dup ACK는 Wireshark가 붙인 표시로 구분하며 대부분 정상 동작입니다.
  • SYN 없는 스트림의 ACK와 그에 대한 RST 응답은 ACK 스캔의 단서이지만, 캡처 시작 시점부터 확인합니다.
profile
코드에 숨겨진 위협을 읽고 AI로 보안의 미래를 설계합니다. 프론트엔드 개발 경험을 자산 삼아 더 견고하고 지능적인 보안 운영 시스템을 구축해 나가는 과정을 기록합니다

0개의 댓글