Hi,

I have written a perl script called Analyze that will run through
sendmail's log files and pull out information regarding Infected mails
captured by ClamAV. I wrote this script as we needed greater visibilty
of what ClamAV was dropping and I couldn't find anything that would give
me the info I required.

By default it will run through the /var/log/maillog and print the full
message headers for each infected mail and then print a summary of the
Virus detected.

It has other options including the ability to:

       1. Display Top Email Sender addresses
         2. Display Top Relay Servers sending Infected mails
         3. Display only  Virus Summary
         4. Can be pointed at any logfile you desire
         5. Can search through logfile for specific Msg ID and show
headers of that mail.

I have included source code below.

Please be gentle as I am relatively new to PERL scripting, but any
enhancements or fixes you can recommend will be greatly appreciated.

If anyone finds this script useful please let me know ).

David Wells


------------------Analyze-----------------------------------------------
------
#!/usr/bin/perl
# Analyze by D J Wells
#
# 16/06/05 
#        
#
# This script processes Sendmail log files and prints the full message
headers 
# from infected mails identified by ClamAV in a Human Readable format.
It then 
# attempts to catalogue# each diffrent type of Virus and print out a
summary 
# of viruses encountered.
# Mangle the variables above the warning to your liking, but it would be

# adviseable not to venture past the warning unless you know a # bit of
perl and are comfortable doing so. # # # CHANGELOG # # 17/06/05 0.1.1
Added New Disply functions for Virus Count to display in Decending order

# 17/06/05 0.1.2 Added ability to search for specific msgid in any
logfile and print headers # 17/06/05 0.1.3 Added help functionality #
17/06/05 0.1.4 Added --viruscount functionality # 17/06/05 0.1.5 Added
total to --viruscount functionality # 20/06/05 0.1.6 Added --from
functionality (Had to add the Email::Address pkg to pull the email
address from the string) 
# 20/06/05 0.1.7 Added --relay functionality  
#
#
use strict;
use Email::Address;

my $ver = "v0.1.7";
our $logfile = "/var/log/maillog";
my $searchstring = "Infected";

print " Argument 1: $ARGV[0]\n";
print " Argument 2: $ARGV[1]\n";

########################################################################
# DO NOT MUCK AROUND BELOW THIS POINT UNLESS YOU KNOW WHAT YOU'RE DOING
########################################################################

my $counter = 0 ;
my @log;
my @infected;
my %virus = ();
my $infected;
our $msgid;
our $msgid_set = 0 ;
my $infectedinst;
my $key;
my $viruscount;
our $total;
our $from_set = 0;
our $relay_set = 0;
my $addr_spec = $Email::Address::addr_spec;
our %email_addresses;
our %relay;
#print "email_address_regexp: $addr_spec\n";

if( ($ARGV[0] =~ /--logfile=(.*)/i or $ARGV[1] =~ /--logfile=(.*)/i) ) {
        $logfile = "$1";
        print "User Input: Logfile = $logfile \n";      
} 

if( ($ARGV[0] =~ /--msgid=(.*)/i or $ARGV[1] =~ /--msgid=(.*)/i) ) {
        $msgid = $1;
        $msgid_set = "1";
        print "User Input: msgid = $msgid \n";
} 

if( ($ARGV[0]  =~ /--viruscount/i or $ARGV[1]  =~ /--viruscount/i) ) {
        $viruscount = "1";
}

if( ($ARGV[0]  =~ /--from/i or $ARGV[1]  =~ /--from/i) )
{
        $from_set = "1";
}

if( ($ARGV[0]  =~ /--relay/i or $ARGV[1]  =~ /--relay/i) )
{
        $relay_set = "1";
}

if( ($ARGV[0] =~ /--help/i or $ARGV[1] =~ /--help/i) )
{
        print "------Analyze $ver by D Wells------------\n";
        print "\tHelp Menu\n";
        print "\t--from*              #Don't print message headers just
print summary of email addresses used to send infected mail\n";
        print "\t--relay*             #Don't print message headers just
print summary of hosts used to send infected mails\n";
        print "\t--viruscount*        #Don't print message headers just
print summary of viruses encountered\n";
        print "\t--msgid=<msgid>*     #look up specific message headers
for certain msgid\n";
        print "\t--logfile=<logfile>  #point analyze to diffrent logfile
Default:/var/log/maillog\n";
        print "\t--help               #print this help menu\n";
        print "\n";
        print "\tNOTE: Options with a * are mutually exclusive and
cannot be run together on same command line.\n";
        exit;
} 

print " Log: $logfile\n";

open ("LOG", "<$logfile") || die ( "$!");
while( <LOG> )
{
        chomp();
        push( @log, $_ );
        if($msgid_set == 0)
        {
                if( $_ =~ /$searchstring/ )
                {
                        push( @infected, $_ );
                } #endif
        } #endif
} #endwhile
print "Import finished\n";
close ( "LOG" );

if($msgid_set == 1)
{
        print " Infected Message: $msgid\n ";
        print
"-----------------------------------------------------------------------
-------------------\n";
        foreach( @log )
        {
                chomp();
                #print "msgid2 = $msgid";
                if( $_ =~ /$msgid/ )
                {
                        print "$_\n";
                } #endif        
        } #endforeach
        exit
} #endif

if( $viruscount == 1 )
{
        foreach(@infected)
        {
                if( /Infected\swith\s(.*)/ )
                {
                        $virus{$1}++;
                } #endif
        }#endforeach
        
        print "\n\n\t ----   Virus Count   ---- \n"; 
        $counter = 1;
        $total = 0; 
        foreach $key (sort hashValueDescendingNum (keys(%virus))) 
        {
                print "\t$counter:\t$virus{$key}   \t\t$key\n";
                $total += $virus{$key};
                $counter++;
        }#endforeach
        print "\tTotal:\t$total  \n";
        exit
}#endif

if( $from_set == 1 )
{
        foreach( @infected )
        {
                #print "infected: $_ \n";
                my $infectedinst = $_;
                if ( $infectedinst =~
/^\w*\s\d*\s\d\d:\d\d:\d\d\s\w*\s\w*\[\d*\]:\s(\w*)/ ) 
                { 
                        our $msgid = $1;
                        #print "msgid = $msgid\n";
                } #endif
                $counter++;
                foreach( @log )
                {
                        chomp();
                        if( $_ =~ /$msgid/ )
                        {
                                #print "variable = $_\n";
                                if ( $_ =~
/^\w*\s\d*\s\d\d:\d\d:\d\d\s\w*\s\w*\[\d*\]:\s\w*:\sfrom..($addr_spec)/)
                                {
                                        #our $from = $1;
                                        #print "from = $from\n";
                                        $email_addresses{$1}++;
                                } #endif
                        } #endif
                } #endforeach
        } #endforeach
        print "\n\n\t ----   Email Addresses Count   ---- \n";
        $counter = 1;
        foreach $key (sort hashValueDescendingEmailAddress
(keys(%email_addresses)))
        {
                print "\t$counter:\t$email_addresses{$key}
\t\t$key\n";
                $counter++;
        }#endforeach
exit    
}#endif
        
if( $relay_set == 1 )
{
        foreach( @infected )
        {
                #print "infected: $_ \n";
                my $infectedinst = $_;
                if ( $infectedinst =~
/^\w*\s\d*\s\d\d:\d\d:\d\d\s\w*\s\w*\[\d*\]:\s(\w*)/ ) 
                { 
                        our $msgid = $1;
                        #print "msgid = $msgid\n";
                } #endif
                $counter++;
                foreach( @log )
                {
                        chomp();
                        if( $_ =~ /$msgid/ )
                        {
                                #print "variable = $_\n";
                                if ( $_ =~ /relay=(.*?\s)/)
                                {
                                        #our $relay = $1;
                                        #print "relay = $relay\n";
                                        $relay{$1}++;
                                } #endif
                        } #endif
                } #endforeach
        } #endforeach
        print "\n\n\t ----   Relay Host Count   ---- \n";
        $counter = 1;
        foreach $key (sort hashValueDescendingRelay (keys(%relay)))
        {
                print "\t$counter:\t$relay{$key}   \t\t$key\n";
                $counter++;
        }#endforeach
exit    
}#endif
        

foreach( @infected )
{
        #print "infected: $_ \n";
        my $infectedinst = $_;
        if ( $infectedinst =~
/^\w*\s\d*\s\d\d:\d\d:\d\d\s\w*\s\w*\[\d*\]:\s(\w*)/ ) 
        { 
                our $msgid = $1;
        } #endif
        $counter++;
        print " Infected Message No: $counter\n ";
        print
"-----------------------------------------------------------------------
-------------------\n";
        foreach( @log )
        {
                chomp();
                if( $_ =~ /$msgid/ )
                {
                        print "$_\n";
                } #endif
        } #endforeach
        if( $infectedinst =~ /Infected\swith\s(.*)/ )
        {
                $virus{$1}++;
        } #endif
        print "\n";
} #endforeach
        
print "\n\n\t ----   Virus Count   ---- \n"; 
$counter = 1;
$total = 0;
foreach $key (sort hashValueDescendingNum (keys(%virus))) 
{
        print "\t$counter:\t$virus{$key}   \t\t$key\n";
        $total += $virus{$key};
        $counter++;
}#endforeach
print "\tTotal:\t$total  \n";


#for my $virus1 ( sort keys %virus ) 
#{
#       $counter++;
#       print "\t $counter: \t $virus1: \t\t\t\t $virus{$virus1} \n";
#} #endfor


#----------------------------------------------------------------------#
#  FUNCTION:  hashValueAscendingNum                                    #
#                                                                      #
#  PURPOSE:   Help sort a hash by the hash 'value', not the 'key'.     #
#             Values are returned in ascending numeric order (lowest   #
#             to highest).                                             #
#----------------------------------------------------------------------#

sub hashValueAscendingNum {
   $virus{$a} <=> $virus{$b};
}


#----------------------------------------------------------------------#
#  FUNCTION:  hashValueDescendingNum                                   #
#                                                                      #
#  PURPOSE:   Help sort a hash by the hash 'value', not the 'key'.     #
#             Values are returned in descending numeric order          #
#             (highest to lowest).                                     #
#----------------------------------------------------------------------#

sub hashValueDescendingNum {
   $virus{$b} <=> $virus{$a};
} 
#----------------------------------------------------------------------#
#  FUNCTION:  hashValueDescendingEmailAddress                         #
#                                                                      #
#  PURPOSE:   Help sort a hash by the hash 'value', not the 'key'.     #
#             Values are returned in descending numeric order          #
#             (highest to lowest).                                     #
#----------------------------------------------------------------------#

sub hashValueDescendingEmailAddress {
   $email_addresses{$b} <=> $email_addresses{$a};
} 

#----------------------------------------------------------------------#
#  FUNCTION:  hashValueDescendingRelay                                 #
#                                                                      #
#  PURPOSE:   Help sort a hash by the hash 'value', not the 'key'.     #
#             Values are returned in descending numeric order          #
#             (highest to lowest).                                     #
#----------------------------------------------------------------------#

sub hashValueDescendingRelay {
   $relay{$b} <=> $relay{$a};


______________________________________________________________________
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email 
______________________________________________________________________
_______________________________________________
http://lurker.clamav.net/list/clamav-users.html

Reply via email to