はじめに
文書チームの検出器は collector.example.test/collect への全 POST を通知します。許可された公開デモも含まれます。許可通信を維持しながら、内部文書アップロードに絞ってください。
この独立環境には前のルート検出器 broad.rules と、完全な合成 TCP/HTTP キャプチャがあります。コマンドは Analyst タブで実行します。記録済みの要求を見るには Traffic Reference タブを選択してください。参照画面が直接開きます。同じ例は traffic/requests.txt にもあります。前の VM のファイルは不要です。本文検査はこの平文 HTTP に対するもので、暗号化 HTTPS には適用しません。
機密文書の情報を見つける
このステップでは、本文の手掛かりが有用でも単独では不十分だと確認します。classification=internal は文書の取扱区分を示す架空の業務フィールドで、完了マーカーではありません。
このステップを始めるには、ラボ画面の Analyst タブを選択してください。
Traffic Reference タブに切り替えて要求本文を比較し、Analyst タブに戻ります。参照を読み、付属検出器を再生します。オプションは前と同じで、-S が指定ルールのみ、-r が入力 PCAP、-l が出力先です。

次のコマンドを実行する前に、Analyst タブに切り替えてください。
cat traffic/requests.txt
mkdir -p broad-output
suricata --runmode single -c suricata.yaml -S broad.rules -r traffic/core.pcap -l broad-output --init-errors-fatal
python3 /opt/c09/read-alerts.py broad-output/eve.json
公開文書 2 件を含む 4 件のアラートになります。classification=public はこのルートで公開デモに使える文書内容を示します。ポリシーはメソッド、送信先、ルート、内部分類の組み合わせです。
新しいバッファを学ぶため本文だけの検出器を試します。http.request_body の後の content は、複数の TCP パケットにまたがっていても復元した本文を検査します。再構築はエンジンが行い、パケット単位の文字列検索とは異なります。分類は長い本文内の 1 フィールドなので、バッファ全体の境界条件は加えません。
前と同様に複数行をそのまま入力します。> はファイルを置き換え、終端の RULE は単独行です。
cat > body.rules <<'RULE'
alert http any any -> any any (msg:"Review document upload"; flow:established,to_server; http.request_body; content:"classification=internal"; sid:1000001; rev:1;)
RULE
mkdir -p body-output
suricata --runmode single -c suricata.yaml -S body.rules -r traffic/core.pcap -l body-output --init-errors-fatal
python3 /opt/c09/read-alerts.py body-output/eve.json
結果は Alerts: 9 です。承認済み送信先の内部文書も、PUT や別の収集先ルートとともに検出されます。機密の単語をどこででも探す条件は広すぎます。この結果は実験として残し、最終ポリシー検出器にはしません。
python3 /opt/c09/check.py body.rules body
両データセットでその本文を含む 9 件が一致します。構文エラーならブロックを書き直せます。追記イベントで件数を誤解しないよう、新しい出力先で再試行してください。
条件を組み合わせてバランスをテストする
このステップでは、学んだ 4 フィールドを有用な検出器にまとめます。POST、正確な収集先ホスト、正確なアップロードルートを維持し、内部分類条件を加えます。
このステップを始めるには、ラボ画面の Analyst タブを選択してください。
最終成果物 local.rules を作ります。別バッファの条件は AND で結合され、同じトランザクションがすべて満たす必要があります。sid:1000001 は一意のローカル識別子で、有効なルールは 1 つで十分です。
次のコマンドを実行する前に、Analyst タブに切り替えてください。
cat > local.rules <<'RULE'
alert http any any -> any any (msg:"Review document upload"; flow:established,to_server; http.method; content:"POST"; startswith; endswith; http.host; content:"collector.example.test"; startswith; endswith; http.uri; content:"/collect"; startswith; endswith; http.request_body; content:"classification=internal"; sid:1000001; rev:1;)
RULE
再生前に -T で構文をテストします。ディレクトリと -l は構文テストにも書き込み可能な出力先を与えます。パケットは読まず設定とルールを読み込みます。構文成功だけでは検出品質は分かりません。
mkdir -p syntax-output
suricata -T -c suricata.yaml -S local.rules -l syntax-output --init-errors-fatal
mkdir -p final-output
suricata --runmode single -c suricata.yaml -S local.rules -r traffic/core.pcap -l final-output --init-errors-fatal
python3 /opt/c09/read-alerts.py final-output/eve.json
結果は Alerts: 2、ポートは 41002 と 41007 です。どちらも内部文書が POST で未承認ルートに送られています。公開デモ、承認済みアップロード、ヘルスチェック、別メソッド・ルートは通知されません。アラートはなお action: allowed と表示します。オフライン検出は観察であり、アップロードを阻止しません。
正例・負例を含む回帰チェッカーを実行します。回帰テストは変更後に既知の一致すべき場合・しない場合を再確認します。表示例に加え、文書名やポートを変えた例も新しい出力先で再生します。古いイベント数ではなくルール自体を検査します。
python3 /opt/c09/check.py local.rules final
両行とも意図した 2 件の一致と、比較例の非検出を示します。もう一度実行しても結果とキャプチャは変わりません。漏れは条件の限定しすぎやバッファ違い、余分な通知は条件不足や緩さを疑います。local.rules を書き直して再試行してください。エンジンを無効にしたり、正常な比較通信を削除したりしないでください。
実証するのは範囲を限定したポリシー検出であり、万能な情報漏えい検出ではありません。大きい本文、暗号化、エンコーディング、他プロトコルは別の設計とテストが必要です。次のチャレンジはポリシーの事実を変え、同じ 4 バッファを使います。
まとめ
ルートのみの検出器と本文のみの実験を比較し、4 つの HTTP フィールドを組み合わせました。新しい出力先と正例・負例のあるデータセットで提出ルールをテストし、可視性の制限を明示しました。



