Skip to content

Instantly share code, notes, and snippets.

@porjo
Last active November 30, 2022 16:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save porjo/4ce7e76191d3198f6798 to your computer and use it in GitHub Desktop.
Save porjo/4ce7e76191d3198f6798 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
# Credit to Ryan Barnett at Spiderlabs.com for original idea
#
# Usage: modgrep.pl -a <logfile>
# -s <search keyword> (optional)
#
use strict;
use warnings;
use Getopt::Std;
use vars qw/ %opt /;
my $options = 'haf:s:';
my $defaultlog = '/usr/local/apache/logs/modsec_audit.log';
getopts( "$options", \%opt ) or &help();
&help() if ($opt{h} or !%opt);
my $sstr;
my $url;
my $count=0;
my %rules;
if ($opt{f}) {
open(LOGFILE,'<',$opt{f}) || die "cant find $opt{f} file $!\n";
} else {
open(LOGFILE,'<',$defaultlog) || die "cant find $defaultlog file $!\n";
}
if ($opt{s}) {
$sstr = $opt{s};
}
# Slurp up to the end of the next Z Section
$/ = "-Z--\n";
while(my $chunk = <LOGFILE>) {
chomp $chunk;
if (($chunk =~ m/ Intercepted/ || $opt{a}) && (($opt{s} && $chunk =~ m/$sstr/) || !$opt{s})) {
$count++;
if ($chunk =~ m/((GET|POST) \/.*)/) {
$url = $1;
}
# If you use a ruleset other than Atomic's then you can change the regex below to grab the rule's ID number and descriptive text
while ($chunk =~ m/\[file "[^\]]+\/(.+\.conf)"\].+\[id "([\d]+)"\].+\[msg "([^"\]]+)"\]/g) {
my $key = "$1_$2";
$rules{$key}{count}++;
$rules{$key}{file} = $1;
$rules{$key}{id} = $2;
$rules{$key}{url} = $url;
$rules{$key}{msg} = $rules{$key}{msg} ? $rules{$key}{msg} : $3;
}
$url = '';
#print "####################\nEntry found for search String ($sstr)\n####################\n";
#print $chunk,"-Z--\n\n";
}
}
close (LOGFILE);
print "\n\nTotal Matches for $sstr : $count\n";
print "Hits\tRule ID\tRule Filename\tRule Message\tURL\n";
foreach my $rule (keys %rules) {
print "$rules{$rule}{count}\t$rules{$rule}{id}\t$rules{$rule}{file}\t$rules{$rule}{msg}\t$rules{$rule}{url}\n";
}
exit;
sub help() {
print << "EOF";
$0 [-h] [-a] [-f file] [-s search]
default : same as -h
-h : this help message
-a : show all activity (defaults to Interceptions only)
-f file : file to search (defaults to /usr/local/apache/logs/modsec_audit.log)
-s search : string to match on - enclosed in quotes if it contains spaces
EOF
exit;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment