📄 snort_stat.pl
字号:
#!/usr/bin/perl ## $Id: snort_stat.pl,v 1.3 2000/11/17 05:28:20 jpickel Exp $# $Revision: 1.3 $## snort_stat.pl is a perl script trying to generate statistical data from every# day snort log file.## USAGE: cat <snort_log> | snort_stat.pl -r -f -a -h -p -n# -r: resolve IP address to domain name# -f: use fixed rather than variable width columns# -a: snort alert format# -h: produce html output# -p: portscan log (in syslog now)# -n: anomsensor log (in syslog)## or put it in the root's crontab file:#59 10 * * * root cat /var/log/authlog | /etc/snort_stat.pl | sendmail root## $Author: jpickel $# Yen-Ming Chen, <chenym@ALUMNI.CMU.EDU># $Date: 2000/11/17 05:28:20 $# # Angelos Karageorgiou, <angelos@unix.gr># contributed the DNS resolve and cache## Andrew R. Baker <andrewb@uab.edu># 2000.03.06 - modifications to read snort alert file# - added html output option## Paul Bobby, <paul.bobby@lmco.com># 03/13/2000 added scan for portscan detection in logs## Ned Patterson, <jpatter@alum.mit.edu> # 4/26/2000 - correctly parse "last message repeated" syslog messages# - variable column widths for text output# # Ryan Jian-Da Li, <jdli@freebsd.csie.nctu.edu.tw># 6/07/2000 - fix the problem of portscan() (add my %s5)# - fix the problem of signature matching# for the case ' IDS154 - PING CyberKit 2.2 Windows'# - enhance portscan(), add port counts#use Getopt::Std; # use Getopt for optionsuse Socket; # use socket for resolving domain name from IPuse vars qw($opt_r $opt_f $opt_a $opt_h $opt_p $opt_n);%HOSTS = (); # Hash for IP <-> domain name mapping getopts('rfahnp') || die "Could not getopts"; # get options in command line$saddr_len = 15;$daddr_len = 15;$timeout = 3; # for name resolver# process whatever comes inwhile (<>) { if ($opt_a) { # process data from a snort alert file chomp(); # if the line is blank, go to the next one if ( $_ eq "" ) { next; } # is this line an alert message unless ( $_ =~ /^\[\*\*\]/ ) { # comment out this line to avoid some warning # print STDERR "Warning, file may be corrupt.\n"; next; } $a = <>; chomp($a); unless ( $a eq "" ) { # strip off the [**] from either end. s/(\s)*\[\*\*\](\s)*//g; } else { print STDERR "Warning, file may be incomplete\n"; next; } $sig = $_; $a =~ m/^(\d+)\/(\d+)\-(\d+)\:(\d+)\:(\d+)\.(\d+)\s ([\d\.]+)[\:]*([\d]*)\s[\-\>]+\s([\d\.]+)[\:]*([\d]*)/ox; $month = $1; $day = $2; $hour = $3; $minute = $4; $second = $5; $saddr = $7; $host = "localhost"; $sport = $9; $daddr = $9; $dport = $10; } else { # If this is a snort log in syslog if ($_ =~ m/^(\w{3}) \s+ (\d+) \s (\d+) \: (\d+) \: (\d+)\s ([\w+\.]*)\s[\w+\/\[\d+\]]*:\s ([^:]+):\s ([\d\.]+)[\:]? ([\d]*)\s[\-\>]+\s ([\d\.]+)[\:]? ([\d]*)/ox) { $month = $1; $day = $2; $hour = $3; $minute = $4; $second = $5; $host = $6; $sig = $7; $saddr = $8; $sport = $9; $daddr = $10; $dport = $11; } elsif ($_ =~ m/^(\w{3})\s+(\d+)\s(\d+)\:(\d+)\:(\d+)\s ([\w+\.]*)\s[\w+\/\[\d+\]]*: \sspp_portscan\:\sPORTSCAN\sDETECTED\sfrom\s([\d\.]+)/ox) { if ($opt_r) { $psaddr = resolve($7); } else { $psaddr = ($7); } push @res , [$psaddr]; push @rescnt , [$psaddr,$8]; # Not used elsewhere. Prob not needed. (Need to find out!) # $tot++; next; } elsif ($_ =~ m/^(\w{3})\s+(\d+)\s(\d+)\:(\d+)\:(\d+)\s ([\w+\.]*)\s[\w+\/\[\d+\]]*\: \sspp_anomsensor\:\sAnomaly\sthreshold\sexceeded\:\s([\d\.]+)\: \s([\d\.]+)\:([\d]+)\s[\-\>]+\s([\d\.]+)\:([\d]+)/ox) { if ($opt_r) { $asaddr = resolve($8); $adaddr = resolve($10); } else { $asaddr = ($8); $adaddr = ($10); } $threshold = $7; $sport = $9; $dport = $11; push @anores , [$threshold,$asaddr,$sport,$adaddr,$dport]; next; } # If a snort message has been repeated several times elsif ($lastwassnort && $_ =~ m/last message repeated (\d+) times/) { # put the data in the matrix again for each repeat $repeats = $1; while ($repeats) { push @result, $result[-1]; $repeats--; } next; } else { $lastwassnort = 0; next; } # Message not related to snort } # if the resolve switch is on if ($opt_r) { $saddr = resolve($saddr); unless ($opt_f) { if ( length($saddr) > $saddr_len ) { $saddr_len = length($saddr); } } $daddr = resolve($daddr); unless ($opt_f) { if ( length($daddr) > $daddr_len ) { $daddr_len = length($daddr); } } } # put those data into a big matrix push @result ,[$month,$day,$hour,$minute,$second, $host,$sig,$saddr,$sport,$daddr,$dport]; $lastwassnort = 1;} # end of snort log# begin statistics# I should've used $#result + 1 as $total in the first version! :($total = $#result + 1;for $i ( 0 .. $#result ) { # for the same pair of attacker and victim with same sig # to see the attack pattern # used in same_attack() $s0{"$result[$i]->[9]:$result[$i]->[7]:$result[$i]->[6]"}++; # for the same pair of attacker and victim # to see how many ways are being tried # used in same_host_dest() $s1{"$result[$i]->[7]:$result[$i]->[9]"}++; # from same host use same method to attack # to see how many attacks launched from one host # used in same_host_sig() $s2{"$result[$i]->[6]:$result[$i]->[7]"}++; # to same victim with same method # to see how many attacks received by one host # used in same_dest_sig_stat() $s3{"$result[$i]->[6]:$result[$i]->[9]"}++; # same signature # to see the popularity of one attack method # used in attack_distribution() $s4{"$result[$i]->[6]"}++; # source ip $s5{"$result[$i]->[7]"}++; # destination ip $s6{"$result[$i]->[9]"}++;}# begin reportprint_head();print_summary();same_attack();same_host_dest();same_host_sig();same_dest_sig_stat();attack_distribution();if ($opt_p) { portscan();}if ($opt_n) { anomsensor();}print_footer();# print the header (e.g. for mail)sub print_head { if($opt_h) { print "<html>\n<head>\n"; print "<title>Snort Statistics</title>"; print "</head>\n<body>\n"; print "<h1>Snort Statistics</h1>\n"; } else { print "Subject: snort daily report\n\n"; }}# print the time of begin and end of the logsub print_summary { if($opt_h) { print "<table>\n"; print "<tr><th>The log begins at:</th>\n"; print "<td>$result[0]->[0] $result[0]->[1] $result[0]->[2]:$result[0]->[3]:$result[0]->[4]</td></tr>\n"; print "<tr><th>The log ends at:</th>\n"; print "<td>$result[$#result]->[0] $result[$#result]->[1] $result[$#result]->[2]:$result[$#result]->[3]:$result[$#result]->[4]</td></tr>\n"; print "<tr><th>Total events:</th><td> $total</td></tr>\n"; print "<tr><th>Signatures recorded:</th><td> ". keys(%s4) ."</td></tr>\n"; print "<tr><th>Source IP recorded:</th><td> ". keys(%s5) ."</td></tr>\n"; print "<tr><th>Destination IP recorded:</th><td> ". keys(%s6) ."</td></tr>\n"; print "<tr><th>Anomaly detected:</th><td> ". eval '$#anores + 1'."</td></tr>\n"; print "</table>\n"; print "<hr>\n"; } else { print "The log begins from: $result[0]->[0] $result[0]->[1] $result[0]->[2]:$result[0]->[3]:$result[0]->[4]\n"; print "The log ends at: $result[$#result]->[0] $result[$#result]->[1] $result[$#result]->[2]:$result[$#result]->[3]:$result[$#result]->[4]\n"; print "Total events: $total\n"; print "Signatures recorded: ". keys(%s4) ."\n"; print "Source IP recorded: ". keys(%s5) ."\n"; print "Destination IP recorded: ". keys(%s6) ."\n"; print "Anomaly recorded: ". eval '$#anores +1'."\n"; }}# to see the frequency of the attack from a certain pair of # host and destinationsub same_attack { if($opt_h) { print "<h3>The number of attack from same host to same destination using same method</h3>\n"; print "<table>\n";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -