#!/usr/bin/perl -w # # grab firewall hits from pfirewall.log and put them in the event log # monitor the log continuously; sleep for short time between reads # # Windows XP: %windir%\pfirewall.log # Windows 7: %systemroot%\system32\logfiles\firewall\pfirewall.log # # 2010-07-03 Initial version # 2010-07-05 Converted to 'tail -f' like functionality; # no state tracking anymore # automatically find logfile or have it specified on command line # # TO DO: # ICMP testing # use Fcntl; use Fcntl qw'SEEK_CUR SEEK_END'; use strict; use Time::Local; use Win32::EventLog; # determine which logfile to use my @logfiles = qw(c:\windows\pfirewall.log c:\windows\system32\logfiles\firewall\pfirewall.log); my $infile; foreach my $logfile (@logfiles) { if (-f $logfile) { $infile = $logfile; last; } } $infile = shift unless (defined $infile); die "Could not find suitable firewall log to use" unless (defined $infile); print "Using '$infile'\n"; # set up signal handling $SIG{INT} = sub { close INFILE; exit; }; # specify server or an unintialized value warning will be thrown my $hostname = `hostname`; $hostname = 'localhost' unless (defined $hostname); chomp $hostname; my $handle=Win32::EventLog->new("Application",$hostname); # open firewall log file die "Could not open $infile: $!" unless (sysopen(INFILE, $infile, O_RDONLY)); # always start from end of file sysseek(INFILE,0,SEEK_END); # continuously read the file (like 'tail -f') while (1) { while () { my ($date,$message); # parse the date or go to the next line if ($_ =~ /(\d+-\d+-\d+ \d+:\d+:\d+) (.*)/) { $date = $1; $message = $2; } else { next; } ##Fields: date time action protocol src-ip dst-ip src-port dst-port size tcpflags tcpsyn tcpack tcpwin icmptype icmpcode info path # 2010-07-04 15:48:21 DROP UDP 168.150.193.3 255.255.255.255 68 67 328 - - - - - - - RECEIVE if ($message =~ /DROP (\S+) (\d+\.\d+\.\d+\.\d+) (\d+\.\d+\.\d+\.\d+) (\S+) (\S+) \d+ \S+ \S+ \S+ \S+ (\S+) (\S+)/) { my $proto = $1; my $srcip = $2; my $dstip = $3; my $srcport = $4; my $dstport = $5; my $icmptype = $6; my $icmpcode = $7; my $string = "$date $proto DROP $srcip:$srcport => $dstip:$dstport\n"; print $string; $handle->Report( { Source => 'WINDOWS_FIREWALL', EventType => EVENTLOG_WARNING_TYPE, Category => 0, EventID => 0, # if this is not defined, "unintialized value" warnings will be produced from Eventlog.pm Data => '0', Strings => $string } ); } } # reset file caret sysseek(INFILE,0,SEEK_CUR); # sleep for short time sleep 5; }