Wireless Credential Dumping using Netsh Command


Description

Identifies attempts to dump Wireless saved access keys in clear text using the Windows built-in utility Netsh.

Query · eql

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"

Investigation fields

Pivot points the source recommends for triage.

  • @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

Implementation guide

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:

Analyst notes

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.
Raw source Wireless Credential Dumping using Netsh Command · Elastic TOML
Esc
Published by elastic/detection-rules ↗, licensed under Elastic License 2.0 ↗. Reproduced here unmodified.
[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/"

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.