Suspicious Command Execution from Visual Studio Code
Detects Visual Studio Code ("Code.exe" on Windows or "Code Helper" on macOS) spawning a shell or downloader whose command line contains an encoded command, a download cradle, or a reverse-shell pattern. Malicious IDE extensions use the editor process to run these commands after install.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2026/10/26"
3integration = ["endpoint"]
4maturity = "production"
5updated_date = "2026/10/26"
6
7[rule]
8author = ["Elastic"]
9description = """
10Detects Visual Studio Code ("Code.exe" on Windows or "Code Helper" on macOS) spawning a shell or downloader whose
11command line contains an encoded command, a download cradle, or a reverse-shell pattern. Malicious IDE extensions
12use the editor process to run these commands after install.
13"""
14from = "now-9m"
15language = "esql"
16license = "Elastic License v2"
17name = "Suspicious Command Execution from Visual Studio Code"
18note = """## Triage and analysis
19
20### Investigating Suspicious Command Execution from Visual Studio Code
21
22`Code.exe` or `Code Helper` started `cmd`, PowerShell, a Unix shell, `curl`, or `wget`, and the command line matches
23an encoded-command, download, or remote-shell pattern. That is common when a malicious VS Code extension, task, or
24workspace script runs through the editor.
25
26### Possible investigation steps
27
28- Review `process.command_line` for the URL, encoded payload, or shell pipe (`curl | sh`, `wget | sh`, `Invoke-Expression`).
29- Review `process.parent.command_line` and `process.parent.args` for `extensionHost` or a path under `.vscode/extensions` or `.vscode/tasks.json`.
30- Identify the extension id from that parent path and compare it with the installed extension.
31- On the same host and user, look for the downloaded file, follow-on processes, and outbound connections.
32
33### False positive analysis
34
35- Developer tasks and integrated terminals often run `curl`, `wget`, `echo`, or `https` URLs. `echo` and `https` in the
36 pattern match many legitimate commands. Confirm the parent is an extension host or an unexpected workspace task before excluding.
37- The rule already excludes command lines containing `docker.internal`, `localhost`, `127.0.0.1`, or `aka.ms/vscode-powershell`.
38- Scope exceptions to a known command line, extension path, host, or user. Do not broadly exclude `Code.exe` or `Code Helper`.
39
40### Response and remediation
41
42- If the command is unapproved, stop the child process, uninstall the extension, and remove any dropped file.
43- Quarantine the payload, collect its hash, and hunt the command line on other hosts.
44- Rotate tokens or credentials the command could have read from the user profile or workspace.
45"""
46references = [
47 "https://www.mdsec.co.uk/2021/01/macos-post-exploitation-shenanigans-with-vscode-extensions/",
48 "https://www.aikido.dev/blog/fake-clawdbot-vscode-extension-malware",
49]
50risk_score = 47
51rule_id = "cb602a92-6613-4425-b983-61fcb02b647c"
52setup = """## Setup
53
54This rule is designed for data generated by [Elastic Defend](https://www.elastic.co/security/endpoint-security), which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
55
56Setup instructions: https://ela.st/install-elastic-defend
57"""
58severity = "medium"
59tags = [
60 "Domain: Endpoint",
61 "OS: Windows",
62 "OS: macOS",
63 "OS: Linux",
64 "Use Case: Threat Detection",
65 "Tactic: Persistence",
66 "Tactic: Execution",
67 "Data Source: Elastic Defend",
68 "Resources: Investigation Guide",
69 "Rule Type: ES|QL",
70 "Platform: Windows",
71 "Platform: macOS",
72 "Platform: Linux"
73]
74timestamp_override = "event.ingested"
75type = "esql"
76
77query = '''
78FROM logs-endpoint.events.process-* METADATA _id, _version, _index
79| WHERE KQL("""event.category:process and event.type:start""")
80 AND process.parent.name IN ("Code Helper (Plugin)", "Code Helper", "Code.exe", "code")
81 AND process.name IN (
82 "cmd.exe", "powershell.exe", "sh", "bash", "zsh",
83 "dash", "nohup", "curl.exe", "curl", "wget",
84 "wget.exe", "pwsh.exe"
85 )
86 AND TO_LOWER(process.command_line) RLIKE """.*(-ec |-enc|-encodedcommand|-nop |-w hidden|https|/dev/tcp|echo|irm |iwr |base64|nohup|http:|iex |invoke-expression|downloadstring|downloadfile|frombase64string|chmod \+|nc -e|ncat|certutil|bitsadmin|invoke-restmethod|curl.*\|.*sh|wget.*\|.*sh).*"""
87 AND NOT TO_LOWER(process.command_line) RLIKE """.*(docker.internal|localhost|127.0.0.1|aka.ms/vscode-powershell).*"""
88| KEEP
89 _id,
90 _version,
91 _index,
92 data_stream.namespace,
93 @timestamp,
94 host.name,
95 host.id,
96 agent.id,
97 host.os.type,
98 user.name,
99 user.domain,
100 process.name,
101 process.parent.name,
102 process.parent.executable,
103 process.command_line,
104 process.executable,
105 process.parent.command_line,
106 process.parent.args
107'''
108
109[rule.investigation_fields]
110field_names = [
111 "host.os.type",
112 "process.parent.name",
113 "process.parent.executable",
114 "process.parent.command_line",
115 "process.parent.args",
116 "process.command_line",
117 "process.executable",
118]
119
120[[rule.threat]]
121framework = "MITRE ATT&CK"
122
123[[rule.threat.technique]]
124id = "T1176"
125name = "Software Extensions"
126reference = "https://attack.mitre.org/techniques/T1176/"
127
128[[rule.threat.technique.subtechnique]]
129id = "T1176.002"
130name = "IDE Extensions"
131reference = "https://attack.mitre.org/techniques/T1176/002/"
132
133[rule.threat.tactic]
134id = "TA0003"
135name = "Persistence"
136reference = "https://attack.mitre.org/tactics/TA0003/"
137
138[[rule.threat]]
139framework = "MITRE ATT&CK"
140
141[[rule.threat.technique]]
142id = "T1059"
143name = "Command and Scripting Interpreter"
144reference = "https://attack.mitre.org/techniques/T1059/"
145
146[[rule.threat.technique.subtechnique]]
147id = "T1059.001"
148name = "PowerShell"
149reference = "https://attack.mitre.org/techniques/T1059/001/"
150
151[[rule.threat.technique.subtechnique]]
152id = "T1059.003"
153name = "Windows Command Shell"
154reference = "https://attack.mitre.org/techniques/T1059/003/"
155
156[[rule.threat.technique.subtechnique]]
157id = "T1059.004"
158name = "Unix Shell"
159reference = "https://attack.mitre.org/techniques/T1059/004/"
160
161[rule.threat.tactic]
162id = "TA0002"
163name = "Execution"
164reference = "https://attack.mitre.org/tactics/TA0002/"
Triage and analysis
Investigating Suspicious Command Execution from Visual Studio Code
Code.exe or Code Helper started cmd, PowerShell, a Unix shell, curl, or wget, and the command line matches
an encoded-command, download, or remote-shell pattern. That is common when a malicious VS Code extension, task, or
workspace script runs through the editor.
Possible investigation steps
- Review
process.command_linefor the URL, encoded payload, or shell pipe (curl | sh,wget | sh,Invoke-Expression). - Review
process.parent.command_lineandprocess.parent.argsforextensionHostor a path under.vscode/extensionsor.vscode/tasks.json. - Identify the extension id from that parent path and compare it with the installed extension.
- On the same host and user, look for the downloaded file, follow-on processes, and outbound connections.
False positive analysis
- Developer tasks and integrated terminals often run
curl,wget,echo, orhttpsURLs.echoandhttpsin the pattern match many legitimate commands. Confirm the parent is an extension host or an unexpected workspace task before excluding. - The rule already excludes command lines containing
docker.internal,localhost,127.0.0.1, oraka.ms/vscode-powershell. - Scope exceptions to a known command line, extension path, host, or user. Do not broadly exclude
Code.exeorCode Helper.
Response and remediation
- If the command is unapproved, stop the child process, uninstall the extension, and remove any dropped file.
- Quarantine the payload, collect its hash, and hunt the command line on other hosts.
- Rotate tokens or credentials the command could have read from the user profile or workspace.
References
Related rules
- Suspicious IDE Extension Installation from VSIX
- Long Base64 Encoded Command via Scripting Interpreter
- AWS SSM Session Manager Child Process Execution
- Potential Prompt Injection Coercing Shell Execution
- Cloud Offensive Framework Execution