📚 네트워크 · 패킷 분석 › 03. Wireshark 패킷 분석 — 139편
이전 글: 138. HTTPS Traffic 이해 · 다음 글: 140. SSH Traffic 이해

1. 개념

FTP가 제어 연결(TCP 21)과 데이터 연결을 나누는 구조, Active·Passive 모드의 방향, 서버 로그(vsftpd)로 추적하는 방법은 63. FTP Active·Passive 모드와 보안에서 다뤘습니다. 이 글은 Wireshark 화면에서 FTP 세션 하나를 처음부터 끝까지 읽는 방법만 다룹니다.

구분Wireshark 프로토콜 이름담기는 내용
제어 연결ftp명령(USER, PASS, PASV, RETR 등)과 3자리 응답 코드, 평문
데이터 연결ftp-data파일 내용, 디렉터리 목록(LIST 결과)
암호화 제어 연결ftp 이후 tlsAUTH TLS 이후 명령이 보이지 않음 (FTPS, RFC 4217)

2. 동작 원리

Wireshark는 제어 연결에서 본 227(PASV) 또는 PORT 명령의 주소·포트를 기억했다가, 그 주소·포트로 생기는 TCP 연결을 ftp-data로 해석합니다.

[제어 연결 tcp.stream 0 : 192.168.10.20:51000 → 192.168.10.30:21]
  220 Service ready
  USER alice          → 331 Password required
  PASS ********       → 230 Login successful
  PASV                → 227 Entering Passive Mode (192,168,10,30,156,65)
        ↓  포트 = 156 × 256 + 65 = 40001
[데이터 연결 tcp.stream 1 : 192.168.10.20:51002 → 192.168.10.30:40001]  ← ftp-data
  RETR report.txt     → 150 Opening data connection
        ↓  (stream 1에서 파일 내용 전송 후 종료)
                      → 226 Transfer complete
  QUIT                → 221 Goodbye
  • 제어 연결이 캡처에 없으면(캡처를 중간부터 시작한 경우 등) Wireshark는 데이터 연결을 ftp-data로 알아보지 못하고 일반 TCP로 표시합니다. 이때는 Decode As로 직접 지정해야 합니다.
  • IPv6나 NAT 환경에서는 확장 명령 EPSV(응답 229), EPRT(RFC 2428)가 쓰이며, 이 경우 응답에 IP 없이 포트만 들어갑니다.

3. 주요 특징

자주 쓰는 FTP 필드 (버전에 따라 이름이 다를 수 있으므로 Details에서 우클릭 → Copy → Field Name으로 확인)

필드의미필터 예
ftp.request.command클라이언트 명령ftp.request.command == "RETR"
ftp.request.arg명령 인자 (계정명, 파일명 등)ftp.request.arg contains ".php"
ftp.response.code서버 응답 코드ftp.response.code == 530
ftp.passive.ip / ftp.passive.port227 응답에 담긴 데이터 주소·포트ftp.passive.port
ftp.active.cip / ftp.active.portPORT 명령에 담긴 주소·포트ftp.active.cip != ip.src
ftp-data.command이 데이터 연결을 만든 명령 (Wireshark가 연결)ftp-data.command contains "STOR"

세션 재구성에 쓰는 응답 코드 (RFC 959)

코드의미분석에서의 역할
220 / 221서비스 준비 / 종료세션 시작·끝 표시, 220 배너에 서버 소프트웨어가 보이기도 함
331 → 230비밀번호 요구 → 로그인 성공인증 성공 시점
530로그인 실패실패 횟수 집계 대상
227 / 229Passive / Extended Passive 진입데이터 연결 포트 확인
150 → 226데이터 연결 열림 → 전송 완료파일 전송 1건의 시작·끝
425 / 550데이터 연결 실패 / 파일 없음·권한 없음실패한 시도 식별

4. 예시

실습 예시 — 본인 소유 실습망의 FTP 서버에 접속하는 트래픽을 캡처해 분석합니다. 명령과 출력은 예시(값은 환경마다 다름)입니다. 서버 설치는 63. FTP Active·Passive 모드와 보안의 Rocky/Ubuntu 절차를 따릅니다.

# 캡처 (Rocky/Ubuntu 공통, 제어+데이터 연결을 모두 담기 위해 호스트 기준 필터)
sudo tcpdump -i ens33 -nn -w /tmp/ftp.pcapng 'host 192.168.10.30'

# 1) 제어 연결의 명령·응답 흐름을 시간순으로
tshark -r /tmp/ftp.pcapng -Y 'ftp' -T fields -E header=y \
  -e frame.number -e tcp.stream -e ftp.request.command -e ftp.request.arg \
  -e ftp.response.code -e ftp.response.arg

# 2) 데이터 연결과 그 연결을 만든 명령
tshark -r /tmp/ftp.pcapng -Y 'ftp-data' -T fields \
  -e tcp.stream -e tcp.dstport -e ftp-data.command | sort -u

# 3) 데이터 연결에서 전송된 파일을 추출 (Wireshark GUI와 같은 기능)
mkdir -p /tmp/ftp_obj
tshark -r /tmp/ftp.pcapng --export-objects ftp-data,/tmp/ftp_obj
sha256sum /tmp/ftp_obj/*

1)번 결과의 형식 예시입니다.

frame.number  tcp.stream  ftp.request.command  ftp.request.arg  ftp.response.code  ftp.response.arg
4             0                                                  220                (vsFTPd x.x.x)
6             0           USER                 alice
8             0                                                  331                Please specify the password.
10            0           PASS                 (평문 비밀번호)
12            0                                                  230                Login successful.
14            0           PASV
15            0                                                  227                Entering Passive Mode (192,168,10,30,156,65).
17            0           RETR                 report.txt

GUI에서는 Tools → Credentials(최신 버전) 메뉴가 FTP의 USER/PASS를 목록으로 보여 주고, File → Export Objects → FTP-DATA가 전송된 파일을 보여 줍니다. 제어 연결은 Follow TCP Stream으로 대화처럼 읽을 수 있습니다(134. Follow TCP Stream).

📷 [실습 화면 삽입 위치] 필터 ftp에 ftp.request.command, ftp.response.code 열을 추가해 로그인부터 226까지 흐름이 보이는 Packet List

📷 [실습 화면 삽입 위치] File → Export Objects → FTP-DATA 창에 전송 파일 이름과 크기가 표시된 화면


5. 보안 관점

패킷에서 보이는 것정상일 수 있는 경우추가 확인이 필요한 경우
PASS 인자가 평문으로 보임레거시 내부 시스템외부 구간을 지나는 평문 FTP (계정 노출)
짧은 시간 530 반복비밀번호 오입력 몇 회다수 계정·다수 시도 (무차별 대입, 05 영역에서 다룸)
STOR 명령 + 웹 스크립트 확장자콘텐츠 배포FTP 루트가 웹 루트와 같은 서버에 스크립트 업로드
ftp.active.cip가 제어 연결 출발지와 다름NAT 설정 오류제3의 주소를 지정하는 FTP Bounce 형태
내부 → 외부 STOR 대용량승인된 파일 교환미승인 목적지로 업로드 (유출 의심, 147. 외부 비정상 통신 분석)

평문 FTP 캡처는 계정 정보를 그대로 담고 있으므로 pcap 자체를 민감 자료로 다루고, 보관·공유 시 148. pcap 증거 보존과 해시 검증의 증거 관리 절차를 따릅니다.


6. SOC 관점

흔적 위치확인할 수 있는 것
패킷 캡처명령·응답 전체, 계정명, 전송 파일 이름과 내용
FTP 서버 로그로그인 성공·실패, 업로드·다운로드 파일 (서버 기준)
방화벽 로그21번과 데이터 포트 범위 허용·차단, 세션 바이트
IDS/IPS평문 로그인, 로그인 실패 반복, 의심 파일 전송 이벤트

관제자가 확인할 질문

  • 230 로그인 성공 이후 어떤 명령(RETR, STOR, DELE, LIST)이 이어졌는가?
  • 150과 226 사이의 데이터 연결에서 실제로 전송된 바이트는 얼마인가?
  • 서버 로그의 전송 기록과 패킷의 ftp-data 연결 수가 일치하는가?

오탐 주의: 데이터 연결이 FTP로 해석되지 않는다고 "FTP 없이 이상한 포트로 대량 전송"으로 판단하면 안 됩니다. 캡처 시작 시점과 제어 연결 존재 여부를 먼저 확인합니다. FTPS는 AUTH TLS 이후 명령이 보이지 않는 것이 정상입니다.


7. 핵심 정리

  • Wireshark에서 FTP는 제어 연결 ftp와 데이터 연결 ftp-data로 나뉘어 보입니다.
  • 227/229 응답이나 PORT 명령의 주소·포트를 근거로 Wireshark가 데이터 연결을 ftp-data로 연결하므로, 제어 연결이 캡처에 있어야 합니다.
  • ftp.request.command와 ftp.response.code만으로 로그인(331→230/530)과 파일 전송(150→226) 흐름을 재구성할 수 있습니다.
  • Export Objects → FTP-DATA와 Tools → Credentials로 전송 파일과 평문 계정을 확인하되, 결과물은 민감 자료로 관리합니다.
  • 캡처를 중간부터 시작한 경우와 FTPS는 정상적으로도 명령이 보이지 않을 수 있음을 먼저 고려합니다.
profile
코드에 숨겨진 위협을 읽고 AI로 보안의 미래를 설계합니다. 프론트엔드 개발 경험을 자산 삼아 더 견고하고 지능적인 보안 운영 시스템을 구축해 나가는 과정을 기록합니다

0개의 댓글