📚 네트워크 · 패킷 분석 › 03. Wireshark 패킷 분석 — 110편
이전 글: 109. Statistics로 전체 흐름 파악 — Conversations·Endpoints·Protocol Hierarchy · 다음 글: 111. Endpoints
Conversation은 두 지점 사이에 오간 트래픽의 묶음입니다. 통계 메뉴 전체의 흐름과 Conversation·Endpoint의 차이는 109. Statistics로 전체 흐름 파악 — Conversations·Endpoints·Protocol Hierarchy에서 다뤘으므로, 이 글은 Conversations 창 하나를 열 단위로 읽고 판단하는 방법에 집중합니다.
탭마다 "두 지점"의 기준이 다릅니다.
| 탭 | 대화를 구분하는 기준 | 답하는 질문 |
|---|---|---|
| Ethernet | MAC 주소 쌍 | 같은 LAN에서 어떤 장비끼리 주고받았나 |
| IPv4 / IPv6 | IP 주소 쌍 | 어떤 호스트끼리 통신했나 (포트 무관) |
| TCP | IP + 포트 쌍 (연결 단위) | 어떤 연결이 크고 오래 지속됐나 |
| UDP | IP + 포트 쌍 | 어떤 UDP 흐름이 있었나 (DNS, NTP, QUIC 등) |
Wireshark는 파일 전체(또는 필터 결과)를 읽으며 대화 표를 누적합니다.
패킷 1개 읽기
↓ 탭 기준 키 생성 (예: TCP → IP A, 포트 A, IP B, 포트 B)
기존 대화에 있음? ── 예 → 방향(A→B / B→A)별 패킷·바이트 누적, 마지막 시각 갱신
│ 아니오
↓
새 대화 생성 (처음 본 시각 = Rel Start)
↓
Duration = 마지막 패킷 시각 − 첫 패킷 시각
Bits/s = 방향별 바이트 × 8 ÷ Duration
A와 B는 서버·클라이언트를 뜻하지 않습니다. 어느 주소가 A가 되는지는 구현에 따라 정해지므로, 누가 연결을 시작했는지는 반드시 첫 SYN(tcp.flags == 0x002)이나 포트(임시 포트 쪽이 클라이언트)로 확인합니다.
주요 열과 읽는 법입니다(버전에 따라 Stream ID 등 열이 추가될 수 있음).
| 열 | 의미 | 분석 포인트 |
|---|---|---|
| Address A / Port A, Address B / Port B | 대화 양 끝 | 서비스 포트가 어느 쪽인지로 방향 추정 |
| Packets, Bytes | 양방향 합계 | 상위 대화 선별 |
| Packets A → B, Bytes A → B | A가 보낸 양 | 업로드·다운로드 비율 계산 |
| Packets B → A, Bytes B → A | B가 보낸 양 | 응답이 없는(0) 대화 찾기 |
| Rel Start | 캡처 시작 기준 첫 패킷 시각 | 다른 이벤트와 순서 대조 |
| Duration | 대화 지속 시간 | 짧고 많음 / 길고 적음 구분 |
| Bits/s A → B, B → A | 평균 전송 속도 | 순간 폭증은 I/O Graph로 따로 확인 |
창 아래 옵션도 판단에 영향을 줍니다.
| 옵션 | 켰을 때 |
|---|---|
| Limit to display filter | 현재 Display Filter 결과만 집계 |
| Absolute start time | Rel Start 대신 실제 시각 표시 (다른 로그와 대조할 때) |
| Name resolution | 주소를 이름으로 표시 (분석 시에는 끄는 편이 안전, 104. Wireshark 화면 구조와 필드 읽는 법) |
대화 행을 오른쪽 클릭하면 Apply as Filter → Selected → A ↔ B로 해당 대화만 필터링하거나, TCP 탭에서 바로 Follow Stream으로 넘어갈 수 있습니다.
실습 예시 — tshark로 같은 표를 만듭니다(Rocky/Ubuntu 공통, 설치는 102. Wireshark 설치와 실행).
F=/tmp/lab.pcapng
tshark -r $F -q -z conv,tcp
tshark -r $F -q -z conv,udp
tshark -r $F -q -z 'conv,ip,ip.addr == 192.168.10.20' # 필터를 붙인 집계
-z conv,tcp 출력의 형식 예시(값은 환경마다 다름, 열 일부 생략)입니다. 방향 화살표 기준은 왼쪽 주소입니다.
| <- | | -> | | Total | Relative | Duration
|Frames Bytes|Frames Bytes|Frames Bytes| Start |
192.168.10.20:51544 <-> 203.0.113.50:443 950 1.3 MB 420 28 kB 1370 1.3 MB 12.40 85.2
192.168.10.20:51602 <-> 198.51.100.7:8443 60 6 kB 60 9 kB 120 15 kB 3.10 3590.0
192.168.10.20:40110 <-> 192.168.10.30:22 1 60 B 1 74 B 2 134 B 40.02 0.0
| 줄 | 읽는 법 |
|---|---|
| 1번째 | 443으로 받은 양이 보낸 양보다 훨씬 큼 → 일반적인 다운로드 형태 |
| 2번째 | 1시간 가까이 적은 양을 주고받음 → 주기 통신(업데이트 확인, 원격 관리 또는 비콘) 여부 확인 대상 |
| 3번째 | 패킷 2개, 지속 0초 → SYN 후 즉시 RST 같은 수립 실패 연결 |
연결 단위로 직접 집계하고 싶다면 tcp.stream을 키로 필드를 추출합니다.
# 스트림별 연결 시작 방향 (첫 SYN의 출발지 = 클라이언트)
tshark -r $F -Y 'tcp.flags == 0x002' -T fields \
-e tcp.stream -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport > /tmp/syn.tsv
# 스트림·출발지별 전송 바이트 합계
tshark -r $F -Y tcp -T fields -e tcp.stream -e ip.src -e frame.len \
| awk '{b[$1" "$2]+=$3} END {for (k in b) print k, b[k]}' | sort -n | head
📷 [실습 화면 삽입 위치] Statistics → Conversations의 TCP 탭을 Duration 기준으로 정렬하고 Absolute start time을 켠 화면
📷 [실습 화면 삽입 위치] 대화 행을 오른쪽 클릭해 Apply as Filter → A ↔ B를 선택하는 메뉴
대화의 모양으로 추가 확인이 필요한 형태를 고를 수 있습니다. 모양만으로 악성 여부를 확정할 수는 없습니다.
| 대화 모양 | 가능한 해석 | 다음 확인 |
|---|---|---|
| 내부 → 외부, 보낸 바이트가 받은 바이트보다 매우 큼 | 백업·파일 업로드, 또는 데이터 유출 | 목적지 평판, 업무 시간, 프로세스(EDR) |
| 긴 Duration, 적은 바이트, 일정한 패킷 간격 | 모니터링·업데이트, 또는 C2 비콘 | 간격 규칙성, SNI·도메인 |
| 한 출발지 → 한 목적지, 포트만 다른 짧은 대화 다수 | 포트 스캔 | 05. 네트워크 스캔 징후 분석 영역 |
| 한 출발지 → 많은 목적지, 같은 포트 | 호스트 탐색, 웜형 확산 | 대상 대역, 성공(응답) 비율 |
| UDP 53 대화의 목적지가 사내 DNS가 아님 | 설정 오류, 또는 DNS 정책 우회 | 144. DNS 악용 유형 — 터널링·DGA·비정상 질의 탐지 |
| 흔적 위치 | Conversations와 대조할 것 |
|---|---|
| 방화벽 세션 로그 | 세션 시작·종료 시각, 송수신 바이트 (NAT 전후 주소 차이 주의) |
| NetFlow·IPFIX | 같은 5-tuple의 바이트·패킷 수 (샘플링 여부 확인) |
| 프록시 로그 | 업로드 크기, 목적지 도메인 |
| EDR | 해당 시각에 연결을 만든 프로세스 |
관제자가 확인할 질문
오탐 주의: 캡처 시작 전에 열린 연결은 Rel Start가 0 근처에 몰리고 Duration이 실제보다 짧게 보입니다. 또 NAT 뒤에서 캡처했다면 여러 내부 호스트가 한 주소로 합쳐져 보입니다. 캡처 지점과 기간을 먼저 확인합니다.
tshark -q -z conv,tcp / conv,udp / conv,ip,<필터>와 tcp.stream 기반 필드 추출로 같은 분석을 CLI에서 합니다.