ネットワーク型IDS「Snort」のシグネチャ作成法:ゼロから始めるLinuxセキュリティ(最終回)
Snortを導入しただけでは、環境に則した侵入検知はできない。各種のログを基に、環境に適したシグネチャを作成しよう。
前回は、Snortの導入方法について説明しました。とはいえ、IDSは導入自体よりも導入後の運用の方が難しく、重要なことです。
IDSの運用には、ログ解析はもちろん、検出ルールの見直しなどが必要です。セキュリティ監視を実施するのであれば、IDSのログだけでなく、システムログやアプリケーションログも解析の対象になります。そこで、今回はログ解析を含めた運用方法について説明します。
ログの重要性
ログにはIDSによるものだけなく、システムログやアプリケーションログがあります。各ログは、その特徴からいろいろな場面で非常に役立ちます。不正アクセスに関する情報を収集するのであれば、IDSから出力されるログ以外にも目を向ける必要があります。
システムログには、ログイン/ログアウトなどのイベントがテキスト形式で出力されます。テキスト形式なので特定の文字列の検索も簡単で、不正アクセスの痕跡を比較的容易に見つけ出すことができます。ホスト型IDSの中には、ログインやログアウトも検出できるものも存在します。以前紹介したTripwireはこのようなイベントを検出できないため、システムログの情報は非常に貴重なものです。
アプリケーションログは、Webアプリケーションなどが生成するログです。この情報もシステムログと同様、非常に有益な情報源といえます。アプリケーションログは通常、アプリケーション上のトラブルシュートやアクセス状況を確認するために利用することが考えられます。この利用方法はまったく間違っていませんが、不正アクセスによる被害を受けてしまった際にも非常に役立ちます。例えば、URLにある異常な文字列を入力するような攻撃であれば、Webアプリケーションのログから知ることができます。
このように書いてしまうと、IDSを導入する必要はないのではと思われるかもしれませんが、もちろんそんなことはありません。IDSであれば、イベントを検出した際に何らかの方法で管理者にそれを通知する仕組みを持っています。しかしながら、システムログやアプリケーションログに頼る場合は、通知する仕組みを自分で作り込まなければなりません。また、IDSのログからはどのような攻撃を実際に受けているか簡単に分かりますが、システムログやアプリケーションログから攻撃の兆候や痕跡を読み取るには、それなりの知識が必要です。
コラム:ログの防衛
前述したように、ログファイルにはシステム上でどのようなことが発生したのかといった情報が残されています。万が一、不正アクセスによる被害を受けてしまったら、ログファイルから侵入経路や攻撃方法などを解析することになります。逆に、これらの情報は攻撃を行った側にとっては残したくないものです。例えるなら、泥棒が仕事を終えて立ち去る際に指紋を消すのと同じことです。攻撃者は、侵入に成功したら立ち去る際にログファイルを削除しようとするものです。
そこで、このログファイルを守ることも考えなければなりません。ログファイルのパーミッションを変更することも必要でしょう。しかしながら、これだけでは万全とはいえません(編注)。
そこで、ログを収集するための専用機を用意することも必要でしょう。また、不正アクセスによる侵入などをIDSでリアルタイムに検出したら、即座にネットワークケーブルを抜いてネットワークから隔離するのも有効な手段といえるでしょう。
ログをベースにしたシグネチャの作成
Webサーバのアクセスログに次のようなログが見つかったとします。
192.168.0.100 - - [07/Jun/2002:01:18:22 +0900] "GET /cgi-bin/test.cgi HTTP/1.1" 404 288 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
「cgi-bin/test.cgi」というファイル名がありますが、このようなファイルがシステムに存在しないとします。システム上に存在しないファイルへのリンクが張られていることはあまりないので、何者かが意図的に上記のようなGET要求を出したと考えられます。CGIファイルなどはよく狙われるものです。CGIの作りが悪いと、意図しない情報が漏えいするなどの被害が考えられます。つまり、何者かが不正アクセスを試みていると判断できるのです。
では、これをSnortで検出できるかというと、もともと用意されているシグネチャではできません。システム上に存在しないCGIファイルやPHPファイルへのアクセスが頻繁に見つかるようであれば、何者かが狙っているかもしれないので注意が必要です。そこで、Snortでtest.cgiへのアクセスを検出できるように、対応するシグネチャを作成してみましょう。シグネチャを作成すれば、新たな攻撃手法が発見されてもすぐに対応できるのです。
Snortのシグネチャは、ルールヘッダと括弧でくくられたルールオプションに分かれています。
alert tcp any any -> 192.168.0.100 80 (msg:"WEG-CGI test.cgi access"; uricontent; "test.cgi"; flags:A+; priority:10;)
上記のシグネチャを作成することで、先ほどまで検出できなかったtest.cgiファイルへのアクセスを検出できるようになります。このシグネチャを例に、作成方法を説明します。
ルールヘッダ
括弧でくくられた部分より左側をルールヘッダと呼びます。ルールヘッダの先頭には、そのルールにマッチしたときに起こす行動(アクション)を指定します。ここでは「alert」が指定されています。これは、マッチしたイベントを検出すると指定されたとおりにアラートを出力し、パケットの内容をログに記録します。
アクションは、すでに紹介したalertも含めて5種類あります。
alert | アラートを出力し、パケットの内容をログに記録する |
---|---|
log | パケットの内容をログに記録する(アラートは出さない) |
pass | パケットをパス(通過)させ、このパケットのチェックを終了する |
activate | アラートを出力し、dynamicを有効にする |
dynamic | activateから呼び出され、指定された処理を実行する |
次に指定するのがプロトコルです。プロトコルは、tcp、udp、icmpが指定可能です。
さらに、IPアドレス、ポート番号とその方向を指定します。
IPアドレスは、ネットマスクと一緒に指定します。よって、ネットワークアドレスでの指定も可能です。クラスCのネットワークアドレスであれば、
192.168.0.0./24
のように指定します。ホスト1台のIPアドレスを指定する場合は、32bitのネットマスクですから「/32」と指定するわけですが、この場合は省略できます。さらに、「any」と指定することも可能です。
ポート番号は、IPアドレスに続けて指定します。ポート番号は1つあるいはレンジ指定が可能です。1番から1024番ポートまでを指定するのであれば、次のように指定します。
1:1024
3000番ポート以上を指定する場合は、次のように指定します。
3000:
また、ポート番号もIPアドレスと同様に、「any」と指定することができます。
データの流れる方向も指定できます。シグネチャの作成例から分かるように、「xxxからzzzへ」流れるものを検出することもできるのです。これには、「<-」「<>」「->」の3つの記号のうちの1つを指定します。
これまでの説明で、シグネチャの作成例では次のようなことを意味していると分かります。
tcp any any -> 192.168.0.100 80
IPアドレス192.168.0.100のホストの80/TCPあてについては、送信元を限定せずに検出する
IPアドレスやポート番号を指定するとき、「!」を前に付けることで否定できます。これは、例えば「特定アドレス以外」からのパケットを検出したいときなどに役立ちます。「192.168.0.100の22/TCP(ssh)へのアクセスで、送信元が192.168.0.0/24からのものは検出しない」ようにするには、
tcp !192.168.0.0/24 any -> 192.168.0.100 22
のように指定すればいいのです。
ルールオプション
ルールオプションには、さらに詳細な条件を指定します。ここで指定した条件により、発生した通信が攻撃なのか単なる通常のアクセスなのかを判断します。各オプションで指定するキーワードと値は「:」(コロン)、複数のオプションを指定する場合は「;」(セミコロン)で区切ります。
代表的なキーワードを紹介しましょう。
●msg
指定された文字列をアラートまたはログに出力します。検出した内容が簡単に分かるような文字列にするといいでしょう。出力する文字列は、「"」(ダブルクオーテーション)でくくります。次のフォーマットで指定します。
msg: "<message text>";
●logto
アラートを検出したときにログを出力するファイルを指定します。バイナリ形式でログを保存する機能を有効にしている場合、この機能は使えません。次のフォーマットで指定します。
logto: "<filename>";
●flags
セットされているTCPフラグを評価します。フラグは、以下のように1文字で指定できます。また、複数を組み合わせて指定することも可能です。
F | FIN |
---|---|
S | SYN |
R | RST |
P | PSH |
A | ACK |
U | URG |
2 | 予約ビット2 |
1 | 予約ビット1 |
0 | フラグのセットなし |
さらに、3つのパラメータを指定することもできます。
+ | 指定されたフラグとそれ以外のフラグが指定されているものにマッチ |
---|---|
* | 指定されたフラグのうちの何かにマッチ |
! | 指定されたフラグがパケットにセットされていないものにマッチ |
「flags: A+;」のように指定されている場合、ACKフラグとそれ以外のフラグがセットされているものにマッチすることを表しています。
●content
指定されたデータとのパターンマッチを行います。送り込まれるデータとマッチすればアラートとして検出します。これは、不正アクセスを検出するとても重要な項目です。テキストデータのほかに、16進のバイナリデータも指定可能です。テキストとバイナリのデータを混在させて指定することもできます。次のフォーマットで指定します。
content: "<content string>";
バイナリデータは「|」でくくります。
content: "|63 68 61 72 73 74 20 3D 20 22 22|";
●uricontent
要求のURI部分だけでマッチングを行います。次のようなフォーマットで指定します。
uricontent; "<content string>";
●nocase
contentで指定された文字列の大文字/小文字を区別しません。
●regex
contentで指定された文字列中で「*」や「?」を使えるようにします。それぞれの意味は以下のとおりです。
* | 任意の文字列にマッチ |
---|---|
? | 任意の1文字にマッチ |
●priority
検出したアラートの重要度を指定します。ポートスキャンなど、攻撃のための事前調査やバッファオーバーフロー攻撃などでその重要度は変わってくるので、区別するためにも指定するとよいでしょう。次のフォーマットで指定します。
priority: <priority integer>;
検出ルールの変更
IDSでは、ログの管理や解析だけが運用というわけではありません。さらに行う必要があるのが、検出ルールの変更です。ネットワーク構成が変更されれば、当然ルールも変える必要があるでしょう。
また、ある意味IDSの特徴といってもいいものに「誤検知」というものがあります。誤検知が発生する原因はいろいろ考えられます。単にIDSの作り自体に問題があることもあれば、設定した検出ルールやシグネチャの作りに問題がある場合などがあります。
設定した検出ルールに問題がある場合は、すぐに修正すべきです。このタイプの誤検知を防ぐには、まずネットワーク構成を理解することです。前回も説明したとおり、IDSの設置場所によっても変わってきますが、仮にDMZに設置したのであれば発生すると想定される通信は限定できるでしょう。Webサーバしか存在しないネットワークならば、SMTPに関する検出ルールは外してもいいでしょう。監視対象が多ければそれだけIDSマシンの負荷が高くなるので、不要なものは対象外とするべきです。
別の考え方もあります。SMTPの通信が発生しないと断定できるのであれば、SMTPの通信が発生すること自体が問題であると判断できます。この場合は、SMTPの通信が発生した時点でアラートとなるような検出ルールを用意するとよいでしょう。
ほかにも、通常の通信にもかかわらずアラートとして検出してしまうことがあります。例えば、稼働監視のために使用しているアプリケーションによる通信がそれに当たります。あるアラートが定期的に検出されるようであれば、その可能性を検討する必要があります。
IDSは、いかに安定した運用にまで持っていくかが大きなポイントです。適切な検出ルールを設定しておかないと、毎日大量のログ解析に追われることになってしまうのですから。
Copyright © ITmedia, Inc. All Rights Reserved.