#VERSION,2.02 # $Id: nikto_reports.plugin 125 2009-07-20 21:59:00Z deity $ ############################################################################### # Copyright (C) 2007 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. ############################################################################### ############################################################################### # PURPOSE # Reporting ############################################################################### sub nikto_report_xml_init { my $id = { name => "reportxml", full_name => "Report as XML", author => "Sullo/Jabra", description => "Produces an XML report.", report_head => \&xml_head, report_host_start => \&xml_host_start, report_host_end => \&xml_host_end, report_item => \&xml_item, report_close => \&xml_close, report_format => 'xml', copyright => "2008 CIRT Inc." }; # load up the templates now xml_open_templates(); return $id; } sub xml_head { my ($file) = @_; # Write header for xml file, return file handle open(OUT, ">>$file") || die print STDERR "+ ERROR: Unable to open '$file' for write: $@\n"; my $xml = xml_change_vars($TEMPLATES{xml_start}); $xml =~ s/\#NIKTODTD/$NIKTOCONFIG{NIKTODTD}/; print OUT "$xml"; return OUT; } ############################################################################### sub xml_close { my ($handle,$mark) = @_; my $xml = xml_change_vars($TEMPLATES{xml_close},$mark); print $handle "$xml\n"; close($handle); return; } ############################################################################### sub xml_host_start { my ($handle, $mark) = @_; my $xml = xml_change_vars($TEMPLATES{xml_host_head},$mark); print $handle "$xml\n"; return; } ############################################################################### sub xml_host_end { my ($handle, $mark) = @_; my $xml = xml_change_vars($TEMPLATES{xml_end},$mark); print $handle "$xml\n"; return; } ############################################################################### sub xml_item { my ($handle, $mark, $item) = @_; my $xml = xml_change_vars($TEMPLATES{xml_host_item},$mark,$item); print $handle "$xml\n"; return; } ############################################################################### sub xml_open_templates { my @ts = dirlist($NIKTOCONFIG{TEMPLATEDIR}); my $have_cirt = 0; foreach my $t (@ts) { open(T, "<$NIKTOCONFIG{TEMPLATEDIR}/$t"); my @TEMPLATE = ; close(T); my $T = join("", @TEMPLATE); $t =~ s/\..*$//; # :-) if ($T =~ /\s?20[0-9]{2}\s?CIRT, Inc/i) { $have_cirt = 1; } $TEMPLATES{$t} = $T; } if (!$have_cirt) { print "\nIt looks like you may have removed the Nikto copyright from the reports. Please remember that this program is copyrighted, takes a lot of work to maintain, and is completely free for non-commercial use.\n\nIf this message has been a mistake, please notify sullo\@cirt.net.\n\n"; } return; } ############################################################################### sub xml_change_vars { my ($template, $mark, $item) = @_; my %variables; my $protocol = "http"; if ($mark->{ssl}) { $protocol .= "s"; } $variables{"#TEMPL_HCTR"} = $NIKTO{TEMPL_HCTR}; $variables{"#TEMPL_END"} = date_disp($mark->{end_time}); $variables{"#TEMPL_HOSTNAME"} = simple_enc($mark->{hostname}); $variables{"#TEMPL_HOST_HEADER"} = $mark->{hostname}; if (defined $mark->{vhost}) { $variables{"#TEMPL_HOST_HEADER"} = $mark->{vhost}; } $variables{"#TEMPL_IP"} = simple_enc($mark->{ip}); $variables{"#TEMPL_ITEMS_TESTED"} = $mark->{total_checks}; $variables{"#TEMPL_PORT"} = $mark->{port}; $variables{"#TEMPL_START"} = date_disp($mark->{start_time}); $variables{"#TEMPL_END"} = date_disp($mark->{end_time}); $variables{"#TEMPL_NIKTO_VER"} = $NIKTO{version}; $variables{"#TEMPL_BANNER"} = simple_enc($mark->{banner}); $variables{"#TEMPL_NIKTO_CLI"} = $CLI{all_options}; $variables{"#TEMPL_CTR"} = $mark->{total_checks}; $variables{"#TEMPL_NIKTO_HOSTS_TESTED"} = $COUNTERS{hosts_total}; $variables{"#TEMPL_ELAPSED"} = $mark->{end_time}-$mark->{start_time}; $variables{"#TEMPL_LINK_NAME"} = "$protocol://$mark->{hostname}:$mark->{port}"; $variables{"#TEMPL_LINK_IP"} = "$protocol://$mark->{ip}:$mark->{port}/"; $variables{"#TEMPL_ITEMS_FOUND"} = $mark->{total_vulns}; $variables{"#TEMPL_LINK_NAME"} = "N/A"; if ($mark->{hostname} ne "") { $variables{"#TEMPL_LINK_NAME"} = "$protocol://$mark->{hostname}:$mark->{port}/"; } foreach my $var (keys %variables) { $template =~ s/$var/$variables{$var}/g; } # Scanner Messages Handling if ($template =~ /\#TEMPL_SMMSG/) { my $template_orig = $template; my $template_final = ""; if ($item->{uri} ne '') { next; } my $OSVDB = $item->{osvdb}; if ($OSVDB !~ /\d+/) { $OSVDB = 0; } $OSVDB_LINK = "http://osvdb.org/$OSVDB"; $template =~ s/\#TEMPL_SMMSG/$item->{message}/; $template =~ s/\#TEMPL_OSVDB_LINK/$OSVDB_LINK/; $template =~ s/\#TEMPL_OSVDB/$OSVDB/; $template =~ s/\#ID/$item->{nikto_id}/; $template_final .= $template; $template = $template_orig; $template = "$template_final\n"; } # Positives Handling if ($template =~ /\#TEMPL_MSG/) { my $template_orig = $template; my $template_final = ""; if ($item->{uri} eq '') { next; } foreach my $uri (split(' ',$item->{uri})) { $item->{uri} = simple_enc($item->{uri}); $variables{"#TEMPL_URI"} = $uri; $variables{"#TEMPL_MSG"} = $item->{message}; $variables{"#TEMPL_HTTP_METHOD"} = $item->{method}; $variables{"#TEMPL_ITEM_IP_LINK"} = "$protocol://$variables{\"#TEMPL_IP\"}:$mark->{port}$variables{\"#TEMPL_URI\"}"; $variables{"#TEMPL_ITEM_NAME_LINK"} = ""; if ($mark->{hostname} ne "") { $variables{"#TEMPL_ITEM_NAME_LINK"} = "$protocol://$variables{\"#TEMPL_HOSTNAME\"}:$mark->{port}$variables{\"#TEMPL_URI\"}"; } $OSVDB = ""; $OSVDB_LINK = ""; foreach my $o (split(/ /, $item->{osvdb})) { if ($o eq "") { $o = "0"; } $OSVDB .= "$o"; $OSVDB_LINK .= "http://osvdb.org/$o"; } $template =~ s/\#TEMPL_OSVDB_LINK/$OSVDB_LINK/; $template =~ s/\#TEMPL_OSVDB/$OSVDB/; $template =~ s/\#ID/$item->{nikto_id}/; foreach my $var (keys %variables) { $template =~ s/$var/$variables{$var}/g; } $template_final .= $template; $template = $template_orig; } $template = "$template_final\n"; } return $template; } ############################################################################### sub simple_xml_enc { my $var = $_[0] || return; $var =~ s/&/%26/g; return $var; } ############################################################################### sub simple_enc { my $var = $_[0] || return; $var =~ s//>/g; $var =~ s/"/"/g; return $var; } sub nikto_reports { } # so core doesn't freak 1;