CGI にする必要はないのですが... Nimda 系の attack があったかどうかを Web server のログから確認します。
CGI 用のディレクトリに入れてください。
URL: http://localhost/cgi-bin/nimda.rb でアタックのあった時間順に結果が表示されます。
実行サンプルを示したいのですが、アタック元を示すのもなんですし...
Web ブラウザでの表示上は Ruby のスクリプトですが、HTML の特殊文字をエスケープしています。 テキストとしてセーブしてご利用ください。
#! /usr/local/bin/ruby
# /home/tetsu/src/ruby/cgi/nimda.rb
# Created: April 02,2002 Tuesday 14:02:24
# Author: tetsu(WATANABE Tetsuya)
# $Id: nimda.rb,v 1.3 2002/04/23 15:54:47 tetsu Exp $
# usage:
def log2time(str)
arr = str.split('[:/]')
Time.mktime(arr[2], arr[1], arr[0], arr[3], arr[4], arr[5])
end
ip = {}
count = Hash.new(0)
f = File.open('/var/log/httpd/access_log')
while f.gets
if ~/cmd\.exe\?/ ||
~/root\.exe\?/ ||
~/XXXXXXXXXXXXXXXX/ ||
~/NNNNNNNNNNNNNNNNNN/
arr = split
log_time = arr[3][1..-1]
time = log2time(log_time)
count[arr[0]] += 1
if ip[arr[0]]
ip[arr[0]] = time if ip[arr[0]] < time
else
ip[arr[0]] = time
end
end
end
f.close
require 'socket'
require 'cgi-lib'
tab_str = CGI::tag('tr') {
CGI::tag('th') { 'date time' } + \
CGI::tag('th') { 'ip address' } + \
CGI::tag('th') { 'attack count' } + \
CGI::tag('th') { 'hostname' }
}
hostname = ''
ip.keys.sort {|a, b|
ip[b] <=> ip[a]
}.each do |k|
begin
arr = TCPSocket.gethostbyname(k)
hostname = arr[0]
rescue SocketError
hostname = CGI::tag('br')
end
tab_str.concat CGI::tag('tr') {
CGI::tag('td') { ip[k].strftime('%x %X') } + \
CGI::tag('td') { k } + \
CGI::tag('td') { count[k] } + \
CGI::tag('td') { hostname }
}
end
CGI::print('Content-Type: text/html') {
CGI::tag('html') {
CGI::tag('head') {
CGI::tag('title') { 'NIMDA attack' } + \
CGI::tag('link', 'href' => '/base.css', 'type' => 'text/css', 'rel' => 'stylesheet')
} +\
CGI::tag('body') {
CGI::tag('h2') { 'NIMDA attack to ' + Socket.gethostname } + \
CGI::tag('table', 'border' => '1') { tab_str }
}
}
}
あんまり役立つものではないのですが、どのくらいアタックがあったか簡単に確認できるように。 かなり頻繁にアタックがあったりしますので、注意してくださいね。
最初の公開です。