@@ -22,7 +22,7 @@ =head1 SYNOPSIS
2222
2323=head1 USAGE
2424
25- Usage: $0 [h] [Gtsrfdbalspj ]
25+ Usage: $0 [h] [Htsrfdbalspjv ]
2626 -H|--host Search rules based on the Host request header
2727 -t|--transaction-id Search rules based on the unique transaction ID
2828 -s|--source-ip Search rules based on the client IP address (can be presented as an address or CIDR block)
@@ -35,7 +35,7 @@ =head1 USAGE
3535 -S|--stdin Read rules from stdin instead of an on-disk file
3636 -p|--partial-chains Do not prune partial chain matches
3737 -j|--json Print rule entries as a JSON blob, rather than nice formatting
38- -v|--verbose Be verbose about various details such as JSON parse failures
38+ -v|--verbose Be verbose about various details such as JSON parse failures and log data
3939
4040
4141=head2 FILTERS
@@ -129,6 +129,10 @@ =head2 USAGE EXAMPLES
129129
130130parse_modsec.pl
131131
132+ Print all log entries and show more detailed information, such as response data and matched rule details
133+
134+ parse_modsec.pl -v
135+
132136Print entries matching a specific source IP:
133137
134138parse_modsec.pl -s 1.2.3.4
@@ -161,7 +165,7 @@ =head2 USAGE EXAMPLES
161165
162166sub usage {
163167print <<"_EOF" ;
164- Usage:$0 [h] [Gtsrfdbalspj ]
168+ Usage:$0 [h] [Htsrfdbalspjv ]
165169-h|--help Print this help
166170-H|--host Search rules based on the Host request header
167171-t|--transaction-id Search rules based on the unique transaction ID
@@ -175,7 +179,7 @@ sub usage {
175179-S|--stdin Read rules from stdin instead of an on-disk file
176180-p|--partial-chains Do not prune partial chain matches
177181-j|--json Print rule entries as a JSON blob, rather than nice formatting
178- -v|--verbose Be verbose about various details such as JSON parse failures
182+ -v|--verbose Be verbose about various details such as JSON parse failures and log data
179183
180184For detailed explanations of various options and example usages, see 'perldoc$0 '
181185
@@ -339,22 +343,44 @@ sub print_matches {
339343}else {
340344printf " \n %s \n " ,' =' x 80 ;
341345
342- # request
343- my $transaction =$entry -> {transaction };
344- my $request =$entry -> {request };
346+ my $transaction =$entry -> {transaction };
347+ my $request =$entry -> {request };
348+ my $response =$entry -> {response };
349+ my $audit_data =$entry -> {audit_data };
350+ my $matched_rules =$entry -> {matched_rules };
351+
352+ if ($transaction ) {
353+ printf " %s \n Transaction ID:%s \n IP:%s \n\n " ,
354+ parse_modsec_timestamp($transaction -> {time }),
355+ $transaction -> {transaction_id },
356+ $transaction -> {remote_address };
357+ }
358+
359+ printf " %s \n " ,$request -> {request_line }
360+ if $request -> {request_line };
361+
362+ if ($request -> {headers }) {
363+ for my $header (sort keys %{$request -> {headers }}) {
364+ printf " %s :%s \n " ,$header ,$request -> {headers }-> {$header };
365+ }
366+ }
367+
368+ if ($verbose ) {
369+ print join (" \n " , @{$request -> {body }}) ." \n "
370+ if $request -> {body };
345371
346- printf " %s \n Transaction ID:%s \n IP:%s \n\n %s \n " ,
347- parse_modsec_timestamp($transaction -> {time }),
348- $transaction -> {transaction_id },
349- $transaction -> {remote_address },
350- $request -> {request_line };
372+ printf " \n %s %s \n " ,$response -> {protocol },$response -> {status }
373+ if $response -> {protocol } &&$response -> {status };
374+
375+ for my $header (sort keys %{$response -> {headers }}) {
376+ printf " %s :%s \n " ,$header ,$response -> {headers }-> {$header };
377+ }
351378
352- for my $header ( sort keys %{ $request -> {headers }}) {
353- printf " %s : %s \n " , $header , $request -> {headers } -> { $header };
379+ printf " \n %s \n " , $response -> {body }
380+ if $response -> {body };
354381}
355382
356- # matched rules
357- for my $chain (@{$entry -> {matched_rules }}) {
383+ for my $chain (@{$matched_rules }) {
358384print " \n " ;
359385my @extra_data ;
360386my $ctr = 0;
@@ -365,11 +391,12 @@ sub print_matches {
365391push @extra_data ,$rule -> {actionset }-> {logdata }if $rule -> {actionset }-> {logdata };
366392}
367393
368- printf " \n --%s \n " ,join " \n --" ,@extra_data if @extra_data &&$verbose ;
394+ printf " \n --%s \n " ,join " \n --" ,@extra_data
395+ if @extra_data &&$verbose ;
369396}
370397
371- # audit message
372- printf " \n -- %s \n\n " , $entry -> { audit_data } -> {action }-> {message }if $verbose ;
398+ printf " \n -- %s \n\n " , $audit_data -> { action } -> { message }
399+ if $ audit_data-> {action }-> {message }&& $verbose ;
373400
374401printf " %s \n " ,' =' x 80 ;
375402}
@@ -531,7 +558,7 @@ sub main {
531558$after = build_datetime($after );
532559
533560# figure where we're reading from
534- $logpath ||=' /var/log/modsec_audit.log' ;
561+ $logpath ||=' /var/log/mod_sec/ modsec_audit.log' ;
535562$fh = get_input({
536563logpath => $logpath ,
537564stdin => $stdin ,
@@ -551,7 +578,7 @@ sub main {
551578delim => $delim ,
552579});
553580
554- # walk through our input, getting an arrayref ofentries valid based on filters and timeframe
581+ # walk through our input, getting an arrayref of valid entries based on filters and timeframe
555582$parsed_ref = grok_input({
556583fh => $fh ,
557584filters => \%filters ,