Trustwave SpiderLabs Uncovers Ov3r_Stealer Malware Spread via Phishing and Facebook Advertising. Learn More

Trustwave SpiderLabs Uncovers Ov3r_Stealer Malware Spread via Phishing and Facebook Advertising. Learn More

Services
Capture
Managed Detection & Response

Eliminate active threats with 24/7 threat detection, investigation, and response.

twi-managed-portal-color
Co-Managed SOC (SIEM)

Maximize your SIEM investment, stop alert fatigue, and enhance your team with hybrid security operations support.

twi-briefcase-color-svg
Advisory & Diagnostics

Advance your cybersecurity program and get expert guidance where you need it most.

tw-laptop-data
Penetration Testing

Test your physical locations and IT infrastructure to shore up weaknesses before exploitation.

twi-database-color-svg
Database Security

Prevent unauthorized access and exceed compliance requirements.

twi-email-color-svg
Email Security

Stop email threats others miss and secure your organization against the #1 ransomware attack vector.

tw-officer
Digital Forensics & Incident Response

Prepare for the inevitable with 24/7 global breach response in-region and available on-site.

tw-network
Firewall & Technology Management

Mitigate risk of a cyberattack with 24/7 incident and health monitoring and the latest threat intelligence.

Solutions
BY TOPIC
Microsoft Exchange Server Attacks
Stay protected against emerging threats
Rapidly Secure New Environments
Security for rapid response situations
Securing the Cloud
Safely navigate and stay protected
Securing the IoT Landscape
Test, monitor and secure network objects
Why Trustwave
About Us
Awards and Accolades
Trustwave SpiderLabs Team
Trustwave Fusion Security Operations Platform
Trustwave Security Colony
Partners
Technology Alliance Partners
Key alliances who align and support our ecosystem of security offerings
Trustwave PartnerOne Program
Join forces with Trustwave to protect against the most advance cybersecurity threats
SpiderLabs Blog

BlackByte Ransomware – Pt 2. Code Obfuscation Analysis

In Part 1 of our BlackByte ransomware analysis, we covered the execution flow of the first stage JScript launcher, how we extracted BlackByte binary from the second stage DLL, the inner workings of the ransomware, and our decryptor code. In this blog, we will detail how we analyzed and de-obfuscated the JScript launcher, BlackByte’s code, and strings.

De-obfuscating the JScript Launcher

We received the original launcher file from an incident response case. It was about 630 KB of JScript code which was seemingly full of garbage code – hiding the real intent.

Our first approach to de-obfuscate the script was to simply scroll through the whole length of this obfuscated code, find some interesting blocks and figure out if there were any eval() function calls. We wanted to find an eval() call because this is where the script likely executes relevant code.

As seen in the screenshot below, we found that the first hundred lines of code were mostly unused, garbage code. At line 2494 is a blob of seemingly Base64 encoded strings (which turned out to be the main payload). Then at line 7511 is a lone eval() call.

JScript Code
Figure 1: Highlights of the obfuscated JScript code

 

The next step was to trace back the code beginning from the eval() call at line 7511, finding the references to the eval’s parameter variable name – “bnlpgh”, then start following the flow and references until we obtained the real code.

Here is an initial flow we followed starting from the eval() call.

Figure 3 - eval flow
Figure 2. Code traceback starting from eval() call

 

Following the code in this fashion, we were able to distinguish the real code from the garbage. We then prettified the code and renamed the variables to be readable. The code snippet below reveals the first layer:

Part2_FirstLayer
Figure 3. Beautified First layer of the obfuscated JScript launcher

 

Above you may see in the first layer code our renamed variable - secondLayerEncoded - this is a string that looks like it was encoded in Base64. Although that is true, it is a Base64 string that has been reversed.

The script creates an XML document object, and using this object, creates an HTML element named “tmp”.  Next, the script writes the decoded second layer from the variable assigned to secondLayerEncoded into the created element. It then reads it back as a “binaryStream” and finally runs it using eval().

After decoding and prettifying the second layer, the result looks like this:

Part2_JScriptRunDllBinary
Figure 4. Beautified code of the second layer JScript code

 

The second layer code reveals that it checks if .NET version 4.0.30319 framework is installed in the system, then proceeds to decode the malware payload (the Base64 strings shown in Figure 2 at line 2494). Afterward, it creates a memory stream object to where it writes the decoded Base64 payload. To run it, it uses the Deserialize_2 method of the System.Runtime.Serialization.Formatters.Binary.BinaryFormatter COM object to load managed code via object Deserialization. When invoked, it creates an instance of “jSfMMrZfotrr” – a class from the malicious .NET DLL loader.

BlackByte: De-obfuscating the Code

The BlackByte binary itself is also heavily obfuscated, both the code and the strings.

Figure 7 - dnspy
Figure 5. BlackByte decompiled using dnSpy

 

The code obfuscation needed some manual refactoring, and it proved to be tedious!

Below is a snippet of the most common code obfuscation technique we found in BlackByte’s code:

Part2_DotNetObfus1
Figure 6. Sample of an obfuscated code

 

In this function, we can remove the if condition in line 7 since it is always true:

9. if ((46945 ^ 472736) == 491969)

And in line 8, since sizeof(double) equals 8, our variable arg_46_0 will be equal to 

-9992+8+9984 which is equals zero. So, we can refactor the code in line 10 like this:

13. Environment.Exit(arg_46_0); // is the same as Environment.Exit(0)

To make it readable, we rename the function and removing all unnessary code, it would look like this:

1. internal static void kill_process()    
2. {
3.    try
4.    {
5.         Process.GetCurrentProcess().Kill();
6.    }
7.    catch
8.    {
9.         Environment.Exit(0);
10.   }
11.}

The same obfuscation technique has been used throughout the code. So, we can painstakingly and manually refactor every function to make it readable.

BlackByte: De-obfuscating the Strings

Another hurdle for analyzing this ransomware is the string obfuscation.

Untitled 3
Figure 7. BlackByte's obfuscated string is represented as a function

 

In the image above, each encrypted string is declared inside a public static object. The call to the method aCDscCCxGvmZ.k(encryptedString) is a call to a string reversal function, where it reverses the chunk of a Base64 string and then afterward joins those chunks together to form a complete Base64 encoded string.

Let’s take for example this encoded string:

public static object P() {
   return aCDscCCxGvmZ.k("AAAACL+BAAAgD") + aCDscCCxGvmZ.k("K95vZqTDABAAA") +
    aCDscCCxGvmZ.k("YbZietcdo57Pk") + aCDscCCxGvmZ.k("AAAAOQDrIJDAC");
 }    

First step is to reverse each chunk:

AAAACL+BAAAgD -> DgAAAB+LCAAAA
K95vZqTDABAAA -> AAABADTqZv59K
YbZietcdo57Pk -> kP75odcteiZbY
AAAAOQDrIJDAC -> CADJIrDQOAAA

Then join all together to form a complete Base64 string:

DgAAAB+LCAAAAAAABADTqZv59KkP75odcteiZbYCADJIrDQOAAAA

The decoded base64 string is a GZip header starting at the 5th byte.

Untitled 5
Figure 8. First 4 bytes is the size of the decrypted string, and the following bytes are the GZIP compressed string.

 

The first four bytes of the data are the length of the decoded string. So, we can remove the first four bytes, then apply GZIP decompression to the remaining data.

 

Untitled 6
Figure 9. GZIP header and the data following it

 

The next step is to decrypt the output with RC4 algorithm with the key [0xCD 0x92 0xCC 0x93 0xCD 0x98]. And finally, we get the decoded string “powershell.exe”

A CyberChef recipe below can help you with the string decoding. It accepts the whole obfuscated string function, parses the encoded string and decode it:

"args": ["User defined", "\"(.*?)\"", true, true, false, false, false, false, "List capture groups"] },
 { "op": "Fork",
   "args": ["\\n", "", false] },
 { "op": "Reverse",
   "args": ["Character"] },
 { "op": "Merge",
   "args": [] },
 { "op": "From Base64",
   "args": ["A-Za-z0-9+/=", true] },
 { "op": "To Hex",
   "args": ["None", 0] },
 { "op": "Find / Replace",
   "args": [{ "option": "Regex", "string": "^\\w{8}" }, "", true, false, true, false] },
 { "op": "From Hex",
   "args": ["Auto"] },
 { "op": "Gunzip",
   "args": [] },
 { "op": "To Hex",
   "args": ["Space", 0] },
 { "op": "RC4",
   "args": [{ "option": "Hex", "string": "CD 92 CC 93 CD 98" }, "Hex", "Latin1"] }
]

CyberChef came in handy when analyzing this malware. But a scripting tool like Python can make the de-obfuscation process faster. I’ll leave that as an exercise:

CyberChef
Figure 10: Decoding the string using CyberChef

 

To end this blog, we'll leave some tips on how to approach obfuscated code like this:

  1. Analyze the code first and see what methods it uses.
  2. Find any string blobs, that may be a result of encryption or encoding. This may be data, a series of hex bytes, or a base64 string. Look for any references to this and follow through.
  3. For scripts, keep an eye on those evaluation expressions, we are talking about eval(). You can sometimes exploit this by replacing it with alert(), msgbox(), console.log(), or a file write operation. And let the script run and see what it prints, however, this is extremely dangerous, so run it in a VM environment.
  4. Learn some encoding and encryption algorithms. Base64, RC4, AES, RSA, or even the simplest bitwise operations like XOR and ROTATE will come in handy.
  5. And lastly, use a tool and debug it. It makes you understand how it works when you follow the code.

For anyone interested, a decompiled source of BlackByte that we have partially de-obfuscated can be downloaded from this Github link:

https://github.com/SpiderLabs/BlackByteDecryptor

Latest SpiderLabs Blogs

Ukrainian Intelligence Claims Successful Compromise of the Russian Ministry of Defense

On March 4, 2024, the Telegram channel of the Main Directorate of Intelligence of the Ministry of Defense of Ukraine (GUR) was updated with assertions that they executed a successful cyberattack...

Read More

Cost Management Tips for Cyber Admins

As anyone who has filled out an expense report can tell you, cost management is everyone's responsibility. Organizations must apply a careful balance of budget planning and expenditures that are in...

Read More

Resurgence of BlackCat Ransomware

Updated March 8: Based on our experience, we believe that BlackCat's claim of shutting down due to law enforcement pressure is a hoax. We anticipate their return under a new guise or brand after...

Read More