Page 1 of 1

sendmail() security question

Posted: Wed Nov 23, 2005 8:27 am
by trukfixer
Because there's been so many mailer or contact feedback form exploits (cgi mailers, form mail, etc) I wrote my own basic feedback form.. Recently in a security discussion, someone mentioned the potential to inject spam by sticking

\\r\nBcc:email1@somewhere.com,email2@somewhere.com\r\nCc:email3@elsewhere.com

into my "reply to" input field (I do some basic checks on that field, but nothing overboard) However, in my own testing of my script I was unable to get this idea to work.. however it does seem possible, and I wonder under what conditions can such an attack actually work??

My feedback form is here: http://www.crazybri.net/feedback.php

my code: (note all instances of @ have been replaced with AT for purposes of this post... Im not interested in being picked up by more spamspiders :)

Code: Select all

<?php
//code is free to use such as it is 
include('config.php');

$email = "";
$src = $_GET['from'];
$user = $_GET['user'];
if(!empty($_POST))
{
    $action = $_POST['action'];
    $uid = $_POST['id'];
    $uid = intval($uid);
    $reply_to = $_POST['sender'];
    $raw_input = $_POST['message'];
    //trim message to 450 check reply_to for an @ if none put noreply AT crazybri.net
    if(!strpos($reply_to,"@"))
    {
        $reply_to = 'noreplyATcrazybri.net';
    }
    $message = substr("$raw_input",0,450);
    $message = str_replace("chr(","",$message);//keeps idiots from sending chr(0), etc- it just breaks it
    $reply = str_replace("chr(","",$reply_to);

    if($action == "news")
    {
       //note this section is only because I link my news feedback page to this feedback form 
      //just a rough hack  
        $nlink = mysql_connect('localhost','tuser','pass');
        mysql_select_db('dbname');
        $query = mysql_query("SELECT email FROM unp_user WHERE userid = '$uid' LIMIT 1",$nlink);
        $data = mysql_fetch_array($query);
        $email = $data['email'];
        send_email($action,$email,$reply,$message);
    }
    else
    {
        send_email("basic","bri AT crazybri.net",$reply,$message);
    }
    header("Location: index.php");
}



$smarty->assign('src',$src);
$smarty->assign('id',$user);
$smarty->assign('title',$title);
$title2 = "CrazyBri Feedback Form- Send feedback or email to selected users";
$smarty->assign("title2",$title2);
include_once("header.php");
$smarty->display('feedback.tpl');
$file=('Feedback');
include_once('footer.php');
$email = "";
function send_email($action,$email,$reply,$message)
{
    mail( $email, "$action Feedback Form Results", $message, "From: $reply<$reply>" );
}
?>
The code is free to use.. I threw it together in a couple minutes of work.. didnt need anything fancy..

My own attempt to inject email results in a feedback email *to* me (I hard code the send to, mind you, it isnt a variable)

Code: Select all

From - Wed Nov 23 09:04:03 2005
X-Account-Key: account3
X-UIDL: 914d4d4736204d7c0b12d9b3642a725c
X-Mozilla-Status: 0201
X-Mozilla-Status2: 00000000
Return-path: <nobody AT server1.controlhosting.net>
Envelope-to: bri AT crazybri.net
Delivery-date: Wed, 23 Nov 2005 09:03:49 -0500
Received: from nobody by server1.controlhosting.net with local (Exim 4.52)
	id 1EevDx-0002uH-D0
	for briATcrazybri.net; Wed, 23 Nov 2005 09:03:49 -0500
To: bri AT crazybri.net
Subject: basic Feedback Form Results
From: helloATcrazybri.net\\r\\nBcc:salesATcrazybri.net,rubberATcrazybri.net<helloATcrazybri.net\\r\\nBcc:salesATcrazybri.net,rubberATcrazybri.net>
Message-Id: <E1EevDx-0002uH-D0ATserver1.controlhosting.net>
Date: Wed, 23 Nov 2005 09:03:49 -0500

Hacker testing see if I can \\r\\nBcc:bodyATcrazybri.net\\r\\n inject some spam into the feedback form
The challenge: under what conditions, and what code, can you inject a string that, when it is ultimately passed to mail() function, it will cause a *line break* and start a new header line as in Cc: and Bcc: etc, in order to exploit the code and use it to send out UCE to 3 or more email addresses?

Posted: Wed Nov 23, 2005 9:12 am
by Charles256
i've noticed a lot of supposed security risks I can't get to work even when I don't do the craziest purification..no matter what people say...which is why in SOME (read SOME SOME SOME ) cases I ignore any screams of to arms in security...only thing I can see in your code is you may want to do some checks for the tell tale code signs, i.e. <?php <?, and the like...

Posted: Wed Nov 23, 2005 9:36 am
by Jenk
Would it not be better to just remove the newline char's, then regex the email addresses to see if they are valid format?


I'm speculating, never had the need to do this myself yet.

e.g.:

Code: Select all

<?php

function CheckMail ($addy)
{
    $addy = str_replace("\r\n", "", $addy);
    if (preg_match("/^[a-zA-Z0-9_\-.]+@[a-zA-Z0-9_\-.]+(\.[a-zA-Z0-9]{2,3})+$/", $addy)) {
        return $addy;
    } else {
        return false;
    }
}
if ($to = CheckMail($_POST['To'])) {
    $to = "To: {$to}\r\n";
}
?>

Posted: Wed Nov 23, 2005 9:50 am
by trukfixer
Jenk wrote:Would it not be better to just remove the newline char's, then regex the email addresses to see if they are valid format?


I'm speculating, never had the need to do this myself yet.

e.g.:

Code: Select all

<?php

function CheckMail ($addy)
{
    $addy = str_replace("\r\n", "", $addy);
    if (preg_match("/^[a-zA-Z0-9_\-.]+@[a-zA-Z0-9_\-.]+(\.[a-zA-Z0-9]{2,3})+$/", $addy)) {
        return $addy;
    } else {
        return false;
    }
}

?>
I considered it. I wanted to offer the option to *not* provide a reply to.. It'd be simple enough to just regex, and if it fails, use the default and throw away the rest.... not a big problem there.. as I said, the above code was just slapped together in a few minutes' work .. I didnt put a lot of deep thought into it :)

My main question is: can such an exploit be made to really work via that feedback form.. that's what I wondered..

Thing is, if I wanted to expand this out to a more robust feedback/contact script, I'd want to be able to know *what* works to exploit such things .. so I can account for such exploits.. :) Ive had some of our customers ask me to build out on this basic form script to do more of what they would like to see, because they all have tried , at last count, over 47 different form mail/submit scripts and so far every one of them was causing problems of one sort or another (exploits, submit floods, etc) and other scripts just didnt have the features they wanted out of it, so... that's why this post/question ..

I'd prefer to keep my code to an absolute minimum (I hate code bloat .. Horde still gives me nightmares!) so I figured a post here might come up with some more elegant solutions and possibilities or ideas I havent considered or heard of :)

Posted: Wed Nov 23, 2005 11:41 am
by trukfixer
OK.. it wasnt working on that particular install because magic_quotes_gpc was on (I forgot about that) , however if magic_quotes_gpc were off, or you in some way got past that ---

the important thing is that the $from variable is just dumping whatever is in the string into the sendmail() headers..
which is the precise problem.. I did a little more google searching for more more specific stuff - namely "email injection" and came up with this:

http://securephp.damonkohler.com/index. ... _Injection

so while that script isnt too terrible at the moment, the important thing is to clean up and validate on anything that may go into the headers..

Thanks to teh guys that ran some tests- the header info from the emails was quite informative as well ..

(gmail bounced one because of the $reply_to<$reply_to> and the <> stuff is just to make it "pretty" for the recipient.. so Im gonna drop its usage from practice..)

The solution is going to be: regex on anything that gets passed to message headers , and on error, either set a default, or toss them back to the form (or redirect them to another page , in the event it is an automated bot, perhaps, would be better)

Thanks for the input, I definitely would be interested in further comments from the gurus (shifflett, Roja, etc)

Posted: Wed Nov 23, 2005 11:43 am
by Charles256
main thing that frustrates me about mail is that sometimes the host will take it, somthimes they won't..it's a horrible game of russian roulette.

Posted: Tue Dec 06, 2005 11:22 pm
by gearb0x
Hey

Just doing some playing around on this topic my self. I cant for the life of me get it to work. I tried IE and firefox, \r\n, and the delimiter that security article speaks of

Magic GPC quotes is off on my server as well

argh this is anoying, trying to fix something i cant even replicate

Posted: Tue Dec 06, 2005 11:37 pm
by John Cartwright
let me suggest PHPMailer.. from my experience it gets the job done extremely well

Posted: Wed Dec 07, 2005 6:18 am
by timvw
If i remember well, when i was testing this problem, i think that the win32 build of php actually inspected the headers...

Posted: Wed Dec 07, 2005 6:25 am
by sheila
gearb0x wrote: Just doing some playing around on this topic my self. I cant for the life of me get it to work. I tried IE and firefox, \r\n, and the delimiter that security article speaks of

Magic GPC quotes is off on my server as well

argh this is anoying, trying to fix something i cant even replicate
Are you trying to prove that your script is vunerable? You can't do it with an ordinary HTML form. The \r\n just get turned into character data and their meaning is lost. You need something running from the command line that POSTs directly to the target URL. I have a Perl script that I use but it could be done with PHP too.

Posted: Wed Dec 07, 2005 7:36 pm
by gearb0x
:oops: never though of that :D

thanks very much will have a play later

Phill

Posted: Tue Dec 13, 2005 10:11 pm
by gearb0x
Just a little update, i got it all working and managed to inject stuff into my systems mailing system (after i /* */ the validation :D)

just something i found on the way, http://tamperdata.mozdev.org/ little plugin for firefox, lets you change stuff at post/get time before the request gets sent. Makes it easier to test these sorts of things ;D