mcpField
D
detecting-network-anomalies-with-zeek

detecting-network-anomalies-with-zeek

github.com/mukul975セキュリティ35.2k62 回インストール8 週間前に更新
リポジトリ

detecting-network-anomalies-with-zeek について

Zeek によるパッシブネットワーク監視を扱う、セキュリティ・ネットワーク担当者向けのスキルです。プロトコルメタデータのログ生成、独自検知、脅威ハンティングを説明し、通信の遮断ではなく観測と分析に重点を置きます。

主な機能

  1. 01接続・DNS・HTTP ログの生成
  2. 02独自の Zeek 検知スクリプト作成
  3. 03ネットワークログでの脅威ハンティング
  4. 04ログの SIEM 転送
  5. 05Notice と SumStats による異常検知

活用シーン

  1. 01ネットワーク出口の通信監視
  2. 02DNS トンネリングやビーコニングの調査
  3. 03過去ログを使ったインシデント分析
  4. 04ネットワークメタデータの SIEM 取り込み

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill detecting-network-anomalies-with-zeek

インストール後、Claude Code で/detecting-network-anomalies-with-zeekを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
references/
api-reference.md
scripts/
agent.py

詳細

Zeek によるネットワーク異常の検出

使用する場面

  • 継続的な可視性を確保するため、ネットワークの重要なチョークポイントにパッシブなネットワークセキュリティ監視を導入する場合
  • SIEM への取り込みや脅威ハンティングに向けて、構造化された接続、DNS、HTTP、SSL、ファイル転送ログを生成する場合
  • 組織固有の脅威、ポリシー違反、ビーコン動作を検出するカスタム Zeek スクリプトを作成する場合
  • セキュリティインシデントを調査するため、ネットワークメタデータの遡及分析を行う場合
  • シグネチャベースのツールでは見逃す可能性がある、プロトコルレベルのメタデータ分析で IDS ソリューションを補完する場合

インラインでトラフィックを積極的にブロックできる IDS/IPS の代替として、TLS 検査なしで暗号化されたペイロードを監視する目的で、またはホストベースのエージェントのほうが適切なエンドポイントで使用しないでください。

前提条件

  • ソースまたはパッケージマネージャーから Zeek 6.0+ をインストール済みであること(zeek --version)
  • パッシブキャプチャ用に、ネットワークインターフェースが SPAN ポート、ネットワーク TAP、または仮想スイッチのミラーに設定されていること
  • ログファイル用に十分なディスク容量があること(監視対象トラフィック 100 Mbps あたり、1 日に 1~5 GB を見積もります)
  • カスタム検出を作成するための Zeek スクリプト言語に関する知識があること
  • 一元的な分析用のログ集約システム(Splunk、Elastic、Graylog)があること

ワークフロー

ステップ 1:Zeek のインストールと設定
# Install Zeek on Ubuntu/Debian
sudo apt install -y zeek

# Or install from source for latest version
git clone --recursive https://github.com/zeek/zeek
cd zeek && ./configure --prefix=/opt/zeek && make -j$(nproc) && sudo make install
export PATH=/opt/zeek/bin:$PATH

# Configure the monitoring interface
sudo vi /opt/zeek/etc/node.cfg
# /opt/zeek/etc/node.cfg
[zeek]
type=standalone
host=localhost
interface=eth1
# Configure local network definitions
sudo vi /opt/zeek/etc/networks.cfg
# /opt/zeek/etc/networks.cfg
10.0.0.0/8       Internal
172.16.0.0/12    Internal
192.168.0.0/16   Internal
# Disable NIC offloading for accurate packet capture
sudo ethtool -K eth1 rx off tx off gro off lro off tso off gso off

# Deploy Zeek
sudo zeekctl deploy

# Verify Zeek is running
sudo zeekctl status
ステップ 2:Zeek ログの理解と確認
# Zeek generates structured log files in /opt/zeek/logs/current/
ls /opt/zeek/logs/current/

# Key log files:
# conn.log       - All network connections (TCP, UDP, ICMP)
# dns.log        - DNS queries and responses
# http.log       - HTTP requests and responses
# ssl.log        - SSL/TLS handshake details
# files.log      - File transfers observed on the network
# notice.log     - Alerts from Zeek detection scripts
# weird.log      - Protocol anomalies and errors
# x509.log       - X.509 certificate details
# smtp.log       - SMTP email transactions
# ssh.log        - SSH connection details

# View connection log with zeek-cut for column selection
cat /opt/zeek/logs/current/conn.log | zeek-cut ts id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes

# View DNS log
cat /opt/zeek/logs/current/dns.log | zeek-cut ts id.orig_h query qtype_name answers

# View HTTP log
cat /opt/zeek/logs/current/http.log | zeek-cut ts id.orig_h host uri method status_code user_agent
ステップ 3:カスタム検出スクリプトの作成
# Create a custom detection script directory
sudo mkdir -p /opt/zeek/share/zeek/site/custom-detections

DNS トンネリングを検出するスクリプトを作成します。

# /opt/zeek/share/zeek/site/custom-detections/dns-tunneling.zeek
@load base/frameworks/notice

module DNSTunneling;

export {
    redef enum Notice::Type += {
        DNS_Tunneling_Detected,
        DNS_Long_Query
    };

    # Threshold: number of unique queries per source in time window
    const query_threshold: count = 200 &redef;
    const time_window: interval = 5min &redef;
    const max_query_length: count = 50 &redef;
}

# Track query counts per source IP
global dns_query_counts: table[addr] of count &create_expire=5min &default=0;

event dns_request(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count)
{
    local src = c$id$orig_h;

    # Check for unusually long domain queries (base64-encoded data)
    if ( |query| > max_query_length )
    {
        NOTICE([
            $note=DNS_Long_Query,
            $msg=fmt("Unusually long DNS query from %s: %s (%d chars)", src, query, |query|),
            $src=src,
            $identifier=cat(src, query)
        ]);
    }

    # Track query volume per source
    dns_query_counts[src] += 1;

    if ( dns_query_counts[src] == query_threshold )
    {
        NOTICE([
            $note=DNS_Tunneling_Detected,
            $msg=fmt("Possible DNS tunneling: %s sent %d queries in %s", src, query_threshold, time_window),
            $src=src,
            $identifier=cat(src)
        ]);
    }
}

ビーコン動作を検出するスクリプトを作成します。

# /opt/zeek/share/zeek/site/custom-detections/beacon-detection.zeek
@load base/frameworks/notice
@load base/frameworks/sumstats

module BeaconDetection;

export {
    redef enum Notice::Type += {
        Possible_Beaconing
    };

    const beacon_threshold: count = 50 &redef;
    const observation_window: interval = 1hr &redef;
}

event zeek_init()
{
    local r1 = SumStats::Reducer(
        $stream="beacon.connections",
        $apply=set(SumStats::SUM)
    );

    SumStats::create([
        $name="detect-beaconing",
        $epoch=observation_window,
        $reducers=set(r1),
        $threshold_val(key: SumStats::Key, result: SumStats::Result) = {
            return result["beacon.connections"]$sum;
        },
        $threshold=beacon_threshold + 0.0,
        $threshold_crossed(key: SumStats::Key, result: SumStats::Result) = {
            NOTICE([
                $note=Possible_Beaconing,
                $msg=fmt("Possible beaconing: %s made %d connections in %s",
                         key$str, result["beacon.connections"]$sum, observation_window),
                $identifier=key$str
            ]);
        }
    ]);
}

event connection_state_remove(c: connection)
{
    if ( c$id$resp_h !in Site::local_nets )
    {
        local key = fmt("%s->%s:%d", c$id$orig_h, c$id$resp_h, c$id$resp_p);
        SumStats::observe("beacon.connections", [$str=key], [$num=1]);
    }
}
ステップ 4:カスタムスクリプトの読み込みとデプロイ
# Add custom scripts to local.zeek
sudo tee -a /opt/zeek/share/zeek/site/local.zeek << 'EOF'

# Custom detection scripts
@load custom-detections/dns-tunneling.zeek
@load custom-detections/beacon-detection.zeek

# Enable additional protocol analyzers
@load protocols/ftp/software
@load protocols/http/software
@load protocols/smtp/software
@load protocols/ssh/detect-bruteforcing
@load protocols/ssl/validate-certs
@load protocols/ssl/log-hostcerts-only
@load protocols/dns/detect-external-names

# Enable file extraction
@load frameworks/files/extract-all-files

# Enable Intel framework for threat intelligence
@load frameworks/intel/seen
@load frameworks/intel/do_notice
EOF

# Reload Zeek configuration
sudo zeekctl deploy

# Verify scripts loaded without errors
sudo zeekctl diag
ステップ 5:Zeek ログを使った脅威ハンティングのクエリ
# Find long-duration connections (possible C2)
cat /opt/zeek/logs/current/conn.log | zeek-cut ts id.orig_h id.resp_h id.resp_p duration | \
  awk '$5 > 3600 {print $0}' | sort -t$'\t' -k5 -rn | head -20

# Find connections with high data transfer volumes
cat /opt/zeek/logs/current/conn.log | zeek-cut ts id.orig_h id.resp_h orig_bytes resp_bytes | \
  awk '$4 > 100000000 || $5 > 100000000 {print $0}'

# Identify rare user agents (potential malware)
cat /opt/zeek/logs/current/http.log | zeek-cut user_agent | sort | uniq -c | sort -n | head -20

# Find self-signed or expired certificates
cat /opt/zeek/logs/current/ssl.log | zeek-cut ts id.orig_h id.resp_h server_name validation_status | \
  grep -v "ok"

# Detect DNS queries to newly registered domains (DGA patterns)
cat /opt/zeek/logs/current/dns.log | zeek-cut ts id.orig_h query | \
  awk -F'\t' '{n=split($3,a,"."); if(length(a[n-1]) > 10) print $0}'

# Find SSH brute force attempts
cat /opt/zeek/logs/current/ssh.log | zeek-cut ts id.orig_h id.resp_h auth_success | \
  grep "F" | awk '{print $2}' | sort | uniq -c | sort -rn | head -10

# Identify unusual port usage
cat /opt/zeek/logs/current/conn.log | zeek-cut id.resp_p proto service | \
  sort | uniq -c | sort -rn | head -50
ステップ 6:SIEM との統合とアラートの設定
# Configure JSON log output for SIEM ingestion
sudo tee /opt/zeek/share/zeek/site/json-logs.zeek << 'EOF'
@load policy/tuning/json-logs.zeek
redef LogAscii::use_json = T;
EOF

# Forward logs to Elastic via Filebeat
# /etc/filebeat/filebeat.yml
sudo tee /etc/filebeat/filebeat.yml << 'EOF'
filebeat.inputs:
  - type: log
    enabled: true
    paths:
      - /opt/zeek/logs/current/*.log
    json.keys_under_root: true
    json.add_error_key: true
    fields:
      source: zeek
    fields_under_root: true

output.elasticsearch:
  hosts: ["https://elastic-siem:9200"]
  index: "zeek-%{+yyyy.MM.dd}"
  username: "elastic"
  password: "${ES_PASSWORD}"
EOF

sudo systemctl enable --now filebeat

# Set up log rotation
sudo tee /etc/cron.d/zeek-logrotate << 'EOF'
0 0 * * * root /opt/zeek/bin/zeekctl cron
EOF

# Monitor Zeek health
sudo zeekctl status
sudo zeekctl netstats

主要な概念

用語定義
Network Security Monitorトラフィックの流れを変更またはブロックすることなく、ネットワークトラフィックを監視して構造化されたメタデータログを生成するパッシブ分析ツールです
Zeek ScriptZeek のドメイン固有言語で記述されたイベント駆動型スクリプトです。ネットワークイベントを処理し、通知、ログ、メトリクスを生成します
Connection Log (conn.log)観測されたすべての接続について、送信元/宛先 IP、ポート、プロトコル、継続時間、バイト数を記録する、Zeek の中核的なログです
Notice Framework検出スクリプトが不審なアクティビティを特定した際にアラートを生成する Zeek のサブシステムです。出力先は notice.log です
SumStats Framework時間枠ごとにメトリクスを追跡する Zeek の統計分析フレームワークです。しきい値に基づく異常検出を可能にします
Intel Framework観測されたネットワークインジケーターを脅威インテリジェンスフィードと照合し、一致した場合にアラートを生成する Zeek モジュールです

ツールとシステム

  • Zeek 6.0+:パッシブなトラフィック分析から、プロトコルレベルの包括的なログを生成するオープンソースのネットワークセキュリティモニターです
  • zeek-cut:タブ区切り形式の Zeek ログファイルから特定の列を抽出し、すばやく分析するための Zeek ユーティリティです
  • zeekctl:単一またはクラスター構成の Zeek インスタンスをデプロイ、監視、管理するための Zeek 管理ツールです
  • RITA (Real Intelligence Threat Analytics):ビーコン動作、DNS トンネリング、その他の脅威インジケーターについて Zeek ログを分析するオープンソースツールです
  • Filebeat:一元的な分析と可視化のために、Zeek の JSON ログを Elasticsearch に転送する Elastic エージェントです

よくあるシナリオ

シナリオ:エンタープライズトラフィックにおけるコマンド&コントロールのビーコン通信の検出

コンテキスト:脅威インテリジェンスレポートによると、特定の脅威アクターは、侵害されたホストに対して60秒間隔でHTTPSビーコン通信を行っています。SOCチームは、2 Gbpsのトラフィックが流れるエンタープライズネットワーク全体で、このパターンを示すホストを特定するためにZeekログを分析する必要があります。

アプローチ:

  1. 高スループットでキャプチャできるよう、AF_PACKETを使用してインターネット出口地点のネットワークタップにZeekを導入します
  2. 1時間の観測ウィンドウで60秒間隔を検出できるよう、しきい値を調整してカスタムビーコン検出スクリプトを有効にします
  3. conn.logをクエリし、接続時間と接続間隔が一貫している外部IPへの接続を特定します。到着間隔の標準偏差が5秒未満の接続に絞り込みます
  4. 疑わしい宛先IPを、ZeekのIntelフレームワークに読み込まれた脅威インテリジェンスフィードと照合します
  5. 関連するTLS証明書をssl.logで調べ、自己署名証明書、異常な発行者名、有効期間の短い証明書がないか確認します
  6. 特定した各ビーコン通信元に対してnoticeを生成し、SOCによるトリアージのためにSIEMへ送ります

注意点:

  • 環境に合わせてビーコン検出のしきい値を調整しないと、正規の更新サービス(Windows Update、ウイルス対策ソフトの更新)による誤検知が発生します
  • CDNやクラウドサービスプロバイダーのIP範囲を除外しないと、通常の多数の反復接続が検出されます
  • CPUコアが不足した状態でZeekを実行すると、高スループットのリンクでパケットがドロップします
  • JSON形式のログ出力を有効にしないと、カスタムパーサーが必要になり、SIEMとの連携が不必要に複雑になります

出力形式

## Zeek Network Anomaly Detection Report

**Sensor**: zeek-sensor-01 (10.10.1.250)
**Monitoring Interface**: eth1 (span port from Core-SW1)
**Analysis Period**: 2024-03-15 00:00 to 2024-03-16 00:00 UTC
**Total Connections Logged**: 2,847,392

### Anomalies Detected

| Notice Type | Source | Destination | Details |
|-------------|--------|-------------|---------|
| DNS_Tunneling_Detected | 10.10.3.45 | 8.8.8.8 | 847 queries to suspect-domain.xyz in 5 min |
| Possible_Beaconing | 10.10.5.12 | 203.0.113.50:443 | 62 connections with 59.8s avg interval |
| SSL::Invalid_Server_Cert | 10.10.8.22 | 198.51.100.33:443 | Self-signed cert, CN=localhost |
| SSH::Password_Guessing | 45.33.32.156 | 10.10.20.11:22 | 487 failed attempts in 30 min |

### Recommendations
1. Isolate 10.10.3.45 and investigate for DNS tunneling malware
2. Block 203.0.113.50 at firewall and forensically image 10.10.5.12
3. Investigate self-signed TLS certificate on 198.51.100.33
4. Block 45.33.32.156 and enforce SSH key-only authentication

コメント