Attackers adopt JavaScript runtime Bun to spread NWHStealer

| May 6, 2026
Attackers adopt JavaScript runtime Bun to spread NWHStealer

In our previous research, we analyzed a Windows infostealer we track as NWHStealer. The attackers behind this stealer are continuously finding new methods to distribute the stealer. During our hunting activities, we noticed how attackers are using a JavaScript runtime called Bun to help distribute it.

Bun is a legitimate, fast, all-in-one JavaScript and TypeScript toolkit designed as a modern, high-performance replacement for Node.js. It is built from the ground up to simplify modern web development by integrating several essential tools into a single executable. 

Its relative newness also makes it appealing for attackers. Bun has not yet been widely seen in malware campaigns, and it allows them to package malicious code into larger executables that may be less easily detected. 

What is NWHStealer and what can it do? 

NWHStealer is a  Rust-based stealer distributed using a range of lures and delivery methods. These include Node.js scripts, MSI installers, and, more recently, JavaScript loaders built with the Bun runtime.  

It is often hosted on legitimate platforms such as GitHub, GitLab, MediaFire, Itch.io, and SourceForge, which helps it blend in with normal software and increases the chances of users downloading it. Attackers continue to create new profiles and lures to spread the stealer. 

Once installed on your PC, NWHStealer can: 

  • Collect system information, including operating system, hardware, security software, user data and connected devices. 
  • Steal data from browsers, extensions and crypto wallets. 
  • Steal data from different applications, including FTP applications such as FileZilla, CoreFTP and messaging apps such as Steam and Discord. 
  • Inject malicious code into browser processes and run additional payloads (e.g. XMRig).
  • Attempt to bypass User Account Control (UAC). 
  • Achieve persistence via scheduled tasks. 
  • Get new command-and-control (C2) addresses from Telegram. 

How to stay safe 

Attackers are constantly adapting their techniques, and the use of newer tools like Bun shows how they try to stay ahead of detection. 

NWHStealer is particularly concerning because of how widely it is distributed, and the types of data it targets. Stolen browser data, saved passwords, and cryptocurrency wallet information can quickly lead to account takeovers, financial loss, and further compromise. 

Here are a few simple ways to stay safe: 

  • Only download software from official websites. 
  • Be cautious with downloads from platforms like GitHub, SourceForge, or file-sharing platforms unless you trust the source. 
  • Attackers are continuing to create new profiles to distribute this stealer across platforms.  Check the profile/developer/publisher’s profile, reputation, and how new it is when downloading something from file hosting providers or blogs. 
  • Check the structure of the archives, that the content, images, txt files are consistent with what you downloaded. Also check the archive name, they usually have recognizable patterns. 
  • Check the file’s publisher and signature before you run it. 


Pro tip: Install Malwarebytes Browser Guard to block malicious sites before they load. 


Technical analysis

The new distribution method: Bun JavaScript Runtime 

According to its official site, Bun is an all-in-one JavaScript, TypeScript & JSX toolkit. It’s built from scratch in Zig and powered by Apple’s JavaScriptCore engine, with a focus on fast startup and low memory usage.

Bun is composed of four main components: 

  • JavaScript Runtime: a JavaScript runtime designed as a drop-in replacement for Node.js. 
  • Package Manager: a fast alternative for npm. 
  • Test Runner: a built-in, Jest-compatible runner that executes tests much faster than standard runners. 
  • Bundler: replaces tools like Webpack, Vite, or esbuild for packaging code. 

In recent campaigns, we detected that NWHStealer is being distributed using a Bun JavaScript Runtime bundle.  

As we saw in our previous research, game-related and other software lures are used to start the infection chain. Some of the detected ZIP names in these recent campaigns include: 

  • Game-related software and cheats such as: 
    • MOUSE_PI_Trainer_v1.0.zip
    • FiveM Mod.zip
    • VampireCrawlers_Trainer_v1.0.zip
    • MagicalPrincess_Trainer_v1.0.zip 
    • TerraTechLegion_Trainer_v1.0.zip 
  • Other software such as: 
    • TradingView-Activation-Script-0.9.zip 
    • AutoTune 2026.zip
    • Metatune by Slate Digital 2026.zip
    • GoGoTv_Plus.zipAutodesk.zip

In the case analyzed in this article, the infection chain starts with an archive containing Installer.exe, which embeds JavaScript code bundled with the Bun runtime. 

The “DW” folder contains another loader, called dw.exe. This self-injection loader is similar to the one analyzed previously, but with a different decryption routine. This loader is not present in all ZIP files analyzed. 

The malicious ZIP contains two loaders
The malicious ZIP contains two loaders 

The Readme.txt file asks the user to manually launch dw.exe if the main .exe file fails to run properly. This gives the attacker two ways to distribute the stealer if the C2 of the main Bun loader is offline. The loader in dw.exe works independently from the Bun JavaScript loader. 

The Readme file inside the ZIP archive
The Readme file inside the ZIP archive
The fake Build Tools setup shown if dw.exe is started
The fake Build Tools setup shown if dw.exe is started

In this article, we don’t analyze dw.exe, as it’s a variant of the previous loaders. Instead, we focus on the JavaScript loader executed with the Bun JavaScript runtime. 

Analysis of the JavaScript Loader  

The executed JavaScript code by the Bun JavaScript runtime is inside the .bun section and is obfuscated.  

The .bun section with the obfuscated JavaScript code
The .bun section with the obfuscated JavaScript code 

The malicious code is implemented in two parts of the code: 

  • sysreq.js: performs the anti-virtualization checks with a score system. 
  • memload.js: communicates with the C2 server, performs decryption and loads the next stage. 
Entry point of the JavaScript loader

The loader runs several PowerShell CIM (Common Information Model) commands and WMI (Windows Management Instrumentation) commands to detect virtual environments. There are different controls related to CPU numbers, disk space, screen resolution, USB devices, hardware manufacturers and products, number of installed software, presence of specific folders such as Browser folders, number of running processes and username. A scoring system is implemented, and based on this score, the loader decides whether to continue with the infection or terminate it.

To detect a virtual environment, the loader executes more than 10 PowerShell commands, such as: 

  • Get-CimInstance -ClassName Win32_DiskDrive | Select-Object Model  
  • Get-CimInstance -ClassName Win32_PhysicalMemory | Select-Object Manufacturer,Speed  
  • Get-CimInstance -ClassName Win32_BIOS | Select-Object Manufacturer  
  • Get-CimInstance -ClassName Win32_BaseBoard | Select-Object Manufacturer,Product  
  • Get-CimInstance -ClassName Win32_DiskDrive | Select-Object PNPDeviceID 
  • (Get-Process -ErrorAction SilentlyContinue).Count 

The results are compared against different strings, for example:

  • Virtualization indicators: qemu, seabios, bochs, vbox, vmware, virtualbox, kvm, xen, parallels, virtio, vmbus, red hat, edk ii
  • Username sandbox: sandbox, malware, virus, sample, vmuser, wdagutilityaccount, defaultuser0
  • MAC associated with virtual environments

The strings are decrypted using XOR and base64 decoding; there are arrays of tuples and each contains the encrypted strings and a key used for XOR decryption. 

Encrypted data with XOR keys
Encrypted data with XOR keys 

Several functions handle string decryption, including one that decrypts the config used in the C2 communication. Partial config: 

C2 server: https://silent-harvester.cc
BUILD_ID: 0ddbfec60307
C2 Path: /api/status, /api/update

The loader obtains and sends an initial request to the endpoint https://C2-server/api/report with encrypted data about the compromised system: 

  • Public IP obtained with a request to api.ipify.org. 
  • System information 
  • Anti-VM result 
  • Base-64 encoded screenshot 
  • Timestamp 

Then it makes two GET HTTP requests: 

  • https://C2-server/api/status?v={BUILD_ID}, to obtain the seed used for AES key derivation. 
  • https://C2-server/api/update?v={BUILD_ID}, to obtain the encrypted payload with AES nonce and authentication tag. 

The next stage is decrypted using AES-256-CBC, with the AES data returned by the C2 and loaded with a self-injection loader using the following APIs: 

  • VirtualAlloc 
  • VirtualProtect 
  • LoadLibraryA 
  • GetProcAddress 
  • RtlAddFunctionTable
  • CreateThread 
  • SearchPathA 

These Win32 APIs are executed through the Bun module bun:ffi, which allows JavaScript to call native libraries. 

At the end of this process, NWHStealer was deployed in the analyzed cases. 

Indicators of Compromise (IOCs) 

Domains 

whale-ether[.]pro: NWH Stealer C2 server 

cosmic-nebula[.]cc: NWH Stealer C2 server 

silent-harvester[.]cc: Bun Loader C2 server 

silent-orbit[.]cc: Bun Loader C2 server 

support-onion[.]club: Bun Loader C2 server 

Hash 

d3a896f450561b2546b418b469a8e10949c7320212eb1c72b48e2b1e37c34ba5 

96fe4ddfe256dc9d2c6faea7c18e2583cd9d9c0099a4ad2cf082f569ee8379f4 

3710fb27d2032ef1eb1252ebf5c4dd516d2b2c0a83fb82c664c89e504b990fa9 

33d07aa24b217f27df6a483295c817da198e12511a6989bcc6b917feaf8e491d 

5427b4cefb329ed0e9585b3ce58a2788baf87e3b0c7221373f9bbd5f32c85b62 

308da9f49ffa1d1744e428b567792ab22712159974e9da8d8e0414ecd81de93e 

021838f30a43026084978bce187c165c6b640d8d474ec009d48078d21ec62025 

c8e96b55f13435c4b43b7209d2403f1a0e0f9deb05edc50e0f777430be693b07 

0614c4cc6375ab6bdcdd2dfa913a67d32c3e8be9b95a4a2aa09bb131b98191c8 

0020999b2e3e4d1b2cfb69e4df9440d3ce05d508573889fdc12b724ce75a0cd8 

0fa42df08cc467ec52b2d388b5575114a8ec067d13f6b1a653ec33fe879f88ca 

15f79980650393d182f81cd6e389210568aa1f5f875e515efe6cb9485d64b7fb 

20454ba58d509300fd694ae6159db4efa1b7ff965f98c29e7d087e20f96578c1 


CNET Editors' Choice Award 2026

According to CNET. Read their review


About the author

Gabriele is a Malware Research Engineer who loves fighting malware. When he's not doing that, you’ll find him enjoying nature, art, and animals.