Cybersecurity researchers have uncovered a malicious npm package disguised as a utility library, marking the latest escalation in a sophisticated and long-running software supply chain campaign tracked under the codename MALFEX.

The package, identified as "imgdecode," was uploaded to the official Node.js package registry on September 30, 2026, by a user profile operating under the handle "malfexteste8." Despite raising alarms among security analysts, the package had already accumulated 979 downloads as of the latest metrics and remained accessible on the npm registry. The threat actor behind the upload maintained the campaign’s momentum by publishing version 1.0.3, reflecting a pattern of rapid iteration designed to evade automated security controls and public exposure.

According to a technical analysis published by security firm SafeDep, the "imgdecode" package conceals a malicious payload within a compiled Node.js native addon. The package utilizes a deceptively simple nine-line JavaScript file whose primary function is to load a Windows dynamic-link library. When a developer or automated script triggers a Node.js program that calls require('imgdecode') within a Windows console environment, the underlying DLL immediately attempts to contact an external repository hosted on GitHub. It downloads an encrypted shellcode payload, decrypts the response locally, and injects the resulting execution into a newly spawned dllhost.exe process to maintain stealth.

The MALFEX campaign itself was first documented by security researchers at Checkmarx and CloudSEK. It represents a persistent software supply chain threat in which an unidentified threat actor has continuously published malicious packages to the npm registry since August 6, 2023. The overarching objective of the campaign is the silent compromise of Windows-based developer workstations and systems. Throughout the operation, malicious packages have been distributed across multiple publisher accounts, including handles such as malfexkkj, malfex_user, malfexteste2, malfexteste3, and malfexteste4.

Security audits of the initial batch of eight identified packages revealed diverse malicious behaviors. Three of the packages were engineered to act as loaders for the Overlord Remote Access Trojan (RAT), while three others—specifically named "cdn-img-fetch," "img-to-native," and "native-runner"—operated in tandem to download and execute a Node.js-based infostealer. A separate infection vector discovered during the campaign relied on postinstall scripts designed to execute JavaScript capable of communicating with external command-and-control servers to fetch subsequent-stage binaries.

MALFEX npm Package 'imgdecode' Hides Shellcode Loader in Windows Native Addon

Investigative timelines highlight the adaptive nature of the threat actor, who frequently reacts to public disclosures and subsequent package removals by publishing functional replacements within days. For instance, after security teams flagged "native-runner" and "img-to-native," the operator introduced substitutes titled "runhelper" and "imgbundle," quickly followed by the initial iterations of "imgdecode."

The Node.js stealer chain associated with these deployments is notable for intentionally omitting traditional install hooks. Instead, the malicious code executes dynamically when the primary package is loaded into memory. For example, "native-runner" lists "img-to-native" as a dependency, which relies on a recursive chain to facilitate execution.

Another component, "Runhelper," was advertised across the registry as a utility designed to assist developers in launching native binaries from Node.js projects. In practice, its architecture mirrors "native-runner," locating a targeted JPEG file within the local directory structure—specifically at cdn-img-fetch/.runtime/rt.jpg—extracting embedded shellcode, copying it into executable memory, and invoking it using Koffi, a Foreign Function Interface (FFI) module for Node.js.

The evolution of "imgdecode" further demonstrates the operator’s refinement of these techniques. Just six hours after "runhelper" was unpublished by registry administrators, the operator released "imgdecode" featuring a compiled DLL dedicated to running shellcode. Starting with version 1.0.1, the DLL assumed the dual responsibility of downloading and decrypting the payload independently. While versions 1.0.1 and 1.0.2 retained a dependency on require('imgbundle') before initializing the DLL, version 1.0.3 successfully decoupled itself, requiring no other MALFEX packages to function.

In its operational workflow, version 1.0.0 of "imgdecode" waits for "imgbundle" to write a file to the cdn-img-fetch/.runtime/ directory. Once the file is detected, the package reads its contents into memory and passes the data to a native Node.js addon for decoding. The core of this addon is a 64-bit Microsoft Visual C++ dynamic-link library that first conducts checks to verify whether it is executing inside a developer terminal. Once confirmed, it fetches an image file named banner.jpg from a specific repository, decrypts the hidden payload using the embedded key nif-runtime-2027, and injects the resulting code directly into dllhost.exe.

Security researchers noted that the DLL performs integrity checks on the decrypted plaintext by examining its initial bytes. If the header matches standard JPEG or PNG file signatures, the DLL terminates its execution. Analysts deduce that this mechanism allows the operator to remotely neutralize or pause the loader by serving benign content that decrypts into a standard image, while serving ordinary files otherwise causes decryption routines to fail safely prior to execution.

MALFEX npm Package 'imgdecode' Hides Shellcode Loader in Windows Native Addon

Although the GitHub repository associated with the account "cavecrew" has since been taken offline, historical archive records from early October 2026 revealed that the hosted image files contained a Go-based downloader. This secondary utility was responsible for retrieving the Node.js stealer and a remote access tool known as "movinlike" from an external server IP address. The underlying Node.js application contained environment configuration files referencing a command-and-control server address alongside a MALFEX license key, suggesting the utilization of modular malware builders or commercial licensing frameworks to construct the attack infrastructure.

Once successfully established on a target system, the malware executes comprehensive environment profiling and anti-analysis checks. It scans for indicators of virtualized environments, sandboxes, and administrative or security analysis utilities such as Wireshark and Process Monitor. Following these validation checks, the payload systematically harvests sensitive user data, targeting files matching specific seed phrases and extensions including .kdbx, .pem, .ppk, and .env. It also extracts cached credentials, session tokens, and configuration data from Chromium-based web browsers, Discord, Telegram, cryptocurrency wallets, and prominent desktop gaming applications including Steam, Epic Games, Riot Games, Battle.net, Minecraft, and Ubisoft platforms.

To maintain persistence across system reboots, the malware establishes active WebSocket communication channels with its command-and-control server, enabling remote operators to issue arbitrary shell commands, manage active processes, transfer files, capture screenshots, log keystrokes, and access clipboard contents. For persistence mechanisms, the software introduces unauthorized Registry Run keys and configures a scheduled task under the misleading title "MicrosoftEdgeUpdateService."

Cybersecurity professionals strongly advise any development teams or individual developers who have installed the affected packages to treat their Windows environments as fully compromised. Recommended incident response measures include isolating affected workstations from the network, auditing system persistence mechanisms, rotating all exposed credentials and access tokens, and securely migrating cryptocurrency assets to newly generated wallets if seed phrases or private keys were stored locally on the machine.

Leave a Reply

Your email address will not be published. Required fields are marked *