#!/usr/bin/perl -w
#
# modified for the Debian package by Christian Hammers <ch@westend.com>
# and "Mario 'BitKoenig' Holbe" <Mario.Holbe@RZ.TU-Ilmenau.DE>
#
# Changelog:
# 2000-12-07,ch@debian.org
#	Added hint to /var/log/auth.log
# 2000-07-04,ch@debian.org
#	Adjusted the regex as the log format had changed.
#
# $Id: snort_stat.pl,v 1.2 1999/11/23 05:33:48 yenming Exp $
# $Revision: 1.2 $
#
# 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
#
# $Author: yenming $
# Yen-Ming Chen, <chenym+@CMU.EDU>
# $Date: 1999/11/23 05:33:48 $
#

#
#####################  set variables  ###############################
#

$portscanlog = "";

$treshold = $ENV{'DEBIAN_SNORT_STATS_TRESHOLD'};
$treshold = 1 unless defined $treshold;
$treshold = 1 unless $treshold =~ /^\d+$/;

$hostname = `hostname`; chomp($hostname);

$theday = `/bin/date --date yesterday +"%h %-d"`; chomp($theday);

#
###################  process whatever comes in  ###################
#

$lastWasSnort = 0;
while (<>) {
  # the portscans
  if (/^(\w{3})+\s+(\d+)\s+([\d: ]+).*spp_portscan: End of portscan from ([\d\.]+)(.*)/) {
    my($tmp_day,$tmp_time,$tmp_ip,$tmp_stats) = ("$1 $2",$3,$4,$5);
    my($tmp_name);
    next if "$tmp_day" ne $theday; # auth.log sometimes rotates weekly
    $tmp_name=`host -t a $tmp_ip 2>/dev/null`;
    if ((not defined $tmp_name) || ($tmp_name eq "")) {
	$tmp_name=$tmp_ip;
    } else {
	$tmp_name=~/Name:\s+([^\s]+)\n/;
	$tmp_name=$1;
    }
    $portscanlog .= "$tmp_time$tmp_name$tmp_stats\n";
    next;
  }
  
  # if the last line was a snort line, check if it's repeated...
  # For snort log, added by $Author: yenming $
  if ($lastWasSnort) {
    if (/^(\w{3})\s+(\d+)\s(\d+)\:(\d+)\:(\d+)\s(\w+)\s
        last\smessage\srepeated\s(\d+)\stimes/ox) {
      $month  = $1; $day   = $2;  $hour  = $3; $minute = $4;
      $second = $5; $host  = $6;  $rep   = $7;

      # put old data n times into a big matrix
      for ($i = 0; $i < $rep; ++$i) {
        push @result , [$month,$day,$hour,$minute,$second,$host,$sig,$saddr,$sport,$daddr,$dport];
      }
      # Don't reset $lastWasSnort here - the 'repeated' line could happen
      # more than one time.
      # A small speed up :-)
      next;
    } else {
      $lastWasSnort = 0;
    }
  }

  # For snort log, added by $Author: yenming $
  # If this is a snort log
  if (/^(\w{3})\s+(\d+)\s(\d+)\:(\d+)\:(\d+)\s([\w-]+)\ssnort\[\d+\]:\s+
      ([^:]+):\s([\d\.]+)[\:]*([\d]*)\s[\-\>]+\s([\d\.]+)[\:]*([\d]*)/ox)
    {
      $month  = $1; $day   = $2;  $hour  = $3; $minute = $4;

      $second = $5; $host  = $6;  $sig   = $8; $saddr  = $9;
      $sport  = $10; $daddr = $11; $dport = $12;
 
      # auth.log gets rotated monthly
      next if "$month $day" ne "$theday";
	
      # put those data into a big matrix
      push @result , [$month,$day,$hour,$minute,$second,$host,$sig,$saddr,$sport,$daddr,$dport];

      $lastWasSnort = 1;
  }
}
exit 0 if ($#result==-1 and $portscanlog eq "");

#
####################  compute statistics  #########################
#

foreach $i (@result) {
  # for the same pair of attacker and victim with same sig
  # to see the attack pattern
  # used in same_attack()
  $s0{"$i->[7],$i->[9],$i->[6]"}++;
}

#
###################  write output  ##################################
#

printf "Subject: %s: snort daily report\n\n", $hostname;

if ($#result != -1) {
    printf
       "The log begins from: %3s %02d %02d:%02d:%02d\n".
       "The log ends at:     %3s %02d %02d:%02d:%02d\n".
       "\n".
       "Look at /var/log/auth.log for detailed logs and at /var/log/snort/ for\n".
       "tcpdump readable packet dumps.\n",
       $result[0]->[0], $result[0]->[1], $result[0]->[2], $result[0]->[3], $result[0]->[4],
       $result[$#result]->[0], $result[$#result]->[1], $result[$#result]->[2], $result[$#result]->[3], $result[$#result]->[4];

# to see the frequency of the attack from a certain pair of
# host and destination
    format SAME_ATTACK_TOP =

The number of events from same host to same destination using same method
===============================================================================
    events                                      from
===============================================================================
.
format SAME_ATTACK =
@>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$s0{$k}, $_[2],                                $hostname
.

    $^	= SAME_ATTACK_TOP;
    $~ = SAME_ATTACK;

    foreach $k (sort { $s0{$b} <=> $s0{$a} } keys %s0) {
	@_ = split ",",$k;
	last if  $s0{$k} <= $treshold;
	$hostname=`host $_[0] 2>/dev/null`;
	$hostname=$_[0] if (not defined $hostname) || ($hostname eq "");
	$hostname=~ s/Name: //g; chomp($hostname);
	write;
    }
}

# write portscan statistics
$portscanlog =~ s/TOTAL //g;
print "\nPORTSCANS:\n$portscanlog";

exit(0);

