Backdoor Masquerading as Legitimate Plugin

As part of our product lineup, we offer security monitoring and malware removal services to our Wordfence Care and Response customers. In the event of a security incident, our incident response team will investigate the root cause, find and remove malware from your site, and help with other complications that may arise as a result of an infection. During the cleanup, malware samples are added to our Threat Intelligence database, which contains over 3.65 million unique malicious samples. Our recently launched Wordfence CLI scanner detects 99% of these samples and indicators of compromise, when using the commercial signature set, and can scan your site even if WordPress is no longer functional.

Today, we would like to share a type of malware that serves as a sophisticated backdoor capable of performing a variety of tasks while masquerading as a real plugin. Complete with a professional looking opening comment implying it is a caching plugin, this rogue code contains numerous functions, adds filters to prevent itself from being included in the list of activated plugins, and has pinging functionality that allows a malicious actor to check if the script is still operational, as well as file modification capabilities. Additionally, it offers the ability to create an admin account, and remotely activate and deactivate plugins.

The sample was discovered during a site clean by one of our analysts on July 18, 2023. A signature was developed by the same analyst the following day and released to production within two weeks after undergoing testing. Customers still using the free version of Wordfence received this signature after a 30 day delay on September 1, 2023.

Our Premium, Care, and Response users are protected against the use of this backdoor via a firewall rule as of October 9, 2023.

Analyzing the Sample

Due to the malware file being rather large in size, we can’t display the entire sample here and will focus on a few key parts instead.

Malicious User Creation

Malicious user creation function (password redacted)

Since the malicious file runs as a plugin within the context of WordPress, it does have access to normal WordPress functionality just like other plugins do. The code above utilizes the wp_create_user function to create a new user account with the username superadmin and a hardcoded password, which we redacted to prevent abuse. The role of this user is set to administrator before displaying a short message via the _pln_json_die function to indicate that the task was performed successfully.

The following function, _pln_cmd_hide is intended to remove the superadmin account when it is no longer needed. This function is likely present for the attacker to remove traces and reduce the chances of detection once the victim has been successfully compromised.

Malicious user deletion function

Malicious user deletion function

While often seen in test code, user creation with hardcoded passwords should be considered a red flag, and the elevation of this user to an administrator is certainly reason enough for suspicion.

Bot Detection

Bot detection function

Bot detection code is often encountered in malware that serves normal content to some users while redirecting or presenting malicious content to other types of users. One common thread shared by these infection scenarios is that site owners find their site looks fine to them but their visitors have reported issues such as seeing spam or being redirected to dubious sites.

Others report that their site looks and behaves completely normally but only shows spam content when visiting from a search engine. Since this kind of malware wants search engines to find the malicious content, it is usually served to them as they index a site. Using keyword stuffing helps increase traffic sent to infected sites. Administrators often report a sudden, unexpected surge in site traffic when their sites are hit by an infection.

While the presence of bot detection code is not enough on its own to classify such a sample as malicious, it certainly is one of the factors that stands out in this piece of malware.

Content Replacement

The plugin adds several filters. Two of them are shown below:

add_filter( 'the_content', 'get_plugin_content', 9999999, 2 );
add_filter( 'the_page_content', 'get_plugin_content');

When WordPress renders post and page content, the get_plugin_content function provided by the malware is invoked. This type of hook is often used to append disclaimers to posts or pages, manipulate excerpt lengths or inject other desired content into the post or page.

Content replacement function

The above content replacement function performs an initial check to see if the currently logged in user is an administrator. If so, they will be shown the normal content. The filter is set to run as late as possible to override other filters, hence the priority of 9999999. Some other conditions are also checked to determine whether unmodified site content is to be served. If the malware determines that these conditions are not met, malicious content is assembled and displayed. Several other functions are invoked to insert spam links/buttons.

Plugin Activation and Deactivation

As mentioned above, the malware makes use of some WordPress functionality such as content filtering when running as a plugin. However, it also provides some remote control functionality that does not rely on it being activated. Instead, in some cases, it just simply includes the relevant files needed for the code to run successfully in the WordPress environment.

Plugin activation/deactivation code

The code above can be used to activate and deactivate arbitrary plugins remotely. This is useful to disable unwanted plugins and also to activate this malicious plugin as needed. The malware contains other cleanup functions that allow it to remove malicious content from the database in addition to the admin user deletion we already discussed.

Remote Invocation

The following code is used to enable the malicious features of this backdoor:

Entry point

The _pln_is_colonel function checks for the presence of a particular user agent string that is needed in order to control features of this backdoor. If the parameter is present, several $_REQUEST parameters will be checked and, if set, their corresponding functions are executed.

Taken together, these features provide attackers with everything they need to remotely control and monetize a victim site, at the expense of the site’s own SEO rankings and user privacy.

Conclusion

In today’s post we presented a backdoor, with features that allow it to work as a standalone script and as a plugin. Remote plugin activation and admin user creation and deletion as well as conditional content filtering allow this backdoor to evade easy detection by the inexperienced user.

Our Premium, Care, and Response users are protected by our malware scanner during file uploads against the upload of this sample as well as many of its variants, and are also protected by our layered approach which uses several other rules that also protect our free users. This means that Wordfence will block any attempts by attackers to compromise a WordPress site by uploading this file. Properly configured scans running on sites with Wordfence Premium, Wordfence Care, and Wordfence Response will also detect this sample in the unlikely event it is uploaded to a site during an infection.

Users of a paid-tier of Wordfence CLI, with access to the commercial signature set, will also have detection for this malware, while users on the free version of Wordfence CLI will not.

It’s important to remember that detection of a compromise is just as important to security as ensuring your site remains protected. By using the Wordfence plugin, and ensuring it has been optimally configured along with following security best practices, you’re ensuring your site remains as protected as possible. Nothing can ever be 100% secure, and risk can never fully be mitigated, so it’s important to have monitoring on your site in the event your site is still compromised despite following all best practices. The Wordfence scanner will alert you to any infections so you can initiate an incident response, and also block malicious malware uploads in the event an attacker gets past a site’s first line of defense.

If you believe that your site might be infected, you can enlist the help of our Incident Response team by purchasing our Care, or Response offering or follow this guide to remove the infection yourself.

If you have a malware sample that was missed during a Wordfence scan, please let us know by sending the sample to us at samples@wordfence.com.

Did you enjoy this post? Share it!

Comments

10 Comments
  • Thanks for this. Free "nulled" themes with malicious code have been an issue for many years, and the same applies to plugins.
    Could you perhaps let us know what the name of the malicious plugin is, or explain why you have decided not to name it?

    • While a nulled plugin is a plugin that is slightly modified (maliciously) from its original, this "plugin" was exclusively malicious code that contained a comment block at the top of the file implying it was a caching plugin. It has no resemblance to an actual plugin you would want to install on your site, which is why we decided not to reveal the name of the singleton file. Our experience is that these comment blocks are often just randomly added to malware to make them look like legitimate plugins. So we didn't omit this information for nefarious reasons, but simply because it should not be relied upon as a sole indicator of compromise.

      However, given the confusion this has caused, the file name was WPCache.php when we discovered it during a site clean. We have seen this exact same file with the name wp-seo-conf.php as well. In other words, file names are not the best indicator of maliciousness in this case. Other variants may exist that use an entirely different name and/or different copied comment block. The comment block we have seen implied that this malicious file was part of the WPCache plugin. To be clear, it was neither part of that plugin nor was it added to the plugin. It was simply a case of a malicious actor adding a comment block from a popular plugin to a malicious file to make it look legitimate.

      Please do not look for files with the above names and delete them thinking they are malware. Instead, inspect them and see if they contain functions that look like our screenshots. You would be likely to find this in the plugins directory of your site.

  • Am I missing something, or did you not mention the name this plugin? Was that by accident or by intention?

    Thanks for keeping WordPress a viable, cost-effective website platform!

    • You will find the answer to this question in a reply to an earlier comment.

  • What is the point if you don't tell what the plugin is?

    • You will find the answer to this question in a reply to an earlier comment.

  • So... what's the name of the "plugin" ?

  • "You will find the answer to this question in a reply to an earlier comment."

    I cannot find ! can you tell us where is the name of this plugim ?

    • Hi Nova,

      Malicious plugins typically contain code that removes them from the plugin listing on your site and are not found on the WordPress.org plugins repository. This means that the only way to actually see them is in the filesystem or database, where they use the plugin filename, which can be anything the attacker wants it to be.

  • Just a friendly reminder that any abusive comments will be sent directly to spam