Snort 1.9.0をインストールして,可変IPアドレス環境向けに設定する

Snortの導入と活用

 侵入検知システムSnort(1.9.0)をインストールして使ってみます.

環境:

  • RedHat Linux 7.1 (Kernel 2.4.18-18.7.x)
  • rp-pppoe-2.6-5 と ppp-2.4.0-2 によるADSL常時接続

Snort 1.9.0のインストール

snort-1.9.0-1snort.i386.rpmを,Snort.orgからダウンロードしてくる.

さらに,libcapも必要ということなので,RPM Repositoryから, libpcap-0.6.2-11.7.1.0.i386.rpm をダウンロードしてきた.

これらのRPMを置いたディレクトリで,

# rpm -ivh *
としてインストールは完了.

Snortの設定 (ルールセット)

# rpm -ql snort-1.9.0-1snort
で確認したところ, インストール後のSnortのディレクトリ配置は,以下のようになっていました.

  • /etc/snort/ :ルールファイル
  • /usr/share/doc/snort-1.9.0/ :ドキュメント

どういうアクセスをSnortに検出させるかの設定ですが,とりあえず検出できるだけ検出させるという方針で行きます.

普通は自サーバに影響しないようなアクセスは,ルールセットから除外するらしいのですが, 今回は興味に任せた情報収集というつもりなので,拾えるものは何でも拾うことにします.

/etc/snort/snort.conf を編集して,末尾でコメント化されているルールセットのinclude群を,非コメント化.有効化しておきます.

#include $RULE_PATH/web-attacks.rules
#include $RULE_PATH/backdoor.rules
#include $RULE_PATH/shellcode.rules
 ・・・
 ↓ コメントを外す
include $RULE_PATH/web-attacks.rules
include $RULE_PATH/backdoor.rules
include $RULE_PATH/shellcode.rules
 ・・・

ホームネットワークの特定 (動的アドレス対応)

 Snortの設定で,HOME_NETとして自マシンのアドレスを特定しておきます.これをやらないと, どうしようもないほど意味のない検出が多発してしまいます.

しかしここに設定すべきIPアドレスは,非固定IPアドレスの常時接続の場合,接続するたびに変わってしまいます.

それで結構面倒な作業を強いられたのでした.

/etc/ppp/ip-up.local を,以下の内容で作成.

/etc/ppp/ip-up.local

/usr/sbin/snort -l /var/log/snort -A full -b -d -D -i ppp0 -c /etc/snort/snort.conf -h $IPLOCAL/32 -S HOME_NET=$IPLOCAL/32
touch /var/lock/subsys/snort

同様に,/etc/ppp/ip-down.local を以下の内容で作成.

/etc/ppp/ip-down.local

. /etc/rc.d/init.d/functions
killproc snort
rm -f /var/lock/subsys/snort

最後に,これらのファイルに実行属性を付けておく.

# chmod 755 /etc/ppp/ip*.local

 Snortはホームネットワークの設定を,起動時にしか読み込んでくれないので, 自マシンのIPアドレスが変更されたタイミングで,必ずSnortを再起動しなければならないという事情があります.

自マシンのIPアドレスが変更されるタイミングは,ADSLの接続確立時であるということと,

  • ADSLの接続時に,ip-up.local が実行される
  • ADSLの切断時に,ip-down.local が実行される

ということなので,これらのスクリプトの中でSnortの起動/停止を行うようにしました.
(参考:pppdのmanページ)

alertの集計

 ここまででひとまずSnortが動作するようになり,検出結果が

/var/log/snort/alert

に出力されます.

例 ↓

[**] [1:384:4] ICMP PING [**]
[Classification: Misc activity] [Priority: 3]
02/02-07:46:02.452012 202.64.23.179 -> 210.170.132.43
ICMP TTL:113 TOS:0x0 ID:18656 IpLen:20 DgmLen:64
Type:8  Code:0  ID:64206   Seq:0  ECHO

[**] [1:2003:2] MS-SQL Worm propagation attempt [**]
[Classification: Misc Attack] [Priority: 2]
02/02-09:21:16.121247 172.128.86.107:1075 -> 210.170.132.43:1434
UDP TTL:109 TOS:0x0 ID:34811 IpLen:20 DgmLen:404
Len: 384
[Xref => url vil.nai.com/vil/content/v_99992.htm][Xref => bugtraq 5311][Xref => bugtraq 5310]
・・・

しっかし,こんな感じで大量に吐かれるメッセージを毎日チェックするのは,骨が折れますので, 集計してやることにします.

ということでPerlで作ったのがこのプログラムです.

snort-summary.pl

#!/usr/bin/perl

use strict;

my($affair,$secline,$timeadrs);
my($affaircode,$affairname);
my($day, $time, $src, $spt, $dst, $dpt);
my($key);
my(%count);
my(@sorted_keys);
my($c);

print "affairname,count\n";

while (<>) {
    if ( /\[\*\*\]/ && !/Portscan/) {

        $affair = $_;
        $affair =~ s/\[\*\*\]//g;
        $affair =~ s/ $//;
        $affair =~ s/,/./g; # for CSV
        chomp($affair);
        ($affaircode, $affairname) = ($affair =~ /\[(\S+)\] (.*)/);
        $affaircode =~ s/:/-/g;

        $secline = <>;
        if ($secline =~ /->/) {
            $timeadrs = $secline;
        } else {
            $timeadrs = <>;
        }

        chomp($timeadrs);
        $timeadrs =~ s/ ->//;
        ($time, $src, $dst) = split(/\s+/, $timeadrs, 3);
        ($day, $time) = split('-', $time, 2);
        ($src, $spt) = split(':', $src, 2);
        ($dst, $dpt) = split(':', $dst, 2);

        $key = $affairname;

        if (defined($count{$key})) {
            $count{$key}++;
        } else {
            $count{$key} = 1;
        }
    }
}

@sorted_keys = sort keys(%count);

foreach $key (@sorted_keys) {
    $c = $count{$key};
    print "$key,$c\n";
}

exit 0;

Perlはあまり得意ではないので,いまいちスマートじゃないと思いますが,まあ動けば良いと.

これを例えば,snort-summary.pl とすれば,

$ ./snort-summary.pl < /var/log/snort/alert > summary.csv
という具合で実行すれば,集計結果のCSVテキストが得られます.

出力例 ↓

affairname,count
(snort_decoder) WARNING: IP dgm len < IP Hdr len!,1
ATTACK RESPONSES 403 Forbidden,96
EXPERIMENTAL WEB-MISC bad HTTP/1.1 request. potentual worm attack,6
WEB-ATTACKS cc command attempt,6
WEB-ATTACKS perl execution attempt,1
WEB-ATTACKS rm command attempt,1
WEB-CGI calendar access,18
WEB-CGI csh access,2
WEB-CGI finger access,1
WEB-CGI formmail access,4
WEB-CGI redirect access,5
WEB-CGI search.cgi access,2
WEB-CGI swc access,9
WEB-FRONTPAGE /_vti_bin/ access,9
WEB-IIS CodeRed v2 root.exe access,161
WEB-IIS ISAPI .ida access,22
WEB-IIS ISAPI .printer access,2
WEB-IIS cmd.exe access,1051
WEB-IIS msadc/msadcs.dll access,1
WEB-IIS scripts access,5
WEB-IIS view source via translate header,59
WEB-MISC /doc/ access,61
WEB-MISC count.cgi access,34
WEB-MISC robots.txt access,148
WEB-MISC whisker HEAD with large datagram,14
事象名と,その件数がカンマ区切りで出力されます.

これなら,そのままExcelで開くも良し,さらに加工するも良し.

我がカモランドでは,この集計処理をCRONに仕込んで自動化し,さらにHTML化しています. また,自分宛にメールとして届いたりもします...(やりすぎ)

メンテナンス

 あと,Snortを有効に使うためには,ルールセットをきちんと更新する必要があります.

ちょくちょく Snort.org とか,Whitehats Network Security Resource などをチェックして, ルールセットを追加しておくべし.

例えば最近だと,MQ SQL Slammerのルールが出ていました.

まぁ,SQL Slammerの場合は,パケットフィルタリングでUDPポート1434をチェックしていれば検知できるのですが, Snortはパケットの中身まで見てくれるので,さらに高度な検知が可能です.

例えば,上記の例における「WEB-」系は,HTTPの「GETメソッドで何を取得しようとしているのか」 まで立ち入ってチェックしてくれているということになります.

参考:

kamolandをフォローしましょう


© 2017 KMIソフトウェア