ixpresso-core: Windows RAT Disguised as a WhatsApp Agent "ixpresso-core," a malicious Windows Remote Access Trojan (RAT) published on npm and disguised as a WhatsApp-integrated AI agent. Once installed, it deploys persistent malware called "Veltrix" that steals browser credentials, Discord and Telegram sessions, cryptocurrency data, and keystrokes, while providing attackers with remote control via a Cloudflare tunnel. The package was published by a newly created account using a temporary email service, and screenshots within the package inadvertently revealed the attacker's own stolen data and development environment. ixpresso-core: Windows RAT Disguised as a WhatsApp Agent Table of Contents TL;DR ixpresso-core is a purpose-built Windows Remote Access Trojan, published to npm under the description “Personal AI System Agent - Control your device via WhatsApp.” There is no WhatsApp integration. Installing any version of this package deploys a persistent agent called Veltrix that steals browser credentials, Discord and Telegram sessions, crypto seed phrases, and a live keystream, while opening an authenticated remote control dashboard accessible over the internet via a Cloudflare tunnel. Impact: - All saved passwords, cookies, and credit card numbers from Chrome, Brave, and Edge extracted via Windows DPAPI - Discord authentication tokens ripped from LevelDB storage across Discord, Discord Canary, Discord PTB, and Chrome - Telegram tdata session folder zipped and exfiltrated full account access without password - Desktop, Documents, and Downloads scanned for files matching wallet/seed/crypto/password keywords - Full system-wide keylog stream exfiltrated in real time to a hardcoded Discord webhook - Clipboard monitored every 15 seconds - Automatic screenshots triggered when focus shifts to banking, login, Discord, or browser windows - Remote desktop live FFmpeg screen stream , shell execution, webcam/microphone access via WebSocket API - Persistence via Windows Scheduled Task WindowsHealthMonitor triggered at every logon Indicators of Compromise IoC : Package Overview The loltestpad account was created on 2026-04-14, the same day as the first publish. The email domain opemails.com is a temporary mail service. Three packages exist under this account, all published within 48 hours: Three ixpresso-core versions shipped in under 40 minutes: The package shipped 64 PNG screenshots from the attacker’s own testing machine inside the public/screenshots/ directory. Two of them were taken at 22:27 and 22:31 UTC on 2026-04-14, six minutes before v1.0.2 published. The earliest batch dates to 2026-03-30, putting development at least two weeks before release. The vault harvest screenshot from that same session tells its own story: the attacker ran Veltrix against their own machine and exfiltrated 94 passwords, 2 credit cards, and 16 autofill entries from their own browser profiles before publishing. The Veltrix dashboard, running on the attacker’s own machine, shows their own stolen data in the VAULT tab: 118 passwords and 125 cookies harvested from their browser profiles: The attacker’s browser address bar autocomplete reveals the default master password in plain text — admin123 embedded in a trycloudflare.com URL from a prior session: The autocomplete history also shows 127.0.0.1:5500/public/index.html — port 5500 is the VS Code Live Server default, confirming the attacker developed and tested the dashboard locally in VS Code before deploying via tunnel. The cookie table in the VAULT screenshots contains RFIHUB.COM as an active session domain. No name or email is directly visible in any screenshot. VS Code Live Server in the browser history confirms local development in VS Code before tunnel deployment. Execution No postinstall hook. The package is positioned as a developer utility the victim runs directly. The bin launcher bin/ixpresso.js spawns the main payload with detached: true , stdio: 'ignore' , and windowsHide: true , unrefs the child, and exits. From the terminal’s perspective, the command finishes cleanly. On startup, src/index.js passes a PowerShell block via -EncodedCommand before loading any application modules: Three actions, one call: a firewall inbound rule named “Windows Security Handler” on TCP 3000, a SetThreadExecutionState 0x80000041 call that prevents sleep and away mode, and ShowWindow hWnd, 0 to hide the console. The base64-encoded command avoids any string matching on the PowerShell command line. Once the server is up and the Cloudflare tunnel connects, the attacker’s Discord channel receives the access link automatically: Persistence PersistenceManager.init runs the moment the Express server is ready: The node runtime is renamed WebSecureSystem.exe and placed inside %APPDATA%\Microsoft\Windows\Protect\ , a directory legitimately used by Windows DPAPI credential protection services. The scheduled task fires at every user logon. A PersistenceService class with a registry Run key mechanism WindowsSecuritySync is present in the codebase but never invoked in v1.0.2 — likely staged for a future version. Credential Theft At T+35 seconds, SessionHijacker.executeSweep runs three operations: Discord token extraction. Four LevelDB paths are scanned: Classic plaintext tokens and v10 DPAPI-encrypted tokens dQw4w9WgXcQ: prefix are both extracted. Encrypted tokens are decrypted using the browser’s master key, recovered via ProtectedData.Unprotect through PowerShell. The resulting token report is uploaded to the Discord webhook. Crypto loot sweep. Desktop, Documents, and Downloads are crawled for .txt , .docx , .csv , .xlsx , .pdf , and .json files under 2 MB whose names match /wallet|seed|phrase|password|secret|crypto|backup|metamask|phantom/i . Matches are zipped and uploaded. Telegram session. The tdata folder %APPDATA%\Telegram Desktop\tdata is zipped if under 24 MB and sent to Discord. That folder alone is sufficient to take over the account without the user’s password. The vault harvest summary from the attacker’s own test machine on April 14, the day of publication, shows 94 passwords and 2 credit cards extracted: A second session from the same machine shows 69 credential bundles, with Google, YouTube, and google.co.in domains visible in the attacker’s own exfiltrated cookie set: At T+45 seconds, VaultScraper.harvest targets Chrome, Brave, and Edge. Each browser’s DPAPI master key is decrypted: All profiles under each browser are enumerated. Login Data, Cookies, and Web Data SQLite databases are scanned with AES-256-GCM decryption on every v10 prefix found. Passwords, cookies, credit card numbers, and autofill entries are serialized to a JSON report and sent to Discord. Surveillance ScoutService.start activates at T+45 seconds. It registers a system-wide keydown hook via uiohook-napi , flushes the keylog buffer every 10 characters or after 1 second of idle, prefixes each flush with the active window title, and delivers to both Discord and MQTT. Clipboard is polled every 15 seconds via Get-Clipboard . The keylog stream, window titles, and clipboard contents all land in the same Discord channel in real time: The window watcher checks the foreground process every 5 seconds and takes an automatic screenshot when it matches chrome , msedge , opera , banking , login , password , discord , or telegram . Remote Control A Cloudflare tunnel exposes the local port 3000 server publicly. The attacker receives the URL in a Discord embed “Cloudwale Tunnel Active” . The dashboard requires a master password admin123 by default, overridable by VELTRIX PASSWORD . The dashboard itself is a browser-based command center served over the tunnel, protected by a master password prompt: The WebSocket API handles live remote desktop via FFmpeg screen streaming, mouse and keyboard injection, webcam and microphone streaming. The HTTP API covers arbitrary PowerShell execution POST /api/shell/exec , full filesystem access list, download, upload, delete any path , process list and kill, on-demand credential harvest, webcam snapshot, 10-second audio capture, and self-destruct POST /api/elite/purge , which wipes the stealth directory and sends a final Discord message. C2 Architecture The Discord webhook is hardcoded in ConfigManager.js as the defaultWebhook : MQTT runs alongside. Each victim publishes heartbeats every 5 seconds for the first minute, then every 30 seconds, to veltrix/signals/VELTRIX-SIGNAL-KEY-SET/