Suspicious Execution with NodeJS
editSuspicious Execution with NodeJS
editIdentifies suspicious Node.js execution patterns, including user-writable runtimes, preload arguments, and inline eval, decode, or child-process usage.
Rule type: eql
Rule indices:
- endgame-*
- logs-crowdstrike.fdr*
- logs-endpoint.events.process-*
- logs-m365_defender.event-*
- logs-sentinel_one_cloud_funnel.*
- logs-system.security*
- logs-windows.forwarded*
- logs-windows.sysmon_operational-*
- winlogbeat-*
Severity: high
Risk score: 73
Runs every: 5m
Searches indices from: now-9m (Date Math format, see also Additional look-back time)
Maximum alerts per execution: 100
References:
Tags:
- Domain: Endpoint
- OS: Windows
- Use Case: Threat Detection
- Tactic: Execution
- Resources: Investigation Guide
- Data Source: Elastic Endgame
- Data Source: Elastic Defend
- Data Source: Windows Security Event Logs
- Data Source: Microsoft Defender XDR
- Data Source: Sysmon
- Data Source: SentinelOne
- Data Source: Crowdstrike
Version: 4
Rule authors:
- Elastic
Rule license: Elastic License v2
Investigation guide
editTriage and analysis
Investigating Suspicious Execution with NodeJS
Possible investigation steps
- Which Node execution path did the alert capture?
-
Focus:
process.executable,process.command_line,process.parent.name, andprocess.pe.original_file_name. - Implication: escalate faster when the match is a user-writable AppData "node.exe", PowerShell-launched preload, or inline decode/spawn pattern; lower suspicion when parent and command-line evidence show a recognized version-manager, IDE, package-manager, or test-runner pattern.
- Do the runtime identity and launcher context fit recognized Node use?
-
Focus:
process.executable,process.pe.original_file_name,process.code_signature.subject_name,process.code_signature.trusted,process.parent.command_line,user.id, andhost.id. - Implication: escalate when the runtime is unsigned, renamed, mismatched to "node.exe", staged from Temp/AppData outside a recognized toolchain, or launched by PowerShell, Office, a browser, an archive utility, or a download path without matching IDE/package/build context; lower suspicion only when runtime identity and parent chain fit the same recurring Node workflow for that user or host. Identity alone does not clear suspicious arguments.
- What do the arguments show about preload, script, or inline execution intent?
- Why: "-r" / "--require" preloads a module at startup; "child_process" enables OS subprocess creation.
-
Focus:
process.command_lineand the script or preload path parsed from it. - Implication: escalate when Node preloads an unexpected module, decodes inline content with atob( or eval(, or references "child_process"; lower suspicion when the target is a recognized preload such as a test harness, transpiler, or source-map helper inside the same project tree.
- If endpoint file telemetry is available, what provenance exists for the script or preload module?
-
Focus: recover file events with
host.id+process.entity_id, orhost.id+process.pid+ a tight alert window as weaker fallback; inspectfile.path,file.origin_url,file.Ext.windows.zone_identifier, andfile.Ext.original.path. !{investigate{"description":"","label":"File events for the Node process","providers":[[{"excluded":false,"field":"host.id","queryType":"phrase","value":"{{host.id}}","valueType":"string"},{"excluded":false,"field":"process.entity_id","queryType":"phrase","value":"{{process.entity_id}}","valueType":"string"},{"excluded":false,"field":"event.category","queryType":"phrase","value":"file","valueType":"string"}]],"relativeFrom":"now-1h","relativeTo":"now"}} - Hint: missing file telemetry is unresolved, not benign; use parsed command-line paths and parent context as weaker evidence.
- Implication: escalate when the script or module was downloaded, extracted, renamed, or staged into AppData/Temp shortly before execution; lower suspicion when it stays in a stable repository, package cache, or product install tree consistent with the parent workflow.
- If child-process or endpoint network telemetry is available, what did Node do next?
-
Focus: recover child and network events with
host.id+process.entity_id, orhost.id+process.pid+ the post-start window as weaker fallback; inspect childprocess.name/process.executable, DNSdns.question.name, and connectiondestination.ip/destination.port. - !{investigate{"description":"","label":"Child processes spawned by Node","providers":[[{"excluded":false,"field":"host.id","queryType":"phrase","value":"{{host.id}}","valueType":"string"},{"excluded":false,"field":"process.parent.entity_id","queryType":"phrase","value":"{{process.entity_id}}","valueType":"string"},{"excluded":false,"field":"event.category","queryType":"phrase","value":"process","valueType":"string"}]],"relativeFrom":"now-1h","relativeTo":"now"}}
- !{investigate{"description":"","label":"Network events for the Node process","providers":[[{"excluded":false,"field":"host.id","queryType":"phrase","value":"{{host.id}}","valueType":"string"},{"excluded":false,"field":"process.entity_id","queryType":"phrase","value":"{{process.entity_id}}","valueType":"string"},{"excluded":false,"field":"event.category","queryType":"phrase","value":"network","valueType":"string"}]],"relativeFrom":"now-1h","relativeTo":"now"}}
- Hint: separate DNS events from connection events before interpreting destinations; missing child or network telemetry is unresolved, not benign.
- Implication: escalate when Node quickly launches shells, LOLBins, archivers, credential tooling, or reaches externally routable destinations unrelated to the workflow; lower suspicion when child activity and destinations stay bounded to recognized local development, build, package-registry, or deployment services.
- If local evidence stays suspicious or unresolved, do related alerts show broader scripting, download, persistence, or beaconing activity?
-
Focus: same-
user.idrelated alerts or process events, especially PowerShell, archive, downloader, persistence, and outbound-connection activity. -
Hint: if
user.idis missing or ambiguous, review same-host alerts and process events forhost.idin the last 48 hours. - !{investigate{"description":"","label":"Alerts associated with the user","providers":[[{"excluded":false,"field":"event.kind","queryType":"phrase","value":"signal","valueType":"string"},{"excluded":false,"field":"user.id","queryType":"phrase","value":"{{user.id}}","valueType":"string"}]],"relativeFrom":"now-48h/h","relativeTo":"now"}}
- !{investigate{"description":"","label":"Alerts associated with the host","providers":[[{"excluded":false,"field":"event.kind","queryType":"phrase","value":"signal","valueType":"string"},{"excluded":false,"field":"host.id","queryType":"phrase","value":"{{host.id}}","valueType":"string"}]],"relativeFrom":"now-48h/h","relativeTo":"now"}}
- Implication: expand scope when the host or user shows staged payload delivery, repeated Node misuse, persistence, or beaconing; keep scope local when behavior is isolated and local evidence supports one recognized workflow.
- Escalate when branch, runtime, argument, lineage, or recovered artifact/child/network evidence shows staged script, unrecognized preload, inline decode, or spawn abuse; close only when those categories tightly support one recognized workflow with no contradictions; preserve artifacts and escalate when evidence is mixed or incomplete.
False positive analysis
-
Developer tooling, version managers, IDEs, package managers, and build/test runners can legitimately run "node.exe" from user-space paths or use "-r" preloads. Confirm one workflow: runtime path/hash/signer, parent, command line, and referenced script or preload path all align with the same toolchain. Without inventory or build records, telemetry-only closure requires exact workflow recurrence for the same
user.idorhost.idcohort plus no contradictory file, child-process, or network evidence; do not close on recurrence alone. -
Treat partial matches as unresolved. An OpenJS signer, "node.exe" name, or familiar parent does not explain AppData execution, inline decode/eval, or child-process behavior by itself. Before creating an exception, validate recurrence of the same Node binary, argument pattern, parent context, and script or preload path; avoid exceptions on
process.nameorprocess.code_signature.subject_namealone.
Response and remediation
-
If confirmed benign, reverse temporary containment and document the exact Node workflow: runtime path/hash/signer, parent launcher, command line, script or preload path, and
user.id/host.idscope. Create an exception only when the same workflow recurs consistently across prior alerts from this rule. -
If suspicious but unconfirmed, preserve the process start event, command line, binary hash/signature, script or preload artifact, child process chain, and any recovered DNS or connection events before containment. Apply reversible containment tied to the finding, such as temporary destination blocking, script quarantine, or heightened monitoring on the affected
host.idanduser.id. Escalate to host isolation only when follow-on execution, persistence, or outbound activity confirms broader compromise and host criticality allows interruption. -
If confirmed malicious, preserve
process.entity_idorprocess.pidwithhost.idand time, parent process context,process.command_line,process.hash.sha256, referenced script or preload paths, child-process lineage, and confirmed network indicators before terminating Node or isolating the host. If direct endpoint response is unavailable, hand off that artifact set to the team that can isolate the system or block destinations. - Scope related hosts and users for the same runtime hash, suspicious command-line pattern, script/preload paths, child-process lineage, and network indicators before deleting scripts, modules, or staged payloads. Then remove only the malicious artifacts identified during triage and remediate the delivery path or launcher that led to Node execution.
-
Post-incident hardening: restrict unrecognized "node.exe" execution from user-writable paths, retain process-start, file-provenance, and network telemetry, and document adjacent variants found during triage, such as renamed Node runtimes, packaged Electron launchers, alternate preload patterns, or
--requireabuse without PowerShell.
Setup
editSetup
This rule is designed for data generated by Elastic Defend, which provides native endpoint detection and response, along with event enrichments designed to work with our detection rules.
Setup instructions: https://ela.st/install-elastic-defend
Additional data sources
This rule also supports the following third-party data sources. For setup instructions, refer to the links below:
Rule query
editprocess where host.os.type == "windows" and event.type == "start" and
(process.name : "node.exe" or ?process.pe.original_file_name == "node.exe" or ?process.code_signature.subject_name : "OpenJS Foundation") and
(
(process.executable : ("?:\\Users\\*\\AppData\\*\\node.exe", "\\Device\\HarddiskVolume*\\Users\\*\\AppData\\*\\node.exe") and process.args : "*.js") or
(process.args : "-r" and process.parent.name : "powershell.exe") or
process.command_line : ("*eval(*", "*atob(*", "*require*child_process*")
)
Framework: MITRE ATT&CKTM
-
Tactic:
- Name: Execution
- ID: TA0002
- Reference URL: https://attack.mitre.org/tactics/TA0002/
-
Technique:
- Name: Command and Scripting Interpreter
- ID: T1059
- Reference URL: https://attack.mitre.org/techniques/T1059/
-
Sub-technique:
- Name: JavaScript
- ID: T1059.007
- Reference URL: https://attack.mitre.org/techniques/T1059/007/
-
Tactic:
- Name: Defense Evasion
- ID: TA0005
- Reference URL: https://attack.mitre.org/tactics/TA0005/
-
Technique:
- Name: Obfuscated Files or Information
- ID: T1027
- Reference URL: https://attack.mitre.org/techniques/T1027/
-
Sub-technique:
- Name: Command Obfuscation
- ID: T1027.010
- Reference URL: https://attack.mitre.org/techniques/T1027/010/