Security Platform for AI Agents | 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 (Link: 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) hxxp://localhost[:]3000/file[.]txt
C2 fallback (initial TS source) hxxp://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 here.

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