Wednesday, February 15, 2006

 

PHP Email Injection - Step by Step Part 1

I recently got to have a little fun with a colleague (who will remain nameless) who was using a PHP script for a contact form. About 2 weeks ago he received several submissions to his contact form that appeared to contain SMTP headers in the "Message" portion of the submission. The form was named "contact.php" and it was obvious that somebody thought that this form might make a good PHP email injection target. If you haven't already read this article on how PHP email injection works, read it now.

Note: I wrote a custom Perl script to automate the injection process, if you would like a copy for legit testing purposes please email me at matt.richard@gmail.com.

The contact form allows the submitter to enter their email address, name and a comment. The email and name input fields have HTML limits of 128 characters which for this article we will assume to be hard limits in the script. Note that I verified these limits in the source later.

Here is the email that he forwarded (some headers snipped):


> To: victim@victim.org
> Subject: Web Contact From said144@victim.org
> From: said144@victim.org <>
> Reply-To: said144@victim.org
> Date: Mon, 6 Feb 2006 06:02:02 -0500 (EST)
>
> Time: Mon, 06 Feb 2006 06:02:01 -0500
> Name: said144@victim.org
> Email: said144@victim.org
> Status: Domain OK.
> Message: had
> Content-Type: text/plain; charset=\"us-ascii\"
> MIME-Version: 1.0
> Content-Transfer-Encoding: 7bit
> Subject: of urope
> bcc: charieses329@aol.com
>
> 379ec90f66d778aeb20b9a9d3f279d8

As you can see from these headers and the body, the injection attempt was not successful. The attacker only managed to get his HTML code in the "Message" section which did not modify the headers. Remember that based on how PHP email injection works we need to find a parameter that is passed in the "$headers" field of the mail() function. In this case I would guess that "Message" doesn't meet that criteria.

So that leaves "email address" and "name". Looking at the headers it appears that "name" appears in the body of the message (won't help) and possibly in the From: header. If we're lucky the From: header is being generated by passing a string to the $header field of mail() which would allow us to inject headers. Both $email_address and $name should work barring some form of server side filtering.

At this point we're really banking on the possibility that the form creates a nice looking From: field by using something like "From: $email_address < $name >" This would give us the opportunity to manipulate either the "$email_address" or "$name" variable. Let's get started executing our attack.

Let's take on the $name field because it comes after the $email_address and we can arbitrarily submit any From: address we want. Using $name will give us the flexibility to add headers without recreating the From: header. We will also want to come up with a good way to disguise the subject and body of the message, more on that later.

To: victim@victim.org
Subject: Web Contact From $name
From: $email_address < $name >
Reply-To: $email_address

Date:
Time:
Name: $name
Email: $email_address
Status: Domain OK.
Message: $message
Our injection has to take 3 factors into consideration:
  1. we want to close the <> so that our header is valid
  2. we need to inject newline - cc: some address - newline
  3. we need to neutralize the hanging ">" that will show up at the end of our header
In an effort to keep things simple we'll start by using something like "f@from.org>\ncc:dest@dest.org\nX-Test:". I'm injecting an extra "X-" header since this information will be ignored by MTA's and mail clients. The only function of this extra header is to prevent the ">" from appearing as a separate line in the header and potentially raising red flags.

This should yield a header like this:
To: victim@victim.org
Subject: Web Contact From f@from.org>\ncc:dest@dest.org\nX-Test:
From: foo@bar.com <>
cc: dest@dest.org
X-Test:
>
Reply-To: foo@bar.com
A quick run of my custom Perl script and voila! An email arrives in my inbox with my injected headers and my arbitrary delivery address in the CC line. Since my address was in the CC line and the victim's address was in the To: line we'll call this a success.

In Part 2 we'll explore how to manipulate the subject and body so that we remove all of the ugly text already in the message and replace it with our own custom text.

Comments:
Cool. Could you please mail me the automator script for testing purposes?

I would like to test this on my code to see if injection works on it.
 
Post a Comment





<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]