Santa Knows If Your Contact Form Uses PHPMailer < 5.2.18

PHPMailer, one of the most used classes for sending emails from within PHP, has a serious vulnerability in versions less than 5.2.18 (current version). The security researcher [Dawid Golunski] just published a limited advisory stating that PHPMailer suffers from a critical flaw that might lead an attacker to achieve remote code execution in the context of the web server user. PHPMailer is used by several open-source projects, among them are: WordPress, Drupal, 1CRM, SugarCRM, Yii and Joomla. A fix has been issued and PHPMailer is urging all users to upgrade their systems.

To trigger this vulnerability (CVE-2016-10033) it seems that the attacker only has to make the web application send out an email using the vulnerable PHPMailer class. Depending on the application itself, this can be accomplished in different ways, such as contact/feedback forms, registration forms, password email resets and so on.

Upon a quick diff analysis, we found that the vulnerable code seems to lie in the following lines of the class.phpmailer.php:

Version 5.2.17

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);
}

Version 5.2.18

if (!empty($this->Sender) and $this->validateAddress($this->Sender)) {
  $params = sprintf('-f%s', escapeshellarg($this->Sender));
}
if (!empty($this->Sender) and !ini_get('safe_mode') and $this->validateAddress($this->Sender)) {
  $old_from = ini_get('sendmail_from');
  ini_set('sendmail_from', $this->Sender);
}

From the code above we can get an idea where the bug comes from. The researcher [Dawid Golunski] claims to have developed a working Remote Code Execution (RCE) Proof of Concept (PoC) exploit and that he will publish it at a later date, in order to give users time to upgrade their systems.

So… sysadmins, what are you waiting for? Go and upgrade, if Santa does not sleep neither should you…

18 thoughts on “Santa Knows If Your Contact Form Uses PHPMailer < 5.2.18

    1. No ini_set is only a runtime modification, that’s fine and expected.

      The problem they are trying to “solve” is that the -f argument added into params is passed onto the sendmail command line by PHP’s mail() function (phpMailer can use either mail() or it can communicate over SMTP directly, mail() is more common).

      By not verifying the Sender address is an actual email address it can allow you to inject arbitrary options to the sendmail command line, obviously that’s not great but it’s really not that big of a deal in this case because these additional parameters are passed internally to escapeshellcmd, so there is protection there against allowing arbitrary execution of other commands than sendmail.

      ( http://php.net/manual/en/function.mail.php )
      “This parameter is escaped by escapeshellcmd() internally to prevent command execution. escapeshellcmd() prevents command execution, but allows to add additional parameters. For security reasons, it is recommended for the user to sanitize this parameter to avoid adding unwanted parameters to the shell command.”

      1. > it’s really not that big of a deal in this case because these additional parameters are passed internally to escapeshellcmd, so there is protection there against allowing arbitrary execution of other commands than sendmail.

        However, if you’re actually running sendmail (as opposed to Exim or Postfix or similar with a sendmail wrapper), escapeshellcmd alone won’t protect you here so this *would* become a big deal – as you can coerce sendmail into dumping the mail to an arbitrary file, which in most configurations leads to RCE – basically, the bug in Roundcube from a month or so ago, but in PHPMailer now.

        So yeah, if you’re running sendmail, worth going into work on Boxing Day for.

  1. Ahhh, I remember PhP (3.x.x – 4.x.x for me). Once you can create a singleton closure that actually works then the whole language is no longer interesting because you have solved the last of PhP’s problems and that is – it has no scope, everything (functions) is normally in the global scope.

    Then you write API’s to white list commands and functions and put the API on a different server and use Apache directives to IP lock the whole thing so that you API is secure, problem is that the server it’s running on has holes in the operating system so hackers get to it anyway.

    PhP has probably done more for the internet (www) as it is today than any other language but it has become a workhorse in that security takes second place to new refinements and features. It is basically a OOP that based on procedural code.

    1. Thanks for your very bad and almost illegible rough draft of what PHP is, even though no one asked for it and you would assume most people here know what it is. It’s almost like you just like hearing yourself talk about technical subjects,do you have a lot of IRL friends/acquaintances ?

      1. Just to give you some idea of what you called “almost illegible” as it *seams* that you don’t php.


        function wrapper()
        {
        function operator()
        {
        return 3;
        }
        }

        operator(); // returns error as function has been created yet
        wrapper();
        $var = operator(); // assigns the value 3 to the variable $var

        What this means is that once created the function named operator() exists in the global scope and is not limited to the scope of the function named wrapper() so at *any* point (or depth) of scope code can litter the global function namespace.

        To fix this problem you need to create a function that is –
        1) A singleton. It can’t be duplicated, cloned, or re-instantiated
        2) A closure. It cannot get any access to or modify the global scope. It is completely limited to it’s own specific scope and cannot return anything except a specified parameter of a specified type.

        Within a singleton closure you can even allow code execution because of it’s isolation (by scope) from other code.

        API- written in php
        An Application Programming Interface (API) essentially provides a means of white-listing operations/functions/commands as opposed to the normal and far less secure method of black-listing activities. Most of the more secure websites use an API and hide or obfuscate the address (IP or namespace) of the actual (Application) server. The web site that you actually visit is just a front end and doesn’t contain any sensitive data etc. On an even more secure system there is another step that separates the API server from the database server.

        While these techniques hugely increase security, they are still vulnerable at the operating system level which is how hackers break things anyway.

        Quote: “PhP has probably done more for the internet (www) as it is today than any other language”

        www: World Wide Web, HTTP, websites
        internet: TCP/IP, www, instant messaging , video conferencing, email etc.

        I deliberately misused the the incorrect term internet and then put the correct term www in brackets as most people today uses these two terms interchangeably and are unable to discern the two. This was not intended to be in anyway unintelligible.

    2. PHP should never really have been born. It has this feeling that it was developed by kids reading a text book without really understanding anything behind what they do used by other kids that saw PHP for Dummies on a shelf somewhere.

      Every damn time I’m asked to audit PHP, there’s always something insanely wrong. The problems exist with every language I ever worked with, but PHP (and MS Visual Basic) seem to amplify the problems.

      I once had a senior PHP developer give me a blank look when I asked him why he wasted nearly a year writing and tweaking over 2k lines of validation code on shitty data stored in a database (to give an idea of the scope here, the SD was storing phone numbers as 32bit ints but unique keys as ASCII then truncating the 7 characters down to 5 before searching) Apparently the concept of uh… validating data *before* storing it seemed to have escaped him entirely.

    1. Given that the x86 architecture will attempt to execute just about any opcode, it’s not a huge stretch to get strings to execute. Probably why more and more programs and websites are incorrectly filtering emails. Easier to blindly filter emails than it is to just encapsulate and avoid executing.

  2. Amazing how hard it is to get details on what the actual vulnerability is…
    And if it’s really the diff you show here, then it’s really not as big of a deal as the fuss it’s getting. The “SMTP sender” address is usually entered by admins and not just any users. And anywhere that it was entered by users, failure to work with spaces should have been an obvious indication of a problem even without precise example of how it can be exploited, so a validation or escaping of some sort was probably added in the calling code. And anywhere that it was not added, deserves to be hacked for stupidity.

    1. These sorts of problems are most often found by sys-admins or sys-ops and if you are one of these people then you won’t make any friends by publicly releasing the details about a vulnerability before most others have patched the problem.

      Sure, on a dedicated server, the sys-admin will fill in things like sender address but 99% of websites (and SMTP servers) are shared servers today so the from address has to be under the control of the hosting account holder who is probably not as aware of the traps.

      Once a SPAMer gets a hold of a problem like this they will hammer the server resource hard and that effects all the clients on a shared server. Firstly the SMTP server will be black listed and that effects all users on a shared server and not just one hosting account. Then there is the (probably) less significant resource burdening.

      I don’t know how it is today but the ‘SPAMMer vs sys-op’ scenario played out for a decade and last I knew the latest weapon the sys-op had was SPF records attached to the DNS zone info.

  3. As usual this exploit is being oversold in this new world of security branding as people try to make names for themselves. This exploit requires the specific condition of the attacker having access to unfiltered input to the setFrom() command provided by PHP Mailer.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.