멀웨어 네트워크 트래픽 분석은(는) 무엇을 하나요?
사용 시점
- 샌드박스 실행으로 PCAP 파일이 생성되었고 네트워크 행동에 대한 상세 분석이 필요한 경우
- 네트워크 탐지 시그니처 작성을 위해 C2 프로토콜 구조를 식별해야 하는 경우
- 멀웨어가 어떤 데이터를 어떤 외부 인프라로 유출하는지 확인해야 하는 경우
- DNS 터널링, DGA(도메인 생성 알고리즘), 패스트플럭스 행동을 분석해야 하는 경우
- 관찰된 멀웨어 네트워크 패턴을 기반으로 Suricata/Snort 시그니처를 생성해야 하는 경우
사용하지 말아야 할 경우: 멀웨어 행동의 호스트 기반 분석; 프로세스 수준 활동 분석에는 Cuckoo 샌드박스 보고서 또는 Volatility 메모리 분석 사용.
사전 요구 사항
- Wireshark 4.x 설치 (대화형 PCAP 분석)
- tshark (Wireshark CLI) (스크립트 기반 패킷 추출)
- Zeek 설치 (PCAP에서 메타데이터 자동 생성)
- Suricata + ET Open/ET Pro 규칙셋 (시그니처 매칭)
- NetworkMiner (파일 추출 및 PCAP에서 자격 증명 탐지)
- Python 3.8+ 및
scapy,dpkt라이브러리 (프로그래밍 방식 패킷 분석)
워크플로우
Step 1: 초기 PCAP 개요
네트워크 트래픽에 대한 개괄적인 이해:
# 캡처 통계
capinfos malware.pcap
# 프로토콜 계층 구조
tshark -r malware.pcap -q -z io,phs
# 엔드포인트 통계 (주요 통신자)
tshark -r malware.pcap -q -z endpoints,ip
# 세션 통계
tshark -r malware.pcap -q -z conv,tcp
# DNS 질의 요약
tshark -r malware.pcap -q -z dns,tree
Step 2: DNS 활동 분석
DGA, 터널링 또는 C2 도메인 확인을 위한 DNS 질의 검사:
# 모든 DNS 질의 추출
tshark -r malware.pcap -T fields -e frame.time -e dns.qry.name -e dns.a \
-Y "dns.flags.response == 1" | sort
# DGA 패턴 감지 (엔트로피가 높은 도메인 이름)
python3 << 'PYEOF'
import math
from collections import Counter
def entropy(s):
p = [n/len(s) for n in Counter(s).values()]
return -sum(pi * math.log2(pi) for pi in p if pi > 0)
# tshark 출력에서 DNS 질의 파싱
import subprocess
result = subprocess.run(
["tshark", "-r", "malware.pcap", "-T", "fields", "-e", "dns.qry.name",
"-Y", "dns.flags.response == 0"],
capture_output=True, text=True
)
domains = set(result.stdout.strip().split('\n'))
print("Suspicious DNS queries (high entropy):")
for domain in domains:
if domain:
subdomain = domain.split('.')[0]
ent = entropy(subdomain)
if ent > 3.5 and len(subdomain) > 10:
print(f" {domain} (entropy: {ent:.2f})")
PYEOF
# DNS 터널링 감지 (큰 TXT 응답)
tshark -r malware.pcap -T fields -e dns.qry.name -e dns.txt \
-Y "dns.resp.type == 16 and dns.resp.len > 100"
Step 3: HTTP/HTTPS C2 통신 분석
웹 기반 명령 및 제어 트래픽 검사:
# HTTP 요청 추출
tshark -r malware.pcap -T fields \
-e frame.time -e ip.src -e ip.dst -e http.host \
-e http.request.method -e http.request.uri -e http.user_agent \
-Y "http.request"
# HTTP 응답 본문 추출 (잠재적 페이로드 다운로드)
tshark -r malware.pcap -T fields \
-e http.host -e http.request.uri -e http.content_type -e tcp.len \
-Y "http.response and tcp.len > 1000"
# POST 데이터 추출 (잠재적 데이터 유출)
tshark -r malware.pcap -T fields \
-e http.host -e http.request.uri -e http.file_data \
-Y "http.request.method == POST"
# TLS 분석 (SNI, JA3 지문)
tshark -r malware.pcap -T fields \
-e tls.handshake.extensions_server_name \
-e tls.handshake.ja3 \
-Y "tls.handshake.type == 1"
# TLS 인증서 세부 정보 추출
tshark -r malware.pcap -T fields \
-e x509ce.dNSName -e x509af.serialNumber \
-e x509sat.utf8String \
-Y "tls.handshake.type == 11"
# HTTP 객체 내보내기 (다운로드된 파일)
tshark -r malware.pcap --export-objects http,exported_files/
Step 4: 비콘닝 패턴 감지
C2 비콘닝을 나타내는 정기적인 주기적 통신 식별:
# PCAP 비콘 감지
from scapy.all import rdpcap, IP, TCP
from collections import defaultdict
import statistics
packets = rdpcap("malware.pcap")
# 대상 IP:포트별 연결 그룹화
connections = defaultdict(list)
for pkt in packets:
if IP in pkt and TCP in pkt:
if pkt[TCP].flags & 0x02: # SYN 플래그
dst = f"{pkt[IP].dst}:{pkt[TCP].dport}"
connections[dst].append(float(pkt.time))
# 비콘닝 시간 간격 분석
print("비콘 분석:")
for dst, times in connections.items():
if len(times) >= 5:
intervals = [times[i+1] - times[i] for i in range(len(times)-1)]
avg = statistics.mean(intervals)
stdev = statistics.stdev(intervals) if len(intervals) > 1 else 0
jitter = (stdev / avg * 100) if avg > 0 else 0
if 10 < avg < 3600 and jitter < 30: # 지터 30% 미만의 규칙적인 간격
print(f" [!] {dst}: {len(times)}개 연결")
print(f" 간격: {avg:.1f}초 ± {stdev:.1f}초 (지터: {jitter:.1f}%)")
print(f" 패턴: 비콘닝 의심")
Step 5: 네트워크 탐지 시그니처 생성
관찰된 트래픽 패턴으로 Suricata/Snort 규칙 생성:
# 기존 시그니처 매칭을 위해 PCAP에 Suricata 실행
suricata -r malware.pcap -l suricata_output/ -c /etc/suricata/suricata.yaml
# 경고 검토
cat suricata_output/fast.log
# 관찰된 패턴에서 커스텀 Suricata 규칙 생성
cat << 'EOF' > custom_malware.rules
# 관찰된 URI 패턴 기반 C2 비콘 탐지
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"멀웨어 MalwareX C2 비콘";
flow:established,to_server;
http.method; content:"POST";
http.uri; content:"/gate.php?id=";
http.user_agent; content:"Mozilla/5.0 (compatible; MSIE 10.0)";
sid:9000001; rev:1;
)
# 알려진 C2 도메인에 대한 DNS 질의
alert dns $HOME_NET any -> any any (
msg:"멀웨어 MalwareX C2 DNS 질의";
dns.query; content:"update.malicious.com";
sid:9000002; rev:1;
)
# 멀웨어 TLS 클라이언트의 JA3 해시 매칭
alert tls $HOME_NET any -> $EXTERNAL_NET any (
msg:"멀웨어 MalwareX JA3 매칭";
ja3.hash; content:"a0e9f5d64349fb13191bc781f81f42e1";
sid:9000003; rev:1;
)
EOF
Step 6: 트래픽에서 파일 및 아티팩트 추출
전송된 파일과 내장 데이터 복구:
# Zeek를 사용한 파일 추출
zeek -r malware.pcap /opt/zeek/share/zeek/policy/frameworks/files/extract-all-files.zeek
ls extract_files/
# NetworkMiner를 사용한 파일 추출 (GUI)
# 또는 특정 프로토콜 내보내기에 tshark 사용
tshark -r malware.pcap --export-objects http,http_objects/
tshark -r malware.pcap --export-objects smb,smb_objects/
tshark -r malware.pcap --export-objects tftp,tftp_objects/
# 추출된 모든 파일 해싱
sha256sum http_objects/* smb_objects/* 2>/dev/null
# 포괄적인 메타데이터를 위한 Zeek 로그 생성
zeek -r malware.pcap
# 출력: conn.log, dns.log, http.log, ssl.log, files.log 등
주요 개념
| 용어 | 정의 |
|---|---|
| 비콘닝(Beaconing) | 일관된 시간 간격과 패킷 크기로 식별 가능한, 멀웨어의 C2 서버에 대한 정기적인 주기적 연결 |
| JA3/JA3S | ClientHello/ServerHello 매개변수에서 해시를 생성하여 멀웨어 TLS 구현을 고유하게 식별하는 TLS 지문 방식 |
| DGA (도메인 생성 알고리즘) | 멀웨어가 C2 서버를 찾기 위해 질의하는 유사난수 도메인 이름을 생성하여 정적 도메인 차단 목록을 회피하는 알고리즘 |
| DNS 터널링 | DNS 인프라를 통해 C2 채널을 구축하거나 데이터를 유출하기 위해 DNS 질의 및 응답에 데이터를 인코딩하는 기법 |
| 패스트 플럭스(Fast Flux) | 도메인의 IP 주소를 빠르게 교체하여 C2 서버 다운을 방지하고 여러 손상된 호스트에 C2를 분산하는 DNS 기법 |
| SNI (서버 이름 표시) | 클라이언트가 연결하는 호스트 이름을 나타내는 TLS 확장; 암호화된 HTTPS 연결에서도 볼 수 있음 |
| 네트워크 시그니처 | 악성 통신을 탐지하기 위해 네트워크 트래픽(헤더, 페이로드, 타이밍)의 특정 패턴을 매칭하는 Suricata/Snort 규칙 |
도구 및 시스템
- Wireshark: 프로토콜 수준에서 네트워크 트래픽을 심층 대화식 검사하는 오픈소스 패킷 분석기
- Zeek: 실시간 또는 캡처된 트래픽에서 구조화된 메타데이터 로그(conn, dns, http, ssl)를 생성하는 네트워크 분석 프레임워크
- Suricata: Lua 스크립팅을 통한 커스텀 탐지 로직 지원, 시그니처 기반 탐지를 위한 고성능 네트워크 IDS/IPS
- NetworkMiner: PCAP 파일에서 파일, 이미지, 자격 증명을 추출하는 네트워크 포렌식 분석 도구
- Scapy: 프로그램적 패킷 분석, 비콘 감지, 프로토콜 디코딩을 위한 Python 패킷 조작 라이브러리
일반적인 시나리오
시나리오: 커스텀 바이너리 C2 프로토콜 디코딩
상황: 멀웨어가 TCP 포트 8443을 통해 커스텀 바이너리 프로토콜로 C2 서버와 통신합니다. 표준 HTTP 분석으로는 결과가 없습니다. PCAP에서 프로토콜 구조를 리버스 엔지니어링해야 합니다.
접근법:
- TCP 포트 8443 대화로 PCAP 필터링 후 TCP 스트림 추적
- 메시지 프레이밍 식별 (길이 접두사, 구분자, 고정 크기 헤더)
- 여러 메시지를 비교하여 정적 헤더 필드와 가변 데이터 필드 식별
- Ghidra의 리버스 엔지니어링 결과와 교차 참조 (바이너리가 분석된 경우)
- 커스텀 프로토콜을 위한 Wireshark 디섹터 또는 Scapy 파서 작성
- 정적 헤더 바이트를 매칭하는 Suricata 규칙 생성
- 위협 인텔리전스 공유를 위한 전체 프로토콜 사양 문서화
주의사항:
- 처음 몇 개의 패킷만 분석하는 경우; 일부 C2 프로토콜은 초기 핸드셰이크 후 행동을 변경함
- 샌드박스에 MITM 기능이 있을 때 TLS 트래픽을 복호화하지 않는 경우
- 합법적인 CDN 또는 클라우드 트래픽을 C2로 혼동하는 경우 (대상 IP 검증 필요)
- TCP/UDP 대신 DNS 또는 ICMP를 사용하는 C2 트래픽을 놓치는 경우
출력 형식
멀웨어 네트워크 트래픽 분석
===================================
PCAP 파일: malware_sandbox.pcap
기간: 300초
총 패킷: 12,847
총 바이트: 4.2 MB
DNS 활동
총 질의 수: 47
DGA 감지: 예 (.com TLD에 23개의 높은 엔트로피 질의)
터널링: 아니오
확인된 C2: update.malicious[.]com -> 185.220.101[.]42
C2 통신
프로토콜: HTTPS (TLS 1.2)
서버: 185.220.101[.]42:443
SNI: update.malicious[.]com
JA3 해시: a0e9f5d64349fb13191bc781f81f42e1
비콘 간격: 60.2초 ± 6.8초 (11.3% 지터)
총 세션 수: 237
전송 데이터: 147 MB
수신 데이터: 2.3 MB
인증서: CN=update.malicious[.]com (자체 서명, 만료됨)
페이로드 다운로드
GET /payload.dll from compromised-site[.]com
크기: 98,304 바이트
SHA-256: abc123def456...
Content-Type: application/octet-stream
데이터 유출
방식: HTTPS POST to /gate.php
Content-Type: application/octet-stream
평균 크기: 15,432 바이트 (요청당)
총 용량: 147 MB (4시간 동안)
SURICATA 경고
[1:2028401] ET MALWARE 일반 C2 비콘 패턴
[1:2028500] ET POLICY 자체 서명 인증서
생성된 시그니처
SID 9000001: MalwareX HTTP 비콘 패턴
SID 9000002: MalwareX DNS C2 도메인
SID 9000003: MalwareX JA3 TLS 지문