マルウェアネットワークトラフィックの分析
使用すべき場面
- サンドボックス実行でPCAPファイルが取得され、ネットワーク動作の詳細な分析が必要な場合
- C2プロトコル構造を特定し、ネットワーク検知シグネチャを作成する場合
- マルウェアがどのデータを外部インフラに流出させているかを特定する場合
- DNSトンネリング、ドメイン生成アルゴリズム(DGA)、またはFast-Flux動作を分析する場合
- 観測されたマルウェアのネットワークパターンに基づいてSuricata/Snortシグネチャを作成する場合
使用すべきでない場面: マルウェアのホストベース分析。プロセスレベルのアクティビティ分析にはCuckooサンドボックスレポートやVolatilityメモリ分析を使用してください。
前提条件
- Wireshark 4.x がインストールされていること(インタラクティブなPCAP分析用)
- tshark(Wireshark CLI)が使用できること(スクリプトによるパケット抽出用)
- Zeek がインストールされていること(PCAPからの自動メタデータ生成用)
- ET Open/ET Pro ルールセットを使用したSuricataがインストールされていること(シグネチャマッチング用)
- NetworkMiner がインストールされていること(PCAPからのファイル抽出と資格情報検出用)
- Python 3.8+ と
scapyおよびdpktライブラリがインストールされていること(プログラムによるパケット分析用)
ワークフロー
ステップ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
ステップ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("疑わしいDNSクエリ(高エントロピー):")
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"
ステップ3: HTTP/HTTPS C2通信の分析
Webベースのコマンド&コントロールトラフィックを調査します:
# 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/
ステップ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" パターン: ビーコニングの可能性が高い")
ステップ5: ネットワーク検知シグネチャの生成
観測されたトラフィックパターンからSuricata/Snortルールを作成します:
# SuricataをPCAPに対して実行し、既存のシグネチャマッチを確認
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:"MALWARE MalwareX C2 Beacon";
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:"MALWARE MalwareX C2 DNS Query";
dns.query; content:"update.malicious.com";
sid:9000002; rev:1;
)
# マルウェアTLSクライアントのJA3ハッシュマッチ
alert tls $HOME_NET any -> $EXTERNAL_NET any (
msg:"MALWARE MalwareX JA3 Match";
ja3.hash; content:"a0e9f5d64349fb13191bc781f81f42e1";
sid:9000003; rev:1;
)
EOF
ステップ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 など
主要な概念
| 用語 | 定義 |
|---|---|
| ビーコニング | マルウェアから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からプロトコル構造をリバースエンジニアリングする必要があります。
アプローチ:
- PCAPをTCPポート8443の会話でフィルタリングし、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...
コンテンツタイプ: application/octet-stream
情報流出
方法: HTTPS POST to /gate.php
コンテンツタイプ: application/octet-stream
平均サイズ: リクエストあたり 15,432 バイト
総容量: 4時間で 147 MB
Suricataアラート
[1:2028401] ET MALWARE Generic C2 Beacon Pattern
[1:2028500] ET POLICY Self-Signed Certificate
生成されたシグネチャ
SID 9000001: MalwareX HTTP beacon pattern
SID 9000002: MalwareX DNS C2 domain
SID 9000003: MalwareX JA3 TLS fingerprint