WP Cost Estimation and Payment Forms Builder has been Exploited. The large number of WordPress commercial plugins are creating a new attack surface on the WordPress site landscape.

Hackers are exploiting an old vulnerability in a commercial WordPress plugin to break into websites and plant backdoors.

Ongoing attacks have been first spotted at the end of last month by incident responders from Defiant, the company behind the Wordfence WordPress firewall plugin.

The vulnerability exploited in the attacks affects “WP Cost Estimation & Payment Forms Builder,” a commercial WordPress plugin for building e-commerce-centric forms that has been on sale on the CodeCanyon marketplace for the last five years.

Hackers were using the hacked site they investigated to hijack incoming traffic and redirect it to other websites. Lets not exclude the attackers abusing the backdoor for other nefarious activities later down the line.

In a report published on the Wordfence official blog, Veenstra and his colleagues broke down the technical details of the exploited vulnerability.

He said hackers were abusing an AJAX-related flaw in the plugin’s upload functionality to save files with nonsensical extensions (such as ngfndfgsdcas.tss) on targeted sites.

In a second step of the exploitation routine, the attackers would then upload a .htaccess file that associated the non-standard file extension with the site’s PHP interpreter, ensuring that when they’d later access the file, the PHP code contained within would execute and activate the backdoor.

In other cases, the attackers exploited another of the plugin’s AJAX-related functions to delete a site’s config and re-configure it to use their malicious database.

All WP Cost Estimation versions before v9.644 are vulnerable to these attacks, according to Wordfence. The good news is that the developer fixed the bug with the release of v9.644 in October 2018, after one user complained about having their site hacked.

The bad news is that the developer didn’t publicly disclose this security issue outside of a short mention in a now-buried CodeCanyon comment, leaving most of his users unaware of the danger they might be in.

According to CodeCanyon, the plugin has been purchased by more than 11,000 users. However, CodeCanyon scripts and plugins are often pirated and made available for free on hundreds of other sites online, and the number of real-world installations is much higher.

Veenstra and the Wordfence team are still looking into the size and reach of these attacks. Backdoors that perform hidden redirects are usually part of the arsenal of cyber-criminal gangs operating malicious botnets, so hacks abusing this plugin flaw might have been going on for a while, and at scale.

Commercial WordPress plugins and themes are notorious bad apples. Web security experts often recommend against buying and using one because they’re often abandoned after a few months or years.

The developer teams behind commercial plugins and themes also don’t have the means or the interest in shipping updates, as they’re usually more focused in making a one-time sale and then moving to another new plugin or theme from where they can make new money, rather than spend their time in unproductive ways such as patching bugs.

In this case, the developer of the WP Cost Estimation appeared to be a lot more reliable than the one behind the abandoned Total Donations plugin.

The Wordfence team said they also identified a second vulnerability in WP Cost Estimation, which they privately disclosed to the plugin author and he had it fixed right away.

“Commercial plugins have the ability to hook into WordPress’s plugin update feature, but they need to provide their own repository to distribute the updates. Many don’t go this route.”

“In this case, the [WP Cost Estimation] plugin properly displays an update in the dash, and the developer mentioned being able to push an automatic update.”

A piece of advice for WordPress site owners when thinking about buying commercial plugins or themes.

“As far as generic advice goes, I think the biggest litmus test is developer responsiveness. On CodeCanyon especially, if you see a developer responding constructively to questions and issues in reviews and comments, it’s a good sign that they’ll be amenable to a vulnerability disclosure and the patch process that follows.”

At the end of January, Wordfence security analysts identified attackers exploiting vulnerabilities in outdated versions of the commercial plugin WP Cost Estimation & Payment Forms Builder, or WP Cost Estimation for short. These flaws were found and patched by the developer a few months ago, but no official public disclosure was made at the time. Following this discovery, our threat intelligence team reviewed updated versions of the plugin for additional security issues. We reported an unpatched directory traversal vulnerability to the developer, Loopus Plugins, who has since released an update addressing the issue. This flaw is present in plugin versions before 9.660.

Any sites using the plugin should update it to the latest available version. Wordfence WAF users, both free and paid, are already protected from each of these vulnerabilities thanks to broad rules built into the firewall. It is still recommended that Wordfence users perform these updates to ensure their sites are as secure as possible.

In today’s post, we’ll look at the original activity that drew our analysts’ attention to the plugin, then discuss the issues our team identified and disclosed to the developer.

File Upload and Delete Vulnerabilities Exploited In The Wild (Versions < 9.644)

During a forensic review of a compromised site, a Wordfence security analyst identified logs indicating the exploit used to take over the site:

POST /wp-admin/admin-ajax.php?action=lfb_upload_form
POST /wp-admin/admin-ajax.php?action=lfb_upload_form
POST /wp-content/uploads/CostEstimationPayment/_/ngfndfgsdcas.tss

The action lfb_upload_form was traced to the installed WP Cost Estimation plugin, which allowed us to piece together what had taken place. The installed version of the plugin was outdated, and the AJAX action allowing file uploads through form submissions was exploitable.

if (strlen($value["name"]) > 4 &&
$value['size'] < 10485760 &&
strpos(strtolower($value["name"]), '.php') === false &&
strpos(strtolower($value["name"]), '.js') === false &&
strpos(strtolower($value["name"]), '.html') === false &&
strpos(strtolower($value["name"]), '.phtml') === false &&
strpos(strtolower($value["name"]), '.pl') === false &&
strpos(strtolower($value["name"]), '.py') === false &&
strpos(strtolower($value["name"]), '.jsp') === false &&
strpos(strtolower($value["name"]), '.asp') === false &&
strpos(strtolower($value["name"]), '.htm') === false &&
strpos(strtolower($value["name"]), '.shtml') === false &&
strpos(strtolower($value["name"]), '.sh') === false &&
strpos(strtolower($value["name"]), '.cgi') === false
) {

The if statement above served as the only security check on uploaded files in older versions (9.526 in this case), performing some basic filename checks in an attempt to prevent files with executable extensions from being uploaded. Generally speaking, blacklisting uploads based on their filename is not an effective means of implementing upload security, as there tend to be techniques to bypass such methods. One such bypass was used here.

In the log entries above, you may have noticed the lfb_upload_form action being fired twice. This attack involved first uploading a web shell script with a meaningless extension, “ngfndfgsdcas.tss”. While the script was a malicious PHP file, the filename did not contain the string “.php”, and bypassed the blacklist. Then, to allow the uploaded file to execute as a PHP script, the following .htaccess file was uploaded:

AddHandler application/x-httpd-php .tss
AddType application/x-httpd-php .tss

These .htaccess rules associated the “.tss” extension with the PHP handler, allowing the shell to run as a PHP script. As of version 9.644 of WP Cost Estimation, released in October 2018, it is no longer possible to upload a valid .htaccess file to perform this bypass.

Interestingly, despite the attackers’ successful uploads, they quickly followed up with a different exploit against the same plugin. It’s unknown why this second exploit was performed, though it’s our assumption that either the uploaded shell or .htaccess file failed to behave as intended, leaving the attackers to go to Plan B.

In this second attack we see a new AJAX action from WP Cost Estimation, followed by a familiar attack pattern:

POST /wp-admin/admin-ajax.php?action=lfb_removeFile
POST /wp-admin/setup-config.php?step=2
POST /wp-admin/install.php?step=2
GET /wp-login.php
POST /wp-login.php
GET /wp-admin/
GET /wp-admin/theme-install.php?upload
POST /wp-admin/update.php?action=upload-theme
GET /wp-content/themes/AdvanceImage5/config.php

The exploited AJAX action, lfb_removeFile, can be used to delete arbitrary files on a vulnerable site:

public function removeFile(){
$formSession = sanitize_text_field($_POST['formSession']);
$file = sanitize_text_field($_POST['file']);
$fileName = $formSession . '_' . $file;
if(file_exists($this->uploads_dir .$fileName)){
unlink($this->uploads_dir .$fileName);
}
die();
}

The workflow for exploiting an arbitrary file delete flaw is usually the same: Delete the vulnerable site’s wp-config.php file. With no database configuration, WordPress assumes a fresh install is taking place. The attacker is then free to connect the site to their own remote database, log in as an administrator, and upload backdoors through the dashboard.

The lfb_removeFile AJAX action (as well as the associated internal removeFile function shown above) were both removed when the developer became aware of exploits and released version 9.644.

New Vulnerability – Upload Directory Traversal

Following the discovery of the earlier patched vulnerabilities, we spent some time reviewing the patches themselves to ensure they were sufficient. In the version we tested, the uploader had been improved in a few ways:

  • The blacklist of disallowed strings in filenames was expanded to block .htaccess uploads.
  • An admin-controlled whitelist of allowed filetypes was added, by default only allowing PNG, JPG, GIF, RAR, and ZIP files.
  • Forms could now have an internal randomSeed value, a short alphanumeric string appended to the user-input upload path in order to prevent existing directories from being accessed.

However, our investigation revealed a bypass case, allowing attackers to overwrite any file with a whitelisted type on an affected site.

$ext = $this->get_extension($value["name"]);
$allowedFiles = explode(",", $item->allowedFiles);
if (in_array('.' . strtolower($ext), $allowedFiles)) {
if (!is_dir($this->uploads_dir . $formSession . $form->randomSeed)) {
mkdir($this->uploads_dir . $formSession . $form->randomSeed);
chmod($this->uploads_dir . $formSession . $form->randomSeed, $this->chmodWrite);
}
move_uploaded_file($value["tmp_name"], $this->uploads_dir . $formSession . $form->randomSeed . '/' . $fileName);
chmod($this->uploads_dir . $formSession . $form->randomSeed . '/' . $fileName, 0644);
}

The code block above, taken from the patched version of the uploadFormFiles function, shows the $formSession and $form->randomSeed variables used in a number of places to define an upload path for a given file.

The intent of this behavior is for each visitor to a site to be given a unique $formSession value as a hidden field in each form, so files they upload can be grouped appropriately in directories. However, this value is ultimately user-supplied when the form is submitted, and is susceptible to directory traversal attacks. For example, submitting a $formSession value like ../../.. would place the uploaded file in the document root of a site, rather than in wp-content/uploads/CostEstimationPayment as intended.

This vulnerability is mitigated in part by the addition of the randomSeed value, which would break most directory traversal attempts by appending a random alphanumeric string following the $formSessioninput. Uploads could still be made to unintended directories, but it would prevent existing files from being overwritten.

Unfortunately, only forms created in the patched version would have an associated randomSeed value stored in the database. Forms which existed prior to the patch, which would certainly be the case for the majority of users, had an empty randomSeed value. This empty value does nothing when appended to the $formSession path, which leaves these forms vulnerable.

Even with a whitelist only allowing images and archives to be uploaded, an attacker could cause serious trouble with an exploit. Any image on a site could be overwritten, allowing defacement campaigns to replace them en masse. If any backups are kept in an accessible location in a zip archive, an attacker could replace this backup with their own poisoned version, containing new users in the database or backdoors buried elsewhere in the file structure. When the backup is restored (perhaps following a mysterious case of overwritten images), these backdoors would be deployed.

Coordinated Disclosure

Once we became aware of the remaining issues, we contacted the developer to begin the process of patching them. We quickly received a response from Charly Biscay of Loopus Plugins. Vendor responses to vulnerability disclosures can be unpredictable, if a response comes at all, but Charly was happy to be notified and worked closely with us through the process of developing a patch.

For this patch, we made three recommendations which were all implemented:

  1. Reject any $formSession containing any non-alphanumeric characters.
  2. Generate new randomSeed values for forms where a value is not present.
  3. Implement .htaccess restrictions in upload directories, so scripts are inaccessible in the event that a successful upload takes place.

The timeline of the discovery, disclosure, and patching of this flaw is as follows:

2019-01-26: Upload directory traversal vulnerability discovered. Vendor contacted through form on CodeCanyon profile.
2019-01-28: Received response from vendor. Continued correspondence via email. Informed vendor of specific issues in WP Cost Estimation plugin.
2019-01-31: Patched version of WP Cost Estimation plugin released on CodeCanyon.

Next Steps

As usual, updating to the latest version of WP Cost Estimation should be made a priority. If your site has been running a vulnerable version of the plugin and you believe your site may have been compromised, consider working with our team on a security audit.

Some good news, sites making use of the Wordfence Firewall are in the clear. Exploits against each vulnerability described in this post are blocked by broad rules which were already built into the WAF, so free users don’t even need to wait. Still, even as a Wordfence user, we recommend performing all available plugin and theme updates to ensure the security of your site.

Conclusion

To recap, our team identified attacks against outdated versions of the WP Cost Estimation & Payment Forms Builder plugin for WordPress. After review, we identified additional flaws and reported these to the developer who quickly released a patch. We recommend all users of this plugin update to the latest version as soon as possible.

Credits: Initial attack data discovered by Security Analyst Nate Smith. Vulnerability assessment and vendor correspondence by Threat Analyst Mikey Veenstra. Thanks to Charly Biscay of Loopus Plugins for the cooperation and quick patch release.


Related Links:

How do I create money online using WordPress?

Using the Current Year in Your Posts – WordPress

WordPress by the Numbers Facts

Chrome warns you if your username or passwords have been hacked

Should I Choose a Hosted or Non-hosted Blogging Platform?

Protect Your Site from Malicious Requests

How much does it cost to build a WordPress website?

How do I install plugins in WordPress?

How to Fix ERR_TOO_MANY_REDIRECTS on Your WordPress Site

Googles John Mueller on Best Site Structure

Context in Outbound Links for High Ranking SEO