The research team at Alert Logic is constantly scouring the internet and our own internal data to identify and cover the most critical and impactful threats for our customers. As part of our deep technical analysis of these threats, we can uncover entirely new vulnerabilities. As part of our work on coverage for a vulnerability in the WP Live chat plugin for WordPress we uncovered a bypass in the latest version of the software which would allow an attacker to upload arbitrary malicious files to vulnerable systems. Following our responsible disclosure policy, we reported the issue to the vendor and Mitre (CVE-2019-11185), and have worked with them to release a patch and raise the bar for security for all users of the software. The vendor in question is commended for being responsive and open to resolving the bug quickly.
Wp Live Chat Pro
Through our proactive research process, we discovered that the WP Live Chat Support Pro (https://wp-livechat.com/) plugin for WordPress contained an arbitrary file upload vulnerability in version v8.0.11 of the plugin. The plugins upload functionality was previously identified as being vulnerable in v8.0.06, as described by CVE-2018-12426, and believed to have been resolved in the following version of the plugin. The implemented protections as part of the patch for CVE-2018-12426 did not fully resolve the issue and the plugin remained vulnerable to unauthenticated arbitrary file uploads. The bypass was achieved using a non-blacklisted executable file extension in conjunction with a whitelisted file extension, and prepending ‘magic bytes’ to the payload to pass MIME checks. Note that we had not seen attackers attempt this specific bypass in our customer data, and do not believe that it was being actively exploited.
The root cause of the upload vulnerability was a flaw in the validation logic while processing the uploaded file. This is a common issue when developers implement bespoke upload functionality instead of using built-in WordPress functionality.
The above code defines the function called as a result of requests submitted to the the WP Live Chat Support plugins ‘remote_upload’ REST endpoint. The plugin leverages the ‘apply_filters’ functionality built into WordPress to hook functionality provided by the ‘Pro’ version of the plugin. If the WordPress site does not have the ‘WP Live Chat Support Pro’ plugin installed as a companion, the request will simply result in a 200-response containing the ‘$return_array’ value of ‘false’.
The upload function logic can be summarized, from the perspective of an attacker, as follows:
- Grab request parameters
- Extract the filename as a lowercase string
- Validate the filename using a blacklist ‘wplc_pro_check_file_name_for_unsafe_extensions’
- Validate the filename using a whitelist ‘wplc_pro_check_file_name_for_safe_extension’
- Move the file to the upload directory
- Validate the files MIME type using ‘wplc_pro_check_file_mime_type’
- Remove file if MIME type is ‘unsafe’ or return the path to the uploaded file if deemed ‘safe’
If the uploaded file fails any of the validation steps, a suitable error response is returned. Each of these validation steps can now be investigated and bypassed in turn, providing an attacker with the means to get malicious code onto the server despite the various validations in place.
Blacklist & Whitelist Bypass
The function used to validate safe extensions is fairly straight forward. An array of disallowed file extensions is created, and the submitted filename is converted to lowercase. A ‘foreach’ loop then calls the ‘strpos()’ PHP function using the filename and each extension. The function finds the position of the first occurrence of the substring in a string, in the case of a blacklist this is beneficial as it eliminates the ability to abuse multiple file extensions on servers that are vulnerable to such attacks.
It is worth noting that ‘.php’ is present within the list of disallowed extension, the public exploit code associated with CVE-2018-12426 demonstrates the uploading of a PHP file with an image set as the content-type.
Unfortunately, as with all blacklists, the code must reference every possibly dangerous file extension in order to be effective. If even one extension is missed, then a bypass exists. In this case a ‘.phtml’ extension will bypass this stage of validation. The ‘.phtml’ extension appears to have been intended as a means of differentiating files that contain both PHP and HTML templating from those that are purely PHP. Regardless, from the perspective or the parser it is no different from a normal PHP file, and as such will execute the contained code.
Having successfully bypassed the blacklist validation, the filename is now passed to the whitelist function where a matching ‘good’ file extension must exist within the filename to pass validation. However the code as implemented confirms only that a ‘good’ extension exists ANYWHERE in the filename. This allows that a ‘.gif.phtml’ file is now deemed acceptable by both the blacklist and whitelist functions. All that remains between the attacker and a successful exploit is a MIME type check.
MIME validation relies upon either the ‘mime_content_type’ or ‘finfo::file’ functions, both of which rely upon ‘magic numbers’ or ‘magic bytes’ to identify a files MIME type. The ‘magic numbers’ or ‘magic bytes’ are a series of bytes which identify a file’s format, typically located at the beginning of a file. The ‘.gif’ image format will start with the byte sequence ‘47 49 46 38 37 61’ or ‘47 49 46 38 39 61’ which appear in ASCII as ‘GIF87a’ and ‘GIF89a’ respectively. These magic bytes are useful in that they are entirely printable ASCII and can be directly inserted before the payloads opening PHP tags. Therefore, the MIME evaluation functions will read the initial bytes of the file, find the magic bytes for a ‘.gif’ image and return the ‘image/gif’ MIME type.
The returned MIME type is naturally an allowed type and the file is left undisturbed in the upload directory. The file has now been successfully uploaded to the server and the path is returned, informing the submitter as to exactly what URI to request to execute the payload.
Remediation and Mitigation
The primary resolution of this vulnerability is to update the plugin to the latest version. If this cannot be achieved, then mitigation options may include:
- Virtual patching using a WAF to filter traffic destined for the WP Live Chat Support ‘remote_upload’ REST endpoint
- Remove write permissions on the ‘wp-content/uploads/wp_live_chat/’ directory
|Initial contact with vendor||April 5, 2019|
|Vulnerability disclosed to vendor||April 8, 2019|
|Vendor accepts vulnerability. Begins working on patch||April 10, 2019|
|Submit to NVD. CVE assigned||April 11, 2019|
|New version released. Confirmed no longer vulnerable||April 12, 2019|
|Responsible Disclosure embargo lifted||April 26, 2019|
About Alert Logic Threat Research
Alert Logic routinely tracks emerging vulnerabilities and active use of new exploits in the wild. This allows us to keep up with the latest tools, techniques, and practices of attackers and provide protection for our customers for their most critical threats.