Recently, security researcher Dawid Golunski released an advisory describing a remote code execution vulnerability in the core of WordPress version 4.6 affecting the PHPMailer library. The vulnerability was published under CVE-2016-10033 and could be used by unauthenticated remote attackers against servers running WordPress with default web server configurations. In this post, we will summarize this advisory and explain the technical aspects of the vulnerability. To start, here is a short video of the exploit being executed by the researcher.
According to the WordPress Foundation, more than 40% of WordPress installations are still using versions 4.6 or older and could be vulnerable to this attack. If you are using WordPress, you should make sure to update to the latest version (4.8 at this time) as soon as possible!
On February 1st, 2017, Sucuri Security disclosed a 0-day vulnerability in WordPress. If you are running WordPress version 4.7.0 which was released on December 6, 2016, or 4.7.1 which was released on January 11th, 2017, you should stop reading and go update immediately!
The disclosure describes the privilege escalation vulnerability which was found in the core of WordPress, affecting the newly updated feature: the REST API. This vulnerability could allow anyone to modify any post or page on a WordPress site without even being authenticated! Pretty scary, right? Good thing this issue was found by security researchers!
They responsibly disclosed the flaw to WordPress Security on January 20th and they fixed it right away, making a silent patch on version 4.7.2, which was released on January 26th, 2017, and protecting anyone who performs automatic updates on their sites. The WordPress Security Team has also reached out to several companies with WAF products including SiteLock, Cloudflare, and Incapsula to help them create rules in their tools to protect their customers and make sure no harm would be done until the fix was released. After that, WordPress hosting providers were alerted about this issue, how the vulnerability worked and how to protect their customers’ sites.
This vulnerability affects the WordPress Rest API. According to the security researcher who discovered the vulnerability, one of these REST endpoints (WP_REST_Posts_Controller) allows anyone to access to view, edit, delete and create posts via the API. The REST API was added and enabled by default on version 4.7.0, leaving versions 4.7.0 and 4.7.1 vulnerable to this flaw!
The flaw in the WordPress REST API works due to a “feature” in PHP, also present in some other languages, called type juggling. It allows the developer to silently change the values of one type to another. Since PHP doesn’t require explicit type definition in a variable declaration, that feature is permitted. What does that mean? It means that when comparing a string to a number, PHP will attempt to convert the string to a number then perform a numeric comparison. If you are comparing a string like “123CODEGUARD” to an integer variable, only the numbers will be used for the comparison operation. Watch the examples below:
The problem is that PHP has two comparison modes: loose and strict. Loose comparisons have a set of operand conversion rules to make it easier for programmers, unfortunately even PHP developers admit that “[it] may not be obvious exactly what will happen when casting between certain types.” Although PHP type-juggling bugs are very common, they are difficult to exploit because you are usually not able to input typed data over HTTP. Unfortunately, that was not the case with the WordPress REST API.
WordPress REST API Code
Let’s go back to the WordPress code now. More specifically the code inside /wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php file, where they found the input validation issue in the update_item function. In this function, the input validation issue that could allow a privilege escalation by a malicious user is the first line of code where they are type-casting the ID from the request to the $id variable. According to this, it would be possible to submit a request to the REST API like /wp-json/wp/v2/posts/123?id=999STRING, which would result in the id variable being set to 999.
Function update_item in class-wp-rest-posts-controller.php file – WordPress 4.7.1
The WordPress Team fixed this in version 4.7.2 by ensuring that the id input is not coerced and is validated prior to proceeding:
Fixed function update_item in class-wp-rest-posts-controller.php file – WordPress 4.7.2
PoC in the wild
As you can imagine since the disclosure of this flaw there are already exploits in the wild being used to target this problem. A video was made and uploaded to Youtube explaining how it the vulnerability works and how to exploit it. You can watch it here:
Some security researchers also published a few Proof of Concept (PoC) tests to check if your site is vulnerable. Here is one from Larry Cashdollar, who works at Akamai:
This is the second part of our exploration MulCiShell Backdoor and File Uploader, a malicious PHP Web Shell that was detected on a customer’s website using CodeGuard’s MalwareGone tool. If you haven’t already, take a look at Part I before continuing. In this post, we’ll wrap things up by discussing the vulnerabilities that were found on this site, which may have allowed the MulCiShell Backdoor and File Uploader to be inserted. To pick up where we left off before, here is a list of installed WordPress plugins installed on the hijacked site:
For this installment, we’ll talk about a webshell called “MulCiShell”, more specifically the “MulCiShell v0.2” backdoor file, which is a PHP Web Shell that we found in another client’s website using CodeGuard’s MalwareGone tool. Here is a snippet of code for this webshell:
Doing a little bit of research we found that the first versions of this webshell dates back to 2009, which is really old for malware like this, but it seems that the developer of this backdoor has been maintaining it as it keeps getting updated with new capabilities and enhancements. As we can see this webshell has many functions and there’s even a changelog in the comment at the top of the file. This specific version was last updated by someone nicknamed KingDefacer.
This is a critical vulnerability. If this is the first you are hearing about it and you manage a Drupal website, I would highly recommend that you go read the Drupal PSA and follow the instructions there before doing anything else.
Google just changed their ranking algorithm to give a boost to sites that use https instead of http. Even if you have a content site or a personal website, it makes sense to take all reasonable measures to secure it from hacking, especially when Google could give your site more traffic.
The easiest way to get https is to use a paid CloudFlare account and turn on Flex HTTPS. This avoids the need to buy and install a security certificate, saving money overall. CloudFlare also helps protect your site from malicious bots, hackers, and denial of service attacks.
To configure CloudFlare for HTTPS, login, click the gear icon next to your site, and choose “CloudFlare settings”. Then set the SSL switch to Flexible SSL. This encrypts communications between CloudFlare and users. CloudFlare still communicates with your web server via http, eliminating the need to make changes there. Most man-in-the-middle attacks happen close to where the user connects, such as an un-encrypted WiFi network vulnerable to Firesheep, or a hotel network that splices ads into web pages, not between major Internet services such as CloudFlare and your hosting provider.
After making the switch its necessary to test the site to make sure you get good lock symbols on all pages. If you have embedded assets using non-secure http protocol, you need to update those to https. Search the code for the string src=”http: to find them.
Green Lock Means Secure
To redirect http to https when using CloudFlare, add the following magic code to your .htaccess file, if you have a Linux/Unix server.