※ご注意
本稿の内容を検証する場合は、必ず影響を及ぼさない限られた環境下で行って下さい。また、本稿を利用した行為による問題に関しましては、筆者および株式会社アットマーク・アイティは一切責任を負いかねます。ご了承ください。
今回はSnortのシグネチャを自作できるようになるために、シグネチャの構造について解説していきたい。通常、あらかじめ用意されたシグネチャだけで事足りることと思うが、それらではカバーできない部分も当然のことながら存在する。そんなとき、自作のシグネチャを活用すれば、まさに“かゆい所に手が届く”Snortを作り出すことができる。
始めに、シグネチャの例を見ていこう。まずは標準添付されているシグネチャの中から1つ抜き出して見てみよう。下記はweb-php.rulesに含まれているシグネチャだ(便宜上改行しているが実際は1行である)。
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"WEB-PHP admin.php file upload attempt"; flow:to_server,established; uricontent:"/admin.php"; nocase; content:"file_name="; reference:bugtraq,3361; classtype:attempted-admin; sid:1300; rev:5;)
それではシグネチャの構成を見ていこう。なお、シグネチャは「ルールヘッダ」と「ルールボディ」の2つのパートに分かれている。これらについては順を追って説明していく。
ルールヘッダは、シグネチャにとって必要不可欠な存在である。ルールヘッダには、ルールアクション、ソース/ディスティネーションIPアドレス、ポート番号、方向指示子を指定する。
例示したシグネチャの先頭に「alert」という部分がある。ここがルールアクションを指定する部分である。「ルールアクション」とは、そのシグネチャにマッチするパケットが存在した場合に、どのような処理を行うのかを指定する部分である。
ルールアクションには「alert」を含め5つのアクションを指定できる。
alert | ルールにマッチしたパケットを記録し、アラートを出力する | |
log | ルールにマッチしたパケットを記録する(アラートは出力しない) | |
pass | ルールにマッチしたパケットを無視する(記録もせず、アラートも出力しない) | |
activate | ルールにマッチしたパケットが存在した場合、アラートを出力し対応するdynamicルールアクションを呼び出す | |
dynamic | 対応するactivateルールアクションから呼び出され、logルールアクションと同様に記録のみを行う | |
上記のうち、activateとdynamicの使い方がいまいち理解しにくいと思うので、少し補足しておこう。以下のサンプルを見ていただきたい。
activate tcp any any -> any 80 (activate:8888; msg "There is web access";) dynamic tcp any any -> any any (activate_by:8888; count:1024;)
上記のように指定すると、80番ポートへのアクセスが発生した場合、そのトラフィック中の1024個のパケットが記録される。activateルールアクションに指定された番号(activate:)とdynamicルールアクションに指定された番号(actibate_by:)が一致していることに注意してほしい。activateルールアクションは、この番号が合致したdynamicルールアクションを呼び出す。そして、呼び出されたdynamicルールアクションは、countで指定された分のパケットを記録する。なお、言うだけやぼなことと思うが、上記のサンプルをそのまま適用してはいけない。
実は、ユーザー独自のルールアクションを定義することも可能であるが、今回は説明を割愛させていただく。通常は上記のルールアクションだけで事足りるはずだ。
ルールアクションの後ろに、半角スペースを1つ置いてプロトコルを指定する。例示したシグネチャでは「tcp」が指定されていることが確認できる。この部分に指定できるプロトコルには、下記のものがある。
残念ながら、現時点でのSnortは上記の4つのプロトコルのみにしか対応していない。最新のプロトコル対応状況については、Snort公式サイトを参照してほしい。なお、1つのシグネチャには1つのプロトコルしか指定できないことに注意してほしい。
ルールアクションとプロトコルに続いて、ソース/ディスティネーションIPアドレスを指定する。IPアドレスの指定方法としては、個別のIPアドレス(例:192.168.1.1)やCIDR(例:192.168.1.0/24)のいずれかを使用する。
場合によっては、「○○以外のIPアドレス」といった指定がしたくなるかもしれない。その場合は、否定演算子である「!」をIPアドレスの直前に付加するとよい(例:!192.168.1.1)。
また、範囲で指定したい場合は、ブラケット([ ])中にカンマ区切りで該当するIPアドレスを列挙すればよい(例:[192.168.1.0/24,192.168.100.1,127.0.0.1])。
もし、ワイルドカードを使用したい場合、すなわち任意の IP アドレスを指定したい場合は、「any」を使用すればよい。
例示したシグネチャでは、ソースIPアドレスに「$EXTERNAL_NET」、ディスティネーションIPアドレスに「$HTTP_SERVERS」が指定されている。これら$で始まる部分はsnort.conf中で定義されている変数である。ちなみにこの部分は、外部から内部のHTTPサーバへのアクセスにマッチする。
ソース/ディスティネーションIPアドレスの後ろに、半角スペース1つを置いて指定するのがポート番号である。ポート番号の指定方法は、IPアドレスのそれに似ている。例えば、ワイルドカードの「any」や否定演算子の「!」が使用できる。
ただし、範囲指定をしたい場合は、その方法が多少異なるので注意が必要である。IPアドレスの場合はブラケット([ ])を使用したが、ポート番号の場合はコロン(:)を使用する。例えば、0から1024までのポートを指定したい場合は、「0:1024」のように指定する。
ちなみに「:1024」や「1024:」のような指定方法もある。前者のように指定すると1024番ポート以下のすべてが対象となり、後者のように指定すると1024番ポート以上のすべてが対象となる。
ネットワークについてある程度の理解を持っておられる方なら、この指定がTCPおよびUDPでのみ有効であることにお気付きになるだろう。では、ICMPやIPではこの指定は不要なのだろうか?
その答えは「不要だが必要」といった禅問答のようなものとなってしまう。実はSnortは、ICMPやIPの場合にはこの部分の指定を無視するのであるが、このポート番号に何らかの値が指定されていることを前提に処理を行うのである。よって、ICMPやIPの場合にはanyを指定するとよい。
さて、ここまで読み進めてきた方の中には、例示したシグネチャ中の「->」という部分が気になっている方がいらっしゃるかもしれない。C言語をご存じの方はアロー演算子を連想されるかもしれないが、ちょっとその発想は横に置いておいてほしい。
閑話休題、方向指示子について説明しよう。方向指示子とはパケットの流れる方向を定義するものである。例示したシグネチャでいえば、「->」が該当するわけであるが、これは、ソースIPアドレスからディスティネーションIPアドレスへのパケットの流れであることを示す。つまり、外部から内部へのパケットがマッチすることになる。
方向指示子には「->」と「<->」の2種類のみが存在する。残念ながら「<-」は存在しないので十分注意してほしい。
ソース/ディスティネーションIPアドレス、ポート番号、そして方向指示子を適切に使用するだけでも、ある程度柔軟な指定が行える。なので、これらの指定方法についてしっかりと理解しておいてほしい。
独自ルールファイルで細かなチューニング
Page1
シグネチャの構成
ルールヘッダ:ルールアクション
ルールヘッダ:プロトコル
ルールヘッダ:ソース/ディスティネーションIPアドレス
ルールヘッダ:ポート番号
ルールヘッダ:方向指示子
ルールボディ:contentオプション
ルールボディ:uricontentオプション
ルールボディ:depthオプション
ルールボディ:offsetオプション
ルールボディ:nocaseオプション
ルールボディ:sessionオプション
ルールボディ:statelessオプション
ルールボディ:regexオプション
ルールボディ:flowオプション
ルールボディ:fragbitsオプション(IPオプション)
ルールボディ:sameipオプション(IPオプション)
ルールボディ:ipoptオプション(IPオプション)
ルールボディ:IDオプション(IPオプション)
ルールボディ:tosオプション(IPオプション)
ルールボディ:ttlオプション(IPオプション)
ルールボディ:seqオプション(TCPオプション)
ルールボディ:flagsオプション(TCPオプション)
ルールボディ:ackオプション(TCPオプション)
ルールボディ:icmp_idオプション(ICMPオプション)
ルールボディ:icmp_seqオプション(ICMPオプション)
ルールボディ:icodeオプション(ICMPオプション)
ルールボディ:itypeオプション(ICMPオプション)
ルールボディ:sidオプション
ルールボディ:revオプション
ルールボディ:priorityオプション
ルールボディ:classtypeオプション
ルールボディ:referenceオプション
ルールボディ:msgオプション
ルールボディ:logtoオプション
Copyright © ITmedia, Inc. All Rights Reserved.