18. 網虫偵測

偵測 W2K Nimda 網虫

package Apache::Detect_worms;
#----------------------------------------------------------------#
# $Id: chapI.sgml,v 1.1.1.1 2003/08/14 00:26:12 ols3 Exp $
# $Log: chapI.sgml,v $
# Revision 1.1.1.1  2003/08/14 00:26:12  ols3
# perl_intro
#
# Revision 1.3  2002/02/15 01:36:32  OLS3
# *** empty log message ***
#
# Revision 1.2  2002/01/06 17:01:47  OLS3
# 網虫偵測模組
#
#----------------------------------------------------------------#

use strict;
use vars qw($VERSION);
use Apache::Constants qw(OK DECLINED FORBIDDEN);
use Cache::FileCache;
use Symbol 'gensym';

$VERSION = 1.00;

my %cache_options = ('default_expires_in' => 86400 );

sub handler
{
    my $r = shift;

    my $file_cache = new Cache::FileCache(\%cache_options);

    unless ($file_cache) {
	return DECLINED;
    }

    my $remote_ip_address = $r->get_remote_host();

    my $visited = $file_cache->get($remote_ip_address);

    unless($visited) {
      my $fh = Apache->gensym;
      my $log_file="/home/apache2/lib/perl/Apache/worm_list." . get_date();
      open($fh, ">> $log_file");
      print $fh "$remote_ip_address\n";
      close($fh);
      $file_cache->set($remote_ip_address, 1);
    }

    return FORBIDDEN;

}

sub get_date {

  my ($sec,$min,$hour,$day,$mon,$year)=localtime(time);

  $mon++;
  if (length ($mon) == 1) {$mon = '0'.$mon;}
  if (length ($day) == 1) {$day = '0'.$day;}
  $year+=1900;
  my $date="$year$mon$day";
  return $date;
}

1;

__END__

wormlist.cgi

#! /usr/bin/perl
# $Id: chapI.sgml,v 1.1.1.1 2003/08/14 00:26:12 ols3 Exp $
# 
# $Log: chapI.sgml,v $
# Revision 1.1.1.1  2003/08/14 00:26:12  ols3
# perl_intro
#
# Revision 1.1  2002/01/06 17:03:06  OLS3
# Initial revision
#
use strict;

my $h = parse_input();

my $d=$h->{d}; 
if ($d) { unless ($d =~ /^200\d{5}$/) {no_this_day();}};
my $log_file;

unless ($d) { $d = get_date(); }

$log_file="/home/apache2/lib/perl/Apache/worm_list.$d";

print <<HTML_HERE;
    <html>
    <head>
    <meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=big5">
    <title>網虫偵測程式</title>
    </head>
    <body bgcolor="white">
    <H3>以下Win2000主機感染 Nimda/CodeRed 網虫,請儘速修補主機漏洞!</H3>
網虫偵測程式 Apache::Detect_worms v1.0.1 (c) 2001 written by OLS3
<br><a href="http://www.tnc.edu.tw">回教網中心</a> <a href="javascript:history.back()">回上一頁</a>
<br>
<font color="red">修補資訊</font>: <a href="http://www.cc.ncku.edu.tw/virus/Nimda/index.htm">W32/Nimda</a>
 <a href="http://www.cc.ncku.edu.tw/virus/CodeRed/">CodeRed</a> (成大區網提供)
    <hr>
日期: $d (觀看時, 建議: 先拿掉您的瀏覽器中的 PROXY 設定.)
HTML_HERE

if (-f $log_file) {
    open(FHD, "$log_file");
    my @all=<FHD>;
    close(FHD);
    foreach (@all) {
	if (is_net_TNC($_)) {
	    print "<br><b><font color=red>縣內主機</font></b> --------> $_";
	} else {
	    print "<br>縣外主機 --------> $_";
	}
    }
} else {
    print "<br>本日尚未有資料\n";
}

print <<HTML_END;
<br><br>
<hr>
這是一個 Nimda /CodeRed 網虫偵測公告的 Apache 模組, 可和 Apache 結合在一起, 並可防止 Linux 主機被咬.
Linux 主機被咬並無大礙, 只是記錄檔中常常會有一堆訊息, 本模組可拒絕 Nimda/CodeRed 攻擊!
<br>請各校經常觀看此一公告程式, 若貴校 W2000 主機名列其中, 請儘速修補漏洞.
<p>記錄檔<br>
HTML_END

history_list();


print <<HTML_END2;
</body>
</html>

HTML_END2


sub get_date {
  my ($sec,$min,$hour,$day,$mon,$year)=localtime(time);
  $mon++;
  if (length ($mon) == 1) {$mon = '0'.$mon;}
  if (length ($day) == 1) {$day = '0'.$day;}
  $year+=1900;
  my $date="$year$mon$day";
  return $date;
}

sub is_net_TNC {
    my $ip=shift;
    if ($ip =~ /^163\.26\.(\d+)/) {
	($1 >= 80 && $1<=206) ? return 1 : return 0;
    } else {
	return 0;
    }
}

# 列出過去的記錄
sub history_list {
    my @history_list=glob("/home/apache2/lib/perl/Apache/worm_list.*");
    foreach (@history_list) {
	my ($n, $d)=split(/\./);
	print qq(<a href="/perl/worm_list.cgi?d=$d">$d</a><br>\n);
    }
}

sub parse_input {
	my $temp=$ENV{'QUERY_STRING'};
	my @pairs=split(/&/,$temp);
	my %OLS3;
	foreach my $item(@pairs) {
		my ($key,$content)=split (/=/,$item,2);
		$content=~tr/+/ /;
		$content=~ s/%(..)/pack("c",hex($1))/ge;
		$OLS3{$key}=$content;
	}
	return \%OLS3;
}

sub no_this_day {
    print "沒有這一天的記錄!\n"; exit;
}