Mac users have historically trusted their operating system to keep them safe. That peace of mind mostly comes from Apple’s strict control over its ecosystem, and the fact that macOS has historically faced fewer mass attacks than Windows. However, that doesn’t mean Macs are invulnerable: threats do exist, and new ones emerge all the time. Over just the past few weeks, security researchers have published reports on at least two new campaigns that target Apple devices.
The malware used in one of the campaigns has been dubbed CrashStealer, while the other is known as ClickLock. Both rely on different tricks to force users into entering their Mac password, which attackers then use to steal account credentials, crypto assets, documents, and much more. In today’s post, we take a close look at how CrashStealer operates — and how to avoid falling victim to it.
A videoconferencing app with CrashStealer inside
It was back in May 2026 that researchers spotted the first signs this malware was being developed, and by early July, they caught it operating in the wild. The malware earned its name because of its core mechanism: it disguises itself as the macOS built-in crash reporting tool (CrashReporter) while functioning as an infostealer designed to hijack sensitive data.
Researchers managed to trace one of the websites users visited to download the malware. The site poses as a legitimate platform for distributing the video conferencing tool Werkbit.
According to researchers, this is the site victims used to download Werkbit, which secretly contained the CrashStealer malware loader. Source
However, you can’t just visit the site and download the software. Before downloading, visitors are asked to enter a special meeting PIN. This setup likely allows the attackers to limit the distribution scope by targeting only specific, pre-selected victims. Exactly how the cybercriminals choose their targets and deliver the PIN remains unknown.
The “lucky” users with a code end up installing the initial malicious payload — named Werkbit Setup. Interestingly, it carries a valid Apple developer certificate and has successfully passed Apple’s notarization process — meaning it cleared the automated prescan for malicious code. As a result, the attackers manage to bypass the operating system’s built-in Gatekeeper defense. This allows the payload to launch without triggering the usual untrusted software warnings.
The Werkbit Setup installer is signed with a valid Apple developer certificate and has passed notarization. Source
Once launched, Werkbit Setup first reaches out to GitHub. Researchers believe using this popular platform helps attackers blend in by making these initial network requests look far less suspicious to security tools. After retrieving instructions from a GitHub repository, the program connects directly to the attackers’ server to fetch CrashStealer itself.
The loader then saves the malware to a temporary macOS folder, launches it, and wipes most of the intermediate setup files. As a result, a fully functional infostealer is up and running within seconds of Werkbit Setup starting. By the way, the user never gets any videoconferencing app.
How CrashStealer works
Unlike the Werkbit Setup loader, the CrashStealer malware itself isn’t signed with an Apple developer certificate. To keep users from suspecting anything, the malware disguises itself as the built-in macOS crash reporting tool, CrashReporter, by using the exact same name, app identifier, and a similar icon.
Once launched, CrashStealer completes a sequence of steps to gain access to sensitive data, establish persistence in the system, and cover its tracks:
Remove metadata — including the attribute that flags the app as an internet download.
Display a fake system prompt asking for the user’s macOS password.
Use the previously captured credentials to gain access to Keychain, the built-in macOS password manager.
Check the computer for installed security tools and malware analysis software.
Collect saved browser passwords, cookies, Keychain contents, and data from other password managers and crypto wallets.
Encrypt the data it stole and prepare it for forwarding to the attackers’ server.
Create a copy of itself and establish persistence to launch automatically every time macOS boots.
Delete temporary files and other installation traces to make detection much harder.
Step two deserves a closer look. The password prompt that the user sees looks extremely convincing. What’s more, the malware immediately verifies whether the credentials are correct: if you make a typo and enter an invalid password, CrashStealer will pop the window right back up to ask you again.
Once launched, CrashStealer displays a pop-up that mimics the standard macOS password request. Source
What data is CrashStealer after?
CrashStealer’s hit list is massive. First and foremost, its operators target Keychain: the built-in macOS password manager where the system stores account credentials, cryptographic keys, certificates, tokens, and more.
Users of third-party password managers aren’t safe either: the malware steals data from 14 of these services, including 1Password, Bitwarden, LastPass, Dashlane, Keeper, KeePassXC, NordPass, Enpass, and RoboForm.
In addition, the malware collects all credentials and cookies stored in Chromium-based browsers — Chrome, Brave, Edge, Opera, Opera GX, Vivaldi, Chromium, and NAVER Whale — as well as Firefox. The attackers clearly have a strong interest in crypto assets: CrashStealer specifically targets data from 80 different crypto wallet extensions, including MetaMask, Phantom, Coinbase Wallet, Trust Wallet, Rabby, Exodus, Keplr, and Solflare.
Finally, the malware scans the Documents and Downloads folders to pick files that might be of interest to the cybercriminals. CrashStealer encrypts all the stolen data with the AES-256-GCM algorithm, ZIP’s it up, and sends it to the attackers’ server.
How to protect your device
The spike in attacks on macOS is a clear wake-up call: Apple users need to get proactive about their security. We recommend:
Researching apps online before installing them
Sticking to utilities from official app stores whenever possible
Using a reliable security solution that blocks malicious websites and stops malware activity on your device
Kaspersky security solutions detect the malware described in this post and assigns to it the verdicts HEUR:Trojan-Downloader.OSX.Agent.gen and HEUR:Trojan-PSW.OSX.Agent.gen.
AI is getting better and better at solving CAPTCHAs. This makes website creators — who still need to verify that they’re dealing with humans rather than bots — come up with increasingly sophisticated proof-of-humanity checks. It seems an average user would no longer be surprised if asked to recite a poem — or, say, dance Gangnam Style — just to access certain websites. The latter could double as an age check, but I digress.
Attackers have learned to exploit this variety of sometimes bizarre checks to their advantage. In our blog, we’ve talked more than once about the ClickFix attack technique, which is all about slipping a malicious instruction to the victim under the guise of yet another CAPTCHA. Historically, this technique has been used to attack users of Windows-powered devices. However, researchers recently discovered a campaign that targets macOS users. In this post, we talk in more detail about the ClickFix attack technique, the new campaign aimed at Mac users, and the criminals’ goals.
What is the ClickFix attack technique?
Many common attacks and scams rely on social engineering, or more simply put — manipulation. Instead of looking for software vulnerabilities, attackers try to trick the user into doing the dirty work themselves: opening a malicious file, clicking a link to a fake website, sharing sensitive data, or running a harmful command.
The ClickFix attack also relies on social engineering, except the scammers aren’t betting on the victim’s fear of an authority figure, but rather on their trust in technology and their habit of following instructions — even when they don’t quite make sense.
In a classic ClickFix scenario, a user visits a compromised or fake website and, instead of the expected page, sees a notification that there’s an issue. The site might claim that to continue, you need to complete an extra verification check, update your browser, or fix an error.
ClickFix: how to infect your own computer with malware in three easy steps. One of the classic variations of the attack targeting Windows users Source
Next, the victim is prompted to follow a few simple steps that look harmless enough at first glance. Usually, this involves copying some text from the attackers’ website, opening the Run window, pasting the text there, and hitting Enter.
In reality, the text is a malicious command that downloads and runs malware on the device. Since the user carries out all the steps themselves, the operating system’s security mechanisms and built-in warnings are often dismissed as just another part of the instructions. In our blog, we’ve covered the typical pretexts used to trick victims into taking dangerous actions; you can read more about them here.
The ClickFix attack scheme quickly began spawning various spin-offs, such as FileFix and ConsentFix. Until recently, the victims of ClickFix and its variants were mostly Windows users, while Mac fans encountered it much more rarely. But lately, the number of ClickFix attacks targeting Apple device owners has been on the rise.
How does the ClickFix attack on macOS work?
The ClickFix attack on Macs, as documented by cybersecurity researchers, begins with the classic fake CAPTCHA scenario. To pass the proof-of-humanity check, attackers prompt the user to copy a command, open Terminal, and paste the text into it.
The contents of the command that the user is prompted to run via Terminal. Source
The more interesting part is what happens after the malicious command is run. First, it downloads a malicious DMG — the standard format for disk images containing installation files in macOS — from a remote server, and saves it to the /tmp temporary folder under a random name. Then the script mounts the disk image without showing it in Finder or creating a desktop icon — keeping it hidden from the user. After that, the script searches the disk image for an app or installation package, and automatically launches it once found.
One case documented in the researchers’ findings involved the widespread AMOS (Atomic macOS Stealer) infostealer being distributed this way. To gain extra privileges on the system, the stealer Trojan displays a fake macOS system authentication window tricking the user into willingly typing in their password.
What are the attackers’ goals?
After the malware is installed, the attackers steal literally everything they can get their hands on from the victim’s device. Atomic macOS Stealer extracts sensitive information stored in Chromium-based browsers (Google Chrome, Microsoft Edge, Brave, Opera, Arc, Vivaldi, CocCoc, and Yandex), as well as Firefox-based ones (LibreWolf, SeaMonkey, Tor Browser, Waterfox, and Zen Browser), such as the following:
Cookies
Saved logins and passwords
Auto-fill data
Saved credit and debit cards
Browser profile data
On top of all that, the attackers also steal PDF, TXT, and RTF files from the victim’s device. The criminals are especially interested in crypto apps; specifically: desktop crypto wallets like Exodus, Electrum, Atomic Wallet, Wasabi Wallet, Bitcoin Core, Litecoin Core, DashCore, Guarda, Binance Wallet, Dogecoin Wallet, and Tonkeeper. The malware also gathers data from more than 200 cryptocurrency-related browser extensions.
But that’s still not everything…
It also targets the Telegram and Discord desktop apps. The malware doesn’t spare Apple’s ecosystem either — stealing Safari cookies, notes from Apple Notes, and passwords stored in the built-in Apple Keychain.
Once a device is infected, Atomic macOS Stealer whisks away everything valuable. Source
All of the collected information is added to a ZIP archive and uploaded to the attackers’ server. In addition, the malware replaces legitimate versions of hardware crypto wallet apps — specifically Ledger Wallet and Trezor Suite — with malicious fakes.
Together, this trove of data gives attackers broad opportunities to further compromise accounts, steal digital assets, and launch new attacks on behalf of the victim.
How do I avoid becoming a victim of ClickFix?
As social engineering attacks continue to grow, users need to be more vigilant than ever. That goes for everything from chatting with strangers on the phone or in messaging apps to everyday online activity.
Never paste commands into your Terminal just because a website asks you to — whether it’s to pass a verification check, confirm your identity, or view hidden content. No legitimate website will ever ask you to enable its features by manually running commands Terminal.
Never enter your macOS administrator password unless you completely understand what app is asking for it.
Regularly install macOS security updates, or better yet, set them to install automatically by going to System Settings → General → Software Update and clicking the i icon next to Automatic Updates. While recent versions of macOS may warn you when you try to paste suspicious or malicious commands into Terminal, this isn’t a reliable feature. For example, the malicious code shown in the screenshot above didn’t trigger any warnings at all on macOS Tahoe 26.5.2.
Trust the warnings from your operating system and security software rather than the instructions — or even the demands — of websites and apps.
In January 2026, we identified multiple attacks involving unknown malware that captures the contents of cryptocurrency wallet windows. During the investigation, we reconstructed the complete infection chain, which consisted of four tightly linked stages initiated by the execution of the previously described malicious PowerShell script TookPS. However, this campaign differs from previous activity in that it uses a new framework to deliver all malicious modules and orchestrate them via an SSH tunnel. In total, the framework includes more than 20 malicious payloads and implants, covering a wide variety of functions. At the time of writing, the threat remains active.
Kaspersky’s products detect this threat as Trojan-Downloader.Win32.TookPS.*, Trojan.Win64.BypassUAC.*, Trojan-Banker.Script.Agent.gen, Trojan.Win32.Dllhijack.*, Backdoor.Win32.TeviRat.*, Trojan-PSW.Win64.Stealer.*, Trojan-Spy.Win64.Keylogger.*, Trojan-Spy.Win64.Agent.*, Trojan.Win64.Agent.*.
Background
TookPS is a downloader used for retrieving malicious commands and scripts from attacker-controlled servers to further propagate attacks. The first campaign using TookPS was discovered in March 2025. At that time, malicious scripts delivered a Python‑based infostealer along with a script that installed and configured an SSH tunnel on the victim’s machine. The next wave appeared in April 2025: the payload was changed, and TookPS was used to deliver the TeviRAT malware with the same SSH installer.
Then at the end of April 2025, TookPS underwent minor changes, yet its attack chain was completely redesigned. Unlike previous incidents, in this case, TookPS was used solely for the initial infection, with an automated SSH bot responsible for payload delivery. This new malicious campaign has multiple stages that cover the full attack lifecycle, from initial infection to persistence and data exfiltration. Among various malware strains, at one of the stages, the TeviRAT backdoor is delivered to the compromised host, ultimately fetching another version of a TookPS script.
We dubbed this updated TookPS campaign “OkoBot”.
Original OkoBot infection chain
We will break down this chain in greater detail later in the article. However, this is not the only version of OkoBot we were able to find. Already in March 2026, we discovered a new phase in the development of the framework, with Volume2 now being installed directly using TookPS. The HDUtil launcher → extl injector → Rilide chain was found to be abandoned in this newer version since it was replaced in full by the identical ext_daemon Volume2 plugin. TeviRAT was also removed, most likely because its functions were covered by the new plugins dispatcher.
New OkoBot infection chain
Initial infection
The initial infection is primarily delivered through two vectors: a ClickFix attack, and malware distributed through GitHub that masquerades as legitimate software. One such example is the fake SQL Server Management Studio (SSMS) package distributed through GitHub. In fact, it is actually the legitimate Audacity — a popular audio editor — compiled with a malicious implant embedded in one of its libraries. Because the repository was indexed by most search engines and appeared at the top of the results for the query SSMS, the malware looked legitimate and quickly earned users’ trust.
Malicious application distribution report
This repository was created at the end of March 2025 and existed until June of that year. It consisted of a single file, README.md, which provided a fake SSMS installation guide written in an official style and likely derived from excerpts of Microsoft’s documentation. However, the download link for the program, located at the beginning of the guide, pointed to the latest release in the same repository.
Both infection vectors trigger the execution of the malicious script TookPS, which installs SSH on the victim’s system, establishes a connection to the attacker-controlled SSH server and subsequently forwards the SSH daemon port. Following a delay, an automated SSH bot connects to the forwarded port.
Back connection
The automated SSH bot collects system information such as usernames, antivirus software installed, the IP address, and OS version. It harvests cryptocurrency wallet files, browser cookies, profiles, and other credentials through an SSH tunnel. For subsequent delivery of malicious modules, it disables Windows Defender notifications via a registry modification. Moreover, it gains access to the graphical session on the victim’s system using the following sequence:
Open firewall ports for inbound RDP traffic
Create a user in the “Remote Desktop Users” group
Replace the legitimate termsrv.dll with a patched one to permit multiple concurrent RDP sessions
Create a scheduled task named Apple Sync to maintain a reverse SSH tunnel that forwards the local RDP port every hour
After that, the SSH bot begins retrieving malicious modules over SFTP.
Launcher with advanced options
One of the deployed modules is HDUtil, an auxiliary utility protected with VMProtect and heavily obfuscated. This launcher is used by the SSH bot during an attack to deploy various malicious modules via the target command. Additionally, it implements three auxiliary commands that were not observed during the attacks we analyzed. Nevertheless, their presence and potential capabilities further demonstrate the high degree of integration among all components of the framework.
Active sessions
At startup, the launcher verifies its execution environment by checking the HWID in the contents of %PROGRAMDATA%\hwid.dat, a technique consistently employed throughout the framework. If the file is missing or contains invalid data, such as a non‑MD5 hash, the launcher terminates without performing any further actions. Otherwise, the specified commands are executed. For example, enumsessions provides a list of sessions along with detailed information, including the session type (Console, Services, RDP, and others), username, connection host, and domain. In turn, enumadapters returns the names of all graphics adapters present on the system.
Example output of HDUtil enumeration commands
UAC bypass
The most important command of the launcher is target, which enables payload execution on the system. An optional nouac argument enables automatic UAC bypassing via Windows RPC and an auto-elevated msconfig.exe program, allowing the payload to run with elevated privileges stealthily. This technique has been known for a long time, discovered and described in 2019 by the Project Zero team, who provided a full report with a detailed technical description.
Below is the list of all HDUtil commands.
Command
Description
target [nouac [user=<user>]] [noattach] <file>
Starts file and prints its output.
If optional argument noattach passed, command to be executed in background.
If optional argument nouac passed, automatic UAC bypass to be performed.
If optional argument user passed, new process to be executed under , otherwise default local administrator to be chosen.
pcopy <file> <dir_src> <dir_dst>
Copies file <file> located in <dir_src> to <dir_dst>. Not used by SSH bot.
enumadapters
Prints names of graphical adapters on current system. Not used by SSH bot.
enumsessions
Prints all sessions on current system. Not used by SSH bot.
Browser extensions loader
The first malicious module delivered to the infected system via SFTP is executed using the previously described launcher with the command .\HDUtil.exe target extl.exe. It is a heavily obfuscated DLL injector protected with VMProtect. At startup, the module enters an infinite loop and uses the EnumWindows and IsWindowVisible API methods to enumerate the PIDs of active windows and retrieve the corresponding executable filenames. For processes associated with widely used Chromium‑based browsers, the module invokes a routine that injects a specialized implant.
The injector opens a process, allocates a memory region, and writes the payload directly into this region as unencrypted raw bytes. Then it resolves two exported implant functions, LdrInitMain and LdrCallMain, based on a pre-specified hash derived from a modified version of DJB2 hash function. The first function performs the final PE unpacking, including rebase operations and the initialization of the import and exception tables. The second function directly initiates malware execution.
Setting up protections on the regions and launching the implant
This loader installs malicious browser extensions and hides them from the user. It uses an internal engine that resolves the addresses of stripped functions by analyzing the byte patterns of their calls using YARA-style syntax. This approach enables the malicious code to access critical Chromium engine functions required for extension installation and management. This functionality is also implemented for other browsers with appropriate modifications. For example, in the case of Microsoft Edge, the corresponding DLL msedge.dll is hooked using the specific patterns.
List of the functions hooked by the malware
Using the obtained address of the BrowserProcess object, the loader traverses the inheritance hierarchy and subsequently resolves a pointer to the function responsible for registering observers of browser‑window creation, specifically ProfileManager::BrowserListObserver::OnBrowserAdded. With a specialized built‑in engine, they are hooked using the attacker’s own implementations while preserving the original function’s address.
The loader replaces the functions it finds with its own
When a new Chromium window is opened, a hooked function is invoked that silently installs extensions. This routine scans the user’s %APPDATA% directory, loads all .crx files (Chromium-based browsers extension format), and records them in the ext_table. The extensions are then installed in the browser.
During installation, the extension is unpacked into a non‑default extensions directory, Local Extension Settings, and its manifest is dynamically modified. An object named custom_args is added, containing the fields hwid (the identifier of the infected system) and browser (the name of the browser in which the extension is installed). Then, using previously resolved internal functions of chrome.dll, the extension is installed and all requested permissions are granted.
Extensions are unpacked into a non-default directory
All extensions loaded in this manner are added to a special array to be subsequently identified among regular extensions and to remain hidden from the user.
The remaining patched functions are used to hide the installed malicious extensions from the user. When invoked with registered extensions as parameters, they perform no operation and return a constant value. This enables the threat actor to suppress notifications related to the malicious nature of the extensions and to exclude them from the displayed list of installed extensions. As a result, the behavior of other extensions remains unaffected.
Stub for hiding malicious extensions
During the attack, the Rilide extension was installed on the victim’s system using the previously described loader. Rilide is a stealer targeting Chromium-based browsers that has been frequently used by Russian-speaking threat actors since April 2023. The malware is designed to steal sensitive user data, including login credentials, cookies, and financial information, with a specific emphasis on cryptocurrency theft.
Plugins dispatcher
The final module delivered via SFTP is an open-source utility called Volume2, which is executed with elevated privileges using the command .\HDUtil.exe target nouac noattach Volume2.exe. The executable was linked with the malicious protobuf.dll library. Although the library seems identical to the legitimate DLL, it has been modified to include a malicious exported function, ProtobufGetVer2. This function decrypts and initiates a malicious implant. The payload is encrypted using AES GCM, initialized with a static 256‑bit key and a 96‑bit nonce. The GCM authentication tag is omitted, resulting in the absence of integrity verification. Starting in March 2026, the name of protobuf.dll was changed to version.dll, although its contents remained a modified ProtoBuf library.
Decrypting implant using AES GCM and subsequent mapping
The loaded implant functions as a malicious plugin dispatcher. Upon initialization, it reads and verifies the HWID before establishing communication with the C2 server via the HTTP protocol. Each request follows a predefined binary format: a 2-byte numeric bot identifier encoded in little-endian format, followed by an AES CBC-encrypted JSON object. By default, the BotID is set to 0, and the key and IV consist of 32 and 16 bytes of 0xff, respectively. The implant polls the server every 20 seconds to retrieve new commands. The request contains client data encoded in Base64, and the server may respond with a command containing three mandatory fields: TaskIndex (the command number from the dispatcher), TaskID (a unique task identifier), and HWID (the client identifier). The dispatcher supports four built-in commands:
Task index
Action
1
Reconfigure client: update session keys, assign ID, switch to another C2
2
Load DLL implant into memory and run its entry point
3
Load plugin into process and register tasks with RegisterPlugin function
4
Restart dispatcher as new process
x
If the task number is none of the above, search for it among the registered plugins
Each plugin is required to export two functions: RegisterPlugin and PluginDispatch. These functions are used to manage and configure plugins. The RegisterPlugin function registers the plugin’s tasks with the dispatcher, whereas the PluginDispatch function is invoked when the plugin is called. Both these functions, as well as other external API functions, are located within the base libraries using one algorithm. This algorithm iterates through the export table and uses a specialized callback that calculates the MurmurHash3 hash and compares it against the target value to identify the appropriate function.
Resolving a plugin initialization function
During the analysis, we were able to discover five plugins that implement functions under their unique task identifiers.
CMD wrapper (10xx): allows running scripts and individual commands in cmd.
PowerShell wrapper (11xx): allows running scripts and individual commands in PowerShell.
Environment enumerator (12xx): gathers system information, active sessions, and processes.
Dropper (14xx): downloads an additional payload directly onto the system both from embedded Base64-encoded binary blob and via URL.
Process injector (16xx): launches additional malicious implants on the target system by injecting them into legitimate processes.
We identified four malicious implants that are delivered to the system via the process injector plugin.
ext daemon
The malware is functionally identical to the browser extensions loader (extl.exe) described above, but less obfuscated and not protected with VMProtect.
SeedHunter
Similarly to extl.exe, this malware monitors the list of active processes in the system and injects an implant into Trezor Suite, Ledger Wallet, and Ledger Live processes. The implant is malware that collects seed phrases of Ledger and Trezor cryptocurrency wallets. Initially, it verifies the HWID, and if it fails, it terminates immediately. Then, based on the value of BaseDllName, the malware determines the process context and uses the corresponding implementation for either Trezor or Ledger. It then utilizes the previously described technique to hook the internal Electron framework functions.
List of functions hooked by the malware
Then the malware communicates with the C2 (moonsand[.]store) over HTTPS, sending a Base64-encoded JSON request containing the fields Pid, HWID, and Build. In response, it receives a JSON payload containing the Wait flag. If this flag is set to true, the malware initiates periodic USB device scans filtered by VID and PID (Vendor and Product ID). Upon detecting a connected Trezor or Ledger hardware wallet, it invokes the hooked functions to display a hard‑coded phishing page designed for seed phrase recovery, with a distinct layout used for each identified wallet. If the Wait flag is set to false, the phishing page is displayed immediately.
When the seed phrase is entered and validated, the JavaScript code of the page outputs the phrase to the console prefixed with @:app:print. This prefix helps identify the malware messages in the hooked function mal_LogConsoleMessage.
Phishing pages for seed phrase recovery
The obtained seed phrase is subsequently sent to the C2 server within a JSON payload containing fields such as App (ledger or trezor), Build, DeviceName, DeviceHardwareId, and SeedData. Furthermore, an identical JSON, encrypted with the RC4 algorithm using the HWID as the key, is saved in a temporary directory under the filename sh_<ts>.json, where <ts> is the file creation timestamp.
MC Keylogger
This module is a keylogger that, in addition to recording user input, performs three malicious activities:
Clipboard logging: periodically checks various clipboard formats, including CF_HDROP for files dragged between windows, CF_DIB for copied bitmap images, and CF_UNICODETEXT for Unicode text. Each format is handled appropriately, and all copy events are logged under the Clipboard section. Text data is written directly to the log, while copied files are recorded by their file paths. Images are saved as JPG files following the naming pattern bf_YYYY-MM-DD hh_mm_ss.jpg, and the path to the saved image is added to the log.
Logging connected devices: logs information about USB devices connected to the system, including hardware characteristics like VID, PID, manufacturer, and other details.
Screenshot creation: creates a screenshot every five minutes with a name in the format sc_YYYY-MM-DD hh_mm_ss.jpg. A corresponding message is recorded in the log under the Screenshot section, including the path to the screenshot.
Thus, the keylogger creates three types of different file artifacts, which are placed in a temporary directory. Below is an example of a log file generated by the keylogger.
Example of the keylogger log file
OkoSpyware
This module, which we dubbed OkoSpyware, captures both keystrokes and the video stream of the target application’s window. It first compiles a list of over 100 executable names, including cryptocurrency wallet applications (such as Exodus or Litecoin QT), password managers (such as KeePassXC or 1Password), and other widely used applications, to identify which processes should be monitored among all active system processes. For each identified process, the module uses a bundled FFmpeg instance to capture an MP4 video of the window while concurrently logging keystrokes within that window. The resulting video file is saved in %TEMP% as media_<ts> (where <ts> is the recording’s start timestamp). In the same folder, a JSON file named oko_<ts>.json is created, containing metadata about the captured stream, such as the process name, intercepted input, the stream’s MD5 hash, and additional details.
Example of an OkoSpyware metadata file
The malware also monitors the state of browsers, and when the window title matches a specified regular expression — for instance, a MetaMask or Tonkeeper wallet extension page — it performs video recording and input logging, adding the window title value to the corresponding field in the JSON metadata file.
Artifacts exfiltration
The TookPS script launched via a scheduled task receives a PowerShell exfiltration script as its payload from the C2. All files created by the MC Keylogger and OkoSpyware are sent to the C2 server to the endpoint ir-post.php. After that, the files are deleted from the victim’s system and a command history file, ConsoleHost_history.txt, is cleared.
Sequential exfiltration of artifacts from the temporary directory
Victims
At the time of writing, we have detected hundreds of victims of the OkoBot campaign in more than 25 countries, with the largest proportion of attacked end users found in Brazil, Vietnam, Canada, Mexico, and Türkiye.
Distribution of users attacked by OkoBot by country, April 2025–June 2026 (download)
Attribution
At the time of writing, we can’t attribute this malicious campaign to any known crimeware actor. However, during the analysis, we observed that the servers hosting the PowerShell scripts used in the initial infection stage implement server-side geoblocking. When attempting to retrieve the malicious script using an IP from Russia or CIS countries, the server returns an empty response. This technique is very popular among Russian-speaking threat actors.
It was previously mentioned that the campaign uses the malicious Rilide extension, an infostealer that is actively spreading on Russian-speaking, invitation-only cybercrime forums. Additionally, the source code of the SeedHunter phishing pages includes comments in Russian.
Conclusion
The framework described here has numerous modules — mostly written in C and C++ — that are obfuscated and use a variety of packing techniques. Across all stages, specific patterns and techniques can be identified that are borrowed and used in other modules, which allows us to conclude that there is a close interconnectedness among all stages, forming a full‑fledged high‑level framework. Overall, these modules enable a wide range of functions, such as collecting local files, executing remote commands, downloading arbitrary browser extensions, and stealing crypto wallets.
The OkoBot campaign has been ongoing for over a year, and it remains active at the time of publication. Moreover, it is adapting, which indicates that this framework is being maintained and distribution campaigns continue.
In January 2026, we identified multiple attacks involving unknown malware that captures the contents of cryptocurrency wallet windows. During the investigation, we reconstructed the complete infection chain, which consisted of four tightly linked stages initiated by the execution of the previously described malicious PowerShell script TookPS. However, this campaign differs from previous activity in that it uses a new framework to deliver all malicious modules and orchestrate them via an SSH tunnel. In total, the framework includes more than 20 malicious payloads and implants, covering a wide variety of functions. At the time of writing, the threat remains active.
Kaspersky’s products detect this threat as Trojan-Downloader.Win32.TookPS.*, Trojan.Win64.BypassUAC.*, Trojan-Banker.Script.Agent.gen, Trojan.Win32.Dllhijack.*, Backdoor.Win32.TeviRat.*, Trojan-PSW.Win64.Stealer.*, Trojan-Spy.Win64.Keylogger.*, Trojan-Spy.Win64.Agent.*, Trojan.Win64.Agent.*.
Background
TookPS is a downloader used for retrieving malicious commands and scripts from attacker-controlled servers to further propagate attacks. The first campaign using TookPS was discovered in March 2025. At that time, malicious scripts delivered a Python‑based infostealer along with a script that installed and configured an SSH tunnel on the victim’s machine. The next wave appeared in April 2025: the payload was changed, and TookPS was used to deliver the TeviRAT malware with the same SSH installer.
Then at the end of April 2025, TookPS underwent minor changes, yet its attack chain was completely redesigned. Unlike previous incidents, in this case, TookPS was used solely for the initial infection, with an automated SSH bot responsible for payload delivery. This new malicious campaign has multiple stages that cover the full attack lifecycle, from initial infection to persistence and data exfiltration. Among various malware strains, at one of the stages, the TeviRAT backdoor is delivered to the compromised host, ultimately fetching another version of a TookPS script.
We dubbed this updated TookPS campaign “OkoBot”.
Original OkoBot infection chain
We will break down this chain in greater detail later in the article. However, this is not the only version of OkoBot we were able to find. Already in March 2026, we discovered a new phase in the development of the framework, with Volume2 now being installed directly using TookPS. The HDUtil launcher → extl injector → Rilide chain was found to be abandoned in this newer version since it was replaced in full by the identical ext_daemon Volume2 plugin. TeviRAT was also removed, most likely because its functions were covered by the new plugins dispatcher.
New OkoBot infection chain
Initial infection
The initial infection is primarily delivered through two vectors: a ClickFix attack, and malware distributed through GitHub that masquerades as legitimate software. One such example is the fake SQL Server Management Studio (SSMS) package distributed through GitHub. In fact, it is actually the legitimate Audacity — a popular audio editor — compiled with a malicious implant embedded in one of its libraries. Because the repository was indexed by most search engines and appeared at the top of the results for the query SSMS, the malware looked legitimate and quickly earned users’ trust.
Malicious application distribution report
This repository was created at the end of March 2025 and existed until June of that year. It consisted of a single file, README.md, which provided a fake SSMS installation guide written in an official style and likely derived from excerpts of Microsoft’s documentation. However, the download link for the program, located at the beginning of the guide, pointed to the latest release in the same repository.
Both infection vectors trigger the execution of the malicious script TookPS, which installs SSH on the victim’s system, establishes a connection to the attacker-controlled SSH server and subsequently forwards the SSH daemon port. Following a delay, an automated SSH bot connects to the forwarded port.
Back connection
The automated SSH bot collects system information such as usernames, antivirus software installed, the IP address, and OS version. It harvests cryptocurrency wallet files, browser cookies, profiles, and other credentials through an SSH tunnel. For subsequent delivery of malicious modules, it disables Windows Defender notifications via a registry modification. Moreover, it gains access to the graphical session on the victim’s system using the following sequence:
Open firewall ports for inbound RDP traffic
Create a user in the “Remote Desktop Users” group
Replace the legitimate termsrv.dll with a patched one to permit multiple concurrent RDP sessions
Create a scheduled task named Apple Sync to maintain a reverse SSH tunnel that forwards the local RDP port every hour
After that, the SSH bot begins retrieving malicious modules over SFTP.
Launcher with advanced options
One of the deployed modules is HDUtil, an auxiliary utility protected with VMProtect and heavily obfuscated. This launcher is used by the SSH bot during an attack to deploy various malicious modules via the target command. Additionally, it implements three auxiliary commands that were not observed during the attacks we analyzed. Nevertheless, their presence and potential capabilities further demonstrate the high degree of integration among all components of the framework.
Active sessions
At startup, the launcher verifies its execution environment by checking the HWID in the contents of %PROGRAMDATA%\hwid.dat, a technique consistently employed throughout the framework. If the file is missing or contains invalid data, such as a non‑MD5 hash, the launcher terminates without performing any further actions. Otherwise, the specified commands are executed. For example, enumsessions provides a list of sessions along with detailed information, including the session type (Console, Services, RDP, and others), username, connection host, and domain. In turn, enumadapters returns the names of all graphics adapters present on the system.
Example output of HDUtil enumeration commands
UAC bypass
The most important command of the launcher is target, which enables payload execution on the system. An optional nouac argument enables automatic UAC bypassing via Windows RPC and an auto-elevated msconfig.exe program, allowing the payload to run with elevated privileges stealthily. This technique has been known for a long time, discovered and described in 2019 by the Project Zero team, who provided a full report with a detailed technical description.
Below is the list of all HDUtil commands.
Command
Description
target [nouac [user=<user>]] [noattach] <file>
Starts file and prints its output.
If optional argument noattach passed, command to be executed in background.
If optional argument nouac passed, automatic UAC bypass to be performed.
If optional argument user passed, new process to be executed under , otherwise default local administrator to be chosen.
pcopy <file> <dir_src> <dir_dst>
Copies file <file> located in <dir_src> to <dir_dst>. Not used by SSH bot.
enumadapters
Prints names of graphical adapters on current system. Not used by SSH bot.
enumsessions
Prints all sessions on current system. Not used by SSH bot.
Browser extensions loader
The first malicious module delivered to the infected system via SFTP is executed using the previously described launcher with the command .\HDUtil.exe target extl.exe. It is a heavily obfuscated DLL injector protected with VMProtect. At startup, the module enters an infinite loop and uses the EnumWindows and IsWindowVisible API methods to enumerate the PIDs of active windows and retrieve the corresponding executable filenames. For processes associated with widely used Chromium‑based browsers, the module invokes a routine that injects a specialized implant.
The injector opens a process, allocates a memory region, and writes the payload directly into this region as unencrypted raw bytes. Then it resolves two exported implant functions, LdrInitMain and LdrCallMain, based on a pre-specified hash derived from a modified version of DJB2 hash function. The first function performs the final PE unpacking, including rebase operations and the initialization of the import and exception tables. The second function directly initiates malware execution.
Setting up protections on the regions and launching the implant
This loader installs malicious browser extensions and hides them from the user. It uses an internal engine that resolves the addresses of stripped functions by analyzing the byte patterns of their calls using YARA-style syntax. This approach enables the malicious code to access critical Chromium engine functions required for extension installation and management. This functionality is also implemented for other browsers with appropriate modifications. For example, in the case of Microsoft Edge, the corresponding DLL msedge.dll is hooked using the specific patterns.
List of the functions hooked by the malware
Using the obtained address of the BrowserProcess object, the loader traverses the inheritance hierarchy and subsequently resolves a pointer to the function responsible for registering observers of browser‑window creation, specifically ProfileManager::BrowserListObserver::OnBrowserAdded. With a specialized built‑in engine, they are hooked using the attacker’s own implementations while preserving the original function’s address.
The loader replaces the functions it finds with its own
When a new Chromium window is opened, a hooked function is invoked that silently installs extensions. This routine scans the user’s %APPDATA% directory, loads all .crx files (Chromium-based browsers extension format), and records them in the ext_table. The extensions are then installed in the browser.
During installation, the extension is unpacked into a non‑default extensions directory, Local Extension Settings, and its manifest is dynamically modified. An object named custom_args is added, containing the fields hwid (the identifier of the infected system) and browser (the name of the browser in which the extension is installed). Then, using previously resolved internal functions of chrome.dll, the extension is installed and all requested permissions are granted.
Extensions are unpacked into a non-default directory
All extensions loaded in this manner are added to a special array to be subsequently identified among regular extensions and to remain hidden from the user.
The remaining patched functions are used to hide the installed malicious extensions from the user. When invoked with registered extensions as parameters, they perform no operation and return a constant value. This enables the threat actor to suppress notifications related to the malicious nature of the extensions and to exclude them from the displayed list of installed extensions. As a result, the behavior of other extensions remains unaffected.
Stub for hiding malicious extensions
During the attack, the Rilide extension was installed on the victim’s system using the previously described loader. Rilide is a stealer targeting Chromium-based browsers that has been frequently used by Russian-speaking threat actors since April 2023. The malware is designed to steal sensitive user data, including login credentials, cookies, and financial information, with a specific emphasis on cryptocurrency theft.
Plugins dispatcher
The final module delivered via SFTP is an open-source utility called Volume2, which is executed with elevated privileges using the command .\HDUtil.exe target nouac noattach Volume2.exe. The executable was linked with the malicious protobuf.dll library. Although the library seems identical to the legitimate DLL, it has been modified to include a malicious exported function, ProtobufGetVer2. This function decrypts and initiates a malicious implant. The payload is encrypted using AES GCM, initialized with a static 256‑bit key and a 96‑bit nonce. The GCM authentication tag is omitted, resulting in the absence of integrity verification. Starting in March 2026, the name of protobuf.dll was changed to version.dll, although its contents remained a modified ProtoBuf library.
Decrypting implant using AES GCM and subsequent mapping
The loaded implant functions as a malicious plugin dispatcher. Upon initialization, it reads and verifies the HWID before establishing communication with the C2 server via the HTTP protocol. Each request follows a predefined binary format: a 2-byte numeric bot identifier encoded in little-endian format, followed by an AES CBC-encrypted JSON object. By default, the BotID is set to 0, and the key and IV consist of 32 and 16 bytes of 0xff, respectively. The implant polls the server every 20 seconds to retrieve new commands. The request contains client data encoded in Base64, and the server may respond with a command containing three mandatory fields: TaskIndex (the command number from the dispatcher), TaskID (a unique task identifier), and HWID (the client identifier). The dispatcher supports four built-in commands:
Task index
Action
1
Reconfigure client: update session keys, assign ID, switch to another C2
2
Load DLL implant into memory and run its entry point
3
Load plugin into process and register tasks with RegisterPlugin function
4
Restart dispatcher as new process
x
If the task number is none of the above, search for it among the registered plugins
Each plugin is required to export two functions: RegisterPlugin and PluginDispatch. These functions are used to manage and configure plugins. The RegisterPlugin function registers the plugin’s tasks with the dispatcher, whereas the PluginDispatch function is invoked when the plugin is called. Both these functions, as well as other external API functions, are located within the base libraries using one algorithm. This algorithm iterates through the export table and uses a specialized callback that calculates the MurmurHash3 hash and compares it against the target value to identify the appropriate function.
Resolving a plugin initialization function
During the analysis, we were able to discover five plugins that implement functions under their unique task identifiers.
CMD wrapper (10xx): allows running scripts and individual commands in cmd.
PowerShell wrapper (11xx): allows running scripts and individual commands in PowerShell.
Environment enumerator (12xx): gathers system information, active sessions, and processes.
Dropper (14xx): downloads an additional payload directly onto the system both from embedded Base64-encoded binary blob and via URL.
Process injector (16xx): launches additional malicious implants on the target system by injecting them into legitimate processes.
We identified four malicious implants that are delivered to the system via the process injector plugin.
ext daemon
The malware is functionally identical to the browser extensions loader (extl.exe) described above, but less obfuscated and not protected with VMProtect.
SeedHunter
Similarly to extl.exe, this malware monitors the list of active processes in the system and injects an implant into Trezor Suite, Ledger Wallet, and Ledger Live processes. The implant is malware that collects seed phrases of Ledger and Trezor cryptocurrency wallets. Initially, it verifies the HWID, and if it fails, it terminates immediately. Then, based on the value of BaseDllName, the malware determines the process context and uses the corresponding implementation for either Trezor or Ledger. It then utilizes the previously described technique to hook the internal Electron framework functions.
List of functions hooked by the malware
Then the malware communicates with the C2 (moonsand[.]store) over HTTPS, sending a Base64-encoded JSON request containing the fields Pid, HWID, and Build. In response, it receives a JSON payload containing the Wait flag. If this flag is set to true, the malware initiates periodic USB device scans filtered by VID and PID (Vendor and Product ID). Upon detecting a connected Trezor or Ledger hardware wallet, it invokes the hooked functions to display a hard‑coded phishing page designed for seed phrase recovery, with a distinct layout used for each identified wallet. If the Wait flag is set to false, the phishing page is displayed immediately.
When the seed phrase is entered and validated, the JavaScript code of the page outputs the phrase to the console prefixed with @:app:print. This prefix helps identify the malware messages in the hooked function mal_LogConsoleMessage.
Phishing pages for seed phrase recovery
The obtained seed phrase is subsequently sent to the C2 server within a JSON payload containing fields such as App (ledger or trezor), Build, DeviceName, DeviceHardwareId, and SeedData. Furthermore, an identical JSON, encrypted with the RC4 algorithm using the HWID as the key, is saved in a temporary directory under the filename sh_<ts>.json, where <ts> is the file creation timestamp.
MC Keylogger
This module is a keylogger that, in addition to recording user input, performs three malicious activities:
Clipboard logging: periodically checks various clipboard formats, including CF_HDROP for files dragged between windows, CF_DIB for copied bitmap images, and CF_UNICODETEXT for Unicode text. Each format is handled appropriately, and all copy events are logged under the Clipboard section. Text data is written directly to the log, while copied files are recorded by their file paths. Images are saved as JPG files following the naming pattern bf_YYYY-MM-DD hh_mm_ss.jpg, and the path to the saved image is added to the log.
Logging connected devices: logs information about USB devices connected to the system, including hardware characteristics like VID, PID, manufacturer, and other details.
Screenshot creation: creates a screenshot every five minutes with a name in the format sc_YYYY-MM-DD hh_mm_ss.jpg. A corresponding message is recorded in the log under the Screenshot section, including the path to the screenshot.
Thus, the keylogger creates three types of different file artifacts, which are placed in a temporary directory. Below is an example of a log file generated by the keylogger.
Example of the keylogger log file
OkoSpyware
This module, which we dubbed OkoSpyware, captures both keystrokes and the video stream of the target application’s window. It first compiles a list of over 100 executable names, including cryptocurrency wallet applications (such as Exodus or Litecoin QT), password managers (such as KeePassXC or 1Password), and other widely used applications, to identify which processes should be monitored among all active system processes. For each identified process, the module uses a bundled FFmpeg instance to capture an MP4 video of the window while concurrently logging keystrokes within that window. The resulting video file is saved in %TEMP% as media_<ts> (where <ts> is the recording’s start timestamp). In the same folder, a JSON file named oko_<ts>.json is created, containing metadata about the captured stream, such as the process name, intercepted input, the stream’s MD5 hash, and additional details.
Example of an OkoSpyware metadata file
The malware also monitors the state of browsers, and when the window title matches a specified regular expression — for instance, a MetaMask or Tonkeeper wallet extension page — it performs video recording and input logging, adding the window title value to the corresponding field in the JSON metadata file.
Artifacts exfiltration
The TookPS script launched via a scheduled task receives a PowerShell exfiltration script as its payload from the C2. All files created by the MC Keylogger and OkoSpyware are sent to the C2 server to the endpoint ir-post.php. After that, the files are deleted from the victim’s system and a command history file, ConsoleHost_history.txt, is cleared.
Sequential exfiltration of artifacts from the temporary directory
Victims
At the time of writing, we have detected hundreds of victims of the OkoBot campaign in more than 25 countries, with the largest proportion of attacked end users found in Brazil, Vietnam, Canada, Mexico, and Türkiye.
Distribution of users attacked by OkoBot by country, April 2025–June 2026 (download)
Attribution
At the time of writing, we can’t attribute this malicious campaign to any known crimeware actor. However, during the analysis, we observed that the servers hosting the PowerShell scripts used in the initial infection stage implement server-side geoblocking. When attempting to retrieve the malicious script using an IP from Russia or CIS countries, the server returns an empty response. This technique is very popular among Russian-speaking threat actors.
It was previously mentioned that the campaign uses the malicious Rilide extension, an infostealer that is actively spreading on Russian-speaking, invitation-only cybercrime forums. Additionally, the source code of the SeedHunter phishing pages includes comments in Russian.
Conclusion
The framework described here has numerous modules — mostly written in C and C++ — that are obfuscated and use a variety of packing techniques. Across all stages, specific patterns and techniques can be identified that are borrowed and used in other modules, which allows us to conclude that there is a close interconnectedness among all stages, forming a full‑fledged high‑level framework. Overall, these modules enable a wide range of functions, such as collecting local files, executing remote commands, downloading arbitrary browser extensions, and stealing crypto wallets.
The OkoBot campaign has been ongoing for over a year, and it remains active at the time of publication. Moreover, it is adapting, which indicates that this framework is being maintained and distribution campaigns continue.