惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Blog — PlanetScale
Blog — PlanetScale
小众软件
小众软件
F
Fortinet All Blogs
博客园 - 叶小钗
博客园_首页
D
DataBreaches.Net
Apple Machine Learning Research
Apple Machine Learning Research
U
Unit 42
爱范儿
爱范儿
aimingoo的专栏
aimingoo的专栏
博客园 - Franky
Martin Fowler
Martin Fowler
酷 壳 – CoolShell
酷 壳 – CoolShell
The Cloudflare Blog
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
IT之家
IT之家
M
MIT News - Artificial intelligence
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
S
SegmentFault 最新的问题
Hugging Face - Blog
Hugging Face - Blog

Security Research | Blog

SloppyRAT: A New Tool For Ransomware Attacks | ThreatLabz Microsoft Exchange Vulnerability: What Admins Should Do C2Looper Backdoor Uses GitHub for C2 | ThreatLabz Midnight Blizzard launches CaptiveCrunch | ThreatLabz ChainDrop NPM Worm Analysis | ThreatLabz Abyssos Modular RAT Analysis | ThreatLabz Frontier AI and Enterprise Readiness | Zscaler Ransomware Victims Research | ThreatLabz Targeted Attack on Middle East Govts (Part 2) | ThreatLabz Technical Analysis of GoGRPC | ThreatLabz Targeted Attack on Middle East Govts (Part 1) | ThreatLabz ClaudeFix: Shared Claude Chats Meet ClickFix | Zscaler Why Do F1 Teams Need Cybersecurity, and What Is AI’s Role? Indirect Prompt Injection Targets AI Agents | ThreatLabz Splunk Enterprise RCE (CVE-2026-20253) | ThreatLabz Edgecution: Malicious Edge Extension Backdoor | ThreatLabz SmartApeSG Supply Chain Attack Targets Okendo | ThreatLabz AI Generated ClickFix Attack Delivers SmartRAT | ThreatLabz What the ThreatLabz 2026 Phishing and Initial Access Report Means for the Public Sector | Zscaler Shai-Hulud: Miasma, Hades, & AI Scanner Evasion | ThreatLabz Zscaler ThreatLabz 2026 Phishing and Initial Access Report Technical Analysis of MLTBackdoor | ThreatLabz When the Scanner Starts Thinking: Learnings from Mythos & GPT 5.5 Cyber in Security Testing | Zscaler OpenClaw Skill Distributes Remcos & GhostLoader | ThreatLabz Tropic Trooper: AdaptixC2 + Custom Beacon | ThreatLabz Do not delete blog (testing) | Zscaler Payouts King Takes Aim at the Ransomware Throne | ThreatLabz The Alibaba Incident and Why Zero Trust Matters More Than Ever In-Memory Loader Drops ScreenConnect | ThreatLabz Supply Chain Attacks Surge in March 2026 | ThreatLabz
Technical Analysis of Zloader Updates | ThreatLabz
ThreatLabz · 2025-09-22 · via Security Research | Blog

In 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.

Example of Zloader’s new code obfuscation techniques and the same function 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 Level

Description

Low 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 processes

High integrity (SID value: 0x3000)

Administrator privileges

System 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 configuration

The 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 key

Description

proto

Indicates the communication protocol used, such as UDP (DNS), HTTPS (DoH), or TLS (DoT).

ip

The resolver IP.

port

The 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.

Zloader’s new static configuration format.

Figure 2: Zloader’s new static configuration format.

Shell commands

Zloader’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.

Command

Description

ldap_bind_s

Authenticates and binds to the LDAP server.

ldap_err2string

Converts an LDAP error code into a human-readable string.

ldap_first_attribute

Retrieves the first attribute of an LDAP entry.

ldap_first_entry

Retrieves the first entry from an LDAP search result.

ldap_get_values

Retrieves the values associated with a specific attribute from an LDAP entry.

ldap_init

Initializes a connection to the LDAP server.

ldap_memfree

Releases allocated memory used by LDAP functions.

ldap_next_attribute

Retrieves the next attribute from an LDAP entry.

ldap_next_entry

Retrieves the next entry from an LDAP search result.

ldap_search_s

Performs a synchronous search on the LDAP server.

ldap_set_option

Sets various options for an LDAP session (e.g., timeout or protocol version).

ldap_value_free

Releases memory used for an array of attribute values.

ldap_search

Performs an asynchronous search on the LDAP server.

Table 3: New LDAP functions added to Zloader’s interactive shell.

Network communication

The 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 traffic

The 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.

Example DNS C2 message comparison between the old and new versions of Zloader.

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:

Zloader DNS tunneling protocol message format.

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 > 24) & 0xFF)
        key = (key & 0xFFFFFF00) | ((key + 1) & 0xFF)
    return result

The examples in the figure below show the final structure and decoded outputs of the DNS requests:

Showcases 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 support

In 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: %s

The introduction of WebSockets in Zloader may be designed to further blend in with legitimate web-based traffic to bypass network-based detections.