Cybercrime

From malware and botnets to the latest cybercriminal schemes, check out what today’s black hat hackers are up to.

Blog > Cybercrime > Anatomy of Locky and Zepto Ransomware

Anatomy of Locky and Zepto Ransomware

Cybercrime

The criminals behind the notorious Locky and Zepto ransomware spam campaigns continue to shift tactics in an effort to circumvent anti-virus detection. Recently, the cybercriminal syndicate has been leveraging obfuscated Windows Script Files (.wsf) and HTML Applications (.hta) inside a zip archive. Such files allow JScript, VBScript, and other scripting languages to execute. By using such file formats as loaders, threat actors are essentially able to repackage their existing JScript code into a .wsf and .hta containers.

Key Findings

 

  • Locky and Zepto ransomware gangs utilize .wsf and.hta to distribute its payloads via spam phishing email.

 

  • Such loaders provide a relatively simple way to obtain indicators of compromise (IOCs) by extracting payload names, XOR keys, padding words, and payload URIs.

 

  • .wsf and .hta loaders remain popular means to spread ransomware amongst various cybercriminals.

 

  • Restricting program execution of .dll files from %TEMP% directory, disabling Windows Script Host, and filtering zip, wsf, and hta attachments at Mail Gateways using Yara ruleset might assist corporations with mitigating the exposure to the Locky and Zepto ransomware email spam campaigns.

 

Image 1: The phishing email with the zip attachment and subject “bank account report” is a typical lure used by the Locky and Zepto gang to entice individuals to open and launch malicious attachments with ransomware loaders (Source: Threattrack)

Image 1: The phishing email with the zip attachment and subject “bank account report” is a typical lure used by the Locky and Zepto gang to entice individuals to open and launch malicious attachments with ransomware loaders (Source: Threattrack)

While investigating a wave of malicious Windows Script File (wsf) and HTML Application (hta) loaders, Flashpoint analyzed those that were used to spread Locky and Zepto ransomware via mass email spam campaigns. In this instance, this same cybercriminal syndicate uses multiple methods to avoid antivirus detection when distributing its .wsf and .hta loaders (as JScript) from the .zip attachments – including, but not limited to, padding phrases injections into Base64 obfuscation, string slicing, and XOR shifting, among other techniques. The goal of this blog post is to dissect Locky and Zepto loaders and provide a quick guide on how to extract indicators of compromise (IOCs) from such loaders.

Image 2: This graph illustrates the frequency of chatter related to hta and wsf loaders identified on various underground communities.

Image 2: This graph illustrates the frequency of chatter related to .hta and .wsf loaders identified on various underground communities.

 In this post, we examine the following three intercepted ransomware loaders (MD5):

1. e629c89718141f11bf06f8a87531c960

2. a20a9443a8411d30216dbdea8a571e31

3. 2e3d6db1af3d1a4854b1032787389d7e

 

The Locky .wsf and hta loaders work as a JSCRIPT payload with the following algorithm:

1. Downloads ransomware binaries from third-party websites masked as Dynamic Library Link (DLL) files in %TEMP%;

2. Executes the following command:

WScript.CreateObject(“WScript.Shell”)[“Run”](“rundll32.exe ” + new ActiveXObject(“Scripting.FileSystemObject”).GetFile(MTm6.ExpandEnvironmentStrings(“%TEMP%/[a-zA-Z]{10,11}.dll + “,qwerty”) 

 

Relevant loader obfuscation techniques

 

1. Loaders use a padding phrase such as “LICIZAX,” “LIVEFAN,” “ROYALSRU” to mix inside the function’s Base64 values in order to obfuscate Base64 decoding routines.

2. Deobfuscated loaders reveal the XOR function in the Base64 section of the payload, which is later decoded using the XOR key:

Image 3: The Base64 deobfuscated section of the payload reveals the Array function.

Image 3: The Base64 deobfuscated section of the payload reveals the Array function.

3. Some function replaces the padding word with an empty string and converts Base64 to ASCII. Knowing the regular expression on the padding word, the process is rather simple. The rest of the expression is easy convertible:

<– var sambadiganeiroLLutan_a5 = [“Z29zeXVpbm1lZ3VyaS53ZWIuZmMyLmNvbS9uYjIwZ2pCVgPADDING==”,”ZnJlZWRvbTAwMDEud2ViLmZjMi5jb20vbmIPADDINGyMGdqQlY=”,”U2V3YXJ0ZS5ob21lcGFnZS50LW9ubGluZS5kPADDINGZS9uYjIwZ2pCVg==”];
–> var sambadiganeiroLLutan_a5 = [“gosyuinmeguri[.]web[.]fc2[.]com/nb20gjBV”, “freedom0001[.]web[.]fc2[.]com/nb20gjBV”, “Sewarte[.]homepage[.]t-online[.]de/nb20gjBV”]
–> var temp29 = “hxxp://gosyuinmeguri[.]web[.]fc2[.]com/nb20gjBV?ErOetvebz=psAHagR”

4. Function and variable names are replaced with random strings:

function load_file(…){…} –> function xyFG7(…){…}
var myList = [“hxxp://malwa[.]re”, …] –> var pdKM23 = […]

5. Attribute references are changed to array lookups:

pdKM23.length –> pdKM23[“length”]

6. Decompose string constants into a concatenation of shorter strings:

pdKM23[“length”] –>
var OP21 = “ngt”;
var jd4 = “le”;
var aSDf = “h”;
pdKM23[jd4 + OP21 + aSDf]

 

How to Extract IOCs From Locky and Zepto Loaders

 

Essentially, we will focus on the instruction set just below the eval() function:

Image 4: The variables below eval() reveal XOR key, payload name, and payload URI.

Image 4: The variables below eval() reveal XOR key, payload name, and payload URI.

1.Payload Name is the first string value as .dll file. In this case, we have the payload name as NqmXYsBdh.dll saved and launched from %TEMP%

2. XOR Key represents the second variable part of the argument that is used to XOR Base64 blob of the payload. For example, we have the following XOR key:

b6vYxEjsTYwJ7mIrZz4WFSGHeaddkwbq.

3. Padding word is identified in the beginning of the script by locating the “this.replace” call. The string value would be used as a padding word to frustrate Base64 conversion later in the loader calls. The padding word is LICIZAX.

Image 5: The padding word is found at the beginning of the loader script.

Image 5: The padding word is found at the beginning of the loader script.

4. In order to obtain Locky and Zepto payload URI is to necessary to remove padding words from strings, decode them using Base64, and concatenate them with the query string. In this case, the payload URI are as follows:

  • goldenladywedding[.]com/vdG76VUY76rjnu?CHhjpz=zhXHhhwS
  • livewebsol[.]com/vdG76VUY76rjnu?CHhjpz=zhXHhhwS
  • www[.]jmetalloysllp.com/vdG76VUY76rjnu?CHhjpz=zhXHhhwS

 

 

Indicators of Compromise (IOCs): Locky and Zepto Loader

 

Loaders (MD5):

  • e629c89718141f11bf06f8a87531c960
  • a20a9443a8411d30216dbdea8a571e31
  • 2e3d6db1af3d1a4854b1032787389d7e

 

Payload Names:

  • KmqGmNc.dll
  • sNzSjRqUUNr.dll
  • jMDarI.dll

 

Payload URLs:

  • goldenladywedding[.]com/vdG76VUY76rjnu?CHhjpz=zhXHhhwS
  • livewebsol[.]com/vdG76VUY76rjnu?CHhjpz=zhXHhhwS
  • www[.]jmetalloysllp[.]com/vdG76VUY76rjnu?CHhjpz=zhXHhhwS
  • hxxp://nihilismus[.]web[.]fc2[.]com/987nkjh8?qCRBHxTJPOz=sEeqwHr
  • hxxp://nstanflorin10[.]go[.]ro/987nkjh8?qCRBHxTJPOz=sEeqwHr
  • hxxp://nihilismus[.]web[.]fc2[.]com/987nkjh8?qCRBHxTJPOz=sEeqwHr
  • hxxp://treasure-force[.]com/87b3ff3rc?zmAppzCb=jqjkjJabc
  • hxxp://quietvain[.]nobody[.]jp/87b3ff3rc?zmAppzCb=jqjkjJabc
  • hxxp://miyufortuneteller[.]web[.]fc2[.]com/87b3ff3rc?zmAppzCb=jqjkjJabc
  • hxxp://maxshoppppsr[.]biz/js/87b3ff3rc?zmAppzCb=jqjkjJabc

 

XOR Keys:

  • PMicq3D4YIXya413yoi4FI1GT4FYMmxf
  • 6o3GGQVYZLVOXy4hSjmJkeBF6T0Cm5Xh
  • 4ptDnDNgVpg2LpwcuWF84V2KZSnvIliK

 

Yara Ruleset:

rule crime_win32_wsf_definition {
meta:
author = “Flashpoint”
strings:
$string1 = “<?xml?>” nocase
$string2 = “JSCRIPT” nocase
$string3 = “package” nocase
condition:
$string1 and #string2 >= 2 and $string3
}

rule crime_win32_locky_wsf {
meta:
author = “Flashpoint”
strings:
$padding1 = “LICIZAX” nocase
$padding2 = “LIVEFAN” nocase
$padding3 = “ROYALSRU” nocase
$re1 = “.replace” nocase
$re2 = “String.fromCharCode” nocase
$xor_key1 = “b6vYxEjsTYwJ7mIrZz4WFSGHeaddkwbq” nocase
$xor_key2 = “6o3GGQVYZLVOXy4hSjmJkeBF6T0Cm5Xh” nocase
$xor_key3 = “4ptDnDNgVpg2LpwcuWF84V2KZSnvIliK” nocase
condition:
crime_win32_wsf_definition and (1 of ($padding*) and 1 of ($xor_key*)) or all of ($re*)
}

rule crime_win32_locky_hta
{
meta:
author = “Flashpoint”
strings:
$string1 = “function”
$string2 = “var “
$string3 = “while”
$string4 = “if “
$string5 = “if(“
$string5 = “break”
$string6 = “do “

condition:
all of them
}

Related Posts

About the author: Vitali Kremez

Vitali Kremez is a Director of Research at Flashpoint. He oversees analyst collection efforts and leads a technical team that specializes in researching and investigating complex cyber attacks, network intrusions, data breaches, and hacking incidents. Vitali is a strong believer in responsible disclosure and has helped enterprises and government agencies deliver indictments of many high-profile investigations involving data breaches, network intrusions, ransomware, computer hacking, intellectual property theft, credit card fraud, money laundering, and identity theft. Previously, Vitali enjoyed a rewarding career as a Cybercrime Investigative Analyst for the New York County District Attorney's Office.

He has earned the majority of certifications available in the information technology, information security, digital forensics, and fraud intelligence fields. A renowned expert, speaker, blogger, and columnist, Vitali has contributed articles to Dark Reading, BusinessReview, and Infosecurity Magazine and is a frequent commentator on cybercrime, hacking incidents, policy, and security.

About the author: Ronnie Tokazowski

Ronnie Tokazowski is a Senior Malware Analyst at Flashpoint who specializes in APT, crimeware, and cryptanalysis. When he’s not cooking, he’s reversing new strains of malware and breaking different malware protocols in order to understand how they work.