#!/usr/bin/perl ########################################################################## # $Id: firewall.pl,v 1.05 2003/06/12 Lars Exp $ ########################################################################## use Getopt::Long; $basedir="/var/log"; $logfile="/var/log/firewall.log"; $TopLines = 10; $PortsOnly = 0; $dns = 0; GetOptions ("l|log=s" => \$logfile, "p|port" => \$PortsOnly, "d|dns" => \$dns, "n=s" => \$TopLines); $TotalEntries=0; @PortCount = (); # Now, let's open the file, and start parsing it. if (open (LOG, $logfile)) { # File is opened, let's go! $line = ; while ($line) { # Only grab the "Port Scan" alerts (for now) if ($line =~ m/ Port Scan attack/) { @item = split(/ /, $line); # account for days with only one digit, extra space is added in syslog if ($item[1] == "") { $item[1] = $item[2]; $item[9] = $item[10]; $item[11] = $item[12]; } # Make all days 2 digits for easy sorting $ldate = $item[0] . " " . sprintf("%02d", $item[1]); # some general statistics $TotalEntries++; $DailyEntries{$ldate}++; # grab the port numner @temp = split (/:/, $item[11]); $port = $temp[1]; if ($line =~ m/ICMP/) { $port = "ICMP"; } # count the number of hits per port $PortCount{$port}++; # Get the source IP of the offenders @stemp = split (/=/, $item[9]); @stemp2 = split (/:/, $stemp[1]); $SourceIP = $stemp2[0]; # print "$SourceIP \n"; $PortAndIP{$port}{$SourceIP}++; } #grab next line; $line = ; } close(LOG); } if (!$PortsOnly){ print "------------------------------------------------\n"; print "Total Number of port scans logged: $TotalEntries\n"; print "------------------------------------------------\n"; } if (keys %DailyEntries && !$PortsOnly) { print "\nPort Scans per day\n"; print "-----------\n"; foreach $This (sort(keys %DailyEntries)) { printf ("%-6s %4d\n", $This, $DailyEntries{$This}); } print "-----------\n"; } if (keys %PortCount) { print "Ports hit\n"; print "-----------\n"; $count=0; foreach $This (sort {$PortCount{$b} <=> $PortCount{$a} }keys %PortCount) { if (++$count <= $TopLines ) { printf ("%5s %4d\n", $This, $PortCount{$This}); } } print "-----------\n"; } $outercount=0; if (!$PortsOnly){ foreach $Port (sort {$PortCount{$b} <=> $PortCount{$a} }keys %PortCount) { if (++$outercount <= $TopLines) { print "Port Number: $Port\n"; $innercount = 0; foreach $SourceIP (sort {$PortAndIP{$Port}{$b} <=> $PortAndIP{$Port}{$a} }keys %{$PortAndIP{$Port}}) { if (++$innercount <= $TopLines) { if ($dns) { printf (" Host: %-50s %6d\n", dns_lookup($SourceIP), $PortAndIP{$Port}{$SourceIP}); } else { printf (" IP: %-16s %6d\n", $SourceIP, $PortAndIP{$Port}{$SourceIP}); } } } } } } sub dns_lookup { my $value = shift; if($value =~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) { unless ($hostcache{$value}) { $hostcache{$value} = lc(gethostbyaddr(pack("C4", split(/\./, $value)), 2)) || "[$value]"; } return $hostcache{$value}; } else { return $value; } }