Phantom Menace: The Ghost Loader Infostealer Campaign
Alessandra
Rizzo
Feb 19, 2026
Introduction
Our in-house NPM package scanner identified a multi-stage credential stealer distributed through the npm registry. The malware, which we have dubbed "Ghost Loader" based on internal naming conventions, employs a sophisticated blockchain-based command and control infrastructure using Binance Smart Chain smart contracts, with multiple dead drop mechanisms for payload delivery.
At moment of writing, we have identified at least eight packages spanning multiple social engineering themes: React ecosystem typosquats, fake AI trading tools, fake Coinbase wallet utility, and Carbon Copy Cloner impersonation. Our analysis of the BSC smart contract configuration reveals three active affiliate partners (Steve, darkslash, Pavel), suggesting additional undiscovered packages may exist.
The packages contain a CLI "setup wizard" that tricks developers into entering their sudo password to perform "system optimizations." The captured password is then passed to a comprehensive credential stealer payload that harvests browser credentials, cryptocurrency wallets, SSH keys, cloud provider configurations, and developer tool tokens. Stolen data is routed to partner-specific Telegram bots based on a campaign identifier embedded in each loader, with credentials stored in the BSC smart contract and updated without modifying the malware itself.
Ghost Loader employs a three-stage delivery chain with interchangeable components: the initial npm package captures credentials and fetches configuration from either a Telegram channel or a Teletype.in page disguised as blockchain documentation. The loader then decodes a GitHub Gist URL and retrieves an AES-256-GCM encrypted payload. The decryption key is split across two sources, half hardcoded in the loader and half retrieved from the dead drop, making static analysis and automated sandbox execution significantly more difficult.
The malware implements a dual revenue model: primary income from credential theft routed through partner Telegram channels, and secondary income through affiliate URL redirects stored in a separate BSC targeting contract. Transaction analysis shows the infrastructure was actively updated as recently as February 5, 2026.
Our analysis indicates this is likely a Malware-as-a-Service (MaaS) offering that was, at least partially, LLM-generated. The author's GitHub activity reveals active use of jailbreak tools and AI coding agents, though our stylometric analysis could not attribute the code to any specific model. This highlights an emerging challenge: AI-assisted malware may be identifiable as such, but attributing it to specific tools or actors is becoming increasingly difficult.
Technical Analysis
Infection Chain
The infection begins when a victim user installs the malicious npm package via postinstall scripts. The packages typosquat legitimate ecosystems and tools, such as React, Carbon Copy Cloner and CoinBase.
The loader presents a minimal fake CLI interface with animated spinners and progress bars.
(asyncfunction main(){clear();console.log(bold("React State Optimizer - Setup Wizard"));console.log(gray("v3.0.9 | High-Performance State Management Configuration"));console.log("==================================================\\n");awaitdelay(500);awaitspinner("Analyzing project structure...",1500);awaitspinner("Checking package dependencies...",1200);awaitspinner("Verifying system compatibility...",1000);console.log("\\n" + bold("⚠ Optimization Required"));console.log(" To ensure maximum performance, this tool needs to adjust system limits (ulimit)");console.log(" and configure kernel parameters for high-frequency state updates.\\n");
(asyncfunction main(){clear();console.log(bold("React State Optimizer - Setup Wizard"));console.log(gray("v3.0.9 | High-Performance State Management Configuration"));console.log("==================================================\\n");awaitdelay(500);awaitspinner("Analyzing project structure...",1500);awaitspinner("Checking package dependencies...",1200);awaitspinner("Verifying system compatibility...",1000);console.log("\\n" + bold("⚠ Optimization Required"));console.log(" To ensure maximum performance, this tool needs to adjust system limits (ulimit)");console.log(" and configure kernel parameters for high-frequency state updates.\\n");
(asyncfunction main(){clear();console.log(bold("React State Optimizer - Setup Wizard"));console.log(gray("v3.0.9 | High-Performance State Management Configuration"));console.log("==================================================\\n");awaitdelay(500);awaitspinner("Analyzing project structure...",1500);awaitspinner("Checking package dependencies...",1200);awaitspinner("Verifying system compatibility...",1000);console.log("\\n" + bold("⚠ Optimization Required"));console.log(" To ensure maximum performance, this tool needs to adjust system limits (ulimit)");console.log(" and configure kernel parameters for high-frequency state updates.\\n");
(asyncfunction main(){clear();console.log(bold("React State Optimizer - Setup Wizard"));console.log(gray("v3.0.9 | High-Performance State Management Configuration"));console.log("==================================================\\n");awaitdelay(500);awaitspinner("Analyzing project structure...",1500);awaitspinner("Checking package dependencies...",1200);awaitspinner("Verifying system compatibility...",1000);console.log("\\n" + bold("⚠ Optimization Required"));console.log(" To ensure maximum performance, this tool needs to adjust system limits (ulimit)");console.log(" and configure kernel parameters for high-frequency state updates.\\n");
It claims to need sudo access to "adjust system limits (ulimit) and configure kernel parameters for high-frequency state updates." When the user enters their password, the loader validates it against the system, captures it, and passes it to the Stage 2 payload.
The loader then fetches the attacker-controlled Telegram channel's public HTML page, extracts a base64-encoded GitHub Gist URL from a channel post, and retrieves the second half of the decryption key from the channel bio, which the attacker marked as bitcoin wallet but it is not a valid address. After decrypting the payload with the combined key, it spawns the infostealer payload as a child process, with the captured password available via environment variable.
Stage 1: Loader
The loader (scripts/setup.js) prompts the user to insert the sudo password and validates it with sudo -S -v -k. The -k flag invalidates the cached credential, -v validates without running a command, and -S reads from stdin. This loop ensures the attacker only receives valid credentials.
It then decodes the Telegram channel URL, encoded in base64 and with characters reversed:
The retrieved file, npm_init_gist.txt , is the encrypted, second stage payload which is decrypted and spawned by the initial setup.js file contained in the NPM package.
The captured sudo password is passed to the Stage 2 payload via the GHOST_PWD environment variable.
In addition to the Telegram channel dead drop mechanism, we have identified a new variant using Teletype.in as an alternative configuration distribution platform. This variant, discovered on February 5, 2026, impersonates "Coinbase Desktop Wallet SDK" and is attributed to the "Pavel" partner.
The loader fetches configuration from a Teletype.in page disguised as legitimate blockchain documentation:
Dead Drop URL: <https://teletype.in/@youtubeshorts/4rhoJvGx1pK>
The page is titled "Ethereum Smart Contract Verification" and contains fake technical information to appear legitimate. Hidden within the content are two critical values:
Field
Value
Purpose
ID
7de98acb7f580be0359f7368a0230829
KEY_PART_B (second half of AES key)
ABI Hash
Base64-encoded Gist URL
Payload location
The "ABI Hash" decodes to the same GitHub Gist used by other variants:
This variant presents as a legitimate Coinbase wallet integration tool with a fake UI:
console.log(bold("Coinbase Desktop Wallet SDK"));console.log(gray("v1.5.14 | Secure Wallet Integration Suite"));console.log(gray("Copyright (c) 2024 Coinbase, Inc.\\n"));
// ProgressbarswithrealistictimingawaitrealisticProgressBar("Wallet Core");logSystem("Loaded 847 cryptographic modules in 0.3s");awaitrealisticProgressBar("Hardware Wallet Bridge");logSystem("USB HID driver compatible");awaitrealisticProgressBar("Keychain Access");
// Fakekeychainauthorizationpromptconsole.log(yellow(bold("⚠ Keychain Authorization Required")));console.log(white("To securely store wallet credentials in the macOS Keychain,"));console.log(white("administrator privileges are required for the initial setup."));
console.log(bold("Coinbase Desktop Wallet SDK"));console.log(gray("v1.5.14 | Secure Wallet Integration Suite"));console.log(gray("Copyright (c) 2024 Coinbase, Inc.\\n"));
// ProgressbarswithrealistictimingawaitrealisticProgressBar("Wallet Core");logSystem("Loaded 847 cryptographic modules in 0.3s");awaitrealisticProgressBar("Hardware Wallet Bridge");logSystem("USB HID driver compatible");awaitrealisticProgressBar("Keychain Access");
// Fakekeychainauthorizationpromptconsole.log(yellow(bold("⚠ Keychain Authorization Required")));console.log(white("To securely store wallet credentials in the macOS Keychain,"));console.log(white("administrator privileges are required for the initial setup."));
console.log(bold("Coinbase Desktop Wallet SDK"));console.log(gray("v1.5.14 | Secure Wallet Integration Suite"));console.log(gray("Copyright (c) 2024 Coinbase, Inc.\\n"));
// ProgressbarswithrealistictimingawaitrealisticProgressBar("Wallet Core");logSystem("Loaded 847 cryptographic modules in 0.3s");awaitrealisticProgressBar("Hardware Wallet Bridge");logSystem("USB HID driver compatible");awaitrealisticProgressBar("Keychain Access");
// Fakekeychainauthorizationpromptconsole.log(yellow(bold("⚠ Keychain Authorization Required")));console.log(white("To securely store wallet credentials in the macOS Keychain,"));console.log(white("administrator privileges are required for the initial setup."));
console.log(bold("Coinbase Desktop Wallet SDK"));console.log(gray("v1.5.14 | Secure Wallet Integration Suite"));console.log(gray("Copyright (c) 2024 Coinbase, Inc.\\n"));
// ProgressbarswithrealistictimingawaitrealisticProgressBar("Wallet Core");logSystem("Loaded 847 cryptographic modules in 0.3s");awaitrealisticProgressBar("Hardware Wallet Bridge");logSystem("USB HID driver compatible");awaitrealisticProgressBar("Keychain Access");
// Fakekeychainauthorizationpromptconsole.log(yellow(bold("⚠ Keychain Authorization Required")));console.log(white("To securely store wallet credentials in the macOS Keychain,"));console.log(white("administrator privileges are required for the initial setup."));
The loader checks for passwordless accounts using dscl . -authonly before prompting for credentials.
Stage 2: Credential Stealer Payload
The full decrypted payload is a comprehensive credential stealer implemented in Node.js and protected with obfuscator.io transformations. It employs obfuscator.io transformations including string array rotation with a checksum-validated shuffle. Strings are stored in an array and accessed through a decoder function.
The decryption key is split across two sources to defeat automated analysis:
Component
Source
Value
Key Part A
Hardcoded in loader
ef36142cde72f97c25cdd1f4f2b40da8
Key Part B
Telegram channel bio
Dynamic (rotatable)
This ensures the payload cannot be decrypted without access to the Telegram channel.
The malware reads the captured password from process.env.GHOST_PWD and escalates to the root user to access protected system resources.
Collection Functions
The malware implements dedicated stealer functions for each data type:
Function
Target
What It Does
findSSHKeys()
SSH credentials
Scans ~/.ssh/ for id_rsa, id_ed25519, id_ecdsa, known_hosts, config
This malware is particularly exhaustive in collecting developer credentials, wallets, SSH keys and cloud configuration files. The full tables of targeted paths is available in the Appendix.
If certain files are protected, the malware uses the captured sudo password for privileged operations.
Analysis of the obfuscated Stage 2 payload revealed the BSC smart contract address through a known-plaintext attack on the string array rotation. The deobfuscation identified a rotation count of 482, which successfully decoded the contract address fragments.
The payload queries contract 0x358733fb7F3d00324A3825c6A0cF54751841C162 using eth_call with selector 0x358733fb:
Upon analyzing the transaction history for the main contract address,0xF9f95728dCb1BdAb4F0214CbE1672BAC072c647c, we have also found that some of the input data in the blockchain resolves to specific domains, which we assess with moderate confidence could be a traffic redirection strategy for potential affiliate programs.
Contract
Address
Purpose
Methods
Config Contract
0x358733fb7F3d00324A3825c6A0cF54751841C162
Stores Telegram bot credentials
Set Config
Targeting Contract
0x269C185BAf4D9e21C8Fef8f5A60dbfC64ca47a4C
Affiliate URL mapping
Set Target, 0xce2b2255
Controller
0xF9f95728dCb1BdAb4F0214CbE1672BAC072c647c
Operator wallet
—
While the primary payload steals credentials and exfiltrates them to partner-specific Telegram bots, the malware also queries a secondary BSC contract to retrieve affiliate redirect URLs. Victims are redirected through URL shorteners (buycry[.]short[.]gy) to sites like nakedly[.]ai, generating additional affiliate revenue for the operators.
Text-based data, such as system fingerprints, clipboard captures containing cryptocurrency addresses or API keys, infection notifications, and heartbeat pings is transmitted via HTTPS POST to the /sendMessage Telegram endpoint.
File-based loot, such as browser databases, wallet files, cloud credentials, and SSH keys is compressed into a tarball using tar -czf "report.tar.gz" and uploaded via multipart/form-data POST through the /sendDocument endpoint.
After exfiltration, the local loot directory is deleted from the victim machine.
LaunchAgent is a background process managed by launchd that automatically starts, stops, and manages jobs, scripts, or applications on behalf of a specific user. Unlike LaunchDaemons, which run as the root user for the entire system, LaunchAgents run only when a user logs in and operate within that user's session.
Attribution
The malware exhibits characteristics consistent with commodity infostealer malware commonly sold on underground forums, and several indicators suggest this is a Malware-as-a-Service (MaaS) offering:
Campaign ID Tracking: The loader sets GHOST_CID: 'darkslash', suggesting operator-specific campaigns. The malware also drops a .ghost_id file containing a randomly generated string marker.
Modular Architecture: Clean separation between loader and payload enables customization
Configurable C2: Telegram bot tokens and chat IDs are easily replaceable
Another indicator, removed in a later version, had the specific MaaS (Malware-as-a-Service) notation left as a comment:
We assess with high confidence that this malware was, at least partially, LLM-generated. The same package we initially found, react-query-core-utils, had a total of 12 versions published in the span of two days before being removed by the author. The differences in versions demonstrate the author was iteratively changing bits and pieces of the malware. For example, an earlier version had the Telegram channel message in clear and subsequently changed to the base64 encoded version with the comment “Obfuscated Endpoint”:
Earlier versions of the package contained extremely verbose helper comments detailing exactly what it was doing, as such:
All the comments followed this thorough explaining in perfect English. Furthermore, the malware targets virtually every wallet, extension and platform, resulting in a malware that reads as the product of someone prompting an LLM to write a Node.js CLI tool that targets a list of every single potential credential path on a victim system. The code in this malware is also “templatey”, meaning that every function follows the same pattern with try-and-except blocks while having an extremely clean, repeating structure.
A few other indicators do suggest, at least partly, active human participation, such as the blockchain C2 mechanism which is a relatively novel technique, the Telegram infrastructure itself and the usage of obfuscator.io family for obfuscation.
In this case, attribution becomes non-trivial. The malware author’s usage of LLM ends up producing malware which will not be reused among threat actors and will probably become drastically different as the threat actor iterates through new versions of the malware.
The accessibility of technical skills through LLM-enabled scripting has successfully armed a potentially low-level technical actor with a multi-stage, multi-layer malware that uses inexpensive C2 communication and malware hosting through NPM, GitHub and Telegram to deliver a comprehensive credential stealer.
The barrier to entry for "credential stealer with blockchain C2 and multi-platform targeting" used to require significant skill. Now it requires intent and iteration. Although this is not a novel concept, it does bear the question of what a motivated and financially resourceful threat actor can achieve with the same tools.
The GitHub account hosting the malware's encrypted payload, stopstalkermebitch, had starred repositories revealing the author's toolkit: jailbreak utilities for removing LLM safety guardrails (heretic), collections of leaked system prompts for AI tools, multiple AI coding assistants (aider, opencode, claude_code_RLM), and resources for running LLMs locally. This profile is consistent with someone who understands how to manipulate language models and has potentially produced typically blocked content, plausibly through AI coding agents as their primary development workflow.
LLM Prompt Experiment
We have conducted a research experiment where we designed a (benign) prompt to be given to multiple LLM models to find whether it is possible to attribute this malware code style to a specific AI model.
YouareaseniorJavaScripttoolingengineerwritingapolished,production-qualityNode.jsCLIsetupwizardfordevelopers.
Thetool should:
Runina terminal andfeel like a professional installer.
Use spinners,coloredoutput,andstaged progress messages
Be written as a single self-contained script
Very important:
Organize the file into clearly labeled sections using comment banners(forexample: utilities,main CLI flow,helper logic,executionlogic).
Prioritize readability andonboarding clarity over brevity.
Include comments that explain what each section isresponsiblefor,asifanother developer will audit ormaintain it.
The structure should read top-to-bottom like a walkthrough.
The script does not need to actually modify the system ornetwork;mockorsimulateanyprivilegedorslowoperations.
Produceonlythefinalscript
YouareaseniorJavaScripttoolingengineerwritingapolished,production-qualityNode.jsCLIsetupwizardfordevelopers.
Thetool should:
Runina terminal andfeel like a professional installer.
Use spinners,coloredoutput,andstaged progress messages
Be written as a single self-contained script
Very important:
Organize the file into clearly labeled sections using comment banners(forexample: utilities,main CLI flow,helper logic,executionlogic).
Prioritize readability andonboarding clarity over brevity.
Include comments that explain what each section isresponsiblefor,asifanother developer will audit ormaintain it.
The structure should read top-to-bottom like a walkthrough.
The script does not need to actually modify the system ornetwork;mockorsimulateanyprivilegedorslowoperations.
Produceonlythefinalscript
YouareaseniorJavaScripttoolingengineerwritingapolished,production-qualityNode.jsCLIsetupwizardfordevelopers.
Thetool should:
Runina terminal andfeel like a professional installer.
Use spinners,coloredoutput,andstaged progress messages
Be written as a single self-contained script
Very important:
Organize the file into clearly labeled sections using comment banners(forexample: utilities,main CLI flow,helper logic,executionlogic).
Prioritize readability andonboarding clarity over brevity.
Include comments that explain what each section isresponsiblefor,asifanother developer will audit ormaintain it.
The structure should read top-to-bottom like a walkthrough.
The script does not need to actually modify the system ornetwork;mockorsimulateanyprivilegedorslowoperations.
Produceonlythefinalscript
YouareaseniorJavaScripttoolingengineerwritingapolished,production-qualityNode.jsCLIsetupwizardfordevelopers.
Thetool should:
Runina terminal andfeel like a professional installer.
Use spinners,coloredoutput,andstaged progress messages
Be written as a single self-contained script
Very important:
Organize the file into clearly labeled sections using comment banners(forexample: utilities,main CLI flow,helper logic,executionlogic).
Prioritize readability andonboarding clarity over brevity.
Include comments that explain what each section isresponsiblefor,asifanother developer will audit ormaintain it.
The structure should read top-to-bottom like a walkthrough.
The script does not need to actually modify the system ornetwork;mockorsimulateanyprivilegedorslowoperations.
Produceonlythefinalscript
We tested this with models from several LLM providers, and also multiple models from one provider. We found that no model produced the same stylistic markers as the npm package’s code. We tested 11 models with identical prompts, and none ended up reproducing the malware's distinctive // --- SECTION --- comment style. Ironically, the triple-dash pattern appears to be the author's personal convention applied post-generation or through exact prompting, not a model fingerprint.
Model
Section Header Style
Malware
// --- SECTION ---
Claude Sonnet 3.5v1
No headers
Claude Sonnet 4
JSDoc /** */
Claude Sonnet 4.5
// ========
Claude Opus 3
JSDoc + markdown
Claude Opus 4.5
// ========
GPT-5
/* ======= */
GPT-5.2
JSDoc
DeepSeek-R1
// ========
Gemini 3
// ========
Kimi 5.2-instant
// ═══════ (box-drawing)
Agentic Malware: A Scary Thought
We continued our investigation by inspecting the GitHub profile of the user who is hosting the encrypted JS payload, stopstalkermebitch.
The user’s activity is private except for the starred repositories, which are for the major part related to LLM tool assistance, development and jailbreaking.
One repository, heretic , is particularly interesting. From the README:
Another one, system-prompts-and-models-of-ai-tools , is a collection of “hidden” default prompts allegedly running under the hood of the most popular LLM models.
Ghost Loader feels like an intermediate stage in AI-assisted malware: the author prompts, the agent generates, the author reviews and iterates. We can call this "human-in-the-loop" malware development. But the author's starred repositories hint at where this is heading. The components for fully autonomous malware development already exist:
Component
Status
Autonomous coding agents
Available (aider, opencode, Claude Code)
Jailbreak tooling
Available (heretic, leaked system prompts)
Free compute
Available (API free tiers, local LLMs)
Free infrastructure
Available (npm, PyPI, GitHub, Telegram, Blockchain)
Success metrics
Available (download counts, exfil confirmations)
What's missing is orchestration: connecting these pieces into a continuous loop where an agent generates payload variants, deploys them, evaluates success rates, and iterates.
Traditional malware detection relies on malware fingerprinting and specific techniques used. In this specific case, most of what we can investigate is disposable: GitHub profiles 1 month old, NPM accounts created with Proton mail, LLM generated code. Fully agentic malware, if that will ever be occurring, would accelerate this to an extreme.
Conclusion
Ghost Loader is an interesting piece of malware due to its clever three-stage delivery chain and blockchain configuration retrieval. Its technical capabilities are standard for a commodity infostealer malware and it seems to be in early stages of development. Perhaps what is most interesting is not its sophistication but its accessibility. The distribution occurs through free infrastructure and disposable accounts, and the malware itself appears to be a partly AI-generated tool, highlighting that the barrier to entry for threat actors in the malware game has lowered significantly. Developing a multi-stage, multi-layer obfuscated malware with real infrastructure behind it seems to require just a couple of days. The countermeasures remain familiar: supply chain monitoring, behavioral detection, and credential hygiene. We assess with high confidence that the volume and velocity of threats like Ghost Loader will increase.
defrule(event):
....
returnall([event_platform == "Mac",fdr_event_type == "ProcessRollup2",image_filename == "/usr/bin/plutil",])deftitle(_):
return"Crowdstrike: plutil was used to modify a plist fileononeormoredevices"
defrule(event):
....
returnall([event_platform == "Mac",fdr_event_type == "ProcessRollup2",image_filename == "/usr/bin/plutil",])deftitle(_):
return"Crowdstrike: plutil was used to modify a plist fileononeormoredevices"
defrule(event):
....
returnall([event_platform == "Mac",fdr_event_type == "ProcessRollup2",image_filename == "/usr/bin/plutil",])deftitle(_):
return"Crowdstrike: plutil was used to modify a plist fileononeormoredevices"
defrule(event):
....
returnall([event_platform == "Mac",fdr_event_type == "ProcessRollup2",image_filename == "/usr/bin/plutil",])deftitle(_):
return"Crowdstrike: plutil was used to modify a plist fileononeormoredevices"