On June 19th, Wordfence Threat Intelligence team discovered a vulnerability present in Comments – wpDiscuz, a WordPress plugin installed on over 80,000 sites. This flaw gave unauthenticated attackers the ability to upload arbitrary files, including PHP files, and achieve remote code execution on a vulnerable site’s server.

We initially reached out to the plugin’s developer on June 18, 2020, and after establishing an appropriate communication channel, we provided the full disclosure details on June 19, 2020. The developers responded on June 20, 2020 to let us know a patch would be coming in version 7.0.4. After several follow-ups, an initial patch was released on July 19, 2020, and a sufficient patch was released on July 23, 2020.

This vulnerability was introduced in the plugin’s latest major version update.This is considered a critical security issue that could lead to remote code execution on a vulnerable site’s server. If you are running any version from 7.0.0 to 7.0.4 of this plugin, we highly recommend updating to the patched version, 7.0.5, immediately.

Both Wordfence Premium and free users are protected by any attacks attempting to exploit this vulnerability due to the firewall’s built-in malicious file upload protection.

Description: Arbitrary File Upload
Affected Plugin: Comments – wpDiscuz
Plugin Slug: wpdiscuz
Affected Versions: 7.0.0 – 7.0.4
CVE ID: Pending.
CVSS Score: 10.0 (CRITICAL)
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Fully Patched Version: 7.0.5

wpDiscuz is a plugin designed to create responsive comment areas on WordPress installations. It allows users to discuss topics and easily customize their comments using a rich text editor. In the latest overhaul of the plugin, versions 7.x.x, they added the ability to include image attachments in comments which are uploaded to the site and included in the comments. Unfortunately, the implementation of this feature lacked security protections creating a critical vulnerability.

The wpDiscuz comments are intended to only allow image attachments. However, due to the file mime type detection functions that were used, the file type verification could easily be bypassed, allowing unauthenticated users the ability to upload any type of file, including PHP files.

Retrieving the Mime Type

The ‘getMimeType’ function used three different methods to determine a file’s mime type. The first check used mime_content_type, which determines a file’s type based on the file’s content. If that PHP function wasn’t available, it would use finfo_file, which also determines a file’s mime type based on the file’s content. Finally, if that function wasn’t available, then it would use wp_check_filetype, which is a WordPress-specific filetype check that determines a file’s mime type based on the file’s name and matches it against a built-in list of allowed file types.

Most files begin with several so-called “Magic Bytes” which are a specific signature that can be used to determine their Mime type. Unfortunately, due to how PHP processes files, it ignores everything in the file before the opening <?php tag. As such, the first two functions used could easily allow for files to be spoofed and appear as allowed image files simply by adding image-specific magic bytes. For example, a user could insert the magic-bytes for a .png file, 89 50 4E 47 0D 0A 1A 0A, at the beginning of a PHP file and fool the first two functions.

 

foreach ($files as $file) {
  $error = false;
  $extension = pathinfo($file["name"], PATHINFO_EXTENSION);
  $mimeType = $this->getMimeType($file, $extension);
…

376
377
378
379
380
381
382
383
384
385
386
387
388
private function getMimeType($file, $extension) {
     $mimeType = "";
     if (function_exists("mime_content_type")) {
         $mimeType = mime_content_type($file["tmp_name"]);
     } elseif (function_exists("finfo_open") && function_exists("finfo_file")) {
         $finfo = finfo_open(FILEINFO_MIME_TYPE);
         $mimeType = finfo_file($finfo, $file["tmp_name"]);
     } elseif ($extension) {
         $matches = wp_check_filetype($file["name"], $this->options->content["wmuMimeTypes"]);
         $mimeType = empty($matches["type"]) ? "" : $matches["type"];
     }
     return $mimeType;
 }

Verifying Allowed File Types

The issue was escalated with the ‘isAllowedFileType’ function that did a check to see if the file was an allowed file type as it used the mime from the ‘getMimeType’ function. Due to the fact that the ‘getMimeType’ function used functions to obtain a file’s mime type based on file content, any file type could easily be spoofed to look like an allowed file type and pass this check.

private function isAllowedFileType($mimeType) {
     $isAllowed = false;
     if (!empty($this->options->content["wmuMimeTypes"]) && is_array($this->options->content["wmuMimeTypes"])) {
         $isAllowed = in_array($mimeType, $this->options->content["wmuMimeTypes"]);
     }
     return $isAllowed;
 }

The Exploit Possibilities

This made it possible for attackers to create any file type and add image identifying features to files to pass the file content verification check. A PHP file attempting to bypass this verification could look something like this in a request:

------WebKitFormBoundaryXPeRFAXCS9qPc2sB
Content-Disposition: form-data; name="wmu_files[0]"; filename="myphpfile.php"
Content-Type: application/php

‰PNG

The file path location was returned as part of the request’s response, allowing a user to easily find the file’s location and access the file it was uploaded to the server. This meant that attackers could upload arbitrary PHP files and then access those files to trigger their execution on the server, achieving remote code execution.

If exploited, this vulnerability could allow an attacker to execute commands on your server and traverse your hosting account to further infect any sites hosted in the account with malicious code. This would effectively give the attacker complete control over every site on your server.

Fortunately, both Wordfence Premium users and those still using the free version are protected against this vulnerability due to the firewall’s built-in malicious file upload protection.

Another way to stay protected.

Wordfence has a feature to disable code execution in the uploads directory. We highly recommend enabling this setting as it will provide additional protection against vulnerabilities like this one that may erroneously allow PHP files to be uploaded into the uploads directory. With this option enabled, attackers will not be able to execute PHP files uploaded into the upload directory, providing an extra layer of security and assisting in thwarting attacks like this one. In the event that a zero-day vulnerability is discovered and actively exploited prior to the creation of a custom firewall rule, having this feature enabled can help keep your site protected.

You can find this feature by going to Wordfence -> All Options -> General Wordfence Options -> ‘Disable Code Execution for Uploads directory’. Simply check the box to enable the feature and save your changes.

The ‘Disable Code Execution for Uploads directory’ option location.

Source Credit – Critical Arbitrary File Upload Vulnerability Patched in wpDiscuz Plugin

Leave a Reply

Your email address will not be published. Required fields are marked *