Technical Analysis of Zloader Updates

IntroductionZloader (a.k.a. Terdot, DELoader, or Silent Night) is a Zeus-based modular trojan that emerged in 2015. Zloader was originally designed to facilitate banking, but has since been repurposed for initial access, providing an entry point into corporate environments for the deployment of ransomware. Following an almost two-year hiatus, Zloader reemerged in September 2023 with significant enhancements to its obfuscation techniques, domain generation algorithm (DGA), anti-analysis techniques and network communication, along with a stealthier approach to infections.In this blog post, Zscaler ThreatLabz examines two new versions of Zloader (2.11.6.0 and 2.13.7.0) that feature improvements to their network communications, anti-analysis techniques, and evasion capabilities. Moreover, Zloader continues to be deployed only at a small number of entities rather than being spread indiscriminately. As a result of this targeted approach, Zloader samples are not frequently observed in the wild.Key TakeawaysZloader is a modular trojan based on the leaked Zeus source code dating back to 2015.Zloader 2.13.7.0 includes improvements and updates to the custom DNS tunnel protocol for command-and-control (C2) communications, along with added support for WebSockets.Zloader continues to evolve its anti-analysis strategies, leveraging innovative methods to evade detection.Zloader attacks are more precise and targeted, with its interactive shell now including new commands that may assist in ransomware operations.Technical AnalysisIn this section, we will explore the various changes that were introduced in the latest versions of Zloader including new evasion techniques, additional functionality for lateral movement, and modifications to network communication.Anti-analysis One notable change to Zloader’s functionality involves the required filename that was expected by the malware. Previously, Zloader samples were expected to be run with a specific hardcoded filename. If the actual filename did not match the expected value, that Zloader sample would not run. This design is likely intended to evade automated malware sandbox environments. However, in the most recent versions, the malware Zloader author introduced two new generic filenames to allow the threat actors that deploy (or update) Zloader with more flexibility. These two generic filenames are Updater.exe and Updater.dll.Another significant change that was made to hinder analysis is more obfuscation layers. This level of obfuscation is achieved using different XOR-based integer decoding functions. To simplify the analysis, ThreatLabz used an IDA script to remove these layers of obfuscation as shown in the example below.import idautils

XOR_KEY = 0xAE # CHANGE ACCORDINGLY
FUNCTION_NAME = "Calculate_Int1" # CHANGE ACCORDINGLY

# Iterate through all functions in the IDA database.
for func_addr in Functions():
func_name = get_func_name(func_addr)
if func_name.startswith(FUNCTION_NAME):
print(f"Processing function: {func_name}")

# Search for cross-references (xrefs) to the function.
for xref in idautils.XrefsTo(func_addr):
print(f"\tFound xref at: {hex(xref.frm)}")

# Grab the DWORD passed and perform a XOR operation on it.
param = ida_bytes.get_byte(xref.frm-1) # CHANGE ACCORDINGLY
result = param ^ XOR_KEY
mov_eax_constant = b'\xB8' + result.to_bytes(4, 'little')
ida_bytes.patch_bytes(xref.frm, mov_eax_constant)
set_cmt(xref.frm, FUNCTION_NAME, 0)The figure below illustrates a function that checks Zloader’s process integrity level, before and after deobfuscation.Figure 1: Example of Zloader’s new code obfuscation techniques and the same function after deobfuscation.The process integrity level is important because Zloader will exit if it detects that the process is being executed with high integrity. In modern versions of Windows, most standard processes run with medium integrity. Thus, this new integrity level check is likely another detection mechanism for malware sandboxes, which often run samples with administrator privileges (i.e., high integrity). If Zloader is executed with medium integrity, the malware will be installed in the %APPDATA% directory. Otherwise, if Zloader has system integrity, the malware will be installed in the %PROGRAMFILES% directory.The typical integrity levels are shown in the table below:Integrity LevelDescriptionLow integrity (SID value: 0x1000)Restricted processes, usually sandboxed (e.g., web browsers like Chrome/Edge running untrusted content)Medium integrity (SID value: 0x2000)Standard user processesHigh integrity (SID value: 0x3000)Administrator privilegesSystem integrity (SID value: 0x4000)Processes running as part of the OS kernel or critical system operations (e.g., trusted installers, system services)Table 1: Summary of Windows process integrity levels.This behavior stands out because user-mode trojans like Zloader typically require elevated privileges to perform various actions. By avoiding elevated permissions, Zloader sacrifices broader system access for the added benefit of evading malware sandbox detection.Static configurationThe Zloader static configuration has also undergone minor changes. The TLS Server Name Indication (SNI) and the DNS nameserver, which functions as the command-and-control (C2 server) for Zloader’s network communication when using the DNS Tunneling protocol, have been relocated to the end of the C2 domain section.The DNS servers used for resolving the C2 nameserver were previously stored in network byte order. The DNS servers are now represented using a mini JSON configuration. A description for each JSON key is shown in the table below:Configuration keyDescriptionprotoIndicates the communication protocol used, such as UDP (DNS), HTTPS (DoH), or TLS (DoT).ipThe resolver IP.portThe resolver port.qps(Queries Per Second) Indicates the maximum number of DNS queries the resolver can process per second.Table 2: Mini JSON configuration for the DNS servers used by Zloader’s DNS Tunneling protocol.If a DNS entry equals 127.0.0.1, Zloader ignores the entry and treats it as a placeholder.The figure below shows the modified static configuration, including the new location of the C2 domains, the mini JSON format, and a placeholder entry for an additional DNS server.Figure 2: Zloader’s new static configuration format.Shell commandsZloader’s interactive shell commands allow a threat actor to execute commands, deploy second-stage malware payloads, run shellcode, exfiltrate data, as well as identify and terminate specific processes. The latest version of Zloader adds a new set of LDAP functions to improve network discovery and expand lateral movement capabilities. The new functions are outlined in the table below.CommandDescriptionldap_bind_sAuthenticates and binds to the LDAP server.ldap_err2stringConverts an LDAP error code into a human-readable string.ldap_first_attributeRetrieves the first attribute of an LDAP entry.ldap_first_entryRetrieves the first entry from an LDAP search result.ldap_get_valuesRetrieves the values associated with a specific attribute from an LDAP entry.ldap_initInitializes a connection to the LDAP server.ldap_memfreeReleases allocated memory used by LDAP functions.ldap_next_attributeRetrieves the next attribute from an LDAP entry.ldap_next_entryRetrieves the next entry from an LDAP search result.ldap_search_sPerforms a synchronous search on the LDAP server.ldap_set_optionSets various options for an LDAP session (e.g., timeout or protocol version).ldap_value_freeReleases memory used for an array of attribute values.ldap_searchPerforms an asynchronous search on the LDAP server.Table 3: New LDAP functions added to Zloader’s interactive shell.Network communicationThe latest versions of Zloader have removed the Domain Generation Algorithm (DGA), which was rarely used in previous versions. In addition to this change, several other important updates have been introduced to Zloader’s DNS tunnel encryption, together with new support for the WebSockets protocol. These updates are explored in the following sections.DNS C2 trafficThe DNS C2 protocol, previously described in our Zloader 2.9.4.0 blog, has undergone significant changes in the latest iterations. In older versions, Zloader relied on TLS encryption for payloads in DNS queries and responses. However, the current implementation replaces this with Base32 encoding layered on top of a custom encryption algorithm. The comparison figure below highlights the differences between the old and new Zloader DNS C2 messages.Figure 3: Example DNS C2 message comparison between the old and new versions of Zloader.The Zloader DNS C2 message format is now the following:Figure 4: Zloader DNS tunneling protocol message format.A new session key field has been introduced that contains a random DWORD, which is used throughout the communication exchange. The session key field is used to generate the final key, which is then used to decode the query’s header and payload. The final key is computed by applying an XOR operation between the Base32-encoded DWORD in the session key and a hardcoded DWORD embedded in the malware binary, which may vary between samples and instances of Zloader. Once the final key is generated, the following algorithm is used to decode the header and payload:def decode_sections(bytes_array, key):
result = bytearray()
for byte in bytes_array:
# XOR uses the last byte of the key, then rotates and increments.
last_byte = key & 0xFF
result.append(byte ^ last_byte)
key = ((key -- 8) & 0xFFFFFFFF) | ((key -- 24) & 0xFF)
key = (key & 0xFFFFFF00) | ((key + 1) & 0xFF)
return resultThe examples in the figure below show the final structure and decoded outputs of the DNS requests:Figure 5: Showcases the final structure and decoded outputs of the DNS requests.The purpose of switching from TLS-based encryption to a custom algorithm may be due to the fact that the TLS messages can easily be identified in DNS traffic due to their well defined structure. Thus, this change was likely made to better evade network-based signatures.After decryption, the Zloader DNS tunnel header is identical to previous versions as shown below:struct zloader_dns_tunnel_header {
unsigned int session_id; // Randomly generated.
unsigned int sequence_num; // Incremented per packet.
byte msg_type; // 1-9
byte reserved; // Reserved
unsigned int generic_var; // Varies by msg_type
};Once all components of the payload have been sent or received, the data format structure aligns with Zloader’s HTTPS communications. The payload is first encrypted using the Zeus VisualEncrypt algorithm, followed by encryption with a randomly generated 32-byte (256-bit) RC4 key. Finally, the RC4 key itself is encrypted with a hardcoded 1,024-bit RSA public key.WebSocket supportIn the latest versions, Zloader introduced WebSockets that can be used to upgrade the HTTP connection with the following hardcoded header:GET %s HTTP/1.1\
Host: %s\
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: %s
Upgrade: websocket
Origin: %s
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: %s
Sec-WebSocket-Key: %sThe introduction of WebSockets in Zloader may be designed to further blend in with legitimate web-based traffic to bypass network-based detections.ConclusionZloader has evolved from a banking trojan into a sophisticated general purpose trojan used by initial access brokers for ransomware attacks. Recent versions of Zloader (2.11.6.0 and 2.13.7.0) feature code obfuscation, additional anti-sandbox measures, new LDAP-based network discovery commands that can be leveraged for lateral movement, and an improved DNS-based network protocol that utilizes custom encryption with the option of using WebSockets. Zscaler CoverageZscaler’s multilayered cloud security platform detects indicators related to Zloader at various levels. The figure below depicts the Zscaler Cloud Sandbox, showing detection details for Zloader.Figure 6: Zscaler Cloud Sandbox report for Zloader.In addition to sandbox detections, Zscaler’s multilayered cloud security platform detects indicators related to Zloader at various levels with the following threat names:Win64.Downloader.ZloaderIndicators Of Compromise (IOCs)IndicatorDescription86ffd411b42d8d06bdb294f48e79393adeea586c56c5c75c1a68ce6315932881Zloader sample SHA25601fc5c5fd03b793437ed707233d067b330fb68a2de87e9d8607c6b75caca6356Zloader sample SHA256adsemail.comZloader HTTPS C2 serveradsmarks.comZloader HTTPS C2 serverdt1.automotosport.netZloader DNS C2 server

The post Technical Analysis of Zloader Updates appeared first on Security Boulevard.

22 September 2025


>>More