NodeLoader Exposed: The Node.js Malware Evading Detection

IntroductionZscaler ThreatLabz discovered a malware campaign leveraging Node.js applications for Windows to distribute cryptocurrency miners and information stealers. We have named this malware family NodeLoader, since the attackers employ Node.js compiled executables to deliver second-stage payloads, including XMRig, Lumma, and Phemedrone Stealer. Node.js is a well-known framework for building web-based services such as chat applications, online gaming platforms, and live collaboration tools. However, it is less frequently used to build native client-side applications for common desktop platforms. As a result, there are very few antivirus signatures for Node.js based malware. In this blog, we dive into the details of NodeLoader and explore the novel techniques used by the threat actors.

Introduction to Malware Binary Triage (IMBT) Course

Looking to level up your skills? Get 10% off using coupon code: MWNEWS10 for any flavor.

Enroll Now and Save 10%: Coupon Code MWNEWS10

Note: Affiliate link – your enrollment helps support this platform at no extra cost to you.

Key Takeaways
ThreatLabz has observed threat actors deploying NodeLoader using the Node Package Manager (NPM) pkg module to turn Node.js code into standalone Windows executable files for malicious purposes.
The threat actors employ social engineering and anti-evasion techniques to deliver NodeLoader undetected.
NodeLoader uses a module called sudo-prompt, a publicly available tool on GitHub and NPM, for privilege escalation.
The malware delivered by NodeLoader includes cryptocurrency miners and information stealers.

Attack ChainAs game streaming has gained in popularity, threat actors are increasingly abusing community platforms like YouTube and Discord to spread malware. Threat actors are creating videos where they show alleged game hacks. However, instead of directing gamers to the game hack, the threat actors are providing links to websites that lead to malware. These websites closely resemble other legitimate gaming websites to avoid raising suspicion, and entice visitors to download a ZIP archive file, extract, and run a malicious executable that we have named NodeLoader. These NodeLoader executables are developed in Node.js and compiled using the pkg module. NodeLoader downloads a PowerShell (PS) script named script.ps1 which in turn, proceeds to download and execute second-stage payloads such as a cryptocurrency miner or information stealers.

The figure below illustrates the entire attack chain.

Figure 1: High-level diagram for the NodeLoader attack chain.

ThreatLabz discovered two YouTube channels with several videos embedding the malicious links in their descriptions. These videos have garnered thousands of views. Some YouTube video descriptions include links to download the malware from popular software distribution services like MediaFire, while others contain links to websites set up by the threat actors themselves.

The figure below shows the malicious links in several YouTube video descriptions:

Figure 2: Example malicious links embedded in YouTube video descriptions that lead to NodeLoader distribution sites.

The malicious website bears a strong resemblance to Korepi (a popular game utility website), as shown in the figure below.

Figure 3: Example malicious website imitating the Korepi game utility website that delivers NodeLoader and ultimately second-stage malware payloads.

Technical AnalysisThe threat actor relies on the user to download, extract, and run the malicious NodeLoader executable file from the fake website. NodeLoader’s code is written in Node.js using JavaScript. The code imports the sudo-prompt module to run commands with elevated privileges. The Node.js code, along with all necessary dependencies, is compiled into a binary executable using the pkg module. This step packages everything needed to run the Node.js code, including the V8 JavaScript engine library.

When the user runs the NodeLoader executable, the V8 JavaScript engine initiates the execution of the Node.js code. Any input/output (I/O) operations are managed by libuv, a multi-platform support library used by Node.js to handle asynchronous I/O tasks. In the compiled NodeLoader executable, the payload and prelude are written in the overlay. The payload is the main source code in bytecode form, which is later executed by the V8 JavaScript engine.

NodeLoader downloads the next stage PS script. Using sudo-prompt for privilege escalation, NodeLoader creates a directory located at C:\ProgramData\SystemInfo and sets the attributes to hidden using the attrib command. NodeLoader then downloads script.ps1, writes the file into the newly created SystemInfo directory as add_exclusion.ps1, and executes it.

User account control (UAC) prompt using sudo-promptOn the Windows platform, the Node.js sudo-prompt package escalates privileges by leveraging the built-in user account control (UAC) system. By default, the Windows UAC prompts the user to allow or deny running tasks as administrator. When NodeLoader is run, sudo-prompt writes the batch command into a file named execute.bat in the user’s temporary directory, then runs this batch file using PS with the -Verb RunAs option.

If UAC is configured to not display a prompt, the batch file will be executed in elevated mode without user consent.
Otherwise, the batch file will execute in elevated mode if the user grants permission in the prompt.

In one example, sudo-prompt was included as a package in the Node.js code but was not used to gain administrator privileges. This meant NodeLoader relied on the user to manually run it as an administrator to work correctly.

In another example, when sudo-prompt is used, the process works differently. It creates a batch file named execute.bat in the temporary folder and runs it automatically using PS.

Defense evasionFor defense evasion, NodeLoader runs the tasklist command to check for the following process names:

chrome.exe
opera.exe
operagx.exe
firefox.exe
steam.exe
spotify.exe
discord.exe
telegram.exe
gamingservice.exe
lightshot.exe
epicgameslauncher.exe

For each process name in the array, NodeLoader calls a function that checks if the given process name is present in the output of the tasklist command using the JS functions includes() and some(). The result of some() (true/false) is then passed to another function, which determines whether the process should continue running or be terminated.

If none of these specified processes are running, NodeLoader terminates. However, if any of these processes are detected, NodeLoader proceeds to the next stage, which involves downloading and executing a PS script via an HTTP GET request.

PowerShell (PS) scriptThe PS script downloads drop1.exe and drop2.exe from the same web server and executes these scripts. In all the cases we observed, drop2.exe was saved as driver.exe and drop1.exe was saved as taskhost.exe, both being downloaded to the previously created directory C:\ProgramData\SystemInfo.

We observed different versions of the PS script. A simpler version was used at first, with additional functionalities being incorporated in later versions. In the later versions, the script included functionality to retrieve and hide the main window of NodeLoader. The malware also added the capability to check if a process is running with administrative privileges.

Payload executionThe PS script downloads the payloads into the directory C:\ProgramData\SystemInfo and executes them. In all the cases we observed, the script downloads an XMRig cryptocurrency miner and an information stealer. The specific information stealer varied in different instances.

XMRig cryptocurrency minerThe drop2.exe executable is a malware dropper that delivers XMRig, an open source cryptocurrency miner. This executable drop2.exe also performs a number of evasion techniques including the following:

The malware adds the directory C:\ProgramData to the Windows Defender exclusion path to avoid detection.
The malware attempts to uninstall Windows updates related to the Windows Malicious Software Removal Tool (KB890830).
The malware sets the registry key Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MRT\DontOfferThroughWUAU to prevent Windows from offering this update even if it is available.
The malware attempts to stop the Windows Event Log Service (EventLog), which is responsible for maintaining a record of system, security, and application events on a Windows system.

In order to establish persistence, the malware creates a service named PHVUTTIO using the sc command, with the binary path set to C:\ProgramData\utblsmnncewd\bbecxurdegum.exe and with the parameter start=”auto” meaning that this service will automatically start when the system boots.The malware then creates a copy of itself in the directory specified in the binary path.

We discovered that the transactions associated with the attacker’s cryptocurrency address were very recent as shown in the figure below.

Figure 4: Recent transactions of the cryptocurrency address associated with the attack.

Phemedrone StealerPhemedrone Stealer was downloaded from the web server using the name drop1.exe. Phemedrone steals data, like history, cookies and login credentials from Google and Microsoft browsers, and uploads it to Telegram.

Lumma Stealer
In addition to downloading Phemedrone, the threat actors utilized a separate malicious URL to deliver a loader for Lumma Stealer. This loader, named taskhost.exe, was downloaded to the C:\ProgramData\SystemInfo directory using a PS script.
The initial loader is a .NET executable, which contains a shellcode and the Lumma Stealer payload, both stored in RC4 encrypted form. The loader decrypts the shellcode and the Lumma Stealer payload. Post decryption, the shellcode is written into its own memory space with PAGE_EXECUTE_READWRITE permissions and executed as a thread, with the base address of the Lumma Stealer payload passed as an argument. The shellcode dynamically resolves APIs by traversing the process environment block (PEB), with the API names stored as plain text strings.
Once the APIs are resolved, the shellcode creates a process named RegAsm.exe in a suspended state, writes the Lumma Stealer payload into the memory of this newly created process, and then executes the payload’s entry point, thereby activating Lumma Stealer.
During our analysis, we observed that the threat actors were periodically changing the stealer malware hosted on the web server.

Low antivirus detection ratesWhen compiled using the pkg NPM module, a single line of code results in a large Windows binary exceeding 35 MB. This large file size complicates detection for some security products. In addition, there are far fewer signatures for malicious JavaScript-based code. As a result, many of the NodeLoader binaries associated with this campaign currently have zero antivirus and EDR detections. The appendix provides indicators of compromise including sample hashes.

ConclusionAs game streaming and community platforms continue to rise in popularity, threat actors will seek new ways to abuse them. This underscores the critical importance of educating those who may fall victim to such attacks and reveal novel techniques for malware distribution to improve detection rates.

Zscaler plays a vital role in thwarting such attacks through full SSL inspection at scale, browser isolation, and policy-driven access control. The Zscaler Cloud Sandbox has consistently proven successful in detecting the malware involved in this campaign and its numerous variants. Zscaler ThreatLabz remains committed to monitoring and tracking these campaigns, sharing valuable insights with the wider community.

Zscaler CoverageZscaler’s multilayered cloud security platform detects indicators related to this campaign at various levels as shown below.

Win64.Downloader.NodeJS
Win64.Coinminer.Xmrig
Win32.PWS.PhemeDrone
Win32.PWS.Lumma

Figure 5: Zscaler Cloud Sandbox report for NodeLoader.

Indicators Of Compromise (IOCs)Host indicatorsType

Stage

IOC

Description

Threat Name

MD5

Stage 2

fd4265d9049571e4610944ada00f3077
95013bd1659067c4f11213dcd1de1023
d93a5a607d72c7efc51640c9ec789ea6
bbeacc49e863e9ec1576ba0128f26579
c99b721ae647bd058d0269d9ecb07421
1555940d0adeb059c695ab317a2c641c
dedc2d7f699be025c3282a0f385fd4d5
bfc83f0def461d7113922a1444b957bb
1a6e1620405531211d4c26fc9f29673e

NodeLoader

executables

Win64.Downloader.NodeJS

MD5

Stage 3

f35825c9bb3ed6e46da5b61363863036
c0be666ffbd3edc3b5bcd9aa6f6a461a
36f9b70a18f331239b6e7ea394837b60
20817afa0a3e77f1b6ccfe6a4488c61c

PS script

PS.Downloader.Xmrig

MD5

Final payload

4cc366dff42687e475c6718f6437f754

Phemedrone Stealer

Win32.PWS.PhemeDrone

MD5

Final payload

b748b605cf8d9e3103701202143aa092

Phemedrone Stealer

Win32.PWS.PhemeDrone

MD5

Final payload

6424419ac4c6f0a24c95233e527c1e8a

XMRig coin miner

Win64.Coinminer.Xmrig

MD5

Final payload

c3fc67d2f8a7f517b1a834f923136865

Lumma Stealer

Win32.PWS.Lumma

Network indicatorsType

Stage

IOC

Description

URL

Stage 1

korepi[.]xyz

Fraudulent website

URL

Stage 2

hxxps://chillers.com[.]ar/temp/lotrik.exe

URL to download

Lumma Stealer

IP

Stage 2

195[.]10[.]205[.]253

Open directory

URL

Stage 4

condedqpwqm[.]shop

Lumma C2

URL

Stage 4

locatedblsoqp[.]shop

Lumma C2

URL

Stage 4

stagedchheiqwo[.]shop

Lumma C2

URL

Stage 4

stamppreewntnq[.]shop

Lumma C2

URL

Stage 4

millyscroqwp[.]shop

Lumma C2

URL

Stage 4

caffegclasiqwp[.]shop

Lumma C2

URL

Stage 4

traineiwnqo[.]shop

Lumma C2

MITRE ATT&CK TechniquesType

Technique Name

T1204.002

User Execution: Malicious File

T1059.001

Command and Scripting Interpreter: PowerShell

T1562.001

Impair Defenses: Disable or Modify Tools

T1562.002

Impair Defenses: Disable Windows Event Logging

T1543.003

Create or Modify System Process: Windows Service

T1041

Exfiltration Over C2 Channel

Article Link: NodeLoader Used to Deliver Malware | ThreatLabz