Perl-related stuff and beyond (but not much)

Wednesday, April 22, 2009

Check your log files for intrusions

CGI::IDS is a nice module on CPAN that enables you to check for a possible intrusion attempts in your web application. But, if evil attempts were made before, it's time to scan the log files. CGI::IDS is very flexible, so I crafted a simple program to check my log files at work.
Here it is:


# - process Apache access log files and check for possible
# attacks via CGI::IDS
# usage: path_to_the_log_file

# dprelec, 2009-01-14

use strict;
use warnings;

use CGI;
use CGI::IDS;

# minimal impact to report for
my $MIN_IMP = 20;

# skip these requests
my $RE_IGNORE = qr/GET(?:.*)\.(?:gif|css|png|jpeg|jpg|pdf|html|js|xml)\s/;

my $ids = CGI::IDS->new();
$ids->set_scan_keys(scan_keys => 1);

my $log = shift or die "Specify input log file.\n";
open $fh, "<", $log or die "Cannot open $log: $!";

while (<$fh>) {
next if /$RE_IGNORE/;

if (/GET\s+(?:[^ ]+)\?([^ ]+)/) {
my %params = CGI->new($1)->Vars;
my $imp = $ids->detect_attacks(request => \%params);

if ($imp > $MIN_IMP) {
print $_ . "\nParams: $1\nImpact: $imp\n\n";

close $fh;

Update: Thanks to all for the answers. It's syntax highlighter that modifies the source code. I'll probably change it. I also ran my code through Perl::Critic, and changed the source code above according to it's suggestions and your comments.


/I3az/ said...

Never seen/heard of CGI::IDS before... thanks for the heads up because that could come in handy.

BTW... Don't know if is mangling your code a bit but the LOG in "while" condition is in lower case.

You can also use lexical variable instead of a global file handle like so....

open my $fh, '<' , $log or die "Cannot open $fh: $!";

while ( <$fh> ) {
close $fh;


chorny said...

You don't need /o for regexes - it means nothing unless you use some variables inside regex.

Also it would be good to use perlcritic on your code - we want modern perl examples for this competition.