Date: Fri, 19 Feb 1999 14:16:28 -0500 (EST)
From: Fyodor <fyodor@dhp.com>
To: ajax <ajax@mobis.com>
Cc: MadHat <madhat@unspecific.com>, "'nmap-hackers@insecure.org'" <nmap-hackers@insecure.org>
Subject: Re: nmap..... via web

On Thu, 18 Feb 1999, ajax wrote:

> anyway, www.mobis.com/ajax/code/nmap/webmap.cgi is my seven minute
> rendering of what i think it should look like, complete with sanity
> checking of the user input variable,

You mean this sanity checking?

   # sanity check
   if ($query->param('ip_address') =~ /[~`\#\$\!\%\^\&\*()\|\[\]\{\}\:\;\?]/ ) 
   { print "<H1><tt>Sorry, Try again. </H1>";
     exit; 
   }

and then later you call:

$output = `$nmap $ipaddress 2>&1`;

This doesn't look very sufficent to me.  For example, the banned chars
don't include space or '-'.  So what is to stop someone from giving an IP
address of '-o/etc/passwd mymachine' and thus overwriting your password
file?  There are a lot of other command lines which could cause damage.
And what if they include a newline and a second command?  Remember our
favorite phf.cgi?  Anyone who writes one of these needs to be very very
careful to ONLY allow what is known to be safe -- don't try to ban the
stuff you know is unsafe (because you won't catch everything).

Note that I havent' actually tested that my 'exploits' work.  Those are
just some of the things that look like problems at first glance.

Cheers,
Fyodor


--
Fyodor                            'finger pgp@www.insecure.org | pgp -fka'
Frustrated by firewalls?          Try nmap: http://www.insecure.org/nmap/
In a free and open marketplace, it would be surprising to have such an
obviously flawed standard generate much enthusiasm outside of the criminal
community.  --Mitch Stone on Microsoft ActiveX

------------------------------------------------------------------------------

#!/usr/bin/perl
# webmap: cheezy front end to nmap written by ajax@mobis.com 
#         for all the marketing people 
# 
# its best to either use suidperl, or make nmap suid-root

use CGI qw/:standard :html3 :fatalsToBrowser/;
use CGI::Carp; #qw(fatalsToBrowser);

# configuration options
$allow_bans = 0;                        # should we ban any hosts?
@banned = ('example.com', 
           'example.com', 
           'example.com', 
           'example.com');              # these hosts are banned
$restrict_hosts = 0;                    # should we restrict hosts?
@only_allow = ('example.com');          # only allow these hosts
$send_email = 0;                        # send mail upon usage of this program?
$email_address = "root\@example.com";   # email address to send email to
$nmap = "/usr/local/bin/nmap -sS -O";   # nmap program and options which will
                                        # be executed followed by dest IP



$query = new CGI;
print $query->header;
if (!($query->param('ip_address'))) { &print_prompt($query); }
&security_check($query);
&do_nmap($query);
print $query->end_html;
exit;

sub security_check
 {
   $not_allowed = 0;
   if ($allow_bans) {
     foreach $host (@banned) {
        if ($ENV{'REMOTE_HOST'} =~ /$host/) { 
           print "<H1>Sorry, Your host is banned.";
           exit; 
        }
     } 
   }
   if($restrict_hosts) {
     foreach $host (@only_allow) {
        if (!($ENV{'REMOTE_HOST'} =~ /$host/)) {
           $not_allowed++;
        }
     }
   }
   # sanity check
   if ($query->param('ip_address') =~ /[~`\#\$\!\%\^\&\*()\|\[\]\{\}\:\;\?]/ ) 
   { print "<H1><tt>Sorry, Try again. </H1>";
     exit; 
   }

   if ($not_allowed) {
      print "<h1>Sorry, You are not connected from one of the allowed hosts.</h1>\n";
      exit;
   }
   return 0;
}

sub do_nmap {
    my($query) = @_;
    my(@values,$key);

 if ($query->param('ip_address') ne "") {
    $ipaddress = $query->param('ip_address');
    print "<b>Results (this may take a minute):</b><br><tt>",
    $output = `$nmap $ipaddress 2>&1`; 
    print "<p><PRE>$output</PRE>";

    if ($send_email) {
       #send email whenever this program was ran
       $hostname = $ENV{'REMOTE_HOST'};
       open (MAIL, "|/usr/bin/sendmail -t") || die "Can't open /usr/bin/sendmail\n";
       print MAIL "To: <",$email_address,">\n";
       print MAIL "From: <",$hostname,">\n";
       print MAIL "Subject: usage of webmap.cgi\n\n";
       print MAIL "------------------------------------------------------\n";
       # print the entire http environment for this session
       foreach $key ($query->param) {
          print MAIL "$key -> ";
          @values = $query->param($key);
          print MAIL join(", ",@values),"\n";
       }
       foreach $key (sort keys %ENV) {
          print MAIL "$key=$ENV{$key}\n";
       }
       print MAIL "------------------------------------------------------\n";
       close (MAIL);
       return 0;

    }
 }
 return 0;
}  


return 0;
sub print_prompt {
   my($query) = @_;

   print $query->start_html,
         "<FONT COLOR=\"#000000\" SIZE=\"3\" FACE=\"\">",
         $query->start_form,
         "<H1>K-RAD ELITE NMAP SCANNER</H1><br>\n",
         "<h5><EM>destinationIP </EM>",
         $query->textfield(-name=>'ip_address',
                           -size=>15),"<BR>",
         "<P>",$query->reset,
         $query->submit('Action','Submit'),
         $query->endform;
}
