⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nikto_core.plugin

📁 Ubuntu packages of security software。 相当不错的源码
💻 PLUGIN
📖 第 1 页 / 共 5 页
字号:
#VERSION,2.03#LASTMOD,01.09.2008################################################################################  Copyright (C) 2006 CIRT, Inc.#  #  This program is free software; you can redistribute it and/or#  modify it under the terms of the GNU General Public License#  as published by the Free Software Foundation; version 2#  of the License only.#  #  This program is distributed in the hope that it will be useful,#  but WITHOUT ANY WARRANTY; without even the implied warranty of#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the#  GNU General Public License for more details.#  #  You should have received a copy of the GNU General Public License#  along with this program; if not, write to the Free Software#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.############################################################################################################################################################### Nikto core functionality###############################################################################sub test_target{ dump_var("Result Hash", \%result); # this is the actual the looped code for all the checks foreach my $CHECKID (sort keys %TESTS)   {    if ($CHECKID >= 500000) { next; } # skip TESTS added manually during run (for reports)   (my $RES, $CONTENT) = fetch($TESTS{$CHECKID}{uri},$TESTS{$CHECKID}{method},$TESTS{$CHECKID}{data});   nprint("- $RES for $TESTS{$CHECKID}{method}:\t$request{whisker}{uri}","v");   $NIKTO{resp_counts}{$RES}{total}++;   # do auth/redir first, independent of test pass/fail   if ($RES eq 401)    {     $result{'www-authenticate'} =~ /realm=\"(.+)\"/;     my $R = $1;     if ($R eq '') { $R = $result{'www-authenticate'} }     my $old_creds = $request{'Authorization'}; # store any creds we have so we don't lose them     if ($REALMS_TESTED{$R} ne 1) { auth_guess($R, $CHECKID); }     if ($old_creds ne '')  { $request{'Authorization'} = $old_creds; } # restore creds     nprint("+ $TESTS{$CHECKID}{uri} - Requires Authentication for realm '$R'") if $CLI{display} =~ /4/;    }   elsif (($RES eq 300) || ($RES eq 301) || ($RES eq 302) || ($RES eq 303) || ($RES eq 307))    {     nprint("+ $TESTS{$CHECKID}{uri} - Redirects ($RES) to " . $result{'location'} . " , $TESTS{$CHECKID}{message}") if $CLI{display} =~ /1/;    }   elsif ($RES eq 200)    {     nprint("+ $TESTS{$CHECKID}{uri} - 200/OK Response could be $TESTS{$CHECKID}{message}") if $CLI{display} =~ /3/;    }   my $m1_method= my $m1o_method= my $m1a_method= my $f2_method= my $f1_method ="content";   my $positive=0;   # how to check each conditional   if ($TESTS{$CHECKID}{match_1} =~ /^[0-9]{3}$/)        { $m1_method="code";  }   if ($TESTS{$CHECKID}{match_1_or} =~ /^[0-9]{3}$/)     { $m1o_method="code"; }   if ($TESTS{$CHECKID}{match_1_and} =~ /^[0-9]{3}$/)    { $m1a_method="code"; }   if ($TESTS{$CHECKID}{fail_1} =~ /^[0-9]{3}$/)         { $f1_method="code";  }   if ($TESTS{$CHECKID}{fail_2} =~ /^[0-9]{3}$/)         { $f2_method="code";  }   # basic match for positive result   if ($m1_method eq "content") { 	if ($CONTENT =~ /$TESTS{$CHECKID}{match_1}/) 	{ 		$positive=1; 		#print "testid:$CHECKID\n";		#print "match_1:$TESTS{$CHECKID}{match_1}:\n";		#exit;	} 	}   else                            {     if (($RES eq $TESTS{$CHECKID}{match_1}) || ($RES eq $FoF{okay}{response}))    	{  $positive=1; }    }   # no match, check optional match   if ((!$positive) && ($TESTS{$CHECKID}{match_1_or} ne ""))    {     if ($m1o_method eq "content")  { if ($CONTENT =~ /$TESTS{$CHECKID}{match_1_or}/) { $positive=1; } }      else                          { if (($RES eq $TESTS{$CHECKID}{match_1_or}) || ($RES eq $FoF{okay}{response})) { $positive=1; } }     }   # matched on something, check fails/ands   if ($positive)    {      if ($TESTS{$CHECKID}{fail_1} ne "")       {        if ($f1_method eq "content") { if ($CONTENT =~ /$TESTS{$CHECKID}{fail_1}/) { next; } }        else { if ($RES eq $TESTS{$CHECKID}{fail_1}) { next; } }       }      if ($TESTS{$CHECKID}{fail_2} ne "")       {        if ($f2_method eq "content") { if ($CONTENT =~ /$TESTS{$CHECKID}{fail_2}/) { next; } }        else { if ($RES eq $TESTS{$CHECKID}{fail_2}) { next; } }      }     if ($TESTS{$CHECKID}{match_1_and} ne "")       {        if ($m1a_method eq "content") { if ($CONTENT !~ /$TESTS{$CHECKID}{match_1_and}/) { next; } }        else { if ($RES ne $TESTS{$CHECKID}{match_1_and}) { next; } }       }     # if it's an index.php, check for normal /index.php to see if it's a FP     if ($TESTS{$CHECKID}{uri} =~ /^\/index.php\?/)       {        my $CONTENT=rm_active_content($CONTENT, $TESTS{$CHECKID}{uri});        if (LW2::md4($CONTENT) eq $FoF{'index.php'}{match}) { next; }        }     # lastly check for a false positive based on file extension or type     if (($m1_method eq "code") || ($m1o_method eq "code"))      {       if (is_404($request{whisker}{uri},$CONTENT,$RES)) { next; }      }     $TARGETS{$CURRENT_HOST_ID}{total_vulns}++;     $TESTS{$CHECKID}{osvdb} =~ s/\s+/ OSVDB\-/g;     nprint("+ OSVDB-$TESTS{$CHECKID}{osvdb}: $TESTS{$CHECKID}{method} $request{whisker}{uri} : $TESTS{$CHECKID}{message}");     $TARGETS{$CURRENT_HOST_ID}{positives}{$CHECKID}=1;    }   } # end check loop nprint("+ $TARGETS{$CURRENT_HOST_ID}{total_checks} items checked: $TARGETS{$CURRENT_HOST_ID}{total_vulns} item(s) reported on remote host"); $TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{stop_time_epoch}=time(); $TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{stop_time_disp}=date_disp($TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{stop_time_epoch});  $TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{elapsed} = $TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{stop_time_epoch} - $TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{start_time_epoch}; nprint("+ End Time:        $TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{stop_time_disp} ($TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{elapsed} seconds)"); nprint($DIV);  return;}###############################################################################sub is_404{ my ($uri, $content, $rescode) = @_; $ext=get_ext($uri); if   (($FoF{$ext}{mode} eq "STD") && (($rescode eq 401) || ($rescode eq 403) || ($rescode eq 404) || ($rescode eq 410))) { return 1; } elsif ($FoF{$ext}{mode} eq "STD")  { return 0; } elsif ($FoF{$ext}{mode} eq "REDIR")   {    if ($result{location} eq $FoF{$ext}{location}) { return 1; }  } elsif (($FoF{$ext}{type} eq "CONTENT")  && ($content =~ /$FoF{$ext}{match}/i))    { return 1; }  elsif (($FoF{$ext}{type} eq "BLANK") && ($content eq ""))                         { return 1; }  elsif ($FoF{$ext}{type} eq "HASH")   {     my $content=rm_active_content($content, $uri);     if (LW2::md4($content) eq $FoF{$ext}{match}) { return 1; }    }return 0;}###############################################################################sub nprint{ my $line=$_[0]; chomp($line); # don't print debug & verbose to output file... if ($_[1] eq "d") 	{  		if ($OUTPUT{debug}) { print "D:" . localtime() . " $line\n"; } 	 	return; 	} elsif ($_[1] eq "v") 	{  		if ($OUTPUT{verbose}) { print "V:" . localtime() . " $line\n"; } 	 	return; 	}  # print to STDOUT if ($line =~ /ERROR\:/) { print STDERR "$line\n"; } else { print "$line\n"; }  # if no file saving, return if ($CLI{file} eq "") { return; }  # HTML is handled elsewhere, sadly if ($CLI{format} eq "txt")  {   $line =~ s/((CVE|CAN)\-[0-9]{4}-[0-9]{4})/http:\/\/cve.mitre.org\/cgi-bin\/cvename.cgi?name\=$1/g;   $line =~ s/(CA\-[0-9]{4}-[0-9]{2})/http:\/\/www.cert.org\/advisories\/$1.html/g;   $line =~ s/BID\-([0-9]{4})/http:\/\/www.securityfocus.com\/bid\/$1/g;   $line =~ s/(IN\-[0-9]{4}\-[0-9]{2})/http:\/\/www.cert.org\/incident_notes\/$1.html/gi;   $line =~ s/(MS[0-9]{2}\-[0-9]{3})/http:\/\/www.microsoft.com\/technet\/security\/bulletin\/$1.asp/gi;   print OUT "$line\n";  }   elsif ($CLI{format} eq "csv")  {   chomp($line);   if ($line =~ /-------------/) { $line="\"$DIV\",\"$DIV\""; }   if ($line =~ /^\+/) { $line =~ s/^\+ (.*) - (.*)/"$1","$2"/; }   $line =~ s/Target IP:       (.*)/"Target IP","$1"/;   $line =~ s/Target Hostname: (.*)/"Target Hostname","$1"/;   $line =~ s/Target Port:     (.*)/"Target Port","$1"/;   $line =~ s/Start Time:      (.*)/"Start Time","$1"/;   $line =~ s/End Time:        (.*)/"End Time","$1"/;   $line =~ s/ERROR: (.*)/"ERROR","$1"/;     chomp($line);   $line =~ s/\t/     /g;   $line =~ s/Server: ([^ ]*)(.*$)/"Server","$1","$2"/;   $line =~ s/Test Options: (.*)/"Test Options","$1\n"/;   $line =~ s/Allowed HTTP Methods: (.*)/"Allowed HTTP Methods","$1"/;   $line =~ s/^\+//;   $line =~ s/^\-//;   $line =~ s/^\s+//;   if ($line !~ /^\"/) { $line = "\"$line\""; }   $line =~ s/\n\r//g;   $line =~ s/\"\"/\"/g;   print OUT "$line\n";  } return;}###############################################################################sub get_ext{ my $uri=$_[0] || return; if ($uri =~ /\/$/)       	{ return "DIRECTORY"; } $uri =~ s/^.*\///; $uri =~ s/(\?|\&|\%).*$//; if ($uri =~ /^\.[^.%]/)  	{ return "DOTFILE"; } if ($uri !~ /\./) 		{ return "NONE"; } $uri =~ s/\".*$//; $uri =~ s/^.*\.//; return $uri;}###############################################################################sub date_disp{ my @time=localtime($_[0]); $time[5]+=1900; $time[4]++; if (length($time[4]) eq 1) { $time[4]="0$time[4]"; } $time[3]++; if (length($time[3]) eq 1) { $time[3]="0$time[3]"; } if (length($time[0]) eq 1) { $time[0]="0$time[0]"; } if (length($time[1]) eq 1) { $time[1]="0$time[1]"; } if (length($time[2]) eq 1) { $time[0]="0$time[2]"; } return "$time[5]-$time[4]-$time[3] $time[2]:$time[1]:$time[0]";}###############################################################################sub map_codes{ my %REQS; my $rs=LW2::utils_randstr(8); # / for OK response $NIKTO{totalrequests}++; $request{'whisker'}->{'uri'} = "/"; delete $request{'whisker'}->{'data'}; $request{'whisker'}->{'method'} = GET; $request{'whisker'}->{'http_eol'}=$http_eol; delete $request{'whisker'}->{'Content-Length'}; LW2::http_close(\%request);  # force-close any old connections dump_var("Request Hash", \%request); if ($CLI{pause} > 0) { sleep $CLI{pause}; } LW2::http_do_request_timeout(\%request,\%result); dump_var("Result Hash", \%result); if ($result{location} ne "")   {    nprint("- Root page / redirects to: $result{location}");    if ($result{location} =~ /^$request{'whisker'}{'host'}/i) # same host     {      $request{'whisker'}->{'uri'} = $result{location};      $request{'whisker'}->{'uri'} =~ s/^http(s)?\:\/\/$request{'whisker'}{'host'}//i;      $request{'whisker'}->{'http_eol'}=$http_eol;      LW2::http_close(\%request);  # force-close any old connections      LW2::http_fixup_request(\%request);      dump_var("Request Hash", \%request);      if ($CLI{pause} > 0) { sleep $CLI{pause}; }      LW2::http_do_request_timeout(\%request,\%result);      dump_var("Result Hash", \%result);     }    else  # different host... ugh... guess     {      $FoF{okay}{response}=200;      $FoF{okay}{type}="STD";     }  } else  {   $FoF{okay}{response}=$result{'whisker'}->{'code'};   my $content=rm_active_content($result{'whisker'}->{'data'});   $FoF{okay}{type}="HASH";   $FoF{okay}{match}=LW2::md4($content);  } # these are some used in mutate that may not be in the db_tests $db_extensions{bak}=1; $db_extensions{data}=1; $db_extensions{dbc}=1; $db_extensions{dbf}=1; $db_extensions{lst}=1; $db_extensions{htx}=1; foreach my $ext (keys %db_extensions)    {    if ($ext eq "DIRECTORY") { next; }  # don't test generic type holder as real extension (added to db_extensions by get_ext)    if ($ext eq "NONE")      { next; }  # don't test generic type holder as real extension (added to db_extensions by get_ext)    if ($ext eq "DOTFILE")   { next; }  # don't test generic type holder as real extension (added to db_extensions by get_ext)    $REQS{"/$rs.$ext"}=$ext;    } # add those generic type holders back as real files $REQS{"/$rs/"}="DIRECTORY"; $REQS{"/$rs"}="NONE"; $REQS{"/.$rs"}="DOTFILE";  foreach my $file (keys %REQS)  {   nprint("- Testing error for file: $file\n","v");   $NIKTO{totalrequests}++;   $request{'whisker'}->{'uri'}    = $file;   $request{'whisker'}->{'method'} = GET;   $request{'whisker'}->{'http_eol'}=$http_eol;   LW2::http_close(\%request);  # force-close any old connections   delete $request{'whisker'}->{'data'};   delete $request{'Content-Encoding'};   delete $request{'Content-Length'};   LW2::http_fixup_request(\%request);   dump_var("Request Hash", \%request);   if ($CLI{pause} > 0) { sleep $CLI{pause}; }   LW2::http_do_request_timeout(\%request,\%result);   dump_var("Result Hash", \%result);   $ext=$REQS{$file};   $FoF{$ext}{response} = $result{'whisker'}->{'code'};   if ($result{location} ne "")      { 	$FoF{$ext}{location} = $result{location};	$file=char_escape($file);	$FoF{$ext}{location} =~ s/$file//;#	if ($ext eq "php")#	 {#print "$ext $FoF{$ext}\n";#print "loc is:$FoF{$ext}{location}\n";  exit; #}     } # handle .com to .org redirs or whatnot   # if it is not specific type, figure out Content or HASH method...   if    ($FoF{$ext}{response} eq 404) { $FoF{$ext}{mode} = "STD";    next; }   elsif ($FoF{$ext}{response} eq 200) { $FoF{$ext}{mode} = "OK";     }   elsif ($FoF{$ext}{response} eq 410) { $FoF{$ext}{mode} = "STD";    next; }   elsif ($FoF{$ext}{response} eq 401) { $FoF{$ext}{mode} = "STD";    next; }   elsif ($FoF{$ext}{response} eq 403) { $FoF{$ext}{mode} = "STD";    next; }   elsif ($FoF{$ext}{response} eq 300) { $FoF{$ext}{mode} = "REDIR";  next; }   elsif ($FoF{$ext}{response} eq 301) { $FoF{$ext}{mode} = "REDIR";  next; }   elsif ($FoF{$ext}{response} eq 302) { $FoF{$ext}{mode} = "REDIR";  next; }   elsif ($FoF{$ext}{response} eq 303) { $FoF{$ext}{mode} = "REDIR";  next; }   elsif ($FoF{$ext}{response} eq 307) { $FoF{$ext}{mode} = "REDIR";  next; }   else  { $FoF{$ext}{mode} = "OTHER";  }   # if we've got an OK/OTHER response, look at content first   my $done=0;      foreach my $string (keys %ERRSTRINGS)       {        nprint ("- Testing error string: $ERRSTRINGS{$string}","d");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -