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

📄 nikto_core.plugin

📁 一个用perl写的功能强大的cgi漏洞检测程序
💻 PLUGIN
📖 第 1 页 / 共 5 页
字号:
 LW::http_fixup_request(\%request); dump_request_hash(); LW::http_do_request(\%request,\%result); dump_result_hash(); if (exists($result{'set-cookie'})) { push(@COOKIES,"/--=--$result{'set-cookie'}"); } return $result{'whisker'}->{'http_resp'}, $result{'whisker'}->{'data'};}######################################################################## return $_[0] 'x' characters#######################################################################sub junk{ return "x" x $_[0];}######################################################################## load the scan database#######################################################################sub load_scan_items{ open(IN,"<$FILES{dbfile}") || die print "+ ERROR: Unable to open '$FILES{dbfile}' for read: $@\n"; @DBFILE=<IN>; close(IN);  open(IN,"<$FILES{serverdbfile}") || die print "+ ERROR: Unable to open '$FILES{serverdbfile}' for read: $@\n"; @SERVERFILE=<IN>; close(IN);  # load a user database if it exists... if (-e $FILES{userdbfile})  {   open(IN,"<$FILES{userdbfile}") || die print "+ ERROR: Unable to open '$FILES{userdbfile}' for read: $@\n";   my @DBFILE_USER=<IN>;   close(IN);    # join them...   foreach $line (@DBFILE_USER) { push(@DBFILE,$line); }  } return;}######################################################################## get server categories#######################################################################sub set_server_cats{ # first figure out server type foreach $line (@SERVERFILE) {  if ($line =~ /^\"/)   {    if ($line =~ /\#/) { $line=~s/\#.*$//; $line=~s/\s+$//; }    chomp($line);    @scat=parse_csv($line);    nprint("servercat compare: '$TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{banner}' to '$scat[1]'","d");    if ($TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{banner} =~ /$scat[1]/i)       {         $TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{category}=$scat[0];         nprint("servercat match:$scat[0]","d");         last;       }   } } if ($TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{category} eq "") { $TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{category}="generic"; }return;}######################################################################## set up the scan database#######################################################################sub set_scan_items{ set_server_cats(); my $shname=$TARGETS{$CURRENT_HOST_ID}{hostname} || $TARGETS{$CURRENT_HOST_ID}{ip}; my ($line, $stype) = ""; my (@item, @scat, $FILES, $RESPS, $METHD, $INFOS, $DATAS) = (); $ITEMCOUNT=0;   # now load checks foreach $line (@DBFILE) {  if ($line =~ /^\"/)  # check  {   chomp($line);      @item=parse_csv($line);   # if the right category or cat is generic...      if (($TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{category} =~ /$item[0]/i)        || ($item[0] =~ /generic/i)        || ($TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{banner} eq "")        || ($CLI{forcegen}))   {    # substitute for @IP, @HOSTNAME in check    $line =~ s/\@IP/$TARGETS{$CURRENT_HOST_ID}{ip}/g;    $line =~ s/\@HOSTNAME/$shname/g;    for (my $i=1;$i<=$#item;$i++)     {      chomp($item[$i]);      if ($i eq 3) { next; }  # skip method      if ($item[$i] =~ /(JUNK\([0-9]+\))/)  # junk text       {        my $j= my $m=$1;        $j=~ s/^JUNK\(//;        $j=~ s/\)//;        $j=junk($j);        $m=~s/([^a-zA-Z0-9])/\\$1/g;        $item[$i] =~ s/$m/$j/;       }     }        if ($item[1] eq "") { $item[2]="/"; }    if (($#item < 4) || ($#item > 6)) { nprint("Invalid check syntax:@item:","d"); }    # Build the check items. First check for any @ values to replace    # this nasty set of loops allows for multiple values per line    if ($item[1] =~ /^\@/)  # multiple checks in one     {      my @clones=();      my $todelete="";      push(@clones,$item[1]);      foreach my $varname (keys %VARIABLES)       {        for (my $i=0;$i<=$#clones;$i++)         {          if ($clones[$i] =~ /$varname/)           {            my @values=split(/ /,$VARIABLES{$varname});            foreach my $val (@values)              {              my $temp=$clones[$i];              $temp =~ s/$varname/$val/g;              push(@clones,$temp);              $todelete=$i;             }           splice(@clones,$todelete,1);           $i--; # step back in the @clones 'cause we deleted one. more work, but it guarantees it's complete           }         }       }      # now actually populate the checks       for (my $i=0;$i<=$#clones;$i++)      {       $ITEMCOUNT++;       $FILES{$ITEMCOUNT}="$CLI{root}$clones[$i]";       $RESPS{$ITEMCOUNT}=$item[2];       $METHD{$ITEMCOUNT}=$item[3];       $INFOS{$ITEMCOUNT}=$item[4];       $DATAS{$ITEMCOUNT}=$item[5];      }     }    else # normal, single check     {      $ITEMCOUNT++;      $FILES{$ITEMCOUNT}="$CLI{root}$item[1]";      $RESPS{$ITEMCOUNT}=$item[2];      $METHD{$ITEMCOUNT}=$item[3];      $INFOS{$ITEMCOUNT}=$item[4];      $DATAS{$ITEMCOUNT}=$item[5];     }   }  } }nprint("- Server category identified as '$TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{category}', if this is not correct please use -g to force a generic scan.","v");nprint("- $ITEMCOUNT server checks loaded","v");if ($ITEMCOUNT eq 0) { nprint("+ Unable to load valid checks!"); exit; }if ($CLI{forcegen}  eq 0) { nprint("+ Forcing full DB scan","v"); }return;}######################################################################## escape all non standard chars in a string (for regex's really)# char_escape 'string'#######################################################################sub char_escape{ my $text=$_[0]||return; $text =~ s/([^a-zA-Z0-9 ])/\\$1/g; return $text;}######################################################################## turn CSV data to an array# parse_csv 'string'#######################################################################sub parse_csv{ my $text = $_[0]; my @new = (); push(@new, $+) while $text =~ m{ "([^\"\\]*(?:\\.[^\"\\]*)*)",?    |  ([^,]+),?    | ,  }gx;  push(@new, undef) if substr($text, -1,1) eq ',';  return @new;}######################################################################## print version info#######################################################################sub version{ my @FILES=dirlist($NIKTO{plugindir},"(^nikto|\.db\$)"); print "$DIV\n$NIKTO{name} Versions\n$DIV\n"; print "File                               Version      Last Mod\n"; print "-----------------------------      --------     ----------\n"; print "Nikto main                         $NIKTO{version}\n"; print "LibWhisker                         $LW::VERSION\n"; my $col1=35; my $col2=13; foreach my $FILE (@FILES)  {   open(FI,"<$NIKTO{plugindir}/$FILE") || die print "- ERROR: Unable to open '$NIKTO{plugindir}/$FILE': $!\n";;;   my @F=<FI>;   close(FI);   my @VERS=grep(/^#VERSION/,@F);   my @MODS=grep(/^#LASTMOD/,@F);   chomp($VERS[0]);   chomp($MODS[0]);   $VERS[0] =~ s/^#VERSION,//;   $MODS[0] =~ s/^#LASTMOD,//;   my $ws1=($col1-length($FILE));   my $ws2=($col2-length($VERS[0]));   print "$FILE", " " x $ws1 , "$VERS[0]", " " x $ws2, "$MODS[0]\n";  } print "$DIV\n"; exit;}######################################################################## send version update info to CIRT.net, if desired#######################################################################sub send_updates{ if ($CONFIG{UPDATES} !~ /yes|auto/i) { return; } my $have_updates=0; my ($updated_version, $answer, $RES); foreach my $ver (keys %UPDATES)   {    if ($UPDATES{$ver} eq 1)     {      if ($ver !~ /[0-9]/)   { next; }        # no version info...useless     if ($ver eq "Win32") { next; }          # also no use     if ($ver eq "Linux-Mandrake") { next; } # just... usually garbage     $have_updates=1;      $updated_version .= "$ver ";    }   }   if (!$have_updates) { return; } if ($updated_version eq "") { return; }  # make sure the outdated.db isn't *too* old open(OD,"<$NIKTO{plugindir}/outdated.db") || die print "- ERROR: Unable to open '$NIKTO{plugindir}/outdated.db': $!\n";; @F=<OD>; close(OD);  my @LASTUPDATED=grep(/^#LASTMOD/,@F); chomp($LASTUPDATED[0]); $LASTUPDATED[0]=~s/^.*,//; my @lu=split(/\./,$LASTUPDATED[0]); my $lm="$lu[2]$lu[0]"; my @NOW=localtime(time); $NOW[5]+=1900; $NOW[4]++; if ($NOW[4] < 10) { $NOW[4]="0$NOW[4]"; } my $now="$NOW[5]$NOW[4]"; if (($now - $lm) > 4) { return; }  # DB is 4 months old... ignore the updates!  $updated_version =~ s/\s+$//;  $updated_version =~ s/^\s+//;   if ($CONFIG{UPDATES} eq "auto") { $answer = "y"; } else  {   $answer=read_data("\n   ***** Portions of the server's ident string ($updated_version)   are not in the Nikto database or is newer than the known string.   Would you like to submit this information (*no server specific data*)   to CIRT.net for a Nikto update (or you may email to sullo\@cirt.net)   (y/n)? ","");  } if ($answer !~ /y/i) { return; }  LW::http_init_request(\%request); my $server="www.cirt.net"; $request{'whisker'}->{'http_ver'}="1.1"; $request{'whisker'}->{'port'}=80; $request{'whisker'}->{'anti_ids'}=""; $request{'User-Agent'}="Nikto Update Agent"; $request{'Host'}="www.cirt.net";  for (my $i=0;$i<=$#ARGV;$i++)  { if (($ARGV[$i] eq "-u") || ($ARGV[$i] eq "-useproxy")) { $CLI{useproxy}=1; last; } }  my  $ip=gethostbyname($server); if ($ip ne "") { $request{'whisker'}->{'host'}= inet_ntoa($ip); } else { $request{'whisker'}->{'host'}=$server; } if (($CONFIG{PROXYHOST} ne "") && ($CLI{useproxy}))  {   $request{'whisker'}->{'proxy_host'}=$CONFIG{PROXYHOST};   $request{'whisker'}->{'proxy_port'}=$CONFIG{PROXYPORT};  } # send data LW::http_fixup_request(\%request); ($RES, $CONTENT) = fetch("/cgi-bin/versions?DATA=$updated_version","GET"); # if res is blank... maybe only proxy to get to net? if (($RES eq "") && ($CONFIG{PROXYHOST} ne ""))  {   $request{'whisker'}->{'proxy_host'}=$CONFIG{PROXYHOST};   $request{'whisker'}->{'proxy_port'}=$CONFIG{PROXYPORT};   ($RES, $CONTENT) = fetch("/cgi-bin/versions?DATA=$updated_version","GET");  } if ($RES eq 407) # requires Auth  {   if ($CONFIG{PROXYUSER} eq "")        {      $CONFIG{PROXYUSER}=read_data("Proxy ID: ","");      $CONFIG{PROXYPASS}=read_data("Proxy Pass: ","noecho");     }   LW::auth_set_header("proxy-basic",\%request,$CONFIG{PROXYUSER},$CONFIG{PROXYPASS});   # and try again   LW::http_fixup_request(\%request);  ($RES, $CONTENT) = fetch("/cgi-bin/versions?DATA=$updated_version","GET");  } if ($CONTENT !~ /SUCCESS/)   {    print "- ERROR ($RES, $CONTENT): Unable to send updated version string(s) to CIRT.net\n";   } else  {   print "- Sent updated version string(s) to CIRT.net\n";   }return;}######################################################################## print usage info#######################################################################sub usage{ nprint($NIKTO{options}); exit;}#######################################################################sub nikto_core { return; } # trap for this plugin being called to run#######################################################################1;

⌨️ 快捷键说明

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