Skip to content

Hunting the Cursor Marketplace Claude Code Backdoor: svc-telemetry, .smt and a Reverse Tunnel

Hunt the Cursor Claude Code Extension SSH Backdoor (2.1.312/2.1.313)

Hunting the Cursor Marketplace Claude Code backdoor: svc-telemetry, .smt, and a reverse tunnel to nowhere

for about eleven hours on October 29, the Cursor extension marketplace served a trojanized build of the Claude Code extension that tried to turn developer laptops into SSH jump boxes. the tunnel mostly failed. the key, the persistence and the recon did not. this is the lab-only walkthrough for hunting it across a fleet, built on the IOCs Cursor and Microsoft actually published, and nothing else.

What changed. Cursor says malicious versions 2.1.312 and 2.1.313 of anthropic.claude-code for macOS and Windows were served from its VS Code extension marketplace on October 29, 2026, from 2:27 a.m. to 1:35 p.m. PT. Anthropic did not publish them. npm, Open VSX and the Microsoft Visual Studio Marketplace were not affected. Microsoft Threat Intelligence published a teardown and hunting queries on October 30. Cursor says the attacker server has been taken down.

scope it before you panic

you are in scope if a Cursor install on macOS or Windows auto-updated or installed anthropic.claude-code 2.1.312 or 2.1.313 from the Cursor marketplace during that window. VS Code users pulling from Microsoft’s marketplace and anyone using the CLI from npm were not served the bad builds. Linux is relevant mostly for the cron persistence pattern Microsoft documented, so do not skip it if your developers sync dotfiles everywhere.

the published hashes, so you can sweep caches and EDR file telemetry:

  • payload extension.js: SHA-256 ecb58cb29078d9646ad1dcdbe51526f2d9cfea06be5fb2ab183e8ecc3ab6bf15, MD5 f49bcd657ef1e626e85ce858958c1769
  • VSIX 2.1.312 darwin: fcbb327e38e61c4fec795e0d0591f52cd1014b813d20a5912104953c3a17c364
  • VSIX 2.1.312 win32: 3de1722901165769893bef57c72594e9a54459faa23f3091b136b79966edd081
  • VSIX 2.1.313 darwin: 80402fdcad8799285fd93044976973ca000da7995fb93363f819bb8e4f84ee6c
  • VSIX 2.1.313 win32: 6786ec90cbd45949695bd7805c9fbb26cfc91bc5fc897de0183d9bcb9cb21731

what the payload actually did

stitched together from Cursor’s notice and Microsoft’s analysis, defanged where it matters:

  1. planted a key. an ED25519 public key with the comment svc-telemetry appended to the user’s authorized_keys. Cursor’s published fingerprint is SHA256:0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk.
  2. tried to enable sshd. systemsetup -setremotelogin on on macOS, and Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 on Windows. both need admin rights, which is why the tunnel failed on most machines. the key and persistence landed anyway.
  3. reverse tunnel. a separate tunnel identity (fingerprint SHA256:KOAU57+ZG6u3MG4WwzPzPX2O5YEe9qdOC1Bl+6MVyDQ) used for tunnel@134[.]209[.]82[.]225 on TCP 22, with a remote forward of -R *:0:localhost:22, autossh -M 0, and the usual quiet options: StrictHostKeyChecking=no, UserKnownHostsFile=/dev/null, ServerAliveInterval=30, ServerAliveCountMax=3, ExitOnForwardFailure=yes, IdentitiesOnly=yes. the identity file sits in /tmp/.stk_ plus 10 hex characters or under $TMPDIR.
  4. beacon. HTTP POST to hxxp://134[.]209[.]82[.]225:8099/beacon, with a local listener on 127.0.0.1:8099. Cursor says it sent environment variable names only, not values. small mercy, still recon.
  5. persistence. macOS: ~/.config/.smt, ~/.config/.smtk and a LaunchAgent at ~/Library/LaunchAgents/com.apple.sysmond.plist. Windows: %USERPROFILE%\.config\smt.cmd and smtk, a Startup\sysmon.cmd, and a scheduled task created with schtasks /create /tn SysMon. Linux pattern per Microsoft: a crontab @reboot /bin/sh "~/.config/.smt".

Microsoft maps it to ATT&CK T1098.004 (SSH authorized keys), T1572 (protocol tunneling), T1053.003 (cron) and T1053.005 (scheduled task). Defender detection names include Trojan:MacOS/SmtShellMal.A, Trojan:MacOS/MalPlistSysmond.A and HackTool:MacOS/RevAnthShell.A.

the lab

everything below runs in a throwaway directory on a Kali box with a fake home directory. there is no payload, no network callout, no tunnel. every “artifact” is an inert text file at the published path, so the hunter has something to find. the goal is to test your detection logic before you push it to a few hundred laptops, not to rebuild the malware.

Kali terminal piping the published svc-telemetry ED25519 public key into ssh-keygen -lf and getting fingerprint SHA256:0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk, matching Cursor's notice.
Step 0: verify the IOC yourself. the public key from the notice hashes to the exact fingerprint Cursor published. if a blog’s fingerprint does not reproduce, the blog is wrong, including this one.

why bother? because the comment string is trivially changeable. matching on svc-telemetry catches this campaign and misses the next copycat. matching on the fingerprint catches this key in any file under any comment. do both.

Kali terminal creating benign lab stand-in files at the published backdoor paths: an authorized_keys entry with a lab key commented svc-telemetry, .config/.smt, .config/.smtk, a .stk_ tunnel identity placeholder, the com.apple.sysmond.plist LaunchAgent, a crontab dump, and an extension.js containing only marker strings.
Step 1: lab only. inert stand-ins at the published paths, generated with a fresh lab key that reuses the svc-telemetry comment on purpose so we can test the fingerprint logic.

the hunter

one bash script, read-only, exits non-zero if anything matches so your RMM or EDR live response can alert on the exit code. it checks:

  • authorized_keys for the svc-telemetry comment, then fingerprints every key and compares against the published IOC, so a renamed key still hits
  • .config/.smt, .config/.smtk and the com.apple.sysmond.plist LaunchAgent
  • temp directories for .stk_ followed by exactly 10 hex characters
  • a crontab dump for anything calling .config/.smt
  • installed extension folders for anthropic.claude-code-2.1.312 and 2.1.313, hashing extension.js against the payload hash and grepping for the C2 IP and key comment
  • running processes for the -R *:0:localhost:22 reverse forward
Kali terminal printing the full hunt_ccx.sh script, which checks authorized_keys fingerprints, persistence files, .stk_ tunnel identities, crontab entries, extension.js hashes and strings, and reverse SSH tunnel processes for the Cursor Claude Code backdoor.
The script itself. read-only, no network, exit 1 on any hit. adapt the paths for your MDM. on Windows, translate to PowerShell against %USERPROFILE%\.ssh\authorized_keys, the smt.cmd and Startup paths, and Get-ScheduledTask SysMon.
Kali terminal running hunt_ccx.sh against the lab home and reporting seven indicator groups: svc-telemetry key with a non-matching fingerprint, .smt, .smtk, the sysmond LaunchAgent, a .stk_ tunnel identity file, an @reboot crontab entry, and IOC strings in extension.js.
Step 2: seven indicator groups. note the first line: the comment matches but the fingerprint does not, because this is our lab key. on a real host that is still worth a look, because someone copying the comment is a choice.

if you get a hit on a real machine

  1. isolate first. network contain the host through your EDR. the attacker server is down per Cursor, but you do not know what else that key unlocked.
  2. preserve. grab the home directory artifacts, the LaunchAgent or scheduled task, crontab, the extension folder and shell history before anyone “cleans it up”.
  3. remediate. Cursor published remediate-macos.sh (run as the affected user) and remediate-windows.ps1 (run elevated). read them before you run them, then run them.
  4. rotate from a clean machine. SSH keys, cloud CLI credentials, Git tokens, package registry tokens and anything sitting in environment variables. Cursor says only variable names were sent, but names tell an attacker exactly which secrets exist and where to aim next time.
  5. rebuild if in doubt. a clean hunt is not a clean host.
Kali terminal archiving lab evidence to evidence-20261101.tgz, removing the svc-telemetry key line, persistence files, .stk_ identities, crontab entry and the malicious extension folders, then re-running the hunter with a clean result and exit code 0.
Step 3: evidence first, then cleanup, then re-hunt. exit 0 means the listed IOCs are gone, not that the host is trustworthy. that judgment is yours.

fleet-scale hunting with Defender

Microsoft published KQL for Defender XDR. the shape of the hunts, so you can port them to whatever SIEM you actually have:

  • DeviceNetworkEvents where RemoteIP == "134.209.82.225", any port. 22 is the tunnel, 8099 is the beacon.
  • DeviceFileEvents matching the payload SHA-256 or the file names .smt, .smtk, smt.cmd, sysmon.cmd and com.apple.sysmond.plist.
  • DeviceEvents with ActionType ScheduledTaskCreated where the task name is SysMon and the command references smt.
  • DeviceEvents with ActionType PlistPropertyModified for the sysmond LaunchAgent on macOS.

if you have no EDR on developer laptops, that is the actual finding of this exercise. the people with the most production access in your company were the ones running an auto-updating plugin marketplace with no telemetry.

the control that would have helped

Microsoft’s prevention advice is dull and correct: allow extensions only from approved publishers, and add an install or update cooldown so a brand new version has to survive a few days in the wild before it reaches your fleet. an eleven hour malicious window against a seven day cooldown is a non-event. the same logic applies to npm, PyPI and every other auto-update channel your developers treat as trusted because it was trusted yesterday.

also worth checking while you are in there: does your developer image even need sshd enabled? the tunnel failed on most machines because users lacked admin rights. that is least privilege doing its job, for once. keep it that way.

the sloth take

the attacker had a reverse tunnel, persistence on three operating systems and a key with a name designed to look like boring telemetry. what they did not have was local admin on most laptops. so the most effective control in this incident was the one developers complain about the most. write that down, then go fingerprint every authorized_keys file you own.

related lab walkthroughs on the site: a different supply chain angle in GitPython CVE-2026-114145 and submodule hooks, and the review side of the house in AI scanning on pull requests.

sources