Persistence via Hidden Run Key Detected

edit
IMPORTANT: This documentation is no longer updated. Refer to Elastic's version policy and the latest documentation.

Persistence via Hidden Run Key Detected

edit

Identifies a persistence mechanism that utilizes the NtSetValueKey native API to create a hidden (null terminated) registry key. An adversary may use this method to hide from system utilities such as the Registry Editor (regedit).

Rule type: eql

Rule indices:

  • logs-endpoint.events.registry-*
  • winlogbeat-*
  • logs-windows.sysmon_operational-*
  • endgame-*
  • logs-crowdstrike.fdr*
  • logs-sentinel_one_cloud_funnel.*
  • logs-m365_defender.event-*

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: Persistence
  • Resources: Investigation Guide
  • Data Source: Elastic Endgame
  • Data Source: Elastic Defend
  • Data Source: Sysmon
  • Data Source: Crowdstrike
  • Data Source: SentinelOne
  • Data Source: Microsoft Defender XDR

Version: 216

Rule authors:

  • Elastic

Rule license: Elastic License v2

Investigation guide

edit

Triage and analysis

Investigating Persistence via Hidden Run Key Detected

Possible investigation steps

  • Does the registry event support hidden or null-terminated Run-value semantics, and what would it launch?
  • Why: trailing Run-key registry.path with launch data can indicate a null-prefixed value name created through NtSetValueKey; raw telemetry can preserve it when regedit does not.
  • Focus: registry.path, registry.hive, registry.value, registry.data.type, and registry.data.strings.
  • Hint: trust the registry event over GUI rendering; record exact registry.data.strings before tools normalize the hidden value name.
  • Implication: escalate when raw evidence supports hidden-value semantics and an unexpected command; lower suspicion only when exact raw value, payload, user, and host match authorized hidden-registry testing. The alert indicates a hiding technique, not one tool.
  • Which hive and logon scope would activate the hidden autorun?
  • Focus: registry.hive, registry.path, user.id, and host.id.
  • Implication: prioritize host-wide containment for machine hives and user-focused containment for user hives; lower urgency only when raw value evidence supports a constrained test user or lab host.
  • Which process wrote the hidden value, and does its identity and launch chain fit the expected test or validation workflow?
  • Focus: process.entity_id, process.executable, process.command_line, process.parent.executable, process.code_signature.subject_name, and process.code_signature.trusted.
  • Hint: use the writer’s process-start event on host.id and process.entity_id to confirm command line, parent, and signer. !{investigate{"description":"","label":"Process events for the registry writer","providers":[[{"excluded":false,"field":"event.category","queryType":"phrase","value":"process","valueType":"string"},{"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"}]],"relativeFrom":"now-1h","relativeTo":"now"}}
  • Implication: escalate when the writer is a script host, document child, remote-admin tool, unsigned/untrusted binary, user-writable executable, or SharpHide-like command line; lower suspicion when signer, path, parent, command line, user, and host align with the same recognized test or validation component.
  • Did the hidden autorun command execute after logon or spawn suspicious follow-on activity?
  • Focus: post-alert process starts on host.id where process.executable or process.command_line matches the registry.data.strings payload.
  • Hint: for user-hive paths, include user.id; for machine-hive paths, check the next interactive logon. Use process.parent.name and process.parent.executable to identify the launcher. !{investigate{"description":"","label":"Process starts matching the hidden Run payload","providers":[[{"excluded":false,"field":"event.category","queryType":"phrase","value":"process","valueType":"string"},{"excluded":false,"field":"event.type","queryType":"phrase","value":"start","valueType":"string"},{"excluded":false,"field":"host.id","queryType":"phrase","value":"{{host.id}}","valueType":"string"},{"excluded":false,"field":"process.command_line","queryType":"phrase","value":"{{registry.data.strings}}","valueType":"string"}],[{"excluded":false,"field":"event.category","queryType":"phrase","value":"process","valueType":"string"},{"excluded":false,"field":"event.type","queryType":"phrase","value":"start","valueType":"string"},{"excluded":false,"field":"host.id","queryType":"phrase","value":"{{host.id}}","valueType":"string"},{"excluded":false,"field":"user.id","queryType":"phrase","value":"{{user.id}}","valueType":"string"}]],"relativeFrom":"now","relativeTo":"now"}}
  • Implication: escalate when the payload launches after logon, runs through a shell, script host, LOLBin, user-writable path, or obfuscated chain, or creates unusual children; no later launch leaves execution unproven, not benign, unless the value and writer are fully explained.
  • Did the same writer modify other startup or hidden-registry locations around the alert time?
  • Focus: writer-scoped registry events, especially registry.path, registry.key, registry.value, and registry.data.strings for Run, RunOnce, Policies\Explorer\Run, or related startup paths.
  • Hint: start with host.id and process.entity_id, then widen only to the same host and startup-path family. !{investigate{"description":"","label":"Registry events from the writer process","providers":[[{"excluded":false,"field":"event.category","queryType":"phrase","value":"registry","valueType":"string"},{"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"}]],"relativeFrom":"now-1h","relativeTo":"now"}}
  • Implication: escalate when the process spreads persistence across startup keys, rewrites the same path, or creates additional hidden or malformed values; a single bounded change lowers scope only after writer and payload are independently explained.
  • If local evidence remains suspicious or unresolved, do same-user or same-host alerts show broader activity?
  • Focus: recent same-user.id alerts tied to persistence, defense evasion, credential access, or lateral movement. !{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"}}
  • Hint: review same-host.id alerts when local evidence is suspicious or incomplete. !{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: broaden containment when related alerts show precursor access, more persistence, credential abuse, or follow-on movement; keep local only when related alerts are absent and the hidden value is otherwise exactly explained.
  • Escalate when hidden Run semantics pair with a suspicious writer, payload, later execution, adjacent persistence, or related alerts; close only when same-host telemetry and corroborating test or validation records explain the exact value, writer, payload, user, and host with no contradictions; preserve registry, process, and payload evidence and escalate when answers remain mixed or incomplete.

False positive analysis

  • Authorized adversary emulation, detection validation, or security-product testing can create hidden Run values to test detection of regedit-hidden startup entries. Close only when process.executable, process.code_signature.subject_name, process.command_line, registry.path, registry.data.strings, user.id, and host.id match the same authorized test chain, and any later process.command_line stays bounded to it. Without validation records, do not close on recurrence alone; keep suspicious or unresolved until exact test scope is verified.
  • Routine software installation can explain ordinary Run-key writes, but should not require a hidden or null-terminated value name. Treat installer or support claims as insufficient unless telemetry proves the exact hidden value, writer, payload, and execution pattern belong to a recognized lab, validation, or product-test workflow.
  • Before an exception, require a verified test or validation workflow, then confirm the same process.executable, process.code_signature.subject_name, registry.path, registry.data.strings, user.id, and host.id pattern recurs across prior alerts from this rule. Build the exception from that minimum confirmed workflow; avoid exceptions on Run paths alone, process.name alone, payload strings alone, or the rule name alone.

Response and remediation

  • If confirmed benign, reverse any temporary containment and record the process.executable, signer, process.command_line, registry.path, exact registry.data.strings, user.id, host.id, and later logon execution pattern that proved the authorized workflow. Keep any exception narrow and tied to the recurring workflow.
  • If suspicious but unconfirmed, first preserve the raw registry event, affected Run-key hive with the hidden value intact when possible, writer process.entity_id, writer command line, process lineage, payload string from registry.data.strings, and related-alert context. Then apply reversible containment tied to those findings, such as isolating the host if its role tolerates it, temporarily preventing the affected user from logging back in, or blocking execution of the referenced payload.
  • If confirmed malicious, preserve the same registry and process evidence before destructive action. Use tooling that can enumerate null-prefixed value names to remove the hidden autorun, collect or quarantine the referenced payload artifact, and review the same process.entity_id, registry.path, and startup-key family for additional hidden or visible autoruns before cleanup. Terminate a recovered payload process only after recording its process.entity_id and command line.
  • After containment, review other hosts and users for the same registry.data.strings, startup-path family, signer, or payload path before deleting artifacts, then verify that no additional Run or RunOnce locations reference the same payload.
  • Post-incident hardening: restrict startup-key modifications to recognized installers and management tools, retain registry and process telemetry needed to correlate hidden Run-key writes with writer lineage and logon execution, and record any adjacent hidden-registry or startup-persistence variant in case notes.

Setup

edit

Setup

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

edit
registry where host.os.type == "windows" and event.type == "change" and length(registry.data.strings) > 0 and

  /* Registry Path ends with backslash */
  registry.path : "*\\Run\\" and
  registry.path : (
    "*\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\",
    "*\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run\\",
    "*\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run\\"
  )

Framework: MITRE ATT&CKTM