PhantomStealer: A Four-Stage .NET Infostealer Hidden Inside a 4.4 MB JavaScript File
Commercially sold MaaS stealer uses WSH dropper, rotational XOR encryption, and process injection into signed Microsoft binaries to harvest credentials from 50+ browsers and 40+ crypto wallets.
This sample is a Phantom Stealer instance -- a commercially sold .NET infostealer marketed via phantomsoftwares.site and Telegram (@Oldphantomoftheopera). The infection chain is a three-stage dropper: a heavily obfuscated Windows Script Host (WSH) JavaScript file executes PowerShell, which decrypts and reflectively loads a .NET injector (DEV.DOWN), which in turn injects the final stealer payload into a aspnet_compiler.exe host process. The stealer targets credentials and session tokens from 50+ Chromium/Gecko-based browsers, Discord, Telegram, 40+ browser-extension crypto wallets, 9 desktop crypto wallets, email clients (Outlook, FoxMail, Thunderbird), FTP clients (FileZilla, WinSCP), WiFi passwords, and clipboard content. It also includes a keylogger and screenshot module. Exfiltration uses operator-configured channels: Discord webhook, Telegram bot, FTP, or SMTP. The malware is active and the C2 domain was first observed in February 2025.
Sample Metadata
| Field | Value |
|---|---|
| Filename | 440924160cd002f96143ab33e2f67a76.js |
| SHA256 | 129ad6e221e949303456a7b3cf381d9f1b1e97b203c689b9b1205d4d37693b28 |
| MD5 | 440924160cd002f96143ab33e2f67a76 |
| SHA1 | ec49cea5c2c4e2a0369ac26b0207b5d17ce2fab7 |
| File Type | JavaScript (Windows Script Host) -- text/plain |
| File Size | 4,609,423 bytes (4.4 MB) |
| VT Detections | Not yet indexed (first seen 2026-03-12) |
| First Seen | 2026-03-12 17:15:16 UTC |
| Reporter | abuse_ch |
| Tags | js, PhantomStealer |
Infection Chain Overview
Stage 1: WSH JavaScript Dropper (.js)
|-- Obfuscated with JavaScriptObfuscator
|-- Decodes base64 -> writes PS1 to C:\Temp\ps_<random>_<timestamp>.ps1
|-- Executes: powershell.exe -ExecutionPolicy Bypass -WindowStyle Hidden -File "<PS1>"
|-- Monitors process, deletes script after execution
|-- Self-terminates WScript/CScript children on timeout via WMI+taskkill
Stage 2: PowerShell Loader (in-memory, ~3.45 MB)
|-- Contains encrypted blob (base64 + rotational XOR)
|-- XOR key: 49vAX3r4J78bDtS8rruEkot178HPGBRpbhFmXjZIHbU= (base64)
|-- Decrypts to second PS1 that loads a .NET assembly via Reflection
Stage 3: .NET Injector DLL -- DEV.DOWN (47 KB)
|-- Type: DEV.DOWN, Method: SHOOT
|-- AES-encrypted payload handling (key: jodTFE2vRldtBtx91i.PYSXl3H4CfuFjxYYPp)
|-- Injects into aspnet_compiler.exe via NtCreateThreadEx + VirtualAllocEx
Stage 4: Phantom Stealer .NET EXE (735 KB)
|-- In-memory execution; self-identifies as "Phantom stealer"
|-- Harvests credentials, wallets, tokens, screenshots, keystrokes
|-- Exfiltrates via Discord webhook / Telegram bot / FTP / SMTP
The attack begins with a 4.4 MB JavaScript file -- unusually large for a dropper, because it carries the entire encrypted payload chain inline. Each stage peels off a layer of obfuscation before handing execution to the next, culminating in a fileless stealer running inside a legitimate Microsoft process.
Static Analysis
Stage 1 -- JavaScript Dropper
| Property | Detail |
|---|---|
| Obfuscator | JavaScriptObfuscator (string-array rotation, control-flow flattening) |
| Runtime | Windows Script Host (WScript.exe / CScript.exe) |
| Anti-analysis | ReDoS pattern (((.+)+)+) used as debugger/engine timing check |
| Execution method | WScript.Shell.Exec() for PowerShell launch |
| File operations | Scripting.FileSystemObject, ADODB.Stream for base64-to-binary decode |
| Temp directory | C:\Temp\ |
| Script naming | ps_<10 random chars>_<unix timestamp>.ps1 |
| Cleanup | DeleteFile on SCRIPT_PATH after execution; taskkill /f /im wscript.exe on timeout |
Key deobfuscated string-table entries include references to powershell, -ExecutionPolicy Bypass, -WindowStyle Hidden, Scripting.FileSystemObject, WScript.Shell, and a WMI query targeting pwsh.exe, wscript.exe, and cscript.exe processes via winmgmts:\\.\root\cimv2.
Stage 2 -- PowerShell Loader
| Property | Detail |
|---|---|
| Size (decoded) | 3,449,814 bytes |
| Encryption | Multi-stage: base64 outer layer + rotational XOR decryption |
| XOR algorithm | Key-byte rotational (rotationTracker += key[keyPos] % 7) |
| Framework | PowerShell .NET reflection ([System.Reflection.Assembly]::Load()) |
| Anti-evasion | Monitors for Aspnet_compiler process presence before executing |
| Execution paths | Invoke-Expression, [ScriptBlock]::Create().Invoke(), anonymous scriptblock |
The PowerShell stage is where the real encryption work happens. A 3.45 MB blob is decoded from base64, then decrypted using a rotational XOR algorithm with a 32-byte key. The rotation tracker increments by key[keyPos] % 7 on each byte, making simple XOR brute-forcing insufficient -- you need the exact key and rotation logic to recover the plaintext.
Stage 3 -- DEV.DOWN .NET Injector
| Property | Detail |
|---|---|
| SHA256 | 195e3d859d8fa9d0c12cd38beef8898e307b71422c8a18c2c3648f5f0220b447 |
| MD5 | 061c1eed62c8326f2c8052851090f33d |
| Size | 47,104 bytes |
| CLR Version | v4.0.30319 |
| Namespace | DEV |
| Entry class/method | DEV.DOWN::SHOOT |
| Injection target | aspnet_compiler.exe (legitimate .NET SDK tool) |
| Techniques | VirtualAllocEx, NtCreateThreadEx, GetProcessById |
| Crypto | AES via System.Security.Cryptography.AesCryptoServiceProvider |
| AES key | jodTFE2vRldtBtx91i.PYSXl3H4CfuFjxYYPp (embedded in #US heap) |
The choice of aspnet_compiler.exe as an injection target is deliberate. It is a signed Microsoft binary that ships with the .NET SDK, making it a plausible process on developer workstations and less likely to trigger application whitelisting alerts. The injector uses VirtualAllocEx to allocate memory in the target process and NtCreateThreadEx to execute the payload -- a classic process injection pattern, but effective when the host process is trusted.
Stage 4 -- Phantom Stealer Payload
| Property | Detail |
|---|---|
| SHA256 | 481fd4fefa706e606cfc368c68f1ef313f07c6e2849a26d7c94f7c8433884a1b |
| MD5 | c8c7d7988cf9eb2a94ba0144f334d8b1 |
| Size | 751,616 bytes |
| CLR Version | v4.0.30319 |
| Architecture | x86 (PE32, GUI subsystem) |
| Sections | .text, .rsrc, .reloc |
| Dependencies | Newtonsoft.Json 13.0, ILMerge/Costura, SharpZipLib |
| Namespace | Stub.* |
| Self-identifier | "Phantom stealer" |
| Build marker | "Bruno" (likely developer alias or build tag) |
The stealer payload is a monolithic .NET executable with Costura-merged dependencies. Its capability modules map cleanly to discrete theft functions:
- Stub.AntiAnalysis -- Sandbox/debugger detection, suspicious process termination
- Stub.Browsers -- Chromium + Gecko credential/cookie/wallet harvesting
- Stub.BrowserWalletExtensionsHelper -- 40+ crypto extension wallets
- Stub.DiscordSendLogs / Stub.UploadToDiscord -- Discord webhook exfiltration
- Stub.TelegramSendLogs / Stub.UploadToTelegram -- Telegram bot exfiltration
- Stub.FtpSendLogs / Stub.UploadToFtp -- FTP exfiltration
- Stub.SmtpSendLogs / Stub.UploadToSmtp -- SMTP exfiltration
- Stub.Downloader -- Download additional payloads (fileless variant supported)
- Stub.FileGrabber / Stub.GrabbedFiles -- File grabbing by extension
- Stub.KeyloggerServices -- Low-level keyboard hook (
WH_KEYBOARD_LL) - Stub.SystemInfo -- System fingerprinting, public IP retrieval
- Stub.Reports -- Log packaging and archival (ZIP with password)
The .text section is approximately 700 KB with embedded compressed libraries via Costura. No external packer was detected.
Behavioral Analysis
Based on static analysis, the following runtime behavior is expected:
Anti-analysis checks. The stealer enumerates running processes via NtQuerySystemInformation, detecting sandboxes, hypervisors, and analysis tools. If a suspicious environment is detected, it self-destructs.
Browser credential harvesting. It reads Login Data (SQLite), Cookies (SQLite), and Web Data from all Chromium user profiles. Notably, it bypasses Chrome v127+ App-Bound Encryption by extracting app_bound_encrypted_key, and falls back to DPAPI-protected master keys for older Chrome versions. All 50+ listed Chromium browsers are targeted.
Crypto wallet extraction. Wallet files are copied from %AppData%\Roaming\ and registry paths for 9 desktop wallets. Browser extension data for 40+ extension wallets is read from Chrome and Edge profiles.
Discord and Telegram harvesting. Discord tokens are extracted from local storage LevelDB files and validated against https://discord.com/api/v9/users/@me. Telegram session data is read from the Windows registry.
Keylogging. A WH_KEYBOARD_LL global hook is installed in a background thread.
Screenshots. The CaptureScreenshot/ScreenshotLoop functions use Graphics.CopyFromScreen for periodic screen capture.
Persistence. An optional registry entry is added to SOFTWARE\Microsoft\Windows\CurrentVersion\Run.
WiFi passwords. The stealer executes netsh wlan show profile name="<SSID>" key=clear for each saved network.
Exfiltration. All stolen data is archived as a password-protected ZIP file. A report summary and the archive are sent to the operator's configured channels (Discord webhook, Telegram bot, FTP, or SMTP). The channel configuration is AES-encrypted within the binary and decrypted at runtime.
Network Indicators
| Type | Value | Purpose |
|---|---|---|
| Domain | phantomsoftwares.site | C2 / Operator infrastructure |
| IP | 199.188.201.183 | C2 server IP (Namecheap, Phoenix US, AS22612) |
| URL | https://www.phantomsoftwares.site/home | Stealer C2 / operator site |
| URL | https://www.phantomsoftwares.site/logo/phantom_discord.png | Discord embed image |
| URL | https://discord.com/api/v9/users/@me | Discord token validation |
| Telegram | https://t.me/Oldphantomoftheopera | Operator Telegram contact |
| Protocol | FTP (port 21) | FTP exfiltration channel |
| Protocol | SMTP | Email exfiltration channel |
C2 infrastructure details: The domain is registered through Namecheap with DNS handled by Cloudflare (jobs.ns.cloudflare.com, serenity.ns.cloudflare.com). Hosting is Namecheap shared hosting (premium309-4.web-hosting.com) running LiteSpeed with PHP 8.1. TLS certificates are Let's Encrypt wildcards (*.phantomsoftwares.site), first issued 2025-02-13. A total of 23 certificates have been observed via crt.sh since the domain went active, indicating over a year of continuous operation.
MITRE ATT&CK TTPs
| ID | Name | Implementation |
|---|---|---|
| T1059.007 | Command and Scripting Interpreter: JavaScript | WSH JS dropper initial execution |
| T1059.001 | Command and Scripting Interpreter: PowerShell | Stage 2 PS1 loader |
| T1140 | Deobfuscate/Decode Files or Information | Base64 + rotational XOR multi-stage decryption |
| T1027 | Obfuscated Files or Information | JavaScriptObfuscator on Stage 1; encrypted blob in Stage 2 |
| T1027.002 | Software Packing | Costura-merged .NET assembly |
| T1620 | Reflective Code Loading | .NET assembly loaded via [Assembly]::Load() |
| T1055 | Process Injection | VirtualAllocEx + NtCreateThreadEx into aspnet_compiler.exe |
| T1055.012 | Process Injection: Process Hollowing | DEV.DOWN injector (Heaven's Gate technique referenced) |
| T1497 | Virtualization/Sandbox Evasion | Stub.AntiAnalysis module |
| T1497.001 | System Checks | Process enumeration for analysis tools |
| T1539 | Steal Web Session Cookie | Browser cookie database extraction |
| T1555.003 | Credentials from Web Browsers | Login Data SQLite harvesting from 50+ browsers |
| T1555 | Credentials from Password Stores | DPAPI + App-Bound Key Chrome decryption |
| T1528 | Steal Application Access Token | Discord token harvesting via LevelDB |
| T1056.001 | Input Capture: Keylogging | WH_KEYBOARD_LL global keyboard hook |
| T1113 | Screen Capture | CopyFromScreen screenshot loop |
| T1083 | File and Directory Discovery | Browser/wallet directory enumeration |
| T1012 | Query Registry | Telegram, Outlook, WinSCP, crypto wallet registry queries |
| T1016 | System Network Configuration Discovery | WiFi SSID/password enumeration via netsh |
| T1082 | System Information Discovery | OS version, CPU, GPU, antivirus via WMI |
| T1057 | Process Discovery | Sandbox evasion process enumeration |
| T1105 | Ingress Tool Transfer | Stub.Downloader (download additional payloads) |
| T1041 | Exfiltration Over C2 Channel | Discord webhook / Telegram bot exfil |
| T1048.003 | Exfiltration Over Alternative Protocol | FTP / SMTP exfil |
| T1560.001 | Archive Collected Data: Archive via Utility | Password-protected ZIP archiving |
| T1547.001 | Boot or Logon Autostart: Registry Run Keys | HKCU Run key persistence (optional) |
| T1070.004 | Indicator Removal: File Deletion | Deletes dropped PS1 script after execution |
IOCs
File Hashes
| SHA256 | MD5 | Description |
|---|---|---|
129ad6e221e949303456a7b3cf381d9f1b1e97b203c689b9b1205d4d37693b28 | 440924160cd002f96143ab33e2f67a76 | Stage 1: JS Dropper |
195e3d859d8fa9d0c12cd38beef8898e307b71422c8a18c2c3648f5f0220b447 | 061c1eed62c8326f2c8052851090f33d | Stage 3: DEV.DOWN .NET Injector DLL |
481fd4fefa706e606cfc368c68f1ef313f07c6e2849a26d7c94f7c8433884a1b | c8c7d7988cf9eb2a94ba0144f334d8b1 | Stage 4: Phantom Stealer .NET EXE |
Network IOCs
| Type | Value |
|---|---|
| Domain | phantomsoftwares.site |
| IP | 199.188.201.183 |
| URL | https://www.phantomsoftwares.site/home |
| URL | https://www.phantomsoftwares.site/logo/phantom_discord.png |
| Telegram | t.me/Oldphantomoftheopera |
Host-Based IOCs
| Type | Value |
|---|---|
| Temp file pattern | C:\Temp\ps_[A-Z0-9]{10}_[0-9]+\.ps1 |
| Process injection target | aspnet_compiler.exe |
| Registry persistence | HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run |
| Debug log | Phantom-DebugFile.log |
| Process: kill target | wscript.exe, cscript.exe |
Crypto / Decryption Artifacts
| Type | Value |
|---|---|
| XOR key (b64) | 49vAX3r4J78bDtS8rruEkot178HPGBRpbhFmXjZIHbU= |
| DEV.DOWN AES key | jodTFE2vRldtBtx91i.PYSXl3H4CfuFjxYYPp |
Campaign Context and Attribution
Malware Family: Phantom Stealer (also referred to internally as "Phantom stealer")
Developer alias: "Bruno" (embedded build marker)
Operator contact: Telegram @Oldphantomoftheopera
Sales/C2 site: https://www.phantomsoftwares.site
Phantom Stealer is a commercially developed and sold infostealer offered as Malware-as-a-Service (MaaS). The operator/developer maintains a website at phantomsoftwares.site (active since February 2025) and a Telegram channel for sales and support. The Telegram handle Oldphantomoftheopera references "The Phantom of the Opera," a theme carried throughout the branding.
The Stub.* namespace and class structure is consistent with multiple .NET stealer codebases that share common lineage (including WhiteSnake Stealer forks and derivatives), though Phantom Stealer appears to be a distinct product with its own development cycle. Specific similarities to the broader .NET stealer ecosystem include identical module naming conventions (Stub.AntiAnalysis, Stub.FileGrabber, etc.), common use of Costura for assembly merging, and identical Discord message formatting patterns.
The delivery via WSH JavaScript dropper is a common technique for bypassing email gateway file type restrictions. The multi-layer encryption (base64 + rotational XOR + in-memory AES) suggests deliberate effort to evade static AV signatures. The injection into aspnet_compiler.exe is notable as this is a signed Microsoft binary, aiding process whitelisting evasion.
The C2 is hosted on Namecheap shared hosting (IP 199.188.201.183, 23 TLS certificates since 2025-02-13), protected by Cloudflare CDN. FTP (port 21) is also exposed on the same IP, matching the in-binary FTP exfiltration capability -- a detail that strengthens the link between the binary's embedded configuration and this specific infrastructure.