Changeset 457
- Timestamp:
- 06/19/2010 03:27:39 AM (3 years ago)
- Location:
- trunk
- Files:
-
- 13 edited
-
nikto.conf (modified) (1 diff)
-
nikto.pl (modified) (4 diffs)
-
plugins/nikto_apacheusers.plugin (modified) (4 diffs)
-
plugins/nikto_auth.plugin (modified) (9 diffs)
-
plugins/nikto_content_search.plugin (modified) (4 diffs)
-
plugins/nikto_core.plugin (modified) (20 diffs)
-
plugins/nikto_headers.plugin (modified) (3 diffs)
-
plugins/nikto_httpoptions.plugin (modified) (8 diffs)
-
plugins/nikto_report_nbe.plugin (modified) (1 diff)
-
plugins/nikto_report_xml.plugin (modified) (1 diff)
-
plugins/nikto_robots.plugin (modified) (2 diffs)
-
plugins/nikto_subdomain.plugin (modified) (4 diffs)
-
plugins/nikto_tests.plugin (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/nikto.conf
r442 r457 17 17 # RFI URL. This remote file should return a phpinfo call, for example: <?php phpinfo(); ?> 18 18 # You may use the one below, if you like. 19 #RFIURL=http://cirt.net/rfiinc.txt?19 RFIURL=http://cirt.net/rfiinc.txt? 20 20 21 21 # IDs never to alert on (Note: this only works for IDs loaded from db_tests) -
trunk/nikto.pl
r452 r457 5 5 use Getopt::Long; 6 6 Getopt::Long::Configure('no_ignore_case'); 7 7 8 # use LW2; ### Change this line to use a different installed version 8 9 … … 90 91 require "$NIKTOCONFIG{'PLUGINDIR'}/nikto_single.plugin"; 91 92 require "$NIKTOCONFIG{'PLUGINDIR'}/LW2.pm"; 92 93 93 94 94 my ($a, $b) = split(/\./, $LW2::VERSION); … … 148 148 # Open reporting 149 149 report_head($CLI{'format'}, $CLI{'file'}); 150 150 151 # Load db_tests 151 152 set_scan_items(); … … 175 176 %FoF = (); 176 177 177 nfetch($mark, "/", "GET", "", "", { nocache => 1, noprefetch => 1, nopostfetch => 1 }, "getinfo"); 178 178 nfetch($mark, "/", "GET", "", "", { nocache => 1, noprefetch => 1, nopostfetch => 1 }, 179 "getinfo"); 180 179 181 if ($CLI{'findonly'}) { 180 182 my $protocol = "http"; -
trunk/plugins/nikto_apacheusers.plugin
r449 r457 30 30 scan_method => \&nikto_apacheusers, 31 31 copyright => "2008 CIRT Inc.", 32 options => {33 enumerate=> "Flag to indicate whether to attempt to enumerate users",34 dictionary=> "Filename for a dictionary file of users",35 size=> "Maximum size of username if bruteforcing",36 home=> "Look for ~user to enumerate",37 cgiwrap=> "User cgi-bin/cgiwrap to enumerate"38 }39 };32 options => { 33 enumerate => "Flag to indicate whether to attempt to enumerate users", 34 dictionary => "Filename for a dictionary file of users", 35 size => "Maximum size of username if bruteforcing", 36 home => "Look for ~user to enumerate", 37 cgiwrap => "User cgi-bin/cgiwrap to enumerate" 38 } 39 }; 40 40 return $id; 41 41 } … … 43 43 sub nikto_apacheusers { 44 44 my ($mark, $parameters) = @_; 45 my $apacheusers =0;46 45 my $apacheusers = 0; 46 47 47 # First ensure that the server is vulnerable 48 48 (my $result, $content) = nfetch($mark, "/~root", "GET", "", "", "", "apacheusers: known user"); … … 66 66 ); 67 67 } 68 $apacheusers =1;69 } 70 68 $apacheusers = 1; 69 } 70 71 71 # If we can't enumerate users then return 72 72 return unless ($apacheusers == 1); 73 73 74 # If we haven't been asked to enumerate users then return 74 return unless (defined $parameters->{'enumerate'} &&75 $parameters->{'enumerate'} == 1);76 75 return unless (defined $parameters->{'enumerate'} 76 && $parameters->{'enumerate'} == 1); 77 77 78 # Now we can attempt to enumerate the users 78 79 my ($url, $dictfile, $size); … … 94 95 my $curl = "$cgidir" . "cgiwrap"; 95 96 (my $result, $content) = 96 nfetch($mark, $curl, "GET", "", "", "", "user_enum_apache: cgiwrap");97 nfetch($mark, $curl, "GET", "", "", "", "user_enum_apache: cgiwrap"); 97 98 if ($content =~ /check your URL/i) { 98 99 push(@cgiwraps, "$curl"); -
trunk/plugins/nikto_auth.plugin
r452 r457 42 42 43 43 sub nikto_auth_load { 44 44 45 # Load up the database as soon as we can 45 46 $REALMS =init_db("db_realms");46 47 $REALMS = init_db("db_realms"); 47 48 %REALMSMATCHED = (); 48 49 } … … 50 51 sub nikto_auth_pre { 51 52 my ($mark, $parameters, $request, $result) = @_; 53 52 54 # If we know the realm then don't bother guessing it 53 55 # See whether we've already guessed it 54 56 55 57 my ($uridir) = $request->{'whisker'}->{'uri'}; 56 58 $uridir =~ s#/[^/]*$#/#g; 57 59 58 if (exists $REALMSMATCHED{$mark->{'hostname'}}{$uridir}) { 60 if (exists $REALMSMATCHED{ $mark->{'hostname'} }{$uridir}) { 61 59 62 # Just set up the auth and return the valid result 60 LW2::auth_set($REALMSMATCHED{$mark->{'hostname'}}{$uridir}{'authtype'}, $request, $REALMSMATCHED{$mark->{'hostname'}}{$uridir}{'id'}, $REALMSMATCHED{$mark->{'hostname'}}{$uridir}{'password'}); 63 LW2::auth_set($REALMSMATCHED{ $mark->{'hostname'} }{$uridir}{'authtype'}, 64 $request, 65 $REALMSMATCHED{ $mark->{'hostname'} }{$uridir}{'id'}, 66 $REALMSMATCHED{ $mark->{'hostname'} }{$uridir}{'password'} 67 ); 68 61 69 # Patch to fix short reads 62 70 $request->{'whisker'}->{'allow_short_reads'} = 1; … … 68 76 sub nikto_auth { 69 77 my ($mark, $parameters, $request, $result) = @_; 70 my ($authtype) = 'basic';71 my ($body) = $result->{'whisker'}->{'data'};72 my ($uri) = $result->{'whisker'}->{'uri'};73 my ($method) = $result->{'whisker'}->{'method'} || "GET";78 my ($authtype) = 'basic'; 79 my ($body) = $result->{'whisker'}->{'data'}; 80 my ($uri) = $result->{'whisker'}->{'uri'}; 81 my ($method) = $result->{'whisker'}->{'method'} || "GET"; 74 82 my ($realm, $save_auth); 75 83 … … 78 86 return $request, $result; 79 87 } 80 88 81 89 # Save to revert 82 90 $save_auth = $result{'www-authenticate'}; 83 91 84 92 # Split up www-authenticate to realm and method 85 93 my @authenticate = split(/ /, $result->{'www-authenticate'}); … … 94 102 $authtype = $authenticate[0]; 95 103 $realm = $authenticate[1]; 96 $realm =~ s/^realm=//;104 $realm =~ s/^realm=//; 97 105 } 98 106 99 107 nprint("+ $uri - Requires Authentication for realm '$realm'") if $OUTPUT{'show_auth'}; 100 108 … … 102 110 foreach my $entry (@{$REALMS}) { 103 111 unless ($realm =~ /$entry->{'realm'}/i || $entry->{realm} eq '@ANY') { next; } 104 112 105 113 if ($result->{'www-authenticate'} =~ /^ntlm/i) { 106 $authtype='ntlm'; 107 } 114 $authtype = 'ntlm'; 115 } 116 108 117 # Set up LW hash 109 118 LW2::auth_set($authtype, $request, $entry->{'id'}, $entry->{'password'}); 119 110 120 # Patch to fix short reads 111 $request->{'whisker'}->{'allow_short_reads'} = 1; 112 LW2::http_fixup_request($request); 121 $request->{'whisker'}->{'allow_short_reads'} = 1; 122 LW2::http_fixup_request($request); 123 113 124 # pause if needed 114 125 if ($CLI{'pause'} > 0) { sleep $CLI{'pause'}; } … … 118 129 dump_var("Auth Request", $request); 119 130 dump_var("Auth Response", $result); 120 131 121 132 if ($result{'www-authenticate'} =~ /^ntlm/i) { 133 122 134 # Deal with ntlm 123 135 my @ntlm_x = split(/ /, $result{'www-authenticate'}); … … 129 141 my $uridir = $request->{'whisker'}->{'uri'}; 130 142 $uridir =~ s#/[^/]*$#/#g; 131 143 132 144 if ($result->{'www-authenticate'} eq '' 133 145 && !defined $result->{'whisker'}->{'error'}) { 134 135 my $message="Default account found for '$realm' at $uridir ($request->{'whisker'}->{'uri'}) (ID '$entry->{'id'}', PW '$entry->{'password'}'). $entry->{message}"; 146 147 my $message = 148 "Default account found for '$realm' at $uridir ($request->{'whisker'}->{'uri'}) (ID '$entry->{'id'}', PW '$entry->{'password'}'). $entry->{message}"; 136 149 if ($entry->{'id'} eq '' && $entry->{'password'} eq '') { 137 $message="Blank credentials found at $uridir ($request{whisker}->{uri}), $entry->{'realm'}: $entry->{'msg'}" 150 $message = 151 "Blank credentials found at $uridir ($request{whisker}->{uri}), $entry->{'realm'}: $entry->{'msg'}"; 138 152 } 139 unless ( $entry->{'checked'} == 1) { 140 add_vulnerability( 141 $mark, 142 $message, 143 $entry->{tid}, 144 0, 145 "GET", 146 $uridir, 147 $result 148 ); 153 unless ($entry->{'checked'} == 1) { 154 add_vulnerability($mark, $message, $entry->{tid}, 0, "GET", $uridir, $result); 149 155 $entry->{checked} = 1; 150 156 } … … 153 159 LW2::http_do_request_timeout($request, $result); # test auth 154 160 $NIKTO{'totalrequests'}++; 155 161 156 162 # Set up so we don't have to repeat in future 157 163 # / isn't a valid entry in a hash - more stupid perl 158 164 159 $REALMSMATCHED{ $mark->{hostname}}{$uridir}{'id'}=$entry->{'id'};160 $REALMSMATCHED{ $mark->{hostname}}{$uridir}{'password'}=$entry->{'password'};161 $REALMSMATCHED{ $mark->{hostname}}{$uridir}{'authtype'}=$authtype;165 $REALMSMATCHED{ $mark->{hostname} }{$uridir}{'id'} = $entry->{'id'}; 166 $REALMSMATCHED{ $mark->{hostname} }{$uridir}{'password'} = $entry->{'password'}; 167 $REALMSMATCHED{ $mark->{hostname} }{$uridir}{'authtype'} = $authtype; 162 168 163 169 # and leave -
trunk/plugins/nikto_content_search.plugin
r436 r457 24 24 25 25 sub nikto_content_search_init { 26 my $id = { name => "content_search",27 full_name => "Content Search",28 author => "Sullo",29 description => "Search resultant content for interesting strings",30 recon_method => \&nikto_content_search_load,31 recon_weight => 1,26 my $id = { name => "content_search", 27 full_name => "Content Search", 28 author => "Sullo", 29 description => "Search resultant content for interesting strings", 30 recon_method => \&nikto_content_search_load, 31 recon_weight => 1, 32 32 postfetch_method => \&nikto_content_search, 33 33 postfetch_weight => 20, 34 copyright => "2010 CIRT Inc"34 copyright => "2010 CIRT Inc" 35 35 }; 36 36 … … 39 39 40 40 sub nikto_content_search_load { 41 41 42 # Load up the database as soon as we can 42 43 $CONTENTSEARCH =init_db("db_content_search");44 %CSMATCHED = ();43 44 $CONTENTSEARCH = init_db("db_content_search"); 45 %CSMATCHED = (); 45 46 46 47 # to try and speed it up - precompile the regular expressions … … 52 53 sub nikto_content_search { 53 54 my ($mark, $parameters, $request, $result) = @_; 54 55 55 56 my $body = $result->{'whisker'}->{'data'}; 56 57 my $file = $result->{'whisker'}->{'uri'}; … … 58 59 59 60 foreach my $testid (@$CONTENTSEARCH) { 60 if ($body =~ $testid->{'compiled'} && 61 !exists $CSMATCHED{$mark->{'hostname'}}{$file}) { 61 if ($body =~ $testid->{'compiled'} 62 && !exists $CSMATCHED{ $mark->{'hostname'} }{$file}) { 63 62 64 # Check whether we've already matched it 63 65 my $outmessage = "$file: $testid->{'message'}"; 64 add_vulnerability($mark, $outmessage, 65 $testid->{'nikto_id'}, 66 $testid->{'osvdb'}, 66 add_vulnerability($mark, $outmessage, $testid->{'nikto_id'}, $testid->{'osvdb'}, 67 67 $method, $file); 68 $CSMATCHED{ $mark->{'hostname'}}{$file} = 1;68 $CSMATCHED{ $mark->{'hostname'} }{$file} = 1; 69 69 } 70 70 } -
trunk/plugins/nikto_core.plugin
r456 r457 130 130 if ((defined $CLI{'file'}) && ($CLI{'file'} eq "-")) { return; } 131 131 132 # print to scan details to standard output if the users wants another format and is saving results to a file132 # print to scan details to standard output if the users wants another format and is saving results to a file 133 133 $line =~ s/(CVE\-[12][0-9]{4}-[0-9]{4})/http:\/\/cve.mitre.org\/cgi-bin\/cvename.cgi?name\=$1/g; 134 134 $line =~ s/(CA\-[12][0-9]{3}-[0-9]{2})/http:\/\/www.cert.org\/advisories\/$1.html/g; 135 135 $line =~ s/BID\-([0-9]{4})/http:\/\/www.securityfocus.com\/bid\/$1/g; 136 $line =~ s/(MS[0-9]{2}\-[0-9]{3})/http:\/\/www.microsoft.com\/technet\/security\/bulletin\/$1.asp/gi; 136 $line =~ 137 s/(MS[0-9]{2}\-[0-9]{3})/http:\/\/www.microsoft.com\/technet\/security\/bulletin\/$1.asp/gi; 137 138 print "$line\n"; 138 139 … … 287 288 $cont =~ s/(?:[0-9]{4}|[0-9]{1,2})[-.\/][0-9]{1,2}[-.\/](?:[0-9]{4}|[0-9]{1,2})//g; 288 289 $cont =~ s/(?:([0-9]{2}:[0-9]{2}(?::[0-9]{2})?)|(?:[0-9]{8,14}|[0-9]{6}))//g; 289 $cont =~ s/(?:mon|tue|wed|thu|fri|sat|sun),? [0-9]{1,2} (?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) [0-9]{4} (?:[0-9]{2}:[0-9]{2}:?(?:[0-9]{2})?)?//ig; 290 $cont =~ s/(?:[0-9]{2,4})? ?(?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)(?:[0-9]{2,4})?\/?(?:[0-9]{2})?(?:[0-9]{2})?//gi; 290 $cont =~ 291 s/(?:mon|tue|wed|thu|fri|sat|sun),? [0-9]{1,2} (?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) [0-9]{4} (?:[0-9]{2}:[0-9]{2}:?(?:[0-9]{2})?)?//ig; 292 $cont =~ 293 s/(?:[0-9]{2,4})? ?(?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)(?:[0-9]{2,4})?\/?(?:[0-9]{2})?(?:[0-9]{2})?//gi; 291 294 $cont =~ s/[0-9\.]+ second//gi; # page load time 292 295 $cont =~ s/[0-9]+ queries//gi; # wordpress … … 317 320 # url encoding, query portion 318 321 if ($file =~ /\?(.*$)/) { 319 my $qs = $1;320 321 # match pages which link to themselves w/diff args322 $cont =~ s/$qs//gs;322 my $qs = $1; 323 324 # match pages which link to themselves w/diff args 325 $cont =~ s/$qs//gs; 323 326 324 327 # url encoded 325 $qs =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg;328 $qs =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg; 326 329 $cont =~ s/$qs//gs; 327 330 } … … 339 342 $sslprint = "$NIKTO{'DIV'}\n"; 340 343 $sslprint .= 341 "+ SSL Info: Ciphers: $mark->{'ssl_cipher'}\n" .342 " Info: $mark->{'ssl_cert_issuer'}\n" .343 " Subject: $mark->{'ssl_cert_subject'}";344 "+ SSL Info: Ciphers: $mark->{'ssl_cipher'}\n" 345 . " Info: $mark->{'ssl_cert_issuer'}\n" 346 . " Subject: $mark->{'ssl_cert_subject'}"; 344 347 } 345 348 … … 424 427 $NIKTO{'mutate_opts'}{'5'} = 425 428 "Attempt to brute force sub-domain names, assume that the host name is the parent domain"; 426 $NIKTO{'mutate_opts'}{'6'} = "Attempt to guess directory names from the supplied dictionary file"; 429 $NIKTO{'mutate_opts'}{'6'} = 430 "Attempt to guess directory names from the supplied dictionary file"; 427 431 428 432 ### CLI STUFF … … 505 509 # screen output 506 510 if (defined $CLI{'display'}) { 507 if ($CLI{'display'} =~ /d/i) { $OUTPUT{'debug'} = 1; }508 if ($CLI{'display'} =~ /v/i) { $OUTPUT{'verbose'} = 1; }509 if ($CLI{'display'} =~ /s/i) { $OUTPUT{'scrub'} = 1; }510 if ($CLI{'display'} =~ /e/i) { $OUTPUT{'errors'} = 1; }511 if ($CLI{'display'} =~ /p/i) { $OUTPUT{'progress'} = 1; }511 if ($CLI{'display'} =~ /d/i) { $OUTPUT{'debug'} = 1; } 512 if ($CLI{'display'} =~ /v/i) { $OUTPUT{'verbose'} = 1; } 513 if ($CLI{'display'} =~ /s/i) { $OUTPUT{'scrub'} = 1; } 514 if ($CLI{'display'} =~ /e/i) { $OUTPUT{'errors'} = 1; } 515 if ($CLI{'display'} =~ /p/i) { $OUTPUT{'progress'} = 1; } 512 516 if ($CLI{'display'} =~ /1/i) { $OUTPUT{'show_redirects'} = 1; } 513 if ($CLI{'display'} =~ /2/i) { $OUTPUT{'show_cookies'} = 1; }514 if ($CLI{'display'} =~ /3/i) { $OUTPUT{'show_ok'} = 1; }515 if ($CLI{'display'} =~ /4/i) { $OUTPUT{'show_auth'} = 1; }516 }517 if ($CLI{'display'} =~ /2/i) { $OUTPUT{'show_cookies'} = 1; } 518 if ($CLI{'display'} =~ /3/i) { $OUTPUT{'show_ok'} = 1; } 519 if ($CLI{'display'} =~ /4/i) { $OUTPUT{'show_auth'} = 1; } 520 } 517 521 518 522 # port(s) … … 622 626 623 627 # POSIX support for status? 624 $NIKTO{'POSIX'}{'support'} =0;628 $NIKTO{'POSIX'}{'support'} = 0; 625 629 eval "use POSIX qw(:termios_h)"; 626 if ( !$@) {627 eval "use Time::HiRes qw(ualarm)";628 if ( !$@) {629 $NIKTO{'POSIX'}{'support'}=1; 630 $NIKTO{'POSIX'}{'echo'} = ECHO | ECHOK | ICANON;631 $NIKTO{'POSIX'}{'noecho'} = $oterm & ~$echo;632 $NIKTO{'POSIX'}{'fd_stdin'} = fileno(STDIN);633 $NIKTO{'POSIX'}{'term'} = POSIX::Termios->new();634 $NIKTO{'POSIX'}{'term'}->getattr($fd_stdin);635 $NIKTO{'POSIX'}{'oterm'} = $NIKTO{'POSIX'}{'term'}->getlflag();636 }637 }630 if (!$@) { 631 eval "use Time::HiRes qw(ualarm)"; 632 if (!$@) { 633 $NIKTO{'POSIX'}{'support'} = 1; 634 $NIKTO{'POSIX'}{'fd_stdin'} = fileno(STDIN); 635 $NIKTO{'POSIX'}{'term'} = POSIX::Termios->new(); 636 $NIKTO{'POSIX'}{'term'}->getattr($fd_stdin); 637 $NIKTO{'POSIX'}{'oterm'} = $NIKTO{'POSIX'}{'term'}->getlflag(); 638 $NIKTO{'POSIX'}{'echo'} = ECHOE | ECHO | ECHOK | ICANON; 639 $NIKTO{'POSIX'}{'noecho'} = $oterm & ~$echo; 640 } 641 } 638 642 return; 639 643 } … … 641 645 ############################################################################### 642 646 sub reset_term { 643 $NIKTO{'POSIX'}{'term'}->setlflag($NIKTO{'POSIX'}{'oterm'});644 $NIKTO{'POSIX'}{'support'}=0; 645 }647 $NIKTO{'POSIX'}{'term'}->setlflag($NIKTO{'POSIX'}{'oterm'}); 648 $NIKTO{'POSIX'}{'support'} = 0; 649 } 646 650 647 651 ############################################################################### 648 652 sub safe_quit { 649 $mark->{'end_time'} = time();650 report_host_end($mark);651 report_close($mark);652 reset_term();653 exit(1);654 }653 $mark->{'end_time'} = time(); 654 report_host_end($mark); 655 report_close($mark); 656 reset_term(); 657 exit(1); 658 } 655 659 656 660 ############################################################################### 657 661 sub check_input { 658 my $key = readkey(); 659 if ($key eq '') { return; } 660 661 lc($key); 662 if ($key eq ' ') { 663 my $line = sprintf("- Completed: %d tests, approximately %.0f%% complete", $NIKTO{'totalrequests'}, ($NIKTO{'totalrequests'} / $NIKTO{'total_checks'}) * 100); 664 if ($NIKTO{'current_plugin'} ne '') { $line .= " (in plugin $NIKTO{'current_plugin'})"; } 662 my $key = readkey(); 663 if ($key eq '') { return; } 664 665 lc($key); 666 if ($key eq ' ') { 667 my $line = sprintf("- Completed: %d tests, approximately %.0f%% complete", 668 $NIKTO{'totalrequests'}, 669 ($NIKTO{'totalrequests'} / $NIKTO{'total_checks'}) * 100); 670 if ($NIKTO{'current_plugin'} ne '') { $line .= " (in plugin $NIKTO{'current_plugin'})"; } 665 671 nprint($line); 666 return;667 } 668 elsif ($key eq 'v') { 669 if ($OUTPUT{'verbose'}) { $OUTPUT{'verbose'}=0; }670 else { $OUTPUT{'verbose'}=1; }671 }672 elsif ($key eq 'd') { 673 if ($OUTPUT{'debug'}) { $OUTPUT{'debug'}=0; }674 else { $OUTPUT{'debug'}=1; }675 }676 elsif ($key eq 'e') { 677 if ($OUTPUT{'errors'}) { $OUTPUT{'errors'}=0; }678 else { $OUTPUT{'errors'}=1; }679 }680 elsif ($key eq 'p') { 681 if ($OUTPUT{'progress'}) { $OUTPUT{'progress'}=0; }682 else { $OUTPUT{'progress'}=1; }683 }684 elsif ($key eq 'r') { 685 if ($OUTPUT{'show_redirects'}) { $OUTPUT{'show_redirects'}=0; }686 else { $OUTPUT{'show_redirects'}=1; }687 }688 elsif ($key eq 'c') { 689 if ($OUTPUT{'show_cookies'}) { $OUTPUT{'show_cookies'}=0; }690 else { $OUTPUT{'show_cookies'}=1; }691 }692 elsif ($key eq 'o') { 693 if ($OUTPUT{'show_ok'}) { $OUTPUT{'show_ok'}=0; }694 else { $OUTPUT{'show_ok'}=1; }695 }696 elsif ($key eq 'a') { 697 if ($OUTPUT{'show_auth'}) { $OUTPUT{'show_auth'}=0; }698 else { $OUTPUT{'show_auth'}=1; }699 }700 elsif (($key eq 'q') || (ord($key) eq 3)){701 safe_quit();702 }703 return;672 return; 673 } 674 elsif ($key eq 'v') { 675 if ($OUTPUT{'verbose'}) { $OUTPUT{'verbose'} = 0; } 676 else { $OUTPUT{'verbose'} = 1; } 677 } 678 elsif ($key eq 'd') { 679 if ($OUTPUT{'debug'}) { $OUTPUT{'debug'} = 0; } 680 else { $OUTPUT{'debug'} = 1; } 681 } 682 elsif ($key eq 'e') { 683 if ($OUTPUT{'errors'}) { $OUTPUT{'errors'} = 0; } 684 else { $OUTPUT{'errors'} = 1; } 685 } 686 elsif ($key eq 'p') { 687 if ($OUTPUT{'progress'}) { $OUTPUT{'progress'} = 0; } 688 else { $OUTPUT{'progress'} = 1; } 689 } 690 elsif ($key eq 'r') { 691 if ($OUTPUT{'show_redirects'}) { $OUTPUT{'show_redirects'} = 0; } 692 else { $OUTPUT{'show_redirects'} = 1; } 693 } 694 elsif ($key eq 'c') { 695 if ($OUTPUT{'show_cookies'}) { $OUTPUT{'show_cookies'} = 0; } 696 else { $OUTPUT{'show_cookies'} = 1; } 697 } 698 elsif ($key eq 'o') { 699 if ($OUTPUT{'show_ok'}) { $OUTPUT{'show_ok'} = 0; } 700 else { $OUTPUT{'show_ok'} = 1; } 701 } 702 elsif ($key eq 'a') { 703 if ($OUTPUT{'show_auth'}) { $OUTPUT{'show_auth'} = 0; } 704 else { $OUTPUT{'show_auth'} = 1; } 705 } 706 elsif (($key eq 'q') || (ord($key) eq 3)) { 707 safe_quit(); 708 } 709 return; 704 710 } 705 711 706 712 ############################################################################### 707 713 sub readkey { 708 if (!$NIKTO{'POSIX'}{'support'}) { return; }709 710 my $key;711 $NIKTO{'POSIX'}{'term'}->setlflag($NIKTO{'POSIX'}{'noecho'});712 $NIKTO{'POSIX'}{'term'}->setattr($NIKTO{'POSIX'}{'fd_stdin'}, TCSANOW);713 eval {714 local $SIG{ALRM} = sub { die; };715 ualarm(1_000);716 sysread(STDIN, $key, 1);717 ualarm(0);718 };719 $NIKTO{'POSIX'}{'term'}->setlflag($NIKTO{'POSIX'}{'oterm'});720 $NIKTO{'POSIX'}{'term'}->setattr($NIKTO{'POSIX'}{'fd_stdin'}, TCSANOW);721 722 return $key;723 }714 if (!$NIKTO{'POSIX'}{'support'}) { return; } 715 716 my $key; 717 $NIKTO{'POSIX'}{'term'}->setlflag($NIKTO{'POSIX'}{'noecho'}); 718 $NIKTO{'POSIX'}{'term'}->setattr($NIKTO{'POSIX'}{'fd_stdin'}, TCSANOW); 719 eval { 720 local $SIG{ALRM} = sub { die; }; 721 ualarm(1_000); 722 sysread(STDIN, $key, 1); 723 ualarm(0); 724 }; 725 $NIKTO{'POSIX'}{'term'}->setlflag($NIKTO{'POSIX'}{'oterm'}); 726 $NIKTO{'POSIX'}{'term'}->setattr($NIKTO{'POSIX'}{'fd_stdin'}, TCSANOW); 727 728 return $key; 729 } 724 730 725 731 ############################################################################### … … 1235 1241 $m->{ssl} = ($checkssl eq "HTTP") ? 0 : 1; 1236 1242 proxy_check($m); 1237 my ($res, $content) = nfetch($m, "/", $method, "", \%headers, { noerror => 1, noprefetch => 1, nopostfetch => 1 }, "Port Check"); 1243 my ($res, $content) = 1244 nfetch($m, "/", $method, "", \%headers, 1245 { noerror => 1, noprefetch => 1, nopostfetch => 1 }, 1246 "Port Check"); 1238 1247 1239 1248 if ($res) { … … 1399 1408 } 1400 1409 1401 if (!$run) { next; }1410 if (!$run) { next; } 1402 1411 1403 1412 my $oldverbose = $OUTPUT{'verbose'}; … … 1414 1423 $OUTPUT{'debug'} = 1; 1415 1424 } 1416 unless ($type eq "prefetch" || $type eq "postfetch") { $NIKTO{'current_plugin'}=$plugin->{'full_name'}; } 1425 unless ($type eq "prefetch" || $type eq "postfetch") { 1426 $NIKTO{'current_plugin'} = $plugin->{'full_name'}; 1427 } 1417 1428 &{ $plugin->{ $type . '_method' } }($mark, $plugin->{'parameters'}, $request, $result); 1418 1429 $OUTPUT{'verbose'} = $oldverbose; … … 1584 1595 # check main nikto versions 1585 1596 foreach my $remotefile (keys %REMOTE) { 1586 my @l = split(/\./, $LOCAL{$remotefile}); 1587 my @r = split(/\./, $REMOTE{$remotefile}); 1588 my $update=0; 1589 if ($LOCAL{$remotefile} eq '') { $update=1; } 1590 elsif ($r[0] > $l[0]) { $update=1; } 1591 elsif ($r[1] > $l[1]) { $update=1; } 1592 elsif ($r[2] > $l[2]) { $update=1; } 1593 1594 if ($update) { 1595 if ($remotefile eq "nikto") { 1596 nprint "+ Nikto has been updated to $REMOTE{$remotefile}, local copy is $NIKTO{'version'}\n"; 1597 nprint "+ No update has taken place. Please upgrade Nikto by visiting http://$server/\n"; 1598 if ($remotemsg ne "") { nprint "+ $server message: $remotemsg\n"; } 1599 exit; 1600 } 1601 push(@DBTOGET, $remotefile); 1602 if ($remotefile !~ /^db_/) { $code_updates = 1; } 1603 } 1604 } 1597 my @l = split(/\./, $LOCAL{$remotefile}); 1598 my @r = split(/\./, $REMOTE{$remotefile}); 1599 my $update = 0; 1600 if ($LOCAL{$remotefile} eq '') { $update = 1; } 1601 elsif ($r[0] > $l[0]) { $update = 1; } 1602 elsif ($r[1] > $l[1]) { $update = 1; } 1603 elsif ($r[2] > $l[2]) { $update = 1; } 1604 1605 if ($update) { 1606 if ($remotefile eq "nikto") { 1607 nprint 1608 "+ Nikto has been updated to $REMOTE{$remotefile}, local copy is $NIKTO{'version'}\n"; 1609 nprint 1610 "+ No update has taken place. Please upgrade Nikto by visiting http://$server/\n"; 1611 if ($remotemsg ne "") { nprint "+ $server message: $remotemsg\n"; } 1612 exit; 1613 } 1614 push(@DBTOGET, $remotefile); 1615 if ($remotefile !~ /^db_/) { $code_updates = 1; } 1616 } 1617 } 1605 1618 1606 1619 # replace local files if updated … … 1640 1653 1641 1654 ############################################################################### 1642 # read_data ( prompt, mode ) 1643 # read STDIN data from the user 1644 # portions of this (POSIX code) were taken from the 1645 # Term::ReadPassword module by Tom Phoenix <rootbeer@redcat.com> (many thanks). 1646 # it has been modified to not require Term::ReadLine, but still requires 1647 # POSIX::Termios of it's a POSIX machine 1655 # portions of this sub were taken from the Term::ReadPassword module. 1656 # It has been modified to not require Term::ReadLine, but still requires 1657 # POSIX::Termios if it's a POSIX machine 1648 1658 ############################################################################### 1649 1659 sub read_data { 1650 if ($NIKTOCONFIG{PROMPTS} =~ /no/i) { return; }1660 if ($NIKTOCONFIG{PROMPTS} eq 'no') { return; } 1651 1661 my ($prompt, $mode, $POSIX) = @_; 1652 my $input = "";1662 my $input; 1653 1663 1654 1664 my %SPECIAL = ("\x03" => 'INT', # Control-C, Interrupt … … 1658 1668 "\x0a" => 'ENT', # LF, Enter 1659 1669 ); 1660 1661 # if we're on a non-POSIX machine we can't not-echo the1662 # characters, so just use getc to avoid the dependency on1663 # POSIX::Termios. We would be best to get rid of this1664 # entirely and use another way...1665 1670 1666 1671 if ($NIKTO{'POSIX'}{'support'}) { … … 1904 1909 1905 1910 if ((!defined $CLI{'nocache'}) && (!$flags_nocache)) { 1906 my $key = $mark->{'ip'} 1907 . $mark->{'hostname'} 1908 . $mark->{'port'} 1909 . $mark->{'ssl'} 1910 . $method 1911 . $uri 1912 . $postdata; 1911 my $key = 1912 $mark->{'ip'} 1913 . $mark->{'hostname'} 1914 . $mark->{'port'} 1915 . $mark->{'ssl'} 1916 . $method 1917 . $uri 1918 . $postdata; 1913 1919 1914 1920 $CACHE{$key}{'method'} = $method; … … 1956 1962 if (($NIKTO{'totalrequests'} % 10) == 0) { 1957 1963 check_input(); 1958 }1964 } 1959 1965 1960 1966 if (defined $CLI{'root'}) { … … 1962 1968 } 1963 1969 else { 1964 $request{'whisker'}->{'uri'} = $uri;1970 $request{'whisker'}->{'uri'} = $uri; 1965 1971 } 1966 1972 $request{'whisker'}->{'method'} = $method; … … 1973 1979 # check for extra HTTP headers 1974 1980 if (defined $headers) { 1981 1975 1982 # loop through the hash ref passed and add each header to request 1976 1983 while (my ($key, $value) = each(%$headers)) { … … 2009 2016 2010 2017 # Snarf what we can from the whisker hash and put in mark 2011 if (!exists $result{'whisker'}->{'error'}) { 2012 if (!exists $mark->{'banner'}) { 2013 $mark->{'banner'} = $result{'server'}; 2014 } 2015 else { 2016 # Check banner hasn't changed 2017 if (exists $result{'server'} && $mark->{'banner'} ne $result{'server'} && !exists $mark->{'bannerchanged'}) { 2018 nprint("+ Server banner has changed from $mark->{banner} to $result{server}, this may suggest a WAF is in place"); 2019 $mark->{'bannerchanged'} = 1; 2020 } 2021 } 2022 2023 if (!exists $mark->{'ssl_cipher'} && $mark->{'ssl'}) { 2024 # Grab ssl details 2025 $mark->{'ssl_cipher'} = $result{'whisker'}->{'ssl_cipher'}; 2026 $mark->{'ssl_cert_issuer'} = $result{'whisker'}->{'ssl_cert_issuer'}; 2027 $mark->{'ssl_cert_subject'} = $result{'whisker'}->{'ssl_cert_subject'}; 2028 } 2029 } 2018 if (!exists $result{'whisker'}->{'error'}) { 2019 if (!exists $mark->{'banner'}) { 2020 $mark->{'banner'} = $result{'server'}; 2021 } 2022 else { 2023 2024 # Check banner hasn't changed 2025 if ( exists $result{'server'} 2026 && $mark->{'banner'} ne $result{'server'} 2027 && !exists $mark->{'bannerchanged'}) { 2028 nprint( 2029 "+ Server banner has changed from $mark->{banner} to $result{server}, this may suggest a WAF is in place" 2030 ); 2031 $mark->{'bannerchanged'} = 1; 2032 } 2033 } 2034 2035 if (!exists $mark->{'ssl_cipher'} && $mark->{'ssl'}) { 2036 2037 # Grab ssl details 2038 $mark->{'ssl_cipher'} = $result{'whisker'}->{'ssl_cipher'}; 2039 $mark->{'ssl_cert_issuer'} = $result{'whisker'}->{'ssl_cert_issuer'}; 2040 $mark->{'ssl_cert_subject'} = $result{'whisker'}->{'ssl_cert_subject'}; 2041 } 2042 } 2030 2043 } 2031 2044 nprint("- $result{'whisker'}{'code'} for $method:\t$uri", "v"); … … 2118 2131 $db_extensions{$ext} = 1; 2119 2132 2120 # Escape chars in the conditionals. This must change if regexs are allowed in the db.2133 # Escape chars in the conditionals. This must change if regexs are allowed in the db. 2121 2134 for (my $y = 5 ; $y <= 9 ; $y++) { $item[$y] = quotemeta($item[$y]); } 2122 2135 -
trunk/plugins/nikto_headers.plugin
r440 r457 28 28 description => "Performs various checks against the headers returned from a HTTP request.", 29 29 postfetch_method => \&nikto_headers_postfetch, 30 scan_method => \&nikto_headers,31 copyright => "2008 CIRT Inc."30 scan_method => \&nikto_headers, 31 copyright => "2008 CIRT Inc." 32 32 }; 33 33 34 34 # some global variables 35 35 use vars qw/%HFOUND/; … … 40 40 sub nikto_headers_postfetch { 41 41 my ($mark, $parameters, $request, $result) = @_; 42 42 43 43 if (exists $result->{'whisker'}->{'error'}) { 44 44 return $request, $result; … … 59 59 my ($mark, $result, $header, $message, $tid) = @_; 60 60 61 if (exists $result->{$header}) 62 {63 my $key =LW2::md5( $mark->{'ip'}64 . $mark->{'hostname'}65 . $mark->{'port'}66 . $mark->{'ssl'}67 . $result->{'whisker'}->{'method'}68 . $header);61 if (exists $result->{$header}) { 62 my $key = 63 LW2::md5( $mark->{'ip'} 64 . $mark->{'hostname'} 65 . $mark->{'port'} 66 . $mark->{'ssl'} 67 . $result->{'whisker'}->{'method'} 68 . $header); 69 69 70 70 if (!exists $HFOUND{$key}) { 71 71 my $value = $result->{$header}; 72 72 $HFOUND{$key} = $value; 73 74 add_vulnerability($mark, $message . " " . $value, $tid, "0", 73 74 add_vulnerability($mark, $message . " " . $value, 75 $tid, "0", 75 76 $result->{'whisker'}->{'method'}, 76 77 $result->{'whisker'}->{'uri'}); -
trunk/plugins/nikto_httpoptions.plugin
r443 r457 72 72 foreach my $m (split /,? /, $allow_methods) { 73 73 my $method = eval_methods($m, "Allow", $dbarray, $mark); 74 if ($method ne "") { $davmethods{$method} = 1 } ;74 if ($method ne "") { $davmethods{$method} = 1 } 75 75 } 76 76 } … … 80 80 foreach my $m (split /,? /, $public_methods) { 81 81 my $method = eval_methods($m, "Public", $dbarray, $mark); 82 if ($method ne "") { $davmethods{$method} = 1 } ;82 if ($method ne "") { $davmethods{$method} = 1 } 83 83 } 84 84 } 85 85 86 86 if (scalar(keys(%davmethods)) > 0) { 87 87 $message = "WebDAV enabled ("; … … 92 92 add_vulnerability($mark, "$message", "999977", "0"); 93 93 } 94 94 95 # Check for other weirdness 95 96 # IIS Debug … … 109 110 %headers = ("Host" => "", 110 111 "Content-Length" => "0",); 111 ($res, $content) = nfetch($mark, "/", "PROPFIND", "", \%headers, { noclean => 1 }, "httpoptions: PROPFIND"); 112 ($res, $content) = 113 nfetch($mark, "/", "PROPFIND", "", \%headers, { noclean => 1 }, "httpoptions: PROPFIND"); 112 114 if ($res == 207) { 113 115 if ($content =~ "<a:href>http://") { … … 124 126 %headers = ("Host" => "Nikto",); 125 127 foreach my $method (split(/ /, "TRACE TRACK")) { 128 126 129 # Check for all flavours of HTTP 127 130 foreach my $version (split(/ /, "1.0 1.1")) { … … 159 162 # Now search database for the method. 160 163 foreach my $item (@$dbarray) { 161 if ($method eq "PROPPATCH" || $method eq "SEARCH" || 162 $method eq "PROPFIND" || $method eq "COPY" || 163 $method eq "LOCK" || $method eq "UNLOCK") { 164 if ( $method eq "PROPPATCH" 165 || $method eq "SEARCH" 166 || $method eq "PROPFIND" 167 || $method eq "COPY" 168 || $method eq "LOCK" 169 || $method eq "UNLOCK") { 164 170 return $method; 165 171 } … … 167 173 if ($item->{'method'} eq $method) { 168 174 if ($item->{'nikto_id'} eq "0") { 175 169 176 # is webdav 170 177 return $method; … … 177 184 } 178 185 } 179 186 180 187 return ""; 181 188 } -
trunk/plugins/nikto_report_nbe.plugin
r391 r457 41 41 42 42 # Write header 43 print OUT "timestamps|network|host|port|nikto_id|prio|$NIKTO{'name'} v$NIKTO{'version'}/$NIKTO{'core_version'}\n"; 43 print OUT 44 "timestamps|network|host|port|nikto_id|prio|$NIKTO{'name'} v$NIKTO{'version'}/$NIKTO{'core_version'}\n"; 44 45 return OUT; 45 46 } 46 47 47 48 sub nbe_item { 48 my ($handle, $mark, $item) = @_; 49 foreach my $uri (split(' ', $item->{'uri'})) { 50 my ( $line, $network ); 51 if ( $item->{'mark'}->{'hostname'} && $item->{'mark'}->{'port'} && $item->{'nikto_id'} ) { 52 if ($item->{'mark'}->{'hostname'} =~ /^(\d+\.\d+\.\d+)\.\d+$/) { 53 $network = $1; 54 } 55 $line.="results|"; 56 $line.="$network|"; 57 $line.="$item->{'mark'}->{'hostname'}|"; 58 $line.="$item->{'mark'}->{'port'}|"; 59 $line.="$item->{'nikto_id'}|"; 60 $line.="Security Warning|"; 61 if ($item->{'osvdb'}) { $line.="OSVDB-$item->{'osvdb'}: " }; 62 if ($item->{'method'}) { $line.="$item->{'method'} " }; 63 if ($uri) { $line.="${'uri'}: " }; 64 $line.=$item->{'message'}; 65 print $handle "$line\n"; 66 } else { 67 my $debug = "Data provided:\n$handle, $mark, $item"; 68 $debug.= "\nContents of \$mark:"; 69 foreach my $key ( sort keys %$mark ) { 70 $debug .= "\n$key - $mark->{$key}"; 71 } 72 $debug.= "\nContents of \$item:"; 73 foreach my $key ( sort keys %$item ) { 74 $debug .= "\n$key - $item->{$key}"; 75 } 76 $debug.= "\nContents of \$item->{mark}:"; 77 foreach my $key ( sort keys %{$item->{mark}} ) { 78 $debug .= "\n$key - $item->{mark}->{$key}"; 79 } 80 #die $debug; 81 nprint("+ Invalid reporting line: $debug"); 82 } 83 } 49 my ($handle, $mark, $item) = @_; 50 foreach my $uri (split(' ', $item->{'uri'})) { 51 my ($line, $network); 52 if ($item->{'mark'}->{'hostname'} && $item->{'mark'}->{'port'} && $item->{'nikto_id'}) { 53 if ($item->{'mark'}->{'hostname'} =~ /^(\d+\.\d+\.\d+)\.\d+$/) { 54 $network = $1; 55 } 56 $line .= "results|"; 57 $line .= "$network|"; 58 $line .= "$item->{'mark'}->{'hostname'}|"; 59 $line .= "$item->{'mark'}->{'port'}|"; 60 $line .= "$item->{'nikto_id'}|"; 61 $line .= "Security Warning|"; 62 if ($item->{'osvdb'}) { $line .= "OSVDB-$item->{'osvdb'}: " } 63 if ($item->{'method'}) { $line .= "$item->{'method'} " } 64 if ($uri) { $line .= "${'uri'}: " } 65 $line .= $item->{'message'}; 66 print $handle "$line\n"; 67 } 68 else { 69 my $debug = "Data provided:\n$handle, $mark, $item"; 70 $debug .= "\nContents of \$mark:"; 71 foreach my $key (sort keys %$mark) { 72 $debug .= "\n$key - $mark->{$key}"; 73 } 74 $debug .= "\nContents of \$item:"; 75 foreach my $key (sort keys %$item) { 76 $debug .= "\n$key - $item->{$key}"; 77 } 78 $debug .= "\nContents of \$item->{mark}:"; 79 foreach my $key (sort keys %{ $item->{mark} }) { 80 $debug .= "\n$key - $item->{mark}->{$key}"; 81 } 82 83 #die $debug; 84 nprint("+ Invalid reporting line: $debug"); 85 } 86 } 84 87 } 85 88 -
trunk/plugins/nikto_report_xml.plugin
r450 r457 188 188 foreach my $c (split(//, $invar)) { 189 189 my $n = ord($c); 190 if (($n > 127) || ($n < 32) || ($n == 38) || ($n == 60) || ($n == 62) | ($n == 34)) { $outvar .= sprintf '%#x', $n; } 190 if (($n > 127) || ($n < 32) || ($n == 38) || ($n == 60) || ($n == 62) | ($n == 34)) { 191 $outvar .= sprintf '%#x', $n; 192 } 191 193 else { $outvar .= $c; } 192 }194 } 193 195 return $outvar; 194 196 } -
trunk/plugins/nikto_robots.plugin
r449 r457 40 40 (my $RES, $CONTENT) = nfetch($mark, "/robots.txt", "GET", "", \%headers, "", "robots"); 41 41 42 if (($RES eq 200) || ($RES eq $FoF{'okay'}{'response'})) 43 { 42 if (($RES eq 200) || ($RES eq $FoF{'okay'}{'response'})) { 44 43 if (is_404("robots.txt", $CONTENT, $RES, $headers{'location'})) { return; } 45 44 … … 49 48 foreach my $line (@DOC) { 50 49 $line = quotemeta($line); 51 if ($line =~ /allow/i) 52 { 50 if ($line =~ /allow/i) { 53 51 chomp($line); 54 52 $line =~ s/\#.*$//; -
trunk/plugins/nikto_subdomain.plugin
r439 r457 32 32 33 33 return $id; 34 }34 } 35 35 36 36 sub nikto_subdomain { … … 48 48 "v"); 49 49 return; 50 }50 } 51 51 52 52 # Check if the start of the domain is "www" … … 55 55 # Remove the www. 56 56 $host =~ s/^www\.//; 57 }57 } 58 58 59 59 my $nocache_enabled = 0; … … 72 72 add_vulnerability($mark, "Subdomain $item->{'subdomain'} found", $item->{'nikto_id'}, 73 73 0); 74 } # End if74 } # End if 75 75 76 } # End foreach76 } # End foreach 77 77 if (!$nocache_enabled) { undef $CLI{'nocache'}; } 78 } # End sub78 } # End sub 79 79 80 80 1; -
trunk/plugins/nikto_tests.plugin
r452 r457 36 36 }; 37 37 return $id; 38 }38 } 39 39 40 40 sub nikto_tests { … … 59 59 # auth is now done in nfetch 60 60 if ($res eq 200) { 61 nprint("+ $uri - 200/OK Response could be $TESTS{$checkid}{'message'}") if $OUTPUT{'show_ok'}; 62 } 61 nprint("+ $uri - 200/OK Response could be $TESTS{$checkid}{'message'}") 62 if $OUTPUT{'show_ok'}; 63 } 63 64 elsif ($res =~ /30(?:[0-3]|7)/) { 64 65 nprint( "+ $uri - Redirects ($res) to " … … 66 67 . " , $TESTS{$checkid}{'message'}") 67 68 if $OUTPUT{'show_redirects'}; 68 }69 } 69 70 70 71 my $m1_method = my $m1o_method = my $m1a_method = my $f2_method = my $f1_method = … … 83 84 if ($content =~ /$TESTS{$checkid}{'match_1'}/) { 84 85 $positive = 1; 85 }86 }86 } 87 } 87 88 else { 88 89 if (($res eq $TESTS{$checkid}{'match_1'}) || ($res eq $FoF{'okay'}{'response'})) { 89 90 $positive = 1; 90 }91 }91 } 92 } 92 93 93 94 # no match, check optional match … … 96 97 if ($content =~ /$TESTS{$checkid}{'match_1_or'}/) { 97 98 $positive = 1; 98 }99 }99 } 100 } 100 101 else { 101 102 if ( ($res eq $TESTS{$checkid}{'match_1_or'}) 102 103 || ($res eq $FoF{'okay'}{'response'})) { 103 104 $positive = 1; 104 }105 }106 }105 } 106 } 107 } 107 108 108 109 # matched on something, check fails/ands … … 111 112 if ($f1_method eq "content") { 112 113 if ($content =~ /$TESTS{$checkid}{'fail_1'}/) { next; } 113 }114 } 114 115 else { 115 116 if ($res eq $TESTS{$checkid}{'fail_1'}) { next; } 116 }117 }117 } 118 } 118 119 if ($TESTS{$checkid}{'fail_2'} ne "") { 119 120 if ($f2_method eq "content") { 120 121 if ($content =~ /$TESTS{$checkid}{'fail_2'}/) { next; } 121 }122 } 122 123 else { 123 124 if ($res eq $TESTS{$checkid}{'fail_2'}) { next; } 124 }125 }125 } 126 } 126 127 if ($TESTS{$checkid}{'match_1_and'} ne "") { 127 128 if ($m1a_method eq "content") { 128 129 if ($content !~ /$TESTS{$checkid}{'match_1_and'}/) { next; } 129 }130 } 130 131 else { 131 132 if ($res ne $TESTS{$checkid}{'match_1_and'}) { next; } 132 }133 }133 } 134 } 134 135 135 136 # if it's an index.php, check for normal /index.php to see if it's a FP … … 137 138 my $content = rm_active_content($content, $uri); 138 139 if (LW2::md4($content) eq $FoF{'index.php'}{'match'}) { next; } 139 }140 } 140 141 141 142 # lastly check for a false positive based on file extension or type 142 143 if (($m1_method eq "code") || ($m1o_method eq "code")) { 143 144 if (is_404($uri, $content, $res, $headers{'location'})) { next; } 144 }145 } 145 146 146 147 $TESTS{$checkid}{'osvdb'} =~ s/\s+/ OSVDB\-/g; … … 149 150 $TESTS{$checkid}{'osvdb'}, 150 151 $TESTS{$checkid}{'method'}, $uri); 151 }152 }152 } 153 } 153 154 154 155 # Percentages 155 if ($OUTPUT{'progress'}) {156 if ($parameters->{'report'}) {157 $progress++;158 if (($progress % $parameters->{'report'}) == 0) {159 my $line = sprintf("- Tests completed: %d %.0f%%",160 $progress, ($progress / $NIKTO{total_checks}) * 100);161 nprint($line);162 } 163 } 164 }165 } # end check loop156 if ($OUTPUT{'progress'}) { 157 if ($parameters->{'report'}) { 158 $progress++; 159 if (($progress % $parameters->{'report'}) == 0) { 160 my $line = sprintf("- Tests completed: %d %.0f%%", 161 $progress, ($progress / $NIKTO{total_checks}) * 100); 162 nprint($line); 163 } 164 } 165 } 166 } # end check loop 166 167 167 168 # Perform mutation tests 168 169 if ($parameters->{'passfiles'}) { 169 170 passchecks($mark); 170 }171 } 171 172 if ($parameters->{'all'}) { 172 173 allchecks($mark); 173 }174 } 174 175 175 176 return; 176 }177 } 177 178 178 179 sub passchecks { … … 203 204 # dir/file 204 205 testfile($mark, "$cgi$dir$file", "passfiles", "299998"); 205 }206 }207 }208 }209 }206 } 207 } 208 } 209 } 210 } 210 211 211 212 sub allchecks { … … 231 232 $dir =~ s/([^a-zA-Z0-9])/\\$1/g; 232 233 $file =~ s/$dir//; 233 }234 } 234 235 if (($file ne "") && ($file !~ /^\?/)) { 235 236 $FILES{$file} = ""; 236 }237 }238 }237 } 238 } 239 } 239 240 240 241 # Now do a check for each item - just check the return status, nothing else … … 242 243 foreach my $file (keys %FILES) { 243 244 testfile($mark, "$dir$file", "all checks", 299999); 244 }245 }246 }245 } 246 } 247 } 247 248 248 249 sub testfile { … … 254 255 nprint("+ ERROR: $uri returned an error: $error", "e"); 255 256 return; 256 }257 } 257 258 if ($res == 200) { 258 259 add_vulnerability($mark, "$uri: file found during $name mutation", "$tid", "0", "GET"); 259 }260 }260 } 261 } 261 262 262 263 1;
Note: See TracChangeset
for help on using the changeset viewer.