Forum Moderators: phranque

Message Too Old, No Replies

Formmail and other perl BCC exploit

Have a theory to stop the bcc spam across multiple programs

         

MThiessen

7:41 pm on Aug 5, 2006 (gmt 0)

10+ Year Member



It has come to my attention that spammers are using guesbook, formmail and forum software to not only annoy our traffic, but to send spam, using US as thier portal.

They use a header attack, they generate bcc or cc fields WITHOUT using the submit form, just but direct line entry.

I have a theory to stop the bcc spam across multiple programs.

I am NOT a programmer, so I need help. Can any of you tell me if this will work?

Here we go: (perl)

Step 1:
Identify the variable that triggers the script to inject email headers:

The below example is taken from the notorious "matts cript archive" formmail.pl

"email" is the form header.

$sender = $form{'email'};
if ($sender =~ /\@.*\@¦,/) {
print "There was a problem sending your message. We apologize for the inconvenience.";
exit;
}
$sender = $form{'email'};
if ($sender =~ /\@.*\@¦,¦bcc:¦\n/i) {
print "There was a problem sending your message. We apologize for the inconvenience.";
exit;
}

(Pipes are NOT supposed to be broken, replace.)

The first subroutine detects more then one address in the header.

The second looks for bcc (blind carbon copy)AND /n (newline) injections.

This solution "appears" to be simple enough to be used on any perl script that uses email. Simply replace $sender = $form{'email'}; with $sender = $any_email_header_variable;

Thus it can be inserted into any perl script using email respond features.

I am not sure this will work, seems almost too easy.

If ANYONE can improve this, or tell me whats the problem, please let me know. Also am open to better solutions.

Thanks!

rocknbil

1:03 am on Aug 6, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



$sender = $form{'email'};

I've thought this over, and I just can't give it away for free, but will try lead you to a solution. You're definately on the right track though. :-) Important to know is that **any** valid mail header can be perverted for this purpose. You can do this in the subject, to, and from fields of a mail header as well. So to effectively slow them down, you need to screen ALL incoming data.

The newline regexp is worthless. They often use an encoded or binary value for the newline and it never matches on \n. But what you CAN rely on is what would come after that newline, the BCC or CC or a content-type header.

Although I won't specify how, I will say this, LOG YOUR DATA. Log everything input to your scripts. This will reveal exactly what they are doing, or trying to do, and you can form regexps and methods to stop it.
To the acual sender's email field - not necessarily what comes in from the form, but what you put in the mail header - apply a variety of screens:

1. If a comma separated list is found, split up the list, strip off and use only the first address in that list. This one possibly allows them to think their list was sent successfully, but it only sends the one. :-)

2. Check for the valid email pattern, there are many good regexps to be found on the web. Something like this, but this is not what I use:

if ($sender!~ /.*\@.*[.].*/) { (message and exit here) }

3. At this point all metacharacters should be already stripped out of the data - but do it again on only the email to-field in case something is bypassing the meta screening.

In your LOGGING routine, do something like this, to ALL FIELDS, not just incoming email field. As you have discovered, ¦ is the pipe operator, you can also use the word 'or':


if (
($field =~ /b*cc\s*:/i) ¦¦
($field =~ /to\s*:/i) ¦¦
($field =~ /content\-type/i)
) { (message and exit here) }

There is actually much more than this but it will lead you in the right direction and slow them down a bit. Plugging up this security hole for someone is a STEAL at $200, although it's seldom appreciated. :-)

KenB

1:22 am on Aug 6, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here is a free solution that the web hosting provider I use is asking people to add into their contact forms:

if (preg_match("/[\\000-\\037]/",$EMAIL)) { die(); }

You should use this string for the email field or any other header type field.

moltar

2:58 am on Aug 6, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



What spammers are doing is pretty easy. Then submit a From or Subject field with an additional new line at the end and then BCC or CC fields. You can't do that through regular HTML <input>, but you can do it from a custom script that a spammer could write. So if your field is, lets say, called 'from'. So normally you'd have just an email address value in it. But the hackers will submit something like:

$from = "joe@example.com\nBcc: spamee@example.com";

Then programmer uses this value for the sendmail input like:

open(SENDMAIL, "¦ /usr/sbin/sendmail"); 
print SENDMAIL "From: $from\n";
...
close(SENDMAIL);

When you print the $form variable, what actually prints is:

From: joe@example.com 
Bcc: spamee@example.com

And sendmail doesn't care, because it's 100% valid input. And than could happen to any field value that you use directly in mail headers (subject, to, from, etc...)

henry0

11:31 am on Aug 6, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I do not know of any using (on purpose) BCC or CC via form
as such why not disallow CC and BCC?

KenB

12:59 pm on Aug 6, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



My web hosting provider state that they were noticing a major problem with spammers using the BCC trick.

The code I provided really is a simple addition to one's PHP contact form and it will protect one from spammers so it is just a good idea.

MThiessen

5:25 pm on Aug 6, 2006 (gmt 0)

10+ Year Member



I tried that php code on a phpformmail and the spammer still got through.

They also get through the perl fix that I originally posted :(

However, I have not get tried that trick on ALL headers, which I am going to do.

I heard that NMS FormMail Version 3.14c1 from sourceforge is not Bcc and cc attackable, and is reasonably secure. Before I search through the code, or convert over to it, can anyone confirm it is secure? If its not, do you know of a form that is?

Thanks!

PS I appreciate the hints you gave. It's a shame you cant outright post the fix, but you have to make money like everyone else, and I can respect this. It's a shame though, because if you released a solid fix free to the public it would go a VERY long way in putting a dent in internet spam.

KenB

5:46 pm on Aug 6, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I tried that php code on a phpformmail and the spammer still got through.

They also get through the perl fix that I originally posted

Did you make sure to change the $EMAIL variable to the variable you use for the $email field and run the same test against your other variables that stick stuff in email headers?

For instance you might need to modify the code to something like this:

if (preg_match("/[\\000-\\037]/",$email) ¦¦ preg_match("/[\\000-\\037]/",$subject)) { die(); }

BananaFish

9:58 pm on Aug 6, 2006 (gmt 0)

10+ Year Member



Here is my hijack check for php. Basically the hack cannot be done without linefeeds or their hex equivalents:
if(preg_match("/\r*\n¦%0a¦%0d/i",$val)){ 
if(preg_match("/boundary¦content-type¦b*cc:/i",$val)){
$jack=1;
}
}

rocknbil

2:35 am on Aug 7, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



BananaFish: Note the proximity of your PHP solution to my perl one. :-D The exception is I don't do an if. Those regexps have no place in any email submitted from the web.

henry0:

I do not know of any using (on purpose) BCC or CC via form as such why not disallow CC and BCC?

If you're asking on a domain level, both I and motar have explained: they insert a newline character into the data input that corresponds to one of the mail headers, then create their own BCC header. If you're asking on a mail server level, this is possible ONLY of you have your own dedicated mail server, I think you can configure sendmail to not allow BCC/CC. But this would mean NO ONE using sendmail could use BCC/CC. It is indeed a partial solution, but most cases you're on shared servers and can't just disable BCC/CC for all domains on that server for the benefit of one domain.

moltar:

$from = "joe@example.com\nBcc: spamee@example.com";

The problem is, it's almost never a \n, and for whatever reason matching on any encoding of a newline doesn't seem to work either. You can find this out by logging if you are attacked. :-)

MThiessen:

It's a shame you can't outright post the fix,
but you have to make money like everyone else, and I can respect this. It's a shame though,
because if you released a solid fix free to the public it would go a VERY long way in putting a dent in internet spam.

This knowledge has come long and hard, and believe me, I barely make enough to cut it, (as my wife ofttimes tells me!) but in truth, there's actually a larger reason. Hackers are watching us, you know they are. If we outright post our methods, this gives them the tools to undo them.

Worse yet, for myself, if one of my tips here were to render my methods ineffective, I would have to go back to all customers affected and fix them. Now, most programmers rationalize this as billable; as a personal ethic, I do not. I've charged for time to fix something, if it no longer works, the original solution was just a patch. If I pay a plasterer to fix a hole in my ceiling and if falls out a week later, I'm sure as hell not paying him to fix it again!

I've been there before, it's not a place I want to be again.

It's a common trick to help avoid hacking by using odd names for our variables, files, database tables, and other unseen server-side methods. Anything you do that cannot be seen by View Source should be kept as hidden as possible.

But follow the clues I've laid out here, watch, wait, think it through - all the clues are there. :-D


open (LOG, ">>$mylog");
foreach $key (keys %data) { print LOG "key: $v value: $data{$v}\n"; }
print LOG '=================',"\n";
close (LOG);

:-P

rocknbil

4:25 am on Aug 7, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



oops. :-)

foreach $key (keys %data) { print LOG "key: $key value: $data{$key}\n"; }

opifex

6:19 am on Aug 7, 2006 (gmt 0)

10+ Year Member



there is a definite way around this one ...... after too many abuses with sendmail it is simpler to use a script to use a valid account to mail your own mails .... but disable sendmail ... to many holes ... I'll post the basic script...very small ... if anyone wants .... you can use the basic elements to modify formail if you want

if interested sticky me

rocknbil

3:47 pm on Aug 7, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



It would be interesting to see, as sendmail is not the problem, it's the data sent to the script.

opifex

7:02 pm on Aug 8, 2006 (gmt 0)

10+ Year Member



problem is that sendmail is too easily accessible on most servers ... some larger hosts now don't even have it istalled in the libraries to prevent such abuses

rocknbil

7:56 pm on Aug 8, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thank you for that solution! However, in the example you sent, it is only effective because you have the $to, $from and $subject hard-coded into your script. In most cases, we need to at least allow the visitor to enter their email address so that we can contact them via email. If you allow that $from to be entered from the form, it is subject to the same vulerabilities we are discussing here.

I suppose this is one good solution, force the visitor to enter their return email address into the data input field, which gets placed into the body of the email - but if they don't, you lose a contact.

opifex

8:19 pm on Aug 8, 2006 (gmt 0)

10+ Year Member



simply add the "senders email" in a field ... use that field as the "from" content as you suggest. i´ve done that and works fine .... as many inputs as you need. there is NO bcc in the script therefore it cant be used .... if a cc is added ... always hard code it. I got targeted by spammers several years ago and started this type of routine .... the spammers left.
different strokes ... i like to keep it simple
*** a contact that doesnt want to be known ... isn't a contact

kaled

9:43 pm on Aug 8, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If I understand the problem correctly, it stems from the use of the Sendmail program within the script.

Kaled.

[edited by: trillianjedi at 1:20 pm (utc) on Aug. 10, 2006]
[edit reason]
[1][edit reason] See Sticky [/edit]
[/edit][/1]

rocknbil

10:39 pm on Aug 8, 2006 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There's nothing wrong with sendmail in respect to this type of attack, it's the way many scripts are allowing data to be sent to sendmail. The same will be true of any other mail proggie. This problem crosses perl, php, asp . . .

"email injection" perl [google.com] is one of the more common searches.

Best of luck everyone! :-)