diff --git a/qa/wirefuzz.pl b/qa/wirefuzz.pl index c712356110..08407bb62c 100755 --- a/qa/wirefuzz.pl +++ b/qa/wirefuzz.pl @@ -73,9 +73,12 @@ my $shuffle; my $useltsuri; my $ltsuribin; my $core_dump; +my $excluderegex; +my $timestamp; +my $keeplogs; Getopt::Long::Configure("prefix_pattern=(-|--)"); -GetOptions( \%config, qw(n=s r=s c=s e=s v=s p=s l=s s=s y z h help) ); +GetOptions( \%config, qw(n=s r=s c=s e=s v=s p=s l=s s=s x=s k y z h help) ); &parseopts(); @@ -93,6 +96,13 @@ sub parseopts { if(@tmpfiles eq 0){ print "parseopts: Pcap filemask was invalid we couldn't find any matching files\n"; exit; + } else { + #escapes for filenames + foreach my $file (@tmpfiles) { + $file =~ s/\(/\\(/g; + $file =~ s/\)/\\)/g; + $file =~ s/\&/\\&/g; + } } } else { @@ -210,6 +220,34 @@ sub parseopts { print "parseopts: going to shuffle the array\n"; $shuffle = "yes"; } + + #keep logs instead of removing them after each run + if ( $config{k} ) { + print "parseopts: going to keep logs instead of removing them\n"; + $keeplogs = "yes"; + } + else { + $keeplogs = "no"; + } + + #maybe we want to exclude a file based on some regex so we can restart the fuzzer after an error + #and not have to worry about hitting the same file. + if ( $config{x} ) { + print "excluding files that match regex of " . $config{x} . "\n"; + $excluderegex = $config{x}; + + my $tmpfilepos = 0; + while ($tmpfilepos <= $#tmpfiles) { + if ($tmpfiles[$tmpfilepos] =~ m/$excluderegex/) { + print "removing " . $tmpfiles[$tmpfilepos] . " because it matches our exclude regex\n"; + splice(@tmpfiles, $tmpfilepos, 1); + } + else { + $tmpfilepos++ + } + } + } + print "******************Initialization Complete**********************\n"; return; @@ -225,8 +263,9 @@ sub printhelp { -p= -l=<(optional) log dir for output if not specified will use current directory.> -v=<(optional) (memcheck|drd|helgrind|callgrind) will run the command through one of the specified valgrind tools.> + -x=<(optional) regex for excluding certian files incase something blows up but we want to continue fuzzing .> -y - + -k Example usage: First thing to do is download and build suricata from git with -O0 so vars don't get optimized out. See the example below: git clone git://phalanx.openinfosecfoundation.org/oisf.git suricatafuzz1 && cd suricatafuzz1 && ./autogen.sh && CFLAGS=\"-g -O0\" ./configure && make @@ -251,13 +290,6 @@ sub printhelp { exit; } -#escapes for filenames -foreach my $file (@tmpfiles) { - $file =~ s/\(/\\(/g; - $file =~ s/\)/\\)/g; - $file =~ s/\&/\\&/g; -} - my $logfile = $logdir . "wirefuzzlog.txt"; open( LOGFILE, ">>$logfile" ) || die( print "error: Could not open logfile! $logfile\n" ); @@ -279,11 +311,11 @@ while ( $successcnt < $loopnum ) { my ( $fuzzedfile, $editcapcmd, $editcapout, $editcaperr, $editcapexit, $editcap_sys_signal, $editcap_sys_coredump ); my ( $fuzzedfiledir, $fuzzedfilename, $fullcmd, $out, $err, $exit, - $suricata_sys_signal, $suricata_sys_coredump ); + $suricata_sys_signal, $suricata_sys_coredump, $report); print "Going to work with file: $file\n"; my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(time); - my $timestamp = sprintf "%4d-%02d-%02d-%02d-%02d-%02d", $year + 1900, + $timestamp = sprintf "%4d-%02d-%02d-%02d-%02d-%02d", $year + 1900, $mon + 1, $mday, $hour, $min, $sec; if ( defined $editeratio ) { @@ -409,20 +441,18 @@ while ( $successcnt < $loopnum ) { if ( $knownerr eq 1 ) { $successcnt++; print "suricata: we have run with success " . $successcnt . " times\n"; + if( $keeplogs eq "yes" ) { + &keep_logs($fuzzedfilename); + $report = $logdir . $fuzzedfilename . "-OUT.txt"; + &generate_report($report, $fullcmd, $out, $err, $exit, "none"); + } &clean_logs($fuzzedfilename); } else { - my $report = $logdir . $fuzzedfilename . "ERR.txt"; - open( REPORT, ">$report" ) - || ( print "Could not open report file! $report\n" ); - print REPORT "COMMAND:$fullcmd\n"; - print REPORT "STDERR:$err\n"; - print REPORT "EXITVAL:$exit\n"; - print REPORT "STDOUT:$out\n"; + my $report = $logdir . $fuzzedfilename . "-ERR.txt"; &process_core_dump(); if ($core_dump) { - print REPORT $core_dump; print "core dump \n $core_dump"; system( "mv " . $ENV{'PWD'} @@ -430,19 +460,41 @@ while ( $successcnt < $loopnum ) { . $logdir . $fuzzedfilename . ".core" ); + &generate_report($report, $fullcmd, $out, $err, $exit, $core_dump); + }else{ + &generate_report($report, $fullcmd, $out, $err, $exit, "none"); } - close(REPORT); exit; } } elsif ( $suricata_sys_signal eq 2 ) { print "suricata: system() got a ctl+c we are bailing as well\n"; + if( $keeplogs eq "yes" ) { + &keep_logs($fuzzedfilename); + } + &clean_logs($fuzzedfilename); exit; } else { + if ( $out =~ /Max memuse of stream engine \d+ \(in use (\d+)\)/ ) { + if ($1 != 0) { + $report = $logdir . $fuzzedfilename . "-OUT.txt"; + &generate_report($report, $fullcmd, $out, $err, $exit, "none"); + print "Stream leak detected " . $1 . " was still in use at exit see " . $report . " for more details\n"; + exit; + } + } else { + print "Stream mem counter could not be found in output\n"; + } + $successcnt++; print "suricata: we have run with success " . $successcnt . " times\n"; print "******************Suricata Complete**********************\n"; + if( $keeplogs eq "yes" ) { + &keep_logs($fuzzedfilename); + $report = $logdir . $fuzzedfilename . "-OUT.txt"; + &generate_report($report, $fullcmd, $out, $err, $exit, "none"); + } &clean_logs($fuzzedfilename); print "******************Next Packet or Exit *******************\n"; } @@ -505,9 +557,8 @@ sub clean_logs { #system("$rmcmd"); } - #remove unified logs for next run if ( unlink(<$logdir . unified*>) > 0 ) { - print "clean_logs: deleted unifed logs for next run \n"; + print "clean_logs: removed unified logs for next run \n"; } else { print "clean_logs: failed to delete unified logs\n:"; @@ -516,3 +567,60 @@ sub clean_logs { return; } + +sub keep_logs { + my $saveme = shift; + unless(defined($editeratio) || $loopnum eq '1'){ + my $saveme = $saveme . "-" . $timestamp; + } + my $savecmd; + + if (-e $logdir . "alert-debug.log"){ + $savecmd = "mv -f " . $logdir + . "alert-debug.log " + . $logdir + . $saveme + . "-alert-debug.log"; + system($savecmd); + } + if (-e $logdir . "fast.log"){ + $savecmd = "mv -f " . $logdir + . "fast.log " + . $logdir + . $saveme + . "-fast.log"; + system($savecmd); + } + if (-e $logdir . "http.log"){ + $savecmd = "mv -f " . $logdir + . "http.log " + . $logdir + . $saveme + . "-http.log"; + system($savecmd); + } + if (-e $logdir . "stats.log"){ + $savecmd = "mv -f " . $logdir + . "stats.log " + . $logdir + . $saveme + . "-stats.log"; + system($savecmd); + } + print "******************Log Move Complete**********************\n"; + return; +} + +sub generate_report { + my ($report, $fullcmd, $stdout, $stderr, $exit, $coredump) = ($_[0], $_[1], $_[2], $_[3], $_[4], $_[5]); + + open( REPORT, ">$report" ) || ( print "Could not open report file! $report\n" ); + print REPORT "COMMAND:$fullcmd\n"; + print REPORT "EXITVAL:$exit\n"; + print REPORT "STDERR:$stderr\n"; + print REPORT "STDOUT:$stdout\n"; + if($coredump ne "none"){ + print REPORT "COREDUMP:$coredump\n"; + } + close(REPORT); +}