npm malware in imgdecode injects code into Windows
The npm malware package imgdecode uses a compiled Node.js component to download encrypted shellcode, meaning instructions designed to run directly in memory, and inject it into a Windows process. SafeDep found that the package's nine-line JavaScript file loads a dynamic-link library (DLL), a compiled file containing executable code. When a Windows application calls require('imgdecode'), the DLL retrieves the encrypted payload from GitHub, decrypts it and starts it inside a new dllhost.exe process.
Imgdecode was uploaded to the npm package registry on September 30, 2026, by the account malfexteste8. It had recorded 979 downloads and remained available at the time of reporting. Its latest release was version 1.0.3. SafeDep linked it to MALFEX, a software supply chain campaign first documented by Checkmarx and CloudSEK. An unknown operator has used the campaign to publish malicious Windows-focused packages since August 6, 2023, through the accounts malfexkkj, malfex_user, malfexteste2, malfexteste3 and malfexteste4.
Eight packages had been identified in the broader campaign. Three acted as loaders for Overlord RAT, with RAT meaning remote access trojan, malware that gives an operator control over a computer. Three others, cdn-img-fetch, img-to-native and native-runner, formed a chain that installed a Node.js data stealer. Another route used a postinstall hook, which is code that runs automatically after a package is installed, to contact an external server and retrieve an unspecified follow-on binary.
The operator rapidly replaced removed packages. Cdn-img-fetch, img-to-native and native-runner 1.0.0 appeared on September 26, 2026. Npm removed native-runner and img-to-native at 4:06 p.m. UTC on September 28. On September 30, imgbundle 1.0.0 was published at 3:29 a.m. as a replacement for img-to-native, followed eight minutes later by runhelper 1.0.0 as a replacement for native-runner. Runhelper was unpublished at 4:13 p.m. Imgdecode versions 1.0.0 and 1.0.1 then appeared at 10:32 p.m. and 11:07 p.m. Version 1.0.2 followed on October 1 at 5:48 p.m. Npm removed imgbundle on October 7 at 11:06 p.m. and cdn-img-fetch on October 8 at 1:03 p.m. Imgdecode 1.0.3 was published on October 11 at 10:09 p.m.
The earlier three-package stealer chain did not rely on an installation hook. Instead, execution began when native-runner was loaded. Cdn-img-fetch downloaded banner.png from the cavecrew/proj GitHub repository and extracted an encrypted block of data. Img-to-native decrypted it with the key malfexteam2027 and saved a Go executable as %APPDATA%\Microsoft\Windows\node_runtime_helper.exe. Native-runner launched that file, which downloaded setup.exe, also called movinlike, from 104.234.65[.]75:700.
Runhelper was presented as a utility for starting native programs from Node.js, but its actual role was to find cdn-img-fetch/.runtime/rt.jpg, recover shellcode from the image, copy it into executable memory and run it through Koffi. Koffi is a Foreign Function Interface (FFI) module that lets JavaScript call compiled native code. SafeDep reported that six hours after runhelper was unpublished, the operator released imgdecode with a compiled DLL for running the shellcode. From version 1.0.1, that DLL could also retrieve and decrypt the payload. Versions 1.0.1 and 1.0.2 still loaded imgbundle first, while version 1.0.3 removed that dependency and could operate without another MALFEX package.
Imgdecode 1.0.0 waited for imgbundle to place data in cdn-img-fetch/.runtime/, read the resulting file into memory and sent it to a native Node.js addon for decoding. The addon is a 64-bit Microsoft Visual C++ DLL. It checks whether it is running in a developer terminal, fetches banner.jpg from cavecrew/proj, decrypts the embedded content with the key nif-runtime-2027 and injects the result into dllhost.exe. SafeDep also found a potential operator-controlled shutoff: if the decrypted content begins with a JPEG or PNG file signature, the DLL stops. The researchers noted that simply serving an ordinary image would generally cause decryption to fail before that check.
The cavecrew GitHub account was no longer accessible, but an Internet Archive capture dated October 6, 2026, showed the image containing the same Go-based downloader used to obtain the Node.js stealer and the movinlike remote access tool from 104.234.65[.]75:700. The Node.js application also contained a .env configuration file with the command-and-control (C2) address 104.234.65[.]75:7007 and a MALFEX licence key. SafeDep said this indicated that a malware builder or licensing system was used to create the payloads.
Before collecting data, the malware checks for virtual machines, sandboxes and analysis programs including Process Monitor and Wireshark. It searches for seed phrases and files ending in .kdbx, .pem, .ppk and .env. It also targets Chromium-based browsers, Discord, Telegram, cryptocurrency wallets and gaming applications including Steam, Epic Games, Riot, Battle.net, Minecraft and Ubisoft. Through a WebSocket connection to its C2 server, the malware can receive instructions for command execution, file transfers, process management, clipboard access, screenshots, and mouse and keyboard control. It attempts to remain on the computer by adding a Registry Run entry and creating a scheduled task named MicrosoftEdgeUpdateService.
For website and hosting teams, the immediate exposure is the Windows development or build computer where a malicious dependency is loaded, rather than a flaw in a deployed website. Theft of .env, .pem and .ppk files can expose configuration data and credentials used to administer applications or infrastructure. Organisations needing assistance with affected IT environments can consider AEU-I, which provides security-first IT, infrastructure and consulting.
Anyone who installed imgdecode or the related MALFEX packages should treat the affected Windows system as potentially compromised. The recommended response is to isolate it, examine the documented persistence locations, rotate credentials from a clean device and move cryptocurrency to new wallets if seed phrases were stored on the computer. Removing the npm package alone does not address malware that may already be running or configured to start again.