ここでは、意識的に ACID は使っていません。 そのうち使うかもしれませんが、検知とか、復旧に関わるものはなるべく単純な形のままにしたいのです。 $ tar xzf snort-2.0.1.tar.gz $ cd snort-2.0.1 snort-2.0.1$ ./configure snort-2.0.1$ make snort-2.0.1$ su snort-2.0.1# make install snort-2.0.1# mkdir /etc/snort snort-2.0.1# cp -p ./etc/snort.conf /etc/snort/. snort-2.0.1# cp -p ./etc/*.config /etc/snort/. snort-2.0.1# cp -p ./etc/*.map /etc/snort/. snort-2.0.1# cp -pr ./rules /etc/snort/. snort-2.0.1# vi /etc/snort/snort.confsnort-2.0.1# groupadd snort snort-2.0.1# useradd -g snort snort snort-2.0.1# mkdir /var/log/snort snort-2.0.1# chown snort:snort /var/log/snort snort-2.0.1# snort -u snort -g snort -c /etc/snort/snort.conf -l /var/log/snort -i eth1 -k none -deDy snort-2.0.1# cat >> /etc/rc.d/rc.local
#var RULE_PATH ../rules/etc/snort/rules にルール定義を置いたので修正 var RULE_PATH ./rules
snort -u snort -g snort -c /etc/snort/snort.conf -l /var/log/snort -i eth1 -k none -deDy
rules ファイルの更新 (ルールセットをアップデートしないと、最新の攻撃を検知できません) http://www.snort.org/dl/rules/ に最新の snortrules ファイルがあるので、これを設置します。 $ tar xzf snortrules-stable.tar.gz $ cd rules 変更点は何かな? rules$ for i in *.config ; do diff /etc/snort/$i $i ; done rules$ for i in *.map ; do diff /etc/snort/$i $i ; done rules$ for i in *.rules ; do diff /etc/snort/rules/$i $i ; done2003-07-29 バージョンでは、MSブラスター用のルールが追加されている模様。rules$ su rules# cp -p *.config /etc/snort/. それぞれのファイルをコピー rules# cp -p *.map /etc/snort/. rules# cp -p *.rules /etc/snort/rules/. rules# snort の再起動 (PID は /var/run/snort_eth1.pid : eth1 は環境によって違います) ルールファイルを更新するスクリプト (reprules.sh) を作ってみました。 root で実行する必要があります。 ルールの自動更新プログラムもありますが、 ワークエリアを指定するために専用の config を書きたくないので、スクリプトで何とかします。
*.config の比較 (変化無し)
*.map の比較 (シグネチャ ID に 2192,2193 が追加されている) 1c1 < # $Id: sid-msg.map,v 1.131 2003/07/21 22:16:01 cazz Exp $ --- > # $Id: sid-msg.map,v 1.132 2003/07/29 16:03:05 cazz Exp $ 2040a2041,2042 > 2192 || NETBIOS DCERPC ISystemActivator bind attempt || cve,CAN-2003-0352 > 2193 || NETBIOS SMB DCERPC ISystemActivator bind attempt || cve,CAN-2003-0352
*.rules の比較 (ポート 135,445 へのアクセスパターンが追加されている) 3c3 < # $Id: netbios.rules,v 1.25 2003/07/21 22:16:01 cazz Exp $ --- > # $Id: netbios.rules,v 1.26 2003/07/29 16:03:05 cazz Exp $ 29a30,32 > alert tcp $EXTERNAL_NET any -> $HOME_NET 135 (msg:"NETBIOS DCERPC ISystemAc 長いので省略 > alert tcp $EXTERNAL_NET any -> $HOME_NET 445 (msg:"NETBIOS SMB DCERPC ISyst 長いので省略 >スクリプト reprules.sh (755)
#!/bin/sh # snort のルールファイルを取得・更新するスクリプト # snort のルールファイル # wget でダウンロードし、ローカルにも保持するファイル # RULES_FILE=snortrules-stable.tar.gz # 更新前のタイムスタンプを取得 TIMESTAMP_OLD=0 if [ -f $RULES_FILE ] ; then TIMESTAMP_OLD=`/usr/bin/stat -t $RULES_FILE | /usr/bin/cut -d ' ' -f 13 -` fi # ルールファイルをダウンロード # (ローカルファイルより新しければダウンロード) # 残念ながら、終了コードでダウンロード状況を見分けることが出来ない。 # wget -q -N http://www.snort.org/dl/rules/$RULES_FILE # 更新後のタイムスタンプを取得 TIMESTAMP_NEW=0 if [ -f $RULES_FILE ] ; then TIMESTAMP_NEW=`/usr/bin/stat -t $RULES_FILE | /usr/bin/cut -d ' ' -f 13 -` fi MSG='' if [ $TIMESTAMP_NEW -le $TIMESTAMP_OLD ] ; then # ダウンロードしなかった MSG="snort rules is not download." else # ダウンロードしたルールファイルのほうが新しい /bin/gtar xzf $RULES_FILE cd ./rules WHATS_NEW='' for i in *.config ; do WHATS_NEW=$WHATS_NEW`/usr/bin/diff /etc/snort/$i $i` ; done for i in *.map ; do WHATS_NEW=$WHATS_NEW`/usr/bin/diff /etc/snort/$i $i` ; done for i in *.rules ; do WHATS_NEW=$WHATS_NEW`/usr/bin/diff /etc/snort/rules/$i $i` ; done if [ -n $WHATS_NEW ] ; then # 新しいルールをダウンロードしたが、変化が無かった MSG="snort rules is downloaded bat not find differences." else # 新しいルールに変化 (追加) があった mv *.config /etc/snort/. mv *.map /etc/snort/. mv *.rules /etc/snort/rules/. MSG="$WHATS_NEW" fi cd .. fi echo $MSG
ログの切り替え (snort の再起動) プレーンテキストのままログを保存するのに便利ですが、一瞬キャプチャが途絶える (下記青文字の部分) ので、気になる方は他の方法 (データベース利用) をお勧めします。 以下のファイルを作成し、定時に実行します。/home/snort/restart.sh 754# crontab -e -u root 上記スクリプトを定時に起動
#!/bin/sh # snort のログを切り替えるスクリプト cd /home/snort DATE=`date +%Y%m%d-%H%M%S` # snort が起動済みかチェック ALIVED=0 PID=`cat /var/run/snort_eth1.pid` if [ ! $PID == '' ]; then ALIVED=`ps -p $PID | grep snort | wc -l` fi if [ $ALIVED == 1 ]; then # 起動済みなので停止させる kill $PID # ログを保存 (リネーム) する mv /var/log/snort/alert /var/log/snort/alert-$DATE fi # ログファイルを snort グループで読めるようにする touch /var/log/snort/alert chmod 640 /var/log/snort/alert chown snort:snort /var/log/snort/alert # PROMISC を強制する /sbin/ifconfig eth1 promisc # snort を起動 (再起動) する /usr/local/bin/snort -u snort -g snort -c /etc/snort/snort.conf -l /var/log/snort -i eth1 -k none -deDy if [ $ALIVED == 1 ]; then # ついでにアーカイブする # 監視していない時間を短くするために、再起動した後にアーカイブします。 /usr/bin/gzip /var/log/snort/alert-$DATE fi
15 4 * * * [ -x /home/snort/restart.sh ] && /home/snort/restart.sh
ログ (/var/log/snort/alert) の読み方 [**] [分類:シグネチャID:リビジョン] 名称 [**] [Classification: Misc activity] [Priority: 3] 月/日/年-時:分:秒.少数秒 送信MACアドレス -> 受信MACアドレス type:0x800 len:0x6A 送信IPアドレス -> 受信IPアドレス ICMP TTL:120 TOS:0x0 ID:32548 IpLen:20 DgmLen:92 Type:8 Code:0 ID:512 Seq:34206 ECHO [Xref => 説明へのリンク]
ログの集計 ログのサマリを計算するスクリプト (logsum.pl) を作ってみました。 $ cat /var/log/snort/alert | logsum.pl 等として実行します。実行結果
1 99.14% 14442 Pr3 ICMP PING CyberKit 2.2 Windows 2 0.21% 30 Pr2 WEB-MISC robots.txt access 3 0.21% 30 Pr2 WEB-CGI count.cgi access 4 0.13% 19 Pr1 WEB-IIS cmd.exe access 5 0.13% 19 Pr1 WEB-IIS ISAPI .ida attempt 6 0.06% 9 Pr3 ICMP Destination Unreachable (Communication Administratively Prohibited) 7 0.03% 5 Pr2 MISC source port 53 to <1024 8 0.03% 5 Pr2 WEB-CGI campus access 9 0.02% 3 Pr2 SCAN SOCKS Proxy attempt 10 0.01% 2 Pr3 BAD-TRAFFIC tcp port 0 traffic 11 0.01% 2 Pr2 ATTACK-RESPONSES 403 Forbidden 12 0.01% 2 Pr2 MS-SQL Worm propagation attempt total: 14568 signalsスクリプト logsum.pl (755)そして、このスクリプトをメール送信するために呼び出してみます。
#!/usr/local/bin/perl use strict ; # 不審なパケットをカウントする my @sign = () ; my %sign = () ; my $total = 0 ; while (<>) { my $line = $_ ; chomp $line ; if ($line eq '') { if (@sign > 0) { my $first = $sign[0] ; $first =~ s/\s*\[\*\*\]\s*//g ; # 両脇の [**] を取り除く $first =~ s/\s*\[\d+:\d+:\d+\]\s*// ; # [1:123:4] を取り除く my($priority) = $sign[1] =~ /\[Priority:\s*(\d+)\]/ ; $first = "Pr$priority ".$first ; $sign{$first} ++ ; $total ++ ; } @sign = () ; } else { push @sign, $line ; } } # カウンタ順にソート (降順) して表示する my $lcnt = 0 ; foreach my $key (sort { $sign{$b} <=> $sign{$a} } keys %sign) { $lcnt ++ ; my $n = $sign{$key} ; printf "%3d ", $lcnt ; printf "%5.2f%% ", $n / $total * 100 ; printf "%6d ", $n ; print "$key\n" ; } print "total: $total signal" ; print "s" if $total > 1 ; print "\n" ;logsum_send.sh (755)$ crontab -e
#!/bin/sh MAILOFADMIN='net-admin@example.com' # 管理者のメールアドレスです。適宜変更してください。 cd /root # とりあえず /root です。環境に応じてカスタマイズしてください。 NOW=`date '+%m/%d %H:%M'` ARCDAY=`date +%Y%m%d` # 昨日なら `date +%Y%m%d -d yesterday` # 今日 (直前に) アーカイブしたアラートファイル ARCPATH='/var/log/snort/alert-'$ARCDAY'-*.gz' # アーカイブされたアラートファイルの存在チェック ARCEXIST=0 for f in $ARCPATH ; do if [ -f $f ]; then ARCEXIST=1 ; fi done # アーカイブされたアラートの復元準備 if [ $ARCEXIST -eq 1 ]; then ZCAT="/bin/zcat $ARCPATH" else ZCAT="" fi # 集計メールを送信する SUBJECT="snort logsum $NOW" if [ -f /var/log/snort/alert ]; then # alert がある場合 (cat /var/log/snort/alert ; $ZCAT) | ./logsum.pl | mail -s "$SUBJECT" $MAILOFADMIN elif [ ! -z $ZCAT ]; then # alert は無いが、アーカイブファイルがある場合 ($ZCAT) | ./logsum.pl | mail -s "$SUBJECT" $MAILOFADMIN fi17:00 にメールを飛ばします。(眠っていない時間をお勧めします)
0 17 * * * [ -x /root/logsum/logsum_send.sh ] && /root/logsum/logsum_send.sh
snort に最適なスイッチ (HUB と呼ぶのか、スイッチなのか難しい) FS808TP-V1 (アライドテレシス) 売価 16,000 円のくせに 100base でポートミラーリング (シャドウポートとも言う) が可能です。激安です。 kermit でも設定が出来るので、リモート操作も完璧です。 写真はアライドテレシスからのパクりです。 クリックするとカタログページへ飛びます。 kermit で操作するときは、以下のファイルを作成し、 # kermit FS808TP-V1 kermit を起動 C-Kermit>c kermit のプロンプトで 'c' を入力 として起動します。(当然、手動でも可)FS808TP-V1.ttyS1
set line /dev/ttyS1 set speed 9600 eight set parity none set stop-bits 1 set flow none set carrier-watch off