analyzing-network-traffic について
パケットキャプチャから通信を再構成する、セキュリティ分析者向けのネットワークフォレンジック技能です。Wireshark、tshark、Zeek、Suricataを使ったオフライン調査を扱います。
主な機能
- 01PCAPの完全性確認と取り扱い
- 02通信のトリアージとフィルタリング
- 03Zeekの構造化ログ分析
- 04Suricataのオフラインアラート確認
- 05C2ビーコンとDNSトンネルの検出
- 06TLSメタデータと証明書の確認
活用シーン
- 01侵入の疑いがあるPCAPの調査
- 02疑わしいC2ビーコンの特徴分析
- 03データ流出の疑いがある通信の評価
- 04ZeekやSuricataのアラートの追跡
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ trilwu/ secskills --skill analyzing-network-trafficインストール後、Claude Code で/analyzing-network-trafficを入力して読み込まれたか確認します。
詳細
ネットワークトラフィックの分析
パケットキャプチャはエンドポイントが偽ることはできても、通信回線は偽れないという意味で、真実を示すものです。ホストのログが残っているかどうかにかかわらず、すべての接続、DNS ルックアップ、転送されたバイトが記録されます。分析とは、平坦なキャプチャからストーリーを組み立てることです。誰が誰と、どのプロトコルで通信したのか、そのパターンは人間によるものか自動化されたものか、そしてネットワークから何が出ていったのかを明らかにします。ツールが出した結論をそのまま読むのではなく、フレームから意図を再構成します。
使用する場面
.pcap/.pcapngキャプチャを侵入の証拠がないかフォレンジック調査する必要がある- 疑わしい C2 ビーコンを確認し、その間隔、ジッター、通信チャネルを特定する必要がある
- データ流出が疑われ、その規模、発生時刻、送信先を特定する必要がある
- 実際に送出されたトラフィックからマルウェアのネットワーク動作を記録する必要がある
- Zeek の
notice.logまたは Suricata のeve.jsonのアラートを調査し、結論を出す必要がある - DNS トンネリング、DGA、または異常な TLS(不審な証明書、まれな JA3、SNI の不一致)が疑われる
使用しない場面
- エンドポイント、ネットワーク、クラウド、ID のテレメトリーを先回りして広く調査し、未検出の侵害を探す場合 —
hunting-threatsを使用してください。このスキルは1つのキャプチャを詳細に分析するものであり、ハンティングでは複数のデータソースを調査します - インシデント対応全体を進める場合 —
responding-to-incidentsを使用してください。トラフィック分析は、そのプロセスに情報を提供する証拠の流れの1つです - トラフィックを「生成する」ためにサンプルを実行する場合 —
analyzing-malwareを使用してください。ここでは、バイナリを実行するのではなく、バイナリが送出した pcap を分析します - 証拠がパケットではなくクラウドのコントロールプレーンのアクティビティである場合(CloudTrail、VPC フローログの欠落、API 呼び出し) —
investigating-aws-incidentsを使用してください - アプリケーションのキャプチャを分析するのではなく、稼働中のアプリケーションを実際にテストする場合 —
testing-web-applicationsを使用してください
キャプチャと取り扱い
キャプチャの取得を適切に行わなければ、その後のすべての手順に欠落が引き継がれます。切り詰められた snaplen やパケットがドロップされたキャプチャは、後から修正できません。
# Full-frame capture, no name resolution, write to disk (never parse live)
tcpdump -i eth0 -nn -s 0 -w case.pcap
# -s 0 takes full frames; a default snaplen truncates payloads and breaks carving
# Ring buffer for long-running capture: 20 files of 200 MB, oldest recycled
tcpdump -i eth0 -nn -s 0 -w case-%Y%m%d-%H%M%S.pcap -G 3600 -C 200 -W 20
# Capture without dropping under load: raise the kernel buffer, filter tightly
tcpdump -i eth0 -nn -s 0 -B 4096 'not port 22' -w case.pcap
# Confirm drops after: the summary line reports "packets dropped by kernel"
キャプチャに欠損がないか、またどのような形式のデータを扱っているかを確認します。
capinfos case.pcap # packet count, duration, drop stats, snaplen, file type
tshark -r case.pcap -q -z io,phs # protocol hierarchy — is the snaplen truncating?
- pcapng と pcap:pcapng にはパケットごとのインターフェイス、コメント、名前レコードが含まれます。従来の
.pcapは単一リンクのフラットな形式です。editcap -F libpcap in.pcapng out.pcapを実行すると、pcap のみを読み取るツール向けに変換できます。 - 巨大なファイルを分割して、ツールやメモリーで扱えるようにします。
editcap -c 1000000 big.pcap chunk.pcap(パケット数による分割)またはeditcap -i 600 big.pcap chunk.pcap(600秒ごとの分割)を使用します。 - 関連するキャプチャを1つの時系列にマージします:
mergecap -w all.pcap a.pcap b.pcap(タイムスタンプ順に並べ替えます)。 - 共有前に時間範囲を切り出します:
editcap -A "2026-07-26 00:00:00" -B "2026-07-26 06:00:00" case.pcap window.pcap。 - 外部共有の前に匿名化します:アドレスを書き換えるには
tcprewrite/bittwisteを使用します。またはeditcap -s <snaplen>を使って各パケットを先頭のsnaplenバイトまでに切り詰めます(ヘッダーを残し、末尾のペイロードを削除します)。ヘッダーやペイロードをさらに詳しくサニタイズするには TraceWrangler を使用します。変更内容を記録し、受領者が変更による痕跡を追わずに済むようにします。
元のファイルのハッシュを取得し、コピーを使って作業します。sha256sum case.pcap の結果をケースの記録に記載します。以降、証拠ファイルは読み取り専用です。
トリアージの絞り込み
広い範囲から始め、重要なフローに絞り込みます。Wireshark では、上から順に確認します。
- Statistics > Protocol Hierarchy — どのプロトコルがどの程度の割合で存在するかを確認します。TLS を想定していたのに平文通信がある場合や、DNS のごく一部がバイト数の大半を占めている場合は、最初に注目すべき兆候です。
- Statistics > Conversations — バイト数と通信時間で並べ替えます。最長と最大のフローが、最初に調べるべき2つの手掛かりです(ビーコンか、大量転送か)。
- Statistics > Endpoints — 最も多くの相手と通信するホストを確認し、内部と外部を一目で見分けます。
- Follow > TCP/HTTP/TLS Stream — 1つの通信を再構成し、アプリケーションが受け取った形で内容を読み取ります。
Wireshark で対話的に行う操作はすべて tshark でスクリプト化できます。これにより、クリック操作をせずにキャプチャ全体からフィールドを抽出できます。
# Top talkers by bytes
tshark -r case.pcap -q -z conv,tcp
# Extract just the fields you want, tab-separated, for further processing
tshark -r case.pcap -T fields -E separator=/t \
-e frame.time_epoch -e ip.src -e ip.dst -e tcp.dstport -e frame.len \
-Y 'tcp.flags.syn==1 && tcp.flags.ack==0' # every connection attempt
# Every HTTP request: host, method, URI, user-agent
tshark -r case.pcap -T fields -e http.host -e http.request.method \
-e http.request.uri -e http.user_agent -Y http.request
ディスプレイフィルターの使いこなし
ディスプレイフィルターはメスです。特に有用なものを紹介します。
| フィルター | 表示されるもの |
|---|---|
http.request | すべての送信 HTTP リクエスト — URI、ホスト、ユーザーエージェント |
dns | すべての DNS。NXDOMAIN(DGA の兆候)を調べるには dns.flags.rcode == 3 を追加します |
tls.handshake.type == 1 | ClientHello のみ — SNI、JA3 の入力情報、提示された暗号スイート |
tls.handshake.type == 2 | ServerHello — 選択された暗号スイート、JA3S の入力情報 |
ip.addr == 10.0.0.5 | ホストとの間のすべてのトラフィック(方向を特定するには src/dst を使用) |
tcp.flags.syn==1 && tcp.flags.ack==0 | 接続の試行 — スキャンやビーコンの周期性 |
tcp.flags.reset==1 | RST — 拒否/切断、ポートスキャンへの応答 |
frame contains "password" | ペイロード全体を対象にしたバイト文字列検索(平文の認証情報、目印) |
tcp.stream eq 7 | ストリームインデックスで再構成された会話を 1 つに絞り込みます |
tcp.analysis.retransmission | タイミング分析を歪めるパケット損失/不安定性 |
http.response.code == 200 && http.content_type contains "octet-stream" | HTTP 経由のファイル転送 |
フィルターは組み合わせて使います。ip.dst == 185.100.87.0/24 && dns は、疑わしいネットブロックへの DNS に絞り込みます。dns.qry.name matches "[a-f0-9]{20,}" は、長い 16 進数のラベルを検出します。
Zeek:主力ツール
Zeek は pcap を構造化されたクエリ可能なログに変換します。数千パケットを超えるキャプチャを調べる際、最も効果の高い手段です。
zeek -r case.pcap
# Or add the community-id field for cross-tool pivoting:
zeek -r case.pcap policy/protocols/conn/community-id-logging
ls # conn.log dns.log http.log ssl.log x509.log files.log notice.log weird.log ...
ログの種類と、それぞれから分かることは次のとおりです。
| ログ | 分かること |
|---|---|
conn.log | すべてのフロー:継続時間、orig/resp のバイト数、状態、サービス — ビーコンや情報漏えい分析の基盤 |
dns.log | すべてのクエリ/応答 — トンネリング、DGA、TXT/NULL の悪用 |
http.log | ホスト、URI、メソッド、ユーザーエージェント、ステータス、リファラー |
ssl.log | TLS バージョン、SNI、JA3/JA3S、証明書チェーン、検証ステータス |
x509.log | 証明書のサブジェクト、発行者、有効期間、自己署名フラグ |
files.log | ワイヤー上で確認されたすべてのファイル — MIME、サイズ、MD5/SHA1、ソースフロー |
notice.log | Zeek 自身による検出(SSL::Invalid_Server_Cert、スキャンなど) |
weird.log | プロトコル違反 — 不適切なポート上のプロトコル、不正なフレーム |
zeek-cut でログを調べます(フィールド名で抽出でき、順序に依存しません)。
# Longest connections first — beacons and tunnels live at the top
cat conn.log | zeek-cut id.orig_h id.resp_h duration orig_bytes resp_bytes \
| sort -t$'\t' -k3 -rn | head
# Every distinct destination one host reached, with hit counts
cat conn.log | zeek-cut id.orig_h id.resp_h | grep '^10\.0\.0\.5' \
| sort | uniq -c | sort -rn
# DNS query names + types, to eyeball tunneling and DGA
cat dns.log | zeek-cut query qtype_name answers | sort | uniq -c | sort -rn | head -50
# Pivot a suspicious flow across all logs by its community-id
cat conn.log | zeek-cut community_id id.orig_h id.resp_h service
community-id フィールドは、同じフローであれば Zeek、Suricata、および多くの EDR で同じ文字列になります。アラートとパケットを対応付けるために使用します。
pcap に対する Suricata の実行
キャプチャに対してシグネチャをオフラインで実行し、ルールセットが何を検出するか確認します。
# Run ET Open / community rules over the pcap, write structured events
suricata -r case.pcap -S /etc/suricata/rules/suricata.rules -l ./out/
# eve.json holds alerts, plus dns/http/tls/flow records if enabled
アラートを抽出し、順位付けします。
jq -c 'select(.event_type=="alert") | {sig:.alert.signature, src:.src_ip, dst:.dest_ip}' \
out/eve.json | sort | uniq -c | sort -rn
アラートは結論ではなく、手掛かりとして扱います。シグネチャがヒットしたら調べるべき場所が分かりますが、それで調査が終わるわけではありません。また、ヒットしなくてもキャプチャに問題がないとは限りません。
ビーコンの検出
自動コールバックは、内容ではなくタイミングとパターンに表れます。conn.log で、長時間にわたって一定の間隔で繰り返され、リクエストサイズが小さく、ほぼ一定の送信元/宛先の組み合わせを探します。人間のトラフィックは断続的で変化に富みますが、ビーコンはメトロノームのように動作します。
# Inter-arrival deltas for one src/dst pair — near-constant gaps = beacon
tshark -r case.pcap -T fields -e frame.time_epoch \
-Y 'ip.src==10.0.0.5 && ip.dst==185.100.87.202' \
| awk 'NR>1{print $1-prev} {prev=$1}' | sort -n | uniq -c
- 規則的な間隔(例:60 秒ごと)にジッター(±%のばらつき)があるのは、典型的な C2 の特徴です。完全に規則的なものはマルウェアではまれですが、軽いジッターはよく見られます。
- 小さく一定のリクエストサイズと、ときどき発生する大きな応答の組み合わせは、タスクを受け取るための定期的なポーリングを示します。
- 長時間続く接続、または数時間にわたり一定の周期で再接続するフローは、持続的な通信チャネルを示している可能性があります。
Zeek のログに対して RITA または beacon-analysis ツールを使い、スコアリングを自動化できます。すべての組み合わせについて間隔とサイズの一貫性を計算するため、1 つずつ目視で確認する必要はありません。
rita import --database case --logs ./ && rita view case beacon:'>=90'
DNS 分析
DNS は、ブロックされることがまれで、ログに記録されないことも多いため、秘密のチャネルとしてよく利用されます。dns.log には、次のような明確に異なるパターンがあります。
トンネリング — DNS をデータパイプとして使用します。
- 1 つの親ドメインへのクエリ量が多い(固有のサブドメインが数千個)
- 長いラベル:
MFRGG43FMQ.tunnel.evil.com、base32/16 進数のように見えるサブドメイン - 上り/下りのエンコードされたペイロードを含む
TXTおよびNULLレコードタイプ - 通常の英語風ホスト名と比べて、ラベルごとのエントロピーが高い
# Subdomain cardinality per parent domain — a tunnel spikes on one domain
cat dns.log | zeek-cut query | rev | cut -d. -f1-2 | rev \
| sort | uniq -c | sort -rn | head
# TXT queries only — legitimate use is sparse; volume is a flag
cat dns.log | zeek-cut query qtype_name | awk -F'\t' '$2=="TXT"' | wc -l
DGA — アルゴリズムで生成されたランデブードメインです。
- マルウェアが存在しない名前を次々と試すため、
NXDOMAINの割合(rcode3)が高い - 言語的な構造のない、ランダムに見えるセカンドレベルドメイン
cat dns.log | zeek-cut rcode_name query | awk -F'\t' '$1=="NXDOMAIN"' \
| wc -l # a burst of NXDOMAIN from one host is a DGA tell
ラベルのエントロピーをスコア化するか、DGA 分類器を使って、cdn-3f2a.example(無害なハッシュ)と qwzjxkbvmn.info(生成されたドメイン)を区別します。ボリューム、エントロピー、NXDOMAIN が揃えば根拠になりますが、どれか 1 つだけなら無害な説明も成り立ちます。
TLS と暗号化トラフィック
鍵がなければ平文は読めませんが、ハンドシェイクからはクライアント、サーバー、そして意図を特定できます。暗号化で隠されるのはコンテンツであり、メタデータではありません。
- JA3/JA3S(および JA4/JA4S)は、ClientHello/ServerHello のパラメーターをハッシュ化し、クライアントとサーバーのフィンガープリントを作成します。関係のないホスト間で共有される珍しい JA3 や、既知の C2 フレームワークと一致する JA3 は、有力な手掛かりです。Zeek の
ssl.logにはja3/ja3sが記録されます。公開・内部の既知の悪性リストと照合してください。 ssl.log/x509.logでは、自己署名証明書、証明書の CN/SAN と一致しない SNI、異常な有効期間(1000 年、または同日限りの証明書)、空欄またはでたらめなサブジェクトフィールド、疑わしいドメインや新規登録ドメインを指す SNIを探します。
# Self-signed or validation-failed TLS, with the SNI and JA3
cat ssl.log | zeek-cut server_name validation_status ja3 ja3s \
| grep -iv '\bok$' | sort | uniq -c | sort -rn
# SNI vs certificate subject mismatch — join ssl.log and x509.log on cert id
cat x509.log | zeek-cut certificate.subject certificate.issuer \
certificate.not_valid_before certificate.not_valid_after
セッションキーを正当に保有している場合(SSLKEYLOGFILE を設定してラボで実行したサンプルや、エクスポートしたマスターシークレットなど)は、Wireshark で復号できます。
Preferences > Protocols > TLS > (Pre)-Master-Secret log filename を設定するか、tshark -r case.pcap -o tls.keylog_file:keys.log -Y http2 を実行します。鍵を持っていない本番 TLS を復号できると思い込んではいけません。行っているのはフィンガープリントの特定であり、内容の読み取りではありません。
HTTP とファイルの抽出
平文の HTTP(および復号済み TLS)では、やり取り全体を確認できます。
- User-Agent の異常 — ハードコードされた、不正な形式の、またはライブラリの既定値の UA(
python-requests、空の UA、誤字のあるブラウザー文字列)が外向きトラフィックに含まれる場合、マルウェアの典型的な兆候です。UA をスタック別に整理し、珍しいものを調査します。 http.logにある疑わしい URI — base64 のように見えるパス、長くランダムなクエリー文字列、実 IP 上の.phpエンドポイント、不透明なデータの POST などです。
転送されたファイルを抽出し、ピボット分析用にハッシュ化します。
# Zeek extracts files automatically when configured; otherwise from files.log:
cat files.log | zeek-cut fuid mime_type filename md5 sha1 tx_hosts rx_hosts
# Carve without Zeek:
foremost -i case.pcap -o carved/ # signature-based file recovery
tcpflow -r case.pcap -o flows/ # reassemble every TCP stream to a file
# NetworkMiner (GUI/CLI) reassembles files, images, and credentials from a pcap
抽出したすべてのアーティファクトをハッシュ化し、疑わしいものを analyzing-malware にピボットします。
sha256sum carved/* — 通信上に現れ、無害なものと一致しないファイルは、次に解析環境で実行するサンプルです。
データ流出の検出
最も重要なのは、データが外部に出ていくことです。conn.log を orig_bytes の降順に並べ替えます。大きな外向きフローが注目すべき対象であり、その方向(orig =内部ホストからの送信)が重要です。
# Biggest outbound transfers from internal hosts
cat conn.log | zeek-cut id.orig_h id.resp_h resp_p orig_bytes duration \
| awk -F'\t' '$4>10000000' | sort -t$'\t' -k4 -rn
- 時間外の転送 — 日中はアイドル状態のワークステーションから、03:00 に大量アップロードが行われる場合です。フローのタイムスタンプを業務時間と照合します。
- 秘密のチャネル — ペイロードを含む ICMP が継続する場合や、DNS に上りデータが含まれる場合です(DNS 分析を参照)。小さなパケットが大量に、単一の宛先へ送信されます。
- 宛先の評判 — クラウドストレージ(
*.s3.amazonaws.com、*.blob.core.windows.net)、ペーストサイト(pastebin、ghostbin)、ファイル共有ドメインが、利用する業務上の理由がないサーバーからの大規模アップロードの宛先になっている場合です。
プロトコルの異常
攻撃者は、誤ったポートやプロトコルにトラフィックを隠します。
- 標準外のポート — 8443 や 4443 での TLS、8080 や 8888 での HTTP、またはランダムに選ばれた高い番号のポートでの C2 です。
conn.logのserviceフィールドは、ポート番号とは無関係に、Zeek が検出したプロトコルを示します。 - 誤ったポートでのプロトコル — Zeek の DPI は、443 での SSH、53 での HTTP、または 22 での TLS を、
conn.log(serviceとid.resp_pが一致しません)とweird.logで検出します。
# Detected service does not match the port — tunneling / evasion
cat conn.log | zeek-cut id.resp_p service | awk -F'\t' \
'($1=="443" && $2!="ssl") || ($1=="53" && $2!="dns")' | sort | uniq -c
- 平文の認証情報 — FTP、Telnet、HTTP Basic、SMTP AUTH、LDAP の簡易バインドです。Wireshark で
frame contains "PASS "を検索するか、NetworkMiner の認証情報タブを使うと、そのまま抽出できます。
IOC の引き継ぎ
キャプチャの価値は、再利用のために抽出する情報にあります。ほかの情報源と同じように、インジケーターを優先度付けします。インフラよりも振る舞いのほうが長く有効です。そして、それぞれの出力を適切な場所に引き継ぎます。
- カービングしたサンプルのファイルシグネチャ —
writing-yara-rulesで.yarを作成し、使用された URI ではなく構造に基づいて検出します。 - パッケージング IOC、攻撃者のピボット、インフラのクラスタリングを完成した成果物にまとめる —
producing-threat-intelligence。 - トラフィックパターンを運用環境に展開する検知に変換する — ログベースのルールには
writing-sigma-rules、より広範なルールパイプラインにはengineering-detectionsを使用します(JA3 用の Suricata シグネチャ、ビーコンの間隔を検知する Zeek のnotice、DNS パターン用の Sigma ルールなど)。 - 関係者向けの最終報告書 —
reporting-security-findings。
各インジケーターについて、元となったフロー、タイムスタンプ、確信度を記録します。コンテキストのない IP は、受け取る側にとってはノイズです。
退けるべき合理化
- 「すべて TLS だから、何も見えない。」 JA3/JA3S、SNI、証明書フィールド、接続タイミングを使えば、復号しなくても暗号化されたトラフィックのフィンガープリントを特定できます。メタデータこそが分析対象です。
- 「アラートが出なかったから、問題はない。」 ビーコン通信や DNS トンネリングは、デフォルトのルールセットをすり抜けることがよくあります。Suricata の検知がないからといって、C2 がないとは限りません。
- 「pcap が大きすぎて分析できない。」 Zeek を実行し、ログを確認して、フィルタリングで絞り込みます。500 万件の生フレームではなく、構造化ログをトリアージします。
- 「ここに C2 トラフィックはない。」 結論を出す前に、DNS、ICMP、長時間続く少量のフローを確認します。C2 は、バイト数で並べ替えていないチャネルに隠れています。
- 「通信量は正常だから、情報流出はない。」 アウトバウンドのバイト数と時間で並べ替えます。数日間にわたる少量ずつの送信や、時間外の単発バーストは、平均値を大きく変えません。
- 「その宛先は CDN/クラウドプロバイダーにすぎない。」 クラウドストレージや CDN のドメインは、まさに現代の情報流出や C2 が隠れる場所です。ドメイン名だけで見過ごさず、フローの特性を確認します。
- 「ペイロードを見ればいい。」 snaplen による切り詰め、暗号化、再構成の欠落があるため、ペイロードから見始めると全体像を見落とします。まずフローメタデータを確認し、注目に値するストリームを読みます。
ATT&CK のカバレッジ
secskills-core/ttp-index.json から生成されます。このファイルを編集してから、
python3 scripts/sync_attack.py --write を実行してください。レポートで引用する前に、
現在の ATT&CK リリースに照らして ID を再確認してください。
コマンドと制御(TA0011)
- T1071 アプリケーション層プロトコル —
analyzing-malware、engineering-detectionsも参照 - T1071.004 DNS —
engineering-detections、hunting-threatsも参照 - T1132 データエンコーディング —
transferring-files、analyzing-malwareも参照 - T1568 動的解決 —
analyzing-malware、hunting-threatsも参照 - T1573 暗号化チャネル —
analyzing-malware、engineering-detectionsも参照
データの持ち出し(TA0010)
- T1048 代替プロトコルによるデータの持ち出し —
transferring-files、hunting-threatsも参照
これらの検出コンテンツ:engineering-detections。プロアクティブな探索:hunting-threats。侵害後の対応:responding-to-incidents。
参考資料
hunting-threats— ネットワークデータを含む、さまざまなテレメトリソースを対象とした、プロアクティブで仮説駆動型の探索responding-to-incidents— この証拠ストリームが情報を提供するインシデント対応プロセスanalyzing-malware— サンプルを実行してトラフィックを生成し、このスキルから抽出したファイルを受け取って分析investigating-aws-incidents— 証拠がパケットではなく、クラウドのコントロールプレーンログである場合writing-yara-rules— 抽出したアーティファクトからファイルシグネチャを作成producing-threat-intelligence— 抽出した IOC を製品としてまとめるreporting-security-findings— ステークホルダー向けの報告書- Wireshark /
tsharkおよびcapinfos— 対話型およびスクリプトによる解析 - Zeek と
zeek-cutおよび community-id — あらゆるキャプチャから構造化ログを生成 - Suricata(ET Open / コミュニティルール)— pcap に対するオフラインシグネチャ実行
- NetworkMiner — キャプチャからファイル、画像、認証情報を再構成
- RITA / beacon-analysis — Zeek ログに対するビーコンの自動スコアリング
tcpdump— キャプチャ。editcap/mergecap— 分割、結合、トリミング、変換