📚 네트워크 · 패킷 분석 › 05. 네트워크 스캔 징후 분석 — 222편
이전 글: 221. FIN Scan · 다음 글: 223. Sequential Scan
ACK Scan 은 연결 없이 ACK 플래그만 설정한 패킷을 여러 포트로 보내는 스캔입니다. 다른 TCP 스캔과 목적이 다릅니다. 열린 포트를 찾는 것이 아니라, 중간에 있는 방화벽이 그 포트를 필터링하는지, 상태 추적을 하는지를 알아내는 데 쓰입니다.
그래서 ACK Scan의 흔적은 "우리 방화벽 정책이 외부에서 어떻게 보이는지 조사당했다"는 의미로 해석합니다. TCP 스캔 유형 비교는 216. TCP Port Scan 특징에서 다뤘습니다.
| 대상 반응 | 스캐너의 판단 | 방어 측 의미 |
|---|---|---|
| RST 수신 | unfiltered (패킷이 호스트까지 도달) | 이 경로에 상태 추적 차단이 없음 |
| 무응답 또는 ICMP Unreachable | filtered | 방화벽이 세션 없는 ACK를 차단 |
RFC 793에 따르면 호스트는 연결이 없는 상태에서 ACK가 설정된 세그먼트를 받으면, 포트가 열려 있든 닫혀 있든 RST로 응답합니다. 그래서 ACK Scan으로는 열림·닫힘을 구분할 수 없고, RST가 돌아오는지(도달했는지) 만 알 수 있습니다.
스캐너 ── ACK (세션 없음) ──→ [방화벽] ──→ [대상 호스트]
│
┌─ 상태 추적 방화벽: 세션 테이블에 없음 → 차단(INVALID·세션 없음 로그)
│ → 스캐너: 무응답 = filtered
└─ 상태 비저장 필터: "ACK 있으면 응답 패킷으로 간주" 규칙이면 통과
↓
대상: 열림·닫힘 관계없이 RST 응답
→ 스캐너: RST = unfiltered
↓
방어 측 흔적: 세션 없는 ACK 차단 로그 다수 / 통과 시 대상의 RST 다수
상태 비저장 필터에서 "ACK가 설정된 인바운드는 응답이므로 허용"하는 규칙은 흔한 설계였고, ACK Scan은 이런 규칙이 남아 있는지를 드러냅니다.
"세션 없는 ACK 차단" 로그는 스캔 외 원인이 많으므로 구분이 핵심입니다.
| 원인 | 모양 | 구분 기준 |
|---|---|---|
| ACK Scan | 한 출발지 → 여러 포트, 1회씩, 데이터 없음 | 포트 다양성, 과거 세션 없음 |
| 세션 타임아웃 | 한 포트, 기존 세션의 연속 | 방화벽 세션 로그에 같은 4-tuple 존재 |
| 비대칭 라우팅 | 특정 경로 트래픽이 지속적으로 차단 | 정상 서비스 포트, 양방향 경로 불일치 |
| 백스캐터 | 우리 주소를 위조한 공격의 응답(SYN/ACK·RST) | SYN/ACK·RST 섞임, 다수 출발지의 서비스 포트에서 옴 |
실습 예시 — 본인 소유 실습망에서 데이터 없는 순수 ACK 패킷을 확인하는 방어 측 명령입니다(Rocky/Ubuntu 공통, 값은 환경마다 다름).
# ACK만 설정된 패킷(SYN·FIN·RST·PSH 없음)
sudo tcpdump -nn -i ens33 'tcp[13] == 0x10'
# 캡처 파일에서 데이터 없는 ACK의 출발지별 목적지 포트 수
tshark -r /tmp/ack.pcapng -Y 'tcp.flags == 0x010 && tcp.len == 0' \
-T fields -e ip.src -e tcp.dstport | sort -u \
| awk '{c[$1]++} END {for (s in c) print c[s], s}' | sort -rn | head
정상 연결에도 데이터 없는 ACK는 매우 많으므로, 위 결과는 목적지 포트 수로 판단합니다. 정상 클라이언트는 쓰는 서비스 포트 몇 개에 몰리고, ACK Scan은 수십~수천 개 포트로 퍼집니다.
방화벽 로그 형식 예시(값은 환경마다 다름, 일부 필드 생략):
kernel: FW-INVALID SRC=203.0.113.45 DST=192.168.10.20 PROTO=TCP SPT=37211 DPT=25 WINDOW=1024 ACK URGP=0
kernel: FW-INVALID SRC=203.0.113.45 DST=192.168.10.20 PROTO=TCP SPT=37211 DPT=53 WINDOW=1024 ACK URGP=0
kernel: FW-INVALID SRC=203.0.113.45 DST=192.168.10.20 PROTO=TCP SPT=37211 DPT=110 WINDOW=1024 ACK URGP=0
| 관찰 | 해석 |
|---|---|
| ACK 단독, DPT만 변화 | 세션 없는 ACK로 포트별 필터링 확인 |
| 모두 INVALID 차단 | 상태 추적 차단이 동작 → 상대 판단은 filtered |
| 대상의 RST가 캡처된다면 | 차단 없이 도달한 구간 → 정책 점검 대상 |
| 흔적 위치 | 확인 내용 |
|---|---|
| 방화벽 | 세션 없는 ACK(INVALID) 차단, 목적지 포트 분포 |
| 방화벽 세션 로그 | 같은 4-tuple의 과거 세션 여부(타임아웃 구분) |
| 패킷 캡처 | 데이터 없는 순수 ACK, 대상의 RST |
| IDS | ACK 스캔·세션 없는 패킷 관련 Alert |
관제자가 확인할 질문
오탐 주의: 세션 타임아웃, 비대칭 라우팅, 방화벽 재시작 직후의 기존 연결 트래픽이 대량의 세션 없는 ACK 로그를 만듭니다. 위 표의 구분 기준을 먼저 적용하고, 포트가 하나이거나 과거 세션이 있으면 스캔으로 올리지 않습니다.