📄 nikto_core.plugin
字号:
chomp($NIKTO{core_version}); $NIKTO{TMPL_HCTR}=0; $NIKTO{TMPL_SUMMARY}=0; $COUNTERS{hosts_total}=$COUNTERS{hosts_completed}=0;return;}###############################################################################sub resolve{ my $ident=$_[0] || return; my ($name, $ip, $dn)=""; # ident is name, lookup IP if ($ident =~ /[^0-9\.]/) # not an IP, assume name { if ($CLI{skiplookup}) { nprint("+ ERROR: -skiplookup set, but given name\n"); exit; } $ip=gethostbyname($ident); if (($ip eq "") && ($request{'whisker'}->{'proxy_host'} ne "")) # can't resolve name to IP, but using proxy { $name=$ident; $ip=$name; } elsif (($ip eq "") && ($request{'whisker'}->{'proxy_host'} eq "")) # can't resolve name to IP, no proxy set { nprint("+ ERROR: Cannot resolve hostname '$ident'\n"); delete $TARGETS{$CURRENT_HOST_ID}; return; } else { use IO::Socket; $ip=inet_ntoa($ip); if (($ip !~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/) && ($ip ne "")) # trap for proxy... { nprint("+ ERROR: Invalid IP '$ip'\n\n"); delete $TARGETS{$CURRENT_HOST_ID}; return; } $name=$ident; } } else # ident is IP, lookup name { if (($ident !~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/) && ($ident ne "")) # trap for proxy... { nprint("+ ERROR: Invalid IP '$ident'\n\n"); delete $TARGETS{$CURRENT_HOST_ID}; return; } $ip=$ident; if (!$CLI{skiplookup}) { use IO::Socket; my $temp_ip=inet_aton($ip); $name=gethostbyaddr($temp_ip,AF_INET); # check reverse dns to avoid an inet_aton error my $rdnsip=gethostbyname($name); if ($rdnsip ne "") { $rdnsip=inet_ntoa($rdnsip); if ($ip ne $rdnsip) { $name=$ip; } # Reverse DNS does not match } else { $name = $ip; } # Reverse DNS does not exist } if ($name eq "") { $name=$ip; } } # set displayname -- name takes precedence if ($name ne "") { $dn=$name; } else { $dn=$ip; } # set this 'host' $request{'whisker'}{'host'} = $name; return $name,$ip,$dn;}###############################################################################sub set_targets{ my $host_ctr=1; if ($CLI{host} eq "") { nprint("+ ERROR: No host specified"); usage(); } # if -p is not set, see if each line has its own ports. if not push 80 to ports_in if (-e $CLI{host}) { nprint("Reading from file '$CLI{host}'","v"); open(IN,"<$CLI{host}") || die print STDERR "+ ERROR: Cannot open '$CLI{host}':$@\n"; while(<IN>) { chomp; s/\#.*$//; if ($_ eq "") { next; } s/\s+//g; $COUNTERS{hosts_total}++; if (/(\:|\,)/) # at least one port is set for host { my $p=""; my @h=split(/\:|\,/); $TARGETS{$host_ctr}{ident}=$h[0]; # preppend anything from CLI, don't duplicate for (my $i=1;$i<=$#h;$i++) { $p.="$h[$i],"; } if ($p !~ /$CLI{ports}(,|$)/) { $p .= "$CLI{ports}"; } $p=~s/\,$//; $TARGETS{$host_ctr}{ports_in}=$p || 80; } else { $TARGETS{$host_ctr}{ports_in} = $CLI{ports} || 80; $TARGETS{$host_ctr}{ident} = $_; } nprint("- Target id:$host_ctr:ident:$TARGETS{$host_ctr}{ident}:ports_in:$TARGETS{$host_ctr}{ports_in}:","d"); $host_ctr++; } close(IN); } # Since it's not a file, it is either a host or an error # test for a full URL and parse, or treat like host and let resolve() sort it out else { $COUNTERS{hosts_total}++; if ($CLI{host} =~ /^https?:\/\//) { my @hostdata=LW2::uri_split($CLI{host}); $TARGETS{$host_ctr}{ident} = $hostdata[2]; $TARGETS{$host_ctr}{ports_in} = $hostdata[3]; if ($hostdata[1] eq "https") { $CLI{ssl}=1; if ($TARGETS{$host_ctr}{ports_in} eq "") { $TARGETS{$host_ctr}{ports_in}=443; } } if (($CLI{root} eq '') && ($hostdata[0] ne '')) { $CLI{root}=$hostdata[0]; nprint("- Added -root value of '$CLI{root}'","d"); } } else { $TARGETS{$host_ctr}{ident}=$CLI{host}; $TARGETS{$host_ctr}{ports_in}=$CLI{ports} || 80; } if ($CLI{vhost} ne '') { $TARGETS{$host_ctr}{vhost}=$CLI{vhost}; } nprint("- Target id:$host_ctr:ident:$TARGETS{$host_ctr}{ident}:ports_in:$TARGETS{$host_ctr}{ports_in}:vhost:$$TARGETS{$host_ctr}{vhost}=$CLI{vhost}:","d"); } return;}###############################################################################sub host_config{ ($TARGETS{$CURRENT_HOST_ID}{hostname}, $TARGETS{$CURRENT_HOST_ID}{ip}, $TARGETS{$CURRENT_HOST_ID}{display_name}) = resolve($TARGETS{$CURRENT_HOST_ID}{ident}); if ($TARGETS{$CURRENT_HOST_ID}{ident} eq "") { return; } port_scan($TARGETS{$CURRENT_HOST_ID}{ports_in}); # make sure we have open ports on this target if (keys(%{$TARGETS{$CURRENT_HOST_ID}{ports}}) eq 0) { nprint("+ No HTTP(s) ports found on $TARGETS{$CURRENT_HOST_ID}{ident} / $TARGETS{$CURRENT_HOST_ID}{ports_in}"); } return;}################################################################################ perform a port scan###############################################################################sub port_scan{ my $portopts=$_[0] || return; my (@t) = (); my %portlist; # if we're using nmap, skip this & let nmap handle port ranges... unless proxied if (!(-X $NIKTOCONFIG{NMAP}) || $CLI{useproxy}) { # break out , items if ($portopts =~ /,/) { foreach (split(/\,/,$portopts)) { push(@t,$_); } } else { push(@t,$portopts); } # ranges for (@t) { s/^\s+//; s/\s+$//; if ($_ !~ /-/) { $portlist{$_}=0; } else { my @x=split(/\-/,$_); for (my $i=$x[0];$i<=$x[1];$i++) { $portlist{$i}=0; } } } # last check for only null lists (i.e., user put in 4-1 as a range) my $invalid= my $have_valid = 0; foreach my $p (keys %portlist) { if (($p =~/[^0-9]/)||($p eq "")) { $invalid=1; last; } $have_valid++; } if ($invalid|!$have_valid) { nprint("+ ERROR: Invalid port option '$CLI{ports}'"); exit; } } # end if not NMAP # if NMAP is defined & no proxy, use that... if not, we do it the hard way if ((-X $NIKTOCONFIG{NMAP}) && !$CLI{useproxy}) { nprint("- Calling nmap:$NIKTOCONFIG{NMAP} $NIKTOCONFIG{NMAPOPTS} -oG - -p $portopts $TARGETS{$CURRENT_HOST_ID}{ip}","v"); foreach my $line (split(/\n/,`$NIKTOCONFIG{NMAP} $NIKTOCONFIG{NMAPOPTS} -oG - -p $portopts $TARGETS{$CURRENT_HOST_ID}{ip}`)) { if ($line !~ /^Host/) { next; } $line =~ s/^.*Ports: //; $line =~ s/Ignored.*$//; $line =~ s/^\s+//; $line =~ s/\s+$//; foreach my $PORTSTRING (parse_csv($line)) { $portlist{(split(/\//,$PORTSTRING))[0]}=0; } } } # test each port... foreach $p (sort keys %portlist) { nprint("- Testing open ports for web servers","v"); if ($p !~ /[0-9]/) { next; } $p =~ s/\s+$//; $p =~ s/^\s+//; foreach my $skip (split(/ /,$NIKTOCONFIG{SKIPPORTS})) { if ($skip eq $p) { next; } } if ($p eq "") { next; } port_check($p); } return;}###############################################################################sub load_databases{ my @dbs=qw/db_404_strings db_outdated db_realms db_tests db_server_msgs db_variables db_favicon/; my $prefix = $_[0]; # verify required files for my $file (@dbs) { if (!-r "$NIKTO{plugindir}/$file") { die nprint("+ ERROR: Can't find/read required file \"$NIKTO{plugindir}/$file\""); } } for my $file (@dbs) { my $filename = $NIKTO{plugindir} . "/" . $prefix . $file; if (!-r $filename) { next; } open(IN,"<$filename") || die nprint("+ ERROR: Can't open \"$filename\":$!\n"); # db_tests if ($file eq 'db_tests') { push(@DBFILE,<IN>); next; } # all the other files require per-line processing else { my @file; # Cleanup while (<IN>) { chomp; $_ =~ s/#.*$//; $_ =~ s/\s+$//; $_ =~ s/^\s+//; if ($_ ne "") { push(@file,$_); } } # db_variables if ($file eq 'db_variables') { foreach my $l (@file) { if ($l =~ /^@/) { my @temp=split(/=/,$l); $VARIABLES{$temp[0]}.= " $temp[1]"; } } } # db_404_strings elsif ($file eq 'db_404_strings') { my $db_404_ctr=keys %ERRSTRINGS; foreach my $l (@file) { $ERRSTRINGS{$db_404_ctr} = $l; $db_404_ctr++; } } # db_outdated elsif ($file eq 'db_outdated') { foreach my $l (@file) { my @T=parse_csv($l); $OVERS{$T[1]}{$T[2]}=$T[3]; $OVERS{$T[1]}{tid}=$T[0]; } } # db_realms elsif ($file eq 'db_realms') { my $db_realms_ctr= keys %REALMS; foreach my $l (@file) { my @t=parse_csv($l); $REALMS{$db_realms_ctr}{tid} = $t[0]; $REALMS{$db_realms_ctr}{realm} = $t[1]; $REALMS{$db_realms_ctr}{id} = $t[2]; $REALMS{$db_realms_ctr}{pw} = $t[3]; $REALMS{$db_realms_ctr}{msg} = $t[4]; $db_realms_ctr++; } } # db_server_msgs elsif ($file eq 'db_server_msgs') { foreach my $l (@file) { my @t=parse_csv($l); $VERSIONS{$t[1]}=$t[2]; $VERSIONS{$t[1]}{tid}=$t[0]; } } # db_favicons elsif ($file eq 'db_favicon') { foreach my $l (@file) { my @t=parse_csv($l); $FAVICONS{$t[1]}=$t[2]; $FAVICONS{$t[1]}{tid}=$t[0]; } } close(IN); } } return;}###############################################################################sub dbcheck{ my @dbs=qw/db_404_strings db_outdated db_realms db_tests db_server_msgs db_variables db_favicon/; my $prefix = $_[0]; if ($prefix eq "" ) { print "\n-->\tNikto Databases\n"; } if ($prefix eq "u" ) { print "\n-->\tUser Databases\n"; } for my $file (@dbs) { my $filename = $NIKTO{plugindir} . "/" . $prefix . $file; if (!-r $filename) { next; } open(IN,"<$filename") || die nprint("+ ERROR: Can't open \"$filename\":$!\n"); print "Syntax Check: $filename\n"; if ($file eq 'db_outdated') { foreach $line (<IN>) { $line =~ s/^\s+//; if ($line =~ /^\#/) { next; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -