Cybersecurity

Zloader: No Longer Silent in the Night

Technical Analysis

In the following sections, we dive into the technical details surrounding Zloader’s new updates to their anti-analysis techniques, embedded configuration, DGA, and network encryption.

Anti-analysis techniques

Zloader uses a combination of API import hashing, junk code, a filename check, and string obfuscation. The following sections analyze each technique.

Imports and API resolution

The newest Zloader samples only import a few functions from the kernel32 library. The remaining imports are resolved at runtime using checksums to obfuscate the functions that are used. This technique, already present in older versions, changes its implementation, adding an XOR constant which changes between samples. Python code that replicates the API hashing algorithm is shown below.


API hashing

Code sample available on GitHub.


Junk code 

Similar to previous versions, Zloader uses custom obfuscation. The new version of Zloader adds junk code that consists of various arithmetic operations, as shown in Figure 1 below.

Figure 1. Example Zloader 2.1 junk code

Figure 1. Example Zloader 2.1 junk code

In Figure 1, the instructions inside the red box are the junk code.

Anti-sandbox

Each Zloader sample expects to be executed with a specific filename. If the filename does not match what the sample expects, it will not execute further. This could evade malware sandboxes that rename sample files. Figure 2 shows an example of a Zloader sample that expects its filename to be CodeForge.exe.

Figure 2. Example of Zloader’s anti-analysis filename check

Figure 2. Example of Zloader’s anti-analysis filename check

ThreatLabz has observed Zloader use the following filenames:

  • CodeForge.exe
  • CyberMesh.exe
  • EpsilonApp.exe
  • FusionBeacon.exe
  • FusionEcho.exe
  • IonBeacon.dll
  • IonPulse.exe
  • KineticaSurge.dll
  • QuantumDraw.exe
  • SpectraKinetic.exe
  • UltraApp.exe


String obfuscation

Similar to prior versions, Zloader implements a string obfuscation algorithm for some of the malware’s important strings such as registry paths, DLL names, and the DGA’s top-level domain (TLD) using XOR with a hardcoded key. Python code that replicates the string obfuscation algorithm is shown below:


String decryption

Code sample available on GitHub

The encryption key differs between samples and is also hardcoded in the .rdata section as shown in Figure 3 below.

Figure 3. Example string obfuscation key used by Zloader

Figure 3. Example string obfuscation key used by Zloader

A list of Zloader’s obfuscated strings is shown in the Appendix.

Static configuration encryption and structure

The Zloader static configuration is still encrypted using RC4 with a hardcoded alphanumeric key, but the structure is slightly different. The botnet ID, campaign name, and command-and-control servers (C2s) are set at fixed offsets, in addition to an RSA public key that replaces the old RC4 key that was used for network encryption. ThreatLabz has observed 15 unique new Zloader samples and all of them have the same RSA public key, likely indicating there is currently only a single threat actor using the malware.

An example Zloader static configuration is shown below.


Zloader static configuration



Domain generation algorithm

When the primary C2 server is not available, Zloader reverts to a DGA. The DGA algorithm has changed in the latest version and no longer contains a different seed per botnet. Python code that replicates Zloader’s new DGA algorithm is shown below.


Domain generation algorithm

Code sample available on GitHub.

The code generates 32 domains per day by using the local system time at midnight (converted to UTC) as a seed. Each of the DGA domains have a length of 20 characters followed by the “.com” TLD.

Network communications

Zloader continues to use HTTP POST requests to communicate with its C2 server. However, the network encryption is now using 1,024-bit RSA with RC4 and the Zeus “visual encryption” algorithms. Zloader uses the custom Zeus BinStorage format where the first 128 bytes are the RSA encrypted RC4 key (32 random bytes) and, the remaining bytes are encrypted with the RC4 key and visual encryption as shown in Figure 4:

Figure 5. Zloader BinStorage object for a hello message (prior to encryption)

Figure 4. Zloader BinStorage object for a hello message (prior to encryption)

The Zeus BinStorage structure uses an ID integer value to represent the information stored, followed by the length and data. The BinStorage ID values in this example are shown in Table 1.

Value (Decimal)Value (Hexadecimal)Description
100020x2712Botnet ID
100250x2729Campaign ID
100010x2711Bot ID
100030x2713Malware version
100060x2716Unknown flag (set to 0x1)

Table 1. Zloader BinStorage hello message fields

ThreatLabz has observed samples containing the following botnet IDs:

  • Bing_Mod2
  • Bing_Mod3
  • Bing_Mod4
  • Bing_Mod5

All of the campaign IDs have been set to the value M1.