はじめに
Snort のような侵入検知システム(IDS)は、悪意のあるネットワークトラフィックを識別するためにルールに大きく依存しています。適切に作成されたルールはシグネチャ(署名)として機能し、データパケット内に特定のパターンが観測された際にシステムがアラートを発報できるようにします。
シグネチャベースの検知は、攻撃者の意図を直接理解するのではなく、既知のパターンを認識することで機能します。これは高速で有用ですが、完璧ではありません。パターンが広すぎると誤検知(False Positive)が発生し、狭すぎると攻撃者がわずかな変更を加えるだけで回避されてしまいます。そのため、優れたルール作成とは、精度と網羅性のバランスを取る作業と言えます。
この実験では、セキュリティアナリストの役割を体験します。アプリケーション層への攻撃を検出できる Snort ルールを作成します。具体的には、PCAP(Packet Capture)ファイルにキャプチャされた SQL インジェクション攻撃のシミュレーションペイロードを分析し、基本的なコンテンツマッチングと高度な正規表現(PCRE)の両方を使用して、HTTP トラフィックを検査し、悪意のある文字列を検出した際にアラートを出す Snort ルールを作成します。
攻撃ペイロードの分析(PCAP)
このステップでは、ネットワークパケットキャプチャファイルを分析し、悪意のあるペイロードがどのようなものかを理解します。検知ルールを作成する前に、セキュリティアナリストは自分が何を検知しようとしているのかを正確に把握しなければなりません。
この順序は重要です。初心者が陥りがちな間違いは、実際のトラフィックを調査する前にシグネチャの作成を始めてしまうことです。実務において、防御側は通常、PCAP、ログサンプル、エクスプロイトの概念実証(PoC)といった証拠から着手します。観測可能なパターンを理解して初めて、それをルールに変換するのです。
環境には、~/project ディレクトリ内に sqli_attack.pcap というファイルが事前に用意されています。このファイルには、攻撃者が Web サーバーに対して SQL インジェクション攻撃を試みているシミュレーションネットワークパケットが含まれています。
この PCAP ファイルの内容を調査するために、tcpdump というツールを使用します。tcpdump コマンドは強力なコマンドラインパケットアナライザーです。-A フラグを使用すると、パケットの内容を ASCII(プレーンテキスト)で表示できるため、HTTP リクエストの読み取りに最適です。-r フラグは、ライブのネットワークインターフェースではなくファイルから読み取るよう tcpdump に指示します。
ターミナルで以下のコマンドを実行し、ペイロードを分析してください。
tcpdump -A -r sqli_attack.pcap
以下のような出力が表示されるはずです。
reading from file sqli_attack.pcap, link-type EN10MB (Ethernet), snapshot length 262144
10:23:45.123456 IP 192.168.1.100.12345 > 192.168.1.10.http: Flags [P.], seq 1:78, ack 1, win 8192, length 77: HTTP: GET /login.php?user=admin'%20UNION%20SELECT%201,2,3-- HTTP/1.1
E..u..@.@............9.P..P.P.......+......GET /login.php?user=admin'%20UNION%20SELECT%201,2,3-- HTTP/1.1
Host: example.com
出力のプレーンテキスト部分をよく見てください。/login.php に対して HTTP の GET リクエストが行われているのがわかります。user パラメータに注目してください:admin'%20UNION%20SELECT%201,2,3--。
%20 はスペース文字を URL エンコードしたものです。UNION SELECT というフレーズは、攻撃者が自身の悪意のあるデータベースクエリの結果を元のクエリと結合しようとする、SQL インジェクション攻撃の典型的なシグネチャです。これこそが、私たちが検知したい正確なシグネチャです。
コンテンツマッチングルールの作成
このステップでは、前のステップで見つけた SQL インジェクションのシグネチャを検出するためのカスタム Snort ルールを作成します。
content キーワードは、ペイロード検査の最も単純な形式です。リテラル文字列を検索するため、高速で論理的な推論が容易です。リテラルマッチングは、検知ロジックを透明化できるため、シグネチャの最初のドラフトとして適していることが多いです。
Snort ルールは特定の構文で記述されます。基本的なルールは、ルールヘッダーとルールオプションで構成されます。
- ヘッダーは、アクション、プロトコル、送信元/宛先 IP アドレス、およびポートを定義します。
- オプションは、検索する特定のコンテンツと、アラートがトリガーされたときに表示するメッセージを定義します。
ポート 80(標準的な HTTP ポート)宛のすべての TCP トラフィックにおいて、UNION%20SELECT という正確な文字列を探すルールを作成します。
nano テキストエディタを使用してカスタムルールファイルを開きます。
nano ~/project/rules/local.rules
ファイルに以下の行を追加してください。
alert tcp any any -> any 80 (msg:"Basic SQL Injection Detected"; content:"UNION%20SELECT"; sid:1000001; rev:1;)
このルールの意味を解説します。
alert: ルールが一致したときに実行するアクション(アラートを生成)。tcp: 検査するプロトコル。any any -> any 80: 送信元 IP とポート(任意)から宛先 IP(任意)のポート 80 へ。msg:"...": アナリストに表示するアラートメッセージ。content:"UNION%20SELECT": Snort がパケットペイロード内で検索する正確な文字列。sid:1000001: Snort ID。カスタムルールには 1,000,000 以上の ID を割り当てる必要があります。rev:1: ルールのリビジョン番号。
行を追加したら、Ctrl+O、Enter、Ctrl+X の順に押してファイルを保存し、nano を終了します。
cat コマンドを使用して、ルールファイルの内容を確認できます。
cat ~/project/rules/local.rules
PCRE(正規表現)の設定
このステップでは、PCRE(Perl Compatible Regular Expressions:Perl 互換正規表現)を使用して検知能力を強化します。
正規表現は、単一の正確なバイトシーケンスではなくパターンのファミリーを記述するため、柔軟性が向上します。これは強力ですが、過剰検知のリスクも高まります。防御側は、攻撃者が基礎となる動作を維持しつつフォーマットを変化させる可能性がある場合に PCRE を使用します。
content キーワードは高速で効果的ですが、非常に厳格です。攻撃者はペイロードをわずかに変更して検知を回避しようとすることがよくあります。例えば、%20(URL エンコードされたスペース)の代わりに、通常のスペース(``)、複数のスペース、あるいはプラス記号(+)を使用するかもしれません。単純な content マッチでは、これらのバリエーションを見逃してしまいます。
PCRE を使用すると、柔軟なパターンを記述できます。UNION SELECT 攻撃のバリエーションを捉えるために、正規表現を使用した 2 つ目のルールを作成します。
ルールファイルを再度開きます。
nano ~/project/rules/local.rules
最初のルールの下の新しい行に、以下の新しいルールを追加してください。
alert tcp any any -> any 80 (msg:"Advanced SQL Injection Detected"; pcre:"/UNION(%20|\s|\+)SELECT/i"; sid:1000002; rev:1;)
pcre オプションを解説します。
pcre:"/ ... /i": スラッシュは正規表現の開始と終了を示します。末尾のiは大文字と小文字を区別しない検索(union、UNION、UnIoNなどに一致)を意味します。UNION: UNION という単語に一致します。(%20|\s|\+): これは OR ロジック(|)を持つキャプチャグループです。%20、または空白文字(\s)、またはプラス記号(\+)のいずれかに一致します。SELECT: SELECT という単語に一致します。
ファイルを保存して nano を終了します(Ctrl+O、Enter、Ctrl+X)。
これで local.rules ファイルには、SQL インジェクションの試行を捉えるために設計された 2 つの異なるルールが含まれているはずです。
ルール検知の検証
最後のステップでは、作成したカスタムルールをテストします。Snort をオフラインモードで実行し、sqli_attack.pcap ファイルを読み込ませて、local.rules に記述したルールを適用するように指示します。
紙の上では正しく見えるルールでも、運用上は失敗する可能性があるため、既知のサンプルに対してテストすることは不可欠です。検証を行うことで、ルールが意図したトラフィックに対して実際に発報することを確認できます。これは、ライブ環境でルールを信頼する前の最低限の要件です。
Snort はさまざまなフラグを指定して実行できます。今回は以下を使用します。
-q: クワイエットモード。大きなバナーや初期化テキストを抑制し、出力を読みやすくします。-c: 使用する設定ファイルまたはルールファイルを指定します。-r: 読み込む PCAP ファイルを指定します。-A console: アラートをターミナルコンソールに直接出力するよう Snort に指示します。
以下のコマンドを実行して、悪意のあるペイロードに対してルールをテストしてください。
sudo snort -q -c rules/local.rules -r sqli_attack.pcap -A console
ルールが正しく記述されていれば、以下のような出力が表示されるはずです。
10/23-10:23:45.123456 [**] [1:1000001:1] Basic SQL Injection Detected [**] [Priority: 0] {TCP} 192.168.1.100:12345 -> 192.168.1.10:80
10/23-10:23:45.123456 [**] [1:1000002:1] Advanced SQL Injection Detected [**] [Priority: 0] {TCP} 192.168.1.100:12345 -> 192.168.1.10:80
おめでとうございます!両方のルールが正常にトリガーされました。最初のルールは正確な文字列に一致し、2 番目のルールは正規表現を使用してパターンに一致しました。あなたはセキュリティアナリストとして、脅威を特定し、それを検知するためのシグネチャをデプロイすることに成功しました。
まとめ
この実験では、カスタム Snort ルールを作成することで、ネットワーク侵入検知の実践的な経験を積みました。まず、生のパケットキャプチャを分析して SQL インジェクション攻撃の特定のシグネチャを特定しました。次に、そのシグネチャを基本的なコンテンツマッチング Snort ルールに変換する方法を学びました。最後に、Perl 互換正規表現(PCRE)を実装して攻撃のバリエーションを捉えることで検知能力をアップグレードし、悪意のあるトラフィックに対して Snort を実行することでルールを正常に検証しました。これらのスキルは、ネットワークインフラストラクチャの防御を任されたサイバーセキュリティ専門家にとって不可欠なものです。



