[metadata] creation_date = "2022/11/01" integration = ["endpoint", "system", "windows", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"] maturity = "production" updated_date = "2026/04/27" [rule] author = ["Elastic"] description = "Identifies attempts to dump Wireless saved access keys in clear text using the Windows built-in utility Netsh." from = "now-9m" index = [ "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-*", ] language = "eql" license = "Elastic License v2" name = "Wireless Credential Dumping using Netsh Command" references = [ "https://learn.microsoft.com/en-us/windows-server/networking/technologies/netsh/netsh-contexts", "https://www.geeksforgeeks.org/how-to-find-the-wi-fi-password-using-cmd-in-windows/", ] risk_score = 73 rule_id = "2de87d72-ee0c-43e2-b975-5f0b029ac600" severity = "high" tags = [ "Domain: Endpoint", "OS: Windows", "Use Case: Threat Detection", "Tactic: Credential Access", "Tactic: Discovery", "Data Source: Elastic Endgame", "Resources: Investigation Guide", "Data Source: Elastic Defend", "Data Source: Windows Security Event Logs", "Data Source: Microsoft Defender XDR", "Data Source: Sysmon", "Data Source: SentinelOne", "Data Source: Crowdstrike", ] timestamp_override = "event.ingested" type = "eql" query = ''' process where host.os.type == "windows" and event.type == "start" and (process.name : "netsh.exe" or ?process.pe.original_file_name == "netsh.exe") and process.args : "wlan" and process.args : "key*clear" ''' note = """## Triage and analysis ### Investigating Wireless Credential Dumping using Netsh Command #### Possible investigation steps - What did the alert-local netsh command expose or export? - Focus: `process.command_line`, `process.executable`, `process.pe.original_file_name`, `process.code_signature.subject_name`. - Implication: escalate when `key=clear` appears with bulk profile listing, `export profile`, omitted profile name, remote `-r`, script-file `-f`, or redirection; lower concern only when one local profile display fits recognized support or recovery. A signed Microsoft binary does not clear credential exposure. - Does the launcher, session, and user context explain why this account retrieved a wireless key on this host? - Focus: `process.parent.executable`, `process.parent.command_line`, `process.Ext.session_info.logon_type`, `user.id`, `host.id`. - Implication: escalate when the parent is a shell, script host, remote-admin chain, document-spawned process, unexpected service identity, or unusual device-support user; lower concern when an interactive support shell or endpoint-management parent on the same host explains the exact command. - Did the same launcher fan out from one display command into broader wireless-profile collection? - Why: attackers often enumerate profile names with `wlan show profiles`, then display or export cleartext secrets; same-launcher enumeration without `key=clear` is precursor discovery. - Focus: related process starts on `host.id` and `process.parent.entity_id`, using `process.executable` and `process.command_line`. $investigate_0 - Implication: escalate when the parent also runs profile enumeration, repeated `show profile`, `export profile`, or export without `name=`; keep review local when activity stays isolated to one profile display. - Hint: If `process.parent.entity_id` is absent, pivot with `host.id`, `process.parent.pid`, and the alert window. - Did the launcher or siblings stage recovered wireless material? - Focus: same-parent process starts on `host.id`, using `process.executable` and `process.command_line`; file events from `host.id` plus `process.entity_id` or weaker `process.pid`, reviewing `file.path`, `file.extension`, and `file.size`. $investigate_1 - Implication: escalate when XML, redirected text, ZIP files, copied profiles, archive tools, copy utilities, cloud-sync clients, shell redirection, or script wrappers stage material for later use or transfer; missing file telemetry is unresolved, not benign. A clean file view lowers concern only when command and lineage also stay limited. - If local evidence remains suspicious or unresolved, do related alerts change scope or urgency? - Focus: related alerts for `user.id`, especially credential-access, lateral-movement, staging, remote-access, or persistence findings. $investigate_2 - Implication: broaden response when the same user or host also shows dumping, staging, remote access, or persistence; keep scope local when related alerts are absent and local evidence supports one bounded workflow. - Hint: If the user view is sparse or the host is shared, review alerts for the same `host.id`. $investigate_3 - Escalate when command intent, lineage, same-launcher collection, staging, file artifacts, or related alerts show bulk credential access or broader compromise; close only when binary identity, command scope, parent workflow, user-host context, and recovery records bind to one recognized support or recovery action; preserve artifacts and escalate when evidence is mixed or incomplete. ### False positive analysis - Helpdesk, field-support, device-recovery, imaging, hardware replacement, or Wi-Fi profile migration can retrieve one saved wireless key. Confirm signed netsh identity, one local profile display or expected export in `process.command_line`, support-tooling parentage, and no bulk enumeration, archive staging, or transfer; use asset or ticket records only to corroborate that exact action, otherwise require the same executable, parent, command pattern, `user.id`, `host.id`, and quiet surrounding activity across prior alerts from this rule. - Before creating an exception, validate recurrence of the same `process.executable`, `process.parent.executable`, `process.command_line` pattern, `user.id`, and `host.id` with the same limited scope. Avoid exceptions on `process.name`, `key=clear` alone, the host alone, or all netsh wireless activity. ### Response and remediation - If confirmed benign, reverse any temporary containment and document which evidence matched the support or recovery workflow: command scope, binary identity, parent workflow, `user.id`, `host.id`, and absence of collection or staging. Create an exception only after the same limited pattern recurs. - If suspicious but unconfirmed, preserve the alert record, case export, volatile process context, `process.entity_id`, `process.command_line`, `process.parent.command_line`, sibling process starts, staged artifacts when recovered, and affected `user.id` and `host.id`. Start with reversible containment such as temporary wireless or network restrictions; use host isolation only if staging, export, transfer, or broader compromise is evident. - If confirmed malicious, isolate the endpoint or terminate the offending process through endpoint-response tooling after recording `process.entity_id`, `process.command_line`, parent context, exposed profile names, staged artifacts, and related-alert evidence. If tooling is unavailable, escalate with the preserved evidence set. - Reset or rotate credentials exposed by the dumped wireless profile. For PSK environments, rotate the affected SSID key; for 802.1X environments, revoke or reissue affected certificates, reset cached credentials, and verify whether the exposed profile could grant broader network access. - Before deleting artifacts, review other hosts and users for the same `process.command_line`, parent pattern, or exported profile artifacts so scoping finishes before evidence is destroyed. - Eradicate only scripts, batch files, XML exports, archives, and persistence mechanisms found during the investigation, then remediate the initial access path that allowed the key retrieval. """ setup = """## Setup This 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. 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: - [CrowdStrike](https://ela.st/crowdstrike-integration) - [Microsoft Defender XDR](https://ela.st/m365-defender) - [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel) - [Sysmon Event ID 1 - Process Creation](https://ela.st/sysmon-event-1-setup) - [Windows Process Creation Logs](https://ela.st/audit-process-creation) """ [rule.investigation_fields] field_names = [ "@timestamp", "host.id", "user.id", "process.entity_id", "process.pid", "process.executable", "process.command_line", "process.args", "process.pe.original_file_name", "process.parent.entity_id", "process.parent.pid", "process.parent.executable", "process.parent.command_line", "process.code_signature.subject_name", "process.code_signature.trusted", ] [transform] [[transform.investigate]] label = "Process starts from the same parent" description = "" 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.parent.entity_id", queryType = "phrase", value = "{{process.parent.entity_id}}", valueType = "string" } ] ] relativeFrom = "now-1h" relativeTo = "now" [[transform.investigate]] label = "File activity for the alerting process" description = "" providers = [ [ { excluded = false, field = "event.category", queryType = "phrase", value = "file", 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" [[transform.investigate]] label = "Alerts associated with the user" description = "" 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" [[transform.investigate]] label = "Alerts associated with the host" description = "" 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" [[rule.threat]] framework = "MITRE ATT&CK" [[rule.threat.technique]] id = "T1003" name = "OS Credential Dumping" reference = "https://attack.mitre.org/techniques/T1003/" [[rule.threat.technique]] id = "T1552" name = "Unsecured Credentials" reference = "https://attack.mitre.org/techniques/T1552/" [[rule.threat.technique.subtechnique]] id = "T1552.001" name = "Credentials In Files" reference = "https://attack.mitre.org/techniques/T1552/001/" [[rule.threat.technique]] id = "T1555" name = "Credentials from Password Stores" reference = "https://attack.mitre.org/techniques/T1555/" [rule.threat.tactic] id = "TA0006" name = "Credential Access" reference = "https://attack.mitre.org/tactics/TA0006/" [[rule.threat]] framework = "MITRE ATT&CK" [[rule.threat.technique]] id = "T1016" name = "System Network Configuration Discovery" reference = "https://attack.mitre.org/techniques/T1016/" [[rule.threat.technique]] id = "T1082" name = "System Information Discovery" reference = "https://attack.mitre.org/techniques/T1082/" [rule.threat.tactic] id = "TA0007" name = "Discovery" reference = "https://attack.mitre.org/tactics/TA0007/"