Changeset 388
- Timestamp:
- 04/11/2010 08:24:23 PM (3 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
-
docs/CHANGES.txt (modified) (1 diff)
-
plugins/nikto_core.plugin (modified) (3 diffs)
-
plugins/nikto_tests.plugin (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/docs/CHANGES.txt
r387 r388 1 2010-04-11 2 - Ticket 125: fetch is dead, long live nfetch 3 - Moved URI error handling and reporting result to nfetch, rather than being in nikto_tests (Ticket 139, partial) 1 4 2010-04-10 2 5 - Merged apacheusers and apache_enum_users together -
trunk/plugins/nikto_core.plugin
r387 r388 1387 1387 my $olddebug = $OUTPUT{'debug'}; 1388 1388 my $olderrors = $OUTPUT{'errors'}; 1389 nprint("- Running $type for \"$plugin->{full_name}\" plugin", "v"); 1389 nprint("- Running $type for \"$plugin->{full_name}\" plugin", "v") 1390 unless ($type eq "prefetch" || $type eq "postfetch"); 1390 1391 if (defined $plugin->{'parameters'}->{'verbose'} 1391 1392 && $plugin->{'parameters'}->{'verbose'} == 1) { … … 1949 1950 1950 1951 ####################################################################### 1951 sub fetch {1952 if ($CLI{'pause'} > 0) { sleep $CLI{'pause'}; }1953 LW2::http_close(\%request); # force-close any old connections1954 $request{'whisker'}->{'uri'} = $_[0];1955 if (defined $CLI{'root'}) {1956 $request{'whisker'}->{'uri'} = $CLI{'root'} . $_[0]; # prepend -root option value1957 }1958 1959 # Set testid in UA1960 my $temp_ua = $request{'User-Agent'};1961 my $testid = $_[3];1962 $request{'User-Agent'} =~ s/\@TESTID/$testid/g;1963 1964 $request{'whisker'}->{'method'} = $_[1];1965 delete $request{'whisker'}->{'data'};1966 delete $request{'Content-Encoding'};1967 delete $request{'Content-Length'};1968 my $header_hash = $_[3];1969 1970 if (defined $_[2]) {1971 my $r = $_[2];1972 $r =~ s/\\\"/\"/g;1973 $request{'whisker'}->{'data'} = $r;1974 }1975 1976 # check for extra HTTP headers1977 if (defined $_[3]) {1978 1979 # loop through the hash ref passed and add each header to request1980 while (my ($key, $value) = each(%$header_hash)) {1981 $request{$key} = $value;1982 }1983 }1984 unless ($_[4]) { LW2::http_fixup_request(\%request); }1985 1986 # Cache1987 if ( defined($CACHE{ $request{'whisker'}->{'uri'} })1988 && !defined($CLI{'nocache'})1989 && ($CACHE{ $request{'whisker'}->{'uri'} }{'method'} eq $request{'whisker'}->{'method'})) {1990 1991 # Get from cache1992 nprint("- Retrieving $request{'whisker'}->{'uri'} from cache.", "v");1993 $result{'whisker'}->{'code'} = $CACHE{ $request{'whisker'}->{'uri'} }{'res'};1994 $result{'whisker'}->{'data'} = $CACHE{ $request{'whisker'}->{'uri'} }{'content'};1995 }1996 else {1997 LW2::http_do_request_timeout(\%request, \%result);1998 $NIKTO{'totalrequests'}++;1999 unless (defined $CLI{'nocache'}) {2000 $CACHE{ $request{'whisker'}->{'uri'} }{'method'} = $request{'whisker'}->{'method'};2001 $CACHE{ $request{'whisker'}->{'uri'} }{'res'} = $result{'whisker'}->{'code'};2002 $CACHE{ $request{'whisker'}->{'uri'} }{'content'} = $result{'whisker'}->{'data'};2003 }2004 if ($OUTPUT{'debug'}) {2005 dump_var("Request Hash", \%request);2006 dump_var("Result Hash", \%result);2007 }2008 }2009 2010 if ( defined $CLI{'display'}2011 && ($CLI{'display'} =~ /2/)2012 && (defined($result{'whisker'}->{'cookies'}))) {2013 foreach my $c (@{ $result{'whisker'}->{'cookies'} }) {2014 nprint("+ $request{'whisker'}->{'uri'} sent cookie: $c");2015 }2016 }2017 2018 # Clean up extra headers2019 if (defined $_[3]) {2020 while (my ($key, $value) = each(%$header_hash)) {2021 delete $request{$key};2022 }2023 }2024 2025 # content search2026 content_search($result{'whisker'}->{'data'},2027 $request{'whisker'}->{'uri'},2028 $request{'whisker'}->{'method'});2029 2030 $request{'User-Agent'} = $temp_ua; # reset UA2031 return $result{'whisker'}->{'code'}, $result{'whisker'}->{'data'};2032 }2033 2034 #######################################################################2035 1952 sub setup_hash { 2036 1953 my ($reqhash, $mark, $testid) = @_; … … 2125 2042 } 2126 2043 } 2127 2128 if ( defined $CLI{'display'} 2044 nprint("- $result{'whisker'}{'code'} for $method:\t$uri", "v"); 2045 2046 # Check for errors to reduce false positives 2047 if (defined $result{'whisker'}->{'error'}) { 2048 $mark->{'total_errors'}++; 2049 nprint("+ ERROR: $uri returned an error: $result{'whisker'}{'error'}\n", "e"); 2050 next; 2051 } 2052 2053 if ( defined $CLI{'display'} 2129 2054 && ($CLI{'display'} =~ /2/) 2130 2055 && (defined($result{'whisker'}->{'cookies'}))) { -
trunk/plugins/nikto_tests.plugin
r387 r388 40 40 41 41 # this is the actual the looped code for all the checks 42 foreach my $ CHECKID(sort keys %TESTS) {43 if ($ CHECKID>= 500000) { next; } # skip TESTS added manually during run (for reports)42 foreach my $checkid (sort keys %TESTS) { 43 if ($checkid >= 500000) { next; } # skip TESTS added manually during run (for reports) 44 44 # replace variables in the uri 45 my @urilist = change_variables($TESTS{$ CHECKID}{'uri'});45 my @urilist = change_variables($TESTS{$checkid}{'uri'}); 46 46 47 47 # Now repeat for each uri 48 48 foreach my $uri (@urilist) { 49 (my $RES, $CONTENT) = 50 fetch($uri, $TESTS{$CHECKID}{'method'}, $TESTS{$CHECKID}{'data'}, $CHECKID); 51 nprint("- $RES for $TESTS{$CHECKID}{'method'}:\t$request{'whisker'}{'uri'}", "v"); 52 53 # Check for errors to reduce false positives 54 if (defined $result{'whisker'}->{'error'}) { 55 56 # An error occured, show in verbose mode and skip 57 # Try it again before we report it fully 58 sleep(1); 59 ($RES, $CONTENT) = 60 fetch($uri, $TESTS{$CHECKID}{'method'}, $TESTS{$CHECKID}{'data'}, $CHECKID); 61 nprint("- $RES for $TESTS{$CHECKID}{'method'}:\t$request{'whisker'}{'uri'}", "v"); 62 63 if (defined $result{'whisker'}->{'error'}) { 64 $mark->{'total_errors'}++; 65 nprint("+ ERROR: $uri returned an error: $result{'whisker'}{'error'}\n", "e"); 66 next; 67 } 68 } 69 70 # do auth/redir first, independent of test pass/fail 71 if ($RES eq 401) { 72 $result{'www-authenticate'} =~ /realm=\"(.+)\"/; 73 my $R = $1; 74 if ($R eq '') { $R = $result{'www-authenticate'} } 75 do_auth($request, $result, $mark); 76 nprint("+ $uri - Requires Authentication for realm '$R'") if $CLI{'display'} =~ /4/; 77 $RES = $result{'whisker'}->{'code'}; 78 $CONTENT = $result{'whisker'}->{'data'}; 79 } 80 elsif ($RES eq 200) { 81 nprint("+ $uri - 200/OK Response could be $TESTS{$CHECKID}{'message'}") 49 (my $res, $content, $error) = 50 nfetch($mark, $uri, $TESTS{$checkid}{'method'}, $TESTS{$checkid}{'data'}, "", "", $checkid); 51 52 # auth is now done in nfetch 53 if ($result eq 200) { 54 nprint("+ $uri - 200/OK Response could be $TESTS{$checkid}{'message'}") 82 55 if $CLI{'display'} =~ /3/; 83 56 } 84 elsif ($ RES=~ /30([0-3]|7)/) {85 nprint( "+ $uri - Redirects ($ RES) to "57 elsif ($result =~ /30([0-3]|7)/) { 58 nprint( "+ $uri - Redirects ($result) to " 86 59 . $result{'location'} 87 . " , $TESTS{$ CHECKID}{'message'}")60 . " , $TESTS{$checkid}{'message'}") 88 61 if $CLI{'display'} =~ /1/; 89 62 } … … 94 67 95 68 # how to check each conditional 96 if ($TESTS{$ CHECKID}{'match_1'} =~ /^[0-9]{3}$/) { $m1_method = "code"; }97 if ($TESTS{$ CHECKID}{'match_1_or'} =~ /^[0-9]{3}$/) { $m1o_method = "code"; }98 if ($TESTS{$ CHECKID}{'match_1_and'} =~ /^[0-9]{3}$/) { $m1a_method = "code"; }99 if ($TESTS{$ CHECKID}{'fail_1'} =~ /^[0-9]{3}$/) { $f1_method = "code"; }100 if ($TESTS{$ CHECKID}{'fail_2'} =~ /^[0-9]{3}$/) { $f2_method = "code"; }69 if ($TESTS{$checkid}{'match_1'} =~ /^[0-9]{3}$/) { $m1_method = "code"; } 70 if ($TESTS{$checkid}{'match_1_or'} =~ /^[0-9]{3}$/) { $m1o_method = "code"; } 71 if ($TESTS{$checkid}{'match_1_and'} =~ /^[0-9]{3}$/) { $m1a_method = "code"; } 72 if ($TESTS{$checkid}{'fail_1'} =~ /^[0-9]{3}$/) { $f1_method = "code"; } 73 if ($TESTS{$checkid}{'fail_2'} =~ /^[0-9]{3}$/) { $f2_method = "code"; } 101 74 102 75 # basic match for positive result 103 76 if ($m1_method eq "content") { 104 if ($ CONTENT =~ /$TESTS{$CHECKID}{'match_1'}/) {77 if ($content =~ /$TESTS{$checkid}{'match_1'}/) { 105 78 $positive = 1; 106 79 } 107 80 } 108 81 else { 109 if (($ RES eq $TESTS{$CHECKID}{'match_1'}) || ($RESeq $FoF{'okay'}{'response'})) {82 if (($result eq $TESTS{$checkid}{'match_1'}) || ($result eq $FoF{'okay'}{'response'})) { 110 83 $positive = 1; 111 84 } … … 113 86 114 87 # no match, check optional match 115 if ((!$positive) && ($TESTS{$ CHECKID}{'match_1_or'} ne "")) {88 if ((!$positive) && ($TESTS{$checkid}{'match_1_or'} ne "")) { 116 89 if ($m1o_method eq "content") { 117 if ($ CONTENT =~ /$TESTS{$CHECKID}{'match_1_or'}/) {90 if ($content =~ /$TESTS{$checkid}{'match_1_or'}/) { 118 91 $positive = 1; 119 92 } 120 93 } 121 94 else { 122 if ( ($ RES eq $TESTS{$CHECKID}{'match_1_or'})123 || ($ RESeq $FoF{'okay'}{'response'})) {95 if ( ($result eq $TESTS{$checkid}{'match_1_or'}) 96 || ($result eq $FoF{'okay'}{'response'})) { 124 97 $positive = 1; 125 98 } … … 129 102 # matched on something, check fails/ands 130 103 if ($positive) { 131 if ($TESTS{$ CHECKID}{'fail_1'} ne "") {104 if ($TESTS{$checkid}{'fail_1'} ne "") { 132 105 if ($f1_method eq "content") { 133 if ($ CONTENT =~ /$TESTS{$CHECKID}{'fail_1'}/) { next; }106 if ($content =~ /$TESTS{$checkid}{'fail_1'}/) { next; } 134 107 } 135 108 else { 136 if ($ RES eq $TESTS{$CHECKID}{'fail_1'}) { next; }137 } 138 } 139 if ($TESTS{$ CHECKID}{'fail_2'} ne "") {109 if ($result eq $TESTS{$checkid}{'fail_1'}) { next; } 110 } 111 } 112 if ($TESTS{$checkid}{'fail_2'} ne "") { 140 113 if ($f2_method eq "content") { 141 if ($ CONTENT =~ /$TESTS{$CHECKID}{'fail_2'}/) { next; }114 if ($content =~ /$TESTS{$checkid}{'fail_2'}/) { next; } 142 115 } 143 116 else { 144 if ($ RES eq $TESTS{$CHECKID}{'fail_2'}) { next; }145 } 146 } 147 if ($TESTS{$ CHECKID}{'match_1_and'} ne "") {117 if ($result eq $TESTS{$checkid}{'fail_2'}) { next; } 118 } 119 } 120 if ($TESTS{$checkid}{'match_1_and'} ne "") { 148 121 if ($m1a_method eq "content") { 149 if ($ CONTENT !~ /$TESTS{$CHECKID}{'match_1_and'}/) { next; }122 if ($content !~ /$TESTS{$checkid}{'match_1_and'}/) { next; } 150 123 } 151 124 else { 152 if ($ RES ne $TESTS{$CHECKID}{'match_1_and'}) { next; }125 if ($result ne $TESTS{$checkid}{'match_1_and'}) { next; } 153 126 } 154 127 } … … 156 129 # if it's an index.php, check for normal /index.php to see if it's a FP 157 130 if ($uri =~ /^\/index.php\?/) { 158 my $ CONTENT = rm_active_content($CONTENT, $uri);159 if (LW2::md4($ CONTENT) eq $FoF{'index.php'}{'match'}) { next; }131 my $content = rm_active_content($content, $uri); 132 if (LW2::md4($content) eq $FoF{'index.php'}{'match'}) { next; } 160 133 } 161 134 162 135 # lastly check for a false positive based on file extension or type 163 136 if (($m1_method eq "code") || ($m1o_method eq "code")) { 164 if (is_404($request{'whisker'}{'uri'}, $ CONTENT, $RES)) { next; }165 } 166 167 $TESTS{$ CHECKID}{'osvdb'} =~ s/\s+/ OSVDB\-/g;137 if (is_404($request{'whisker'}{'uri'}, $content, $result)) { next; } 138 } 139 140 $TESTS{$checkid}{'osvdb'} =~ s/\s+/ OSVDB\-/g; 168 141 add_vulnerability($mark, 169 "$request{'whisker'}{'uri'}: $TESTS{$ CHECKID}{'message'}",170 $ CHECKID,171 $TESTS{$ CHECKID}{'osvdb'},172 $TESTS{$ CHECKID}{'method'},142 "$request{'whisker'}{'uri'}: $TESTS{$checkid}{'message'}", 143 $checkid, 144 $TESTS{$checkid}{'osvdb'}, 145 $TESTS{$checkid}{'method'}, 173 146 $uri 174 147 );
Note: See TracChangeset
for help on using the changeset viewer.