#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_html_init
{
   my $id =
   {
      name         	=> "reporthtml",
      full_name    	=> "Report as HTML",
      author       	=> "Sullo/Jabra",
      description  	=> "Produces an HTML report.",
      report_head  	=> \&html_head,
      report_host_start => \&html_host_start,
      report_host_end 	=> \&html_host_end,
      report_item  	=> \&html_item,
      report_close 	=> \&html_close,
      report_format  	=> 'htm',
      copyright    	=> "2008 CIRT Inc."
   };
   # load up the templates now
   html_open_templates();
   return $id;
}

sub html_head
{
   my ($file) = @_;
   # Write header for html file, return file handle
   open(OUT, ">>$file") || die print STDERR "+ ERROR: Unable to open '$file' for write: $@\n";

   my $html = html_change_vars($TEMPLATES{htm_start});
   $html =~ s/\#NIKTODTD/$NIKTOCONFIG{NIKTODTD}/;
   print OUT "$html";

   return OUT;
}
###############################################################################
sub html_close
{
   my ($handle,$mark) = @_;
   my $html = html_change_vars($TEMPLATES{htm_close},$mark);
   print $handle "$html\n";

   close($handle);
   return;
}
###############################################################################
sub html_host_start
{
   my ($handle, $mark) = @_;
   my $html = html_change_vars($TEMPLATES{htm_host_head},$mark);
   print $handle "$html\n";

   return;
}
###############################################################################
sub html_host_end
{
   my ($handle, $mark) = @_;
   my $html = html_change_vars($TEMPLATES{htm_end},$mark);
   print $handle "$html\n";

   return;
}
###############################################################################
sub html_item
{
   my ($handle, $mark, $item) = @_;
   my $html = html_change_vars($TEMPLATES{htm_host_item},$mark,$item);
   print $handle "$html\n";

   return;
}
###############################################################################
sub html_open_templates
{
    my @ts        = dirlist($NIKTOCONFIG{TEMPLATEDIR});
    my $have_cirt = 0;
    foreach my $t (@ts)
    {
        open(T, "<$NIKTOCONFIG{TEMPLATEDIR}/$t");
        my @TEMPLATE = <T>;
        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 html_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_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_enc
{
    my $var = $_[0] || return;
    $var =~ s/</&lt;/g;
    $var =~ s/>/&gt;/g;
    $var =~ s/"/&quot;/g;
    return $var;
}

sub nikto_reports { }    # so core doesn't freak

1;
