Copilot Readiness and Enterprise AI Security | Knostic Blog

New Malicious VS Code Extension Backdoor: Remote Text Fetcher

Written by Knostic Team | Jun 2, 2026 4:36:53 PM
đź’ˇ Kirin runs in the developer's IDE and blocks malicious extensions and packages before they execute. Try it free for up to 5 licenses.

What Happened

AgentMesh automatically discovered a malicious VS Code extension that fetches and executes operator-controlled shell commands on every VS Code startup, targeting developers on Windows, macOS, and Linux. Extension has been removed from the VS Code Marketplace. No scan engines on VirusTotal flagged the sample at validation time.

Remote Text Fetcher v0.0.1

Field

Value

Marketplace ID

DorianN612.remote-text-fetcher

Publisher

DorianN612 (unverified) / GitHub: DorianKalliope

Published

May 27, 2026

Installs

0 (caught before distribution)

AgentMesh

extensions/128356 — CRITICAL / DANGEROUS

VirusTotal

0 detections

SHA-256 (VSIX)

8136e6e1260e85c860c26245e7622c8bc2f82d741afb445e9ddccaee78990f4b

SHA-256 (extension.js)

4392173461fb74e295021d6ef9f74260181d8c2a27b6e43fa1a697422cf3a9e0

MD5 (VSIX)

256347f689733a99899415f818d29818

Behavior: Remote Text Fetcher is not a text utility. On every VS Code startup (activationEvents: ["onStartupFinished"]), it reads a URL from the VS Code config key agentService.url, issues an HTTP GET, base64-decodes each line of the response, and executes each decoded string via child_process.exec. No user interaction required. The VSIX contains no embedded payload — the attacker controls what runs by serving commands from the C2 URL.

Simple attack flow

  1. User installs the Remote Text Fetcher VS Code extension.
  2. On every VS Code startup (activationEvents: ["onStartupFinished"]), the extension activates automatically.
  3. The extension reads a hidden configuration value from agentService.url — a namespace not declared in package.json.
  4. The URL can be pre-seeded by the attacker through a malicious .vscode/settings.json file in a cloned repository or workspace.
  5. The extension sends an HTTP GET request to the configured URL.
  6. The server responds with newline-separated base64-encoded shell commands.
  7. The extension decodes each line and executes it via child_process.exec.
  8. All fetch and decode errors are silently ignored.

    End result: arbitrary shell command execution on the developer workstation every time VS Code starts.

IoCs

Type

Value

Config key read (undeclared)

agentService.url

Config key declared (decoy)

remoteTextFetcher.url (does nothing)

C2 fallback (compiled JS)

http://localhost:3000/file.txt

C2 fallback (initial TS source)

http://localhost:3000/commands.txt (commit f3c3bea0)

Live C2

Operator-supplied via agentService.url — not hardcoded in artifact

C2 protocol

HTTP GET → newline-separated base64-encoded shell commands

Execution

child_process.exec(Buffer.from(line, 'base64').toString('utf8'))

Error handling

Fetch and decode errors silently ignored

Install path (Windows)

%USERPROFILE%\.vscode\extensions\DorianN612.remote-text-fetcher-0.0.1\

Install path (mac/Linux)

~/.vscode/extensions/DorianN612.remote-text-fetcher-0.0.1/

GitHub

github.com/DorianKalliope/remote-text-fetcher

Internal dev name

agent-service (CHANGELOG.md, commit f3c3bea080fd)

Payload analysis: No live payload captured during analysis. Runtime execution chain characterized through static analysis of the VSIX artifact.

Config namespace mismatch (key finding)

The package.json declares remoteTextFetcher.url — visible in the VS Code Settings UI. The compiled extension.js reads agentService.url — an undeclared namespace, invisible to the user and to any reviewer inspecting package.json alone.

The GitHub TypeScript source was sanitized post-publication in two commits, but the compiled VSIX was never rebuilt. The malicious agentService.url read survives in the shipped binary. The internal development name agent-service (CHANGELOG.md, commit f3c3bea080fd) maps directly to the agentService config namespace, confirming the mismatch is intentional.

Git timeline (DorianKalliope/remote-text-fetcher):

Commit

Action

f3c3bea080fd

Initial commit — agentService namespace, URL: localhost:3000/commands.txt

b852cfabee0a

Partial sanitization — URL updated to file.txt, namespace still agentService

f4627a742da6

Full sanitization — namespace renamed to remoteTextFetcher in TS; VSIX not rebuilt

bbfd0cf03ecd–9e163cdd7688

12x automated vcs-metadata.txt commits

Publisher seeding

Two days before publishing the malicious extension, DorianN612 published a clean functional extension (“RealTime Word Counter”), likely intended to establish marketplace credibility.

 

Extension ID: DorianN612.wordcountertool

Published: May 25, 2026

SHA-256: 142cd54412362ca249a3feffb263c67fd1a200176254d66cb173c98376dbcf7b

 

AgentMesh classified the extension as SAFE:

https://agentmesh.knostic.ai/extensions/122264

 

Static analysis found no malicious functionality. Unlike Remote Text Fetcher, the source and compiled artifacts matched exactly.

Detection anchors

  • Extension JS reads config namespace not declared in its own package.json
  • Buffer.from(<var>, 'base64').toString('utf8') passed directly to child_process.exec
  • onStartupFinished + outbound HTTP fetch + no declared commands or UI contribution
  • agentService.url present in any VS Code settings file (workspace or user scope)
  • CHANGELOG.md internal name differs from published extension name
  • Source/compiled divergence: TS source and compiled JS use different config namespaces