📄 nikto_core.plugin
字号:
chomp($line); if ($line eq "") { next; } my @L=parse_csv($line); if ($line !~ /^\".*\"\,\".*\"\,\".*\"$/) { print STDERR "\tERROR: Invalid syntax ($#L): $line\n"; next; } if ($#L ne 2) { print STDERR "\tERROR: Invalid syntax ($#L): $line\n"; next; } $ENTRIES{"$L[0]"}++; } foreach $entry (keys %ENTRIES) { if ($ENTRIES{$entry} > 1) { print STDERR "\tERROR: Duplicate ($ENTRIES{$entry}): $entry\n"; } } print "\t" . keys(%ENTRIES) . " entries\n"; } elsif ($file eq 'db_tests') { my %ENTRIES; foreach my $line (<IN>) { if ($line !~ /^\"/) { next; } my @L=parse_csv($line); if ($L[4] !~ /(GET|POST|TRACE|TRACK|OPTIONS|SEARCH|INDEX)/i) { print STDERR "\tERROR: Possibly invalid method: $L[4] on ($line)\n"; } if ($L[5] eq "") { print STDERR "\tERROR: blank conditional: $line"; next; } if ($line !~ /^\".*\",\".*\",\".*\",\".*\",\".*\"/) { print STDERR "\tERROR: Invalid syntax ($#L): $line\n"; next; } if ($line !~ /^(\".*\",){11}\".*\"/) { print STDERR "\tERROR: Invalid syntax ($#L): $line\n"; next; } if (($L[3] =~ /^\@CGI/) && ($L[3] !~ /^\@CGIDIRS/)) { print STDERR "\tERROR: Possible \@CGIDIRS misspelling: $line"; } $ENTRIES{"$L[3],$L[4],$L[5],$L[6],$L[7],$L[8],$L[9],$L[10],$L[12]"}++; } foreach $entry (keys %ENTRIES) { if ($ENTRIES{$entry} > 1) { print STDERR "\tERROR: Duplicate ($ENTRIES{$entry}): $entry\n"; } } print "\t" . keys(%ENTRIES) . " entries\n"; } elsif ($file eq 'db_server_msgs') { foreach $line (<IN>) { $line =~ s/^\s+//; if ($line =~ /^\#/) { next; } chomp($line); if ($line eq "") { next; } my @L=parse_csv($line); if ($line !~ /^\".*\"\,\".*\"$/) { print STDERR "\tERROR: Invalid syntax ($#L): $line\n"; next; } if ($#L ne 1) { print STDERR "\tERROR: Invalid syntax ($#L): $line\n"; next; } # test regex to look for errors "test" =~ /$L[0]/; $ENTRIES{"$L[0]"}++; } foreach $entry (keys %ENTRIES) { if ($ENTRIES{$entry} > 1) { print STDERR "\tERROR: Duplicate ($ENTRIES{$entry}): $entry\n"; } } print "\t" . keys(%ENTRIES) ." entries\n"; } elsif ($file eq 'db_variables') { my $ctr=0; foreach $line (<IN>) { if ($line !~ /^\@/) { next; } if ($line !~ /^\@.+\=.+$/i ) { print STDERR "\tERROR: Invalid syntax: $line\n"; } $ctr++; } print "\t$ctr entries\n"; } elsif ($file eq 'db_realms') { my $ctr=0; foreach $line (<IN>) { if ($line !~ /^\"/) { next; } chomp($line); my @L=parse_csv($line); if ($#L ne 3) { print STDERR "\tERROR: Invalid syntax: $line\n"; } $ctr++; } print "\t$ctr entries\n"; } elsif ($file eq 'db_404_strings') { my $ctr=0; foreach $line (<IN>) { # not really any syntax to check $ctr++; } print "\t$ctr entries\n"; } elsif ($file eq 'db_favicon') { my $ctr=0; foreach $line (<IN>) { if ($line !~ /^\"/) { next; } chomp($line); my @L=parse_csv($line); if ($#L ne 1) { print STDERR "\tERROR: Invalid syntax: $line\n"; } $ctr++; } print "\t$ctr entries\n"; } close(IN); } if ($_[0] eq "") { dbcheck('u'); } # do this once #### check that all plugins are in nikto_plugin_order.txt print "\n-->\tPlugin order ($NIKTO{plugindir}/nikto_plugin_order.txt)\n"; my @NIKTOFILES=dirlist($NIKTO{plugindir},"(\.plugin\$)"); my %PLUGS; foreach my $pluginf (@NIKTOFILES) { chomp($pluginf); $pluginf =~ s/\#.*$//; $pluginf =~ s/\..*$//; $pluginf =~ s/\s+//; if (($pluginf eq "") || ($pluginf eq "nikto_core")) { next; } $PLUGS{$pluginf}=0; } open(ORDERFILE,"<$NIKTO{plugindir}/nikto_plugin_order.txt") || die print STDERR "\tERROR: Unable to open '$NIKTO{plugindir}/nikto_plugin_order.txt' for read: $@\n"; foreach my $line (<ORDERFILE>) { chomp($line); $line =~ s/\#.*$//; $line =~ s/\s+/ /; if (($line eq "") || ($line eq " ")) { next; } $PLUGS{$line}=1; } close(ORDERFILE); my $bad=0; foreach my $p (sort keys %PLUGS) { if ($PLUGS{$p} eq 0) { $bad=1; print STDERR "\tERROR: plugin '$p' not in nikto_plugin_order.txt\n"; } } if (!$bad) { print STDERR "\tOrder file okay\n"; } #### check that all plugins are named properly print "-->\tPlugin conventions ($NIKTO{plugindir}/*.plugin)\n"; $bad=0; foreach my $pluginf (@NIKTOFILES) { chomp($pluginf); $pluginf =~ s/\#.*$//; $pluginf =~ s/\..*$//; $pluginf =~ s/\s+//; if (($pluginf eq "") || ($pluginf eq "nikto_core")) { next; } open(IN,"<$NIKTO{plugindir}/$pluginf.plugin") || die print STDERR "\tERROR: Unable to open '$NIKTO{plugindir}/$pluginf.plugin' for read: $@\n"; my @F=<IN>; close(IN); my $CT=grep(/sub $pluginf/,@F); if ($CT < 1) { print STDERR "\tERROR: file '$pluginf\.plugin' does not have 'sub $pluginf' defined.\n"; $bad++; } } if (!$bad) { print "\tPlugin syntax okay\n"; } print "\n"; exit;}###############################################################################sub get_banner{ (my $RES, $CONTENT) = fetch("/","HEAD"); $TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{banner}=$result{'server'}; $TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{banner_disp}=$result{'server'}; $TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{banner_disp} =~ s/</</g; $TARGETS{$CURRENT_HOST_ID}{ports}{$CURRENT_PORT}{banner_disp} =~ s/</>/g; return;}###############################################################################sub port_check{ my $port=$_[0] || return 0; $port=~s/(^\s+|\s+$)//g; my $oldhost=$request{'whisker'}->{'host'}; $request{'whisker'}->{'uri'}="/"; $request{'whisker'}->{'method'}="HEAD"; # test for proxy proxy_check() unless $PROXYCHECKED; # try http if (!$CLI{ssl}) { nprint("- Checking for HTTP on port $TARGETS{$CURRENT_HOST_ID}{ip}:$port","v"); $request{'whisker'}->{'ssl'}=0; $request{'whisker'}->{'port'}= $port; $request{'whisker'}->{'http_eol'}=$http_eol; dump_var("Request Hash", \%request); LW2::http_close(\%request); # force-close any old connections LW2::http_fixup_request(\%request); if ($CLI{pause} > 0) { sleep $CLI{pause}; } if (!LW2::http_do_request_timeout(\%request,\%result)) { # this will fix for some Apaches that are smart enough to answer non ssl reqs on an ssl server if ($result{'whisker'}->{'data'} !~ /speaking plain HTTP to an SSL/) { $TARGETS{$CURRENT_HOST_ID}{ports}{$port}{ssl}=0; nprint("- Server found: $TARGETS{$CURRENT_HOST_ID}{ip}:$port \t$result{'server'}","d"); $request{'whisker'}->{'host'}=$oldhost; dump_var("Result Hash", \%result); return; } } else { dump_var("Result Hash", \%result); } } # try https nprint("- Checking for HTTPS on port $TARGETS{$CURRENT_HOST_ID}{ip}:$port","v"); $request{'whisker'}->{'ssl'}=1; $request{'whisker'}->{'port'}= $port; $request{'whisker'}->{'http_eol'}=$http_eol; dump_var("Request Hash", \%request); LW2::http_close(\%request); # force-close any old connections LW2::http_fixup_request(\%request); if ($CLI{pause} > 0) { sleep $CLI{pause}; } if (LW2::http_do_request_timeout(\%request,\%result) eq 0) { $TARGETS{$CURRENT_HOST_ID}{ports}{$port}{ssl}=1; dump_var("Result Hash", \%result); $request{'whisker'}->{'host'}=$oldhost; nprint("- Server found: $TARGETS{$CURRENT_HOST_ID}{ip}:$port \t$result{'server'}","d"); } dump_var("Result Hash", \%result); return;}################################################################################ this ugly, and potentially dangerous if untrusted plugins are present###############################################################################sub run_plugins{ open(ORDERFILE,"<$NIKTO{plugindir}/nikto_plugin_order.txt"); my @ORDER=<ORDERFILE>; close(ORDERFILE); foreach my $pluginf (@ORDER) { if ($pluginf =~ /^\#/) { next; } chomp($pluginf); $pluginf =~ s/\s+//; if ($pluginf eq "") { next; } eval { require "$NIKTO{plugindir}/$pluginf\.plugin"; }; if ($@) { nprint("- Could not load or parse plugin: $pluginf\.plugin\nError: ",""); warn $@; nprint("- The plugin could not be run.",""); } else { nprint("- Calling plugin: $pluginf\.plugin","d"); # just call it...hope it works...taint doesn't like this very much for obvious reasons &$pluginf; } }return;}###############################################################################sub check_updates{ LW2::http_init_request(\%request); my (%REMOTE, %LOCAL, @DBTOGET) = (); my ($pluginmsg, $remotemsg) = ""; my $code_updates=0; my $serverdir="/nikto/UPDATES/$NIKTO{version}"; my $server="www.cirt.net"; $request{'whisker'}->{'version'}="1.1"; $request{'whisker'}->{'port'}=80; $request{'whisker'}->{'anti_ids'}=""; $request{'User-Agent'}="Nikto Update Agent"; $request{'whisker'}->{'host'}=$server; for (my $i=0;$i<=$#ARGV;$i++) { if (($ARGV[$i] eq "-u") || ($ARGV[$i] eq "-useproxy")) { $CLI{useproxy}=1; last; } } if (($NIKTOCONFIG{PROXYHOST} ne "") && ($CLI{useproxy})) { $request{'whisker'}->{'proxy_host'}=$NIKTOCONFIG{PROXYHOST}; $request{'whisker'}->{'proxy_port'}=$NIKTOCONFIG{PROXYPORT}; } # retrieve versions file LW2::http_close(\%request); # force-close any old connections LW2::http_fixup_request(\%request); (my $RES, $CONTENT) = fetch("$serverdir/versions.txt","GET"); if ($RES eq 407) # requires Auth { if ($NIKTOCONFIG{PROXYUSER} eq "") { $NIKTOCONFIG{PROXYUSER}=read_data("Proxy ID: ",""); $NIKTOCONFIG{PROXYPASS}=read_data("Proxy Pass: ","noecho"); } LW2::auth_set("proxy-basic",\%request,$NIKTOCONFIG{PROXYUSER},$NIKTOCONFIG{PROXYPASS}); # and try again LW2::http_close(\%request); # force-close any old connections LW2::http_fixup_request(\%request); ($RES, $CONTENT) = fetch("$serverdir/versions.txt","GET"); } if ($RES eq "") # lookup failure? { LW2::http_close(\%request); # force-close any old connections $request{'whisker'}->{'host'}=$NIKTOCONFIG{CIRT}; $request{'Host'}="www.cirt.net"; LW2::http_fixup_request(\%request); ($RES, $CONTENT) = fetch("$serverdir/versions.txt","GET"); } if ($RES ne 200) { print STDERR "+ ERROR ($RES): Unable to get $request{'whisker'}->{'host'}$serverdir/versions.txt\n"; exit; } # make hash for (split(/\n/,$CONTENT)) { my @l=parse_csv($_); if ($_ =~ /^msg/) { $remotemsg="$l[1]"; next; } $REMOTE{$l[0]}=$l[1]; } # get local versions of plugins/dbs my @NIKTOFILES=dirlist($NIKTO{plugindir},""); foreach my $file (@NIKTOFILES) { my $v=""; open(LOCAL,"<$NIKTO{plugindir}/$file") || print STDERR "+ ERROR: Unable to open '$NIKTO{plugindir}/$file' for read: $@\n"; my @l=<LOCAL>; close(LOCAL); my @VERS=grep(/^#VERSION/,@l); chomp($VERS[0]); $LOCAL{$file}=(parse_csv($VERS[0]))[1]; } # check main nikto versions foreach my $remotefile (keys %REMOTE) { if ($remotefile eq "nikto") # main program version { if ($REMOTE{$remotefile} > $NIKTO{version}) { print "+ Nikto has been updated to $REMOTE{$remotefile}, local copy is $NIKTO{version}\n"; print "+ No update has taken place. Please upgrade Nikto by visiting http://$server/\n"; if ($remotemsg ne "") { print "+ $server message: $remotemsg\n"; } exit; } next; } if (($LOCAL{$remotefile} eq "") || ($REMOTE{$remotefile} > $LOCAL{$remotefile})) { push(@DBTOGET,$remotefile); if ($remotefile !~ /^db_/) { $code_updates=1; } } elsif ($REMOTE{$remotefile} < $LOCAL{$remotefile}) # local is newer (!) { print STDERR "+ ERROR: Local '$remotefile' (ver $LOCAL{$remotefile}) is NEWER than remote (ver $REMOTE{$remotefile}).\n"; } } # replace local files if updated
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -