Potential PowerShell Pass-the-Hash/Relay Script
editPotential PowerShell Pass-the-Hash/Relay Script
editDetects PowerShell scripts associated with NTLM relay or pass-the-hash tooling and SMB/NTLM negotiation artifacts. Attackers use relay and PtH techniques to authenticate without passwords and pivot to other systems.
Rule type: query
Rule indices:
- logs-windows.powershell*
- 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:
- https://github.com/Kevin-Robertson/Invoke-TheHash/blob/master/Invoke-WMIExec.ps1
- https://github.com/Kevin-Robertson/Invoke-TheHash/blob/master/Invoke-SMBExec.ps1
- https://github.com/dafthack/Check-LocalAdminHash/blob/master/Check-LocalAdminHash.ps1
- https://github.com/nettitude/PoshC2/blob/master/resources/modules/Invoke-Tater.ps1
- https://github.com/Kevin-Robertson/Inveigh/blob/master/Inveigh.ps1
Tags:
- Domain: Endpoint
- OS: Windows
- Use Case: Threat Detection
- Tactic: Credential Access
- Resources: Investigation Guide
- Data Source: PowerShell Logs
Version: 110
Rule authors:
- Elastic
Rule license: Elastic License v2
Investigation guide
editTriage and analysis
Investigating Potential PowerShell Pass-the-Hash/Relay Script
Possible investigation steps
- Does the visible script content implement relay-listener behavior, pass-the-hash execution, target validation, or more than one?
-
Focus:
powershell.file.script_block_textand any file-backedfile.path. - Implication: escalate when the fragment builds NTLMSSP/SMB messages, starts HTTP/SMB/proxy listeners, forwards authentication, references WMI/SMB/WinRM helpers, or pairs byte arrays with target selection; lower suspicion only for parser or lab text with no targeting, listener, credential, or execution logic.
- Does full script reconstruction reveal target lists, credential material, service names, or listener settings the matching fragment did not show?
- Why: script block logging often splits relay mode, target configuration, and execution helpers into separate fragments.
-
Focus:
powershell.file.script_block_id,powershell.sequence,powershell.total, and reconstructedpowershell.file.script_block_textonhost.id; reassemble bypowershell.sequenceand treat missing fragments as unresolved. !{investigate{"description":"","label":"All PowerShell 4104 fragments for this script on this host","providers":[[{"excluded":false,"field":"host.id","queryType":"phrase","value":"{{host.id}}","valueType":"string"},{"excluded":false,"field":"powershell.file.script_block_id","queryType":"phrase","value":"{{powershell.file.script_block_id}}","valueType":"string"},{"excluded":false,"field":"event.code","queryType":"phrase","value":"4104","valueType":"string"}]],"relativeFrom":"now-1h","relativeTo":"now"}} - Implication: escalate on remote targets, password hashes, "TargetList", "SMBRelayTarget", "wpad.dat", "WPAD", listener ports, service names, execution helpers, or fan-out logic; lower suspicion only for research or validation code with no credential material, targets, listener, or execution path.
- Which recovered PowerShell process explains launch context and downstream pivots?
-
Focus: If endpoint process telemetry exists, recover the matching process via
host.id + process.pidbefore interpretingprocess.*orprocess.parent.*; if absent, keep launch context unresolved. Recordprocess.command_line,process.parent.executable,process.Ext.session_info.logon_type,process.Ext.authentication_id, andprocess.entity_id. !{investigate{"description":"","label":"Process events for the PowerShell instance","providers":[[{"excluded":false,"field":"process.pid","queryType":"phrase","value":"{{process.pid}}","valueType":"string"},{"excluded":false,"field":"host.id","queryType":"phrase","value":"{{host.id}}","valueType":"string"},{"excluded":false,"field":"event.category","queryType":"phrase","value":"process","valueType":"string"}]],"relativeFrom":"now-1h","relativeTo":"now"}} -
Implication: escalate when the recovered launch shows encoded commands, remote-administration launchers, Office or browser parents, elevated context, or service/network logon sessions that do not fit the user; do not infer legitimacy from
process.pidalone. - Do authentication events show local operator context or relay/PtH follow-on?
-
Focus: same-
host.id/user.idWindows Security events forevent.code4624, 4625, or 4648; reviewsource.ip,winlog.event_data.AuthenticationPackageName, andwinlog.logon.type. !{investigate{"description":"","label":"Windows Security authentication events for the user","providers":[[{"excluded":false,"field":"host.id","queryType":"phrase","value":"{{host.id}}","valueType":"string"},{"excluded":false,"field":"user.id","queryType":"phrase","value":"{{user.id}}","valueType":"string"},{"excluded":false,"field":"event.code","queryType":"phrase","value":"4624","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"},{"excluded":false,"field":"event.code","queryType":"phrase","value":"4625","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"},{"excluded":false,"field":"event.code","queryType":"phrase","value":"4648","valueType":"string"}]],"relativeFrom":"now-24h","relativeTo":"now"}} -
Hint: bridge recovered
process.Ext.authentication_idtowinlog.event_data.TargetLogonIdonly for the local session; prove relay/PtH with same-host inbound NTLM withoutuser.id, target-host 4624/4625, or DC-side 4776 for reconstructed targets or sources. - Implication: escalate when local, target-host, or DC authentication shows unexpected type 3 NTLM, repeated failures, privileged sessions, or explicit-credential use tied to reconstructed targets; missing authentication telemetry is unresolved, not benign.
- Do network events show outbound relay or hash-validation activity to targets named in the script?
- Why: relay code often resolves targets, then reaches SMB, RPC, WinRM, or HTTP destinations; listener-only capture may not.
-
Focus: If endpoint network telemetry exists, scope same-host events to
host.id,process.pid, and the alert window, or use reconstructed targets when process identity is unavailable; separate DNS (dns.question.name,dns.resolved_ip) from connections (destination.ip,destination.port). !{investigate{"description":"","label":"Network events for the PowerShell process","providers":[[{"excluded":false,"field":"process.pid","queryType":"phrase","value":"{{process.pid}}","valueType":"string"},{"excluded":false,"field":"host.id","queryType":"phrase","value":"{{host.id}}","valueType":"string"},{"excluded":false,"field":"event.category","queryType":"phrase","value":"network","valueType":"string"}]],"relativeFrom":"now-1h","relativeTo":"now"}} - Implication: escalate when the host fans out to named targets or reaches SMB, RPC, WinRM, or relay ports (80, 443, 445) outside the declared test scope; listener scripts stay suspicious with little outbound traffic when reconstruction shows "SMBRelayTarget", "wpad.dat", or similar relay-ready settings. Missing network telemetry is unresolved, not benign.
- If local evidence remains suspicious or incomplete, do related alerts widen the user or host scope?
-
Focus: related alerts for
user.id; if quiet, comparehost.idfor adjacent relay, pass-the-hash, remote-service, persistence, or post-compromise alerts. - !{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: broaden when local evidence stays suspicious or unresolved and related alerts show connected relay, listener-only capture, hash-validation fan-out, or lateral-movement behavior; keep local when surrounding alerts are absent or confined to the same declared test scope.
- Weigh script intent, reconstruction, launch context, authentication follow-on, network contact, and related-alert scope: escalate when they align on unauthorized relay or pass-the-hash activity; close only when reconstructed content, launch, source, and available auth or network evidence support one controlled workflow with no contradictions; preserve and escalate if evidence is mixed or incomplete.
False positive analysis
-
Controlled testing, incident-response, or protocol-research workflows can trigger this rule when reconstructed
powershell.file.script_block_textnames only recognized targets or stays limited to parser/validation routines, recovered launch context matches the operator workflow, and authentication or network telemetry shows no live relay, listener, or execution outside scope. If engagement or change records exist, require alignment; otherwise, confirm recurringuser.id,host.id, source pattern, recovered launch pattern, and target or port pattern across prior alerts from this rule. Do not close if hashes, listener ports, or follow-on authentication diverge. -
Before creating an exception, validate recurring
user.id,host.id, recovered launch pattern, source pattern, and target set across prior alerts. Build the exception from that minimum workflow. Avoid exceptions on byte sequences alone,user.namealone, or host alone.
Response and remediation
- If confirmed benign, reverse any temporary containment and document the script content, recovered launch chain, source path pattern, target set, and session origin or logon-type pattern that proved the lab, response, or troubleshooting workflow. Create an exception only if the same workflow recurs across prior alerts from this rule.
-
If suspicious but unconfirmed, preserve the reconstructed
powershell.file.script_block_text,powershell.file.script_block_id, fragment ordering metadata, recovered process and parent details, named targets, listener ports, service names, UNC paths, and related authentication or network evidence before destructive actions. - Apply reversible containment first, such as host isolation if tolerable or temporary controls on exposed accounts and named targets. Avoid terminating processes or deleting artifacts until possible credential misuse and lateral movement scope is clearer.
-
If confirmed malicious, isolate the endpoint when possible; otherwise escalate with the recorded
host.id, recovered process identifiers, source IP values, named targets, and authentication evidence. Rotate or invalidate impacted credentials, review named systems for successful SMB/WMI/WinRM/service activity, restrict exposed NTLM pathways where supported, then remove only the scripts, services, scheduled tasks, persistence, or staging artifacts found during the investigation. - Retain PowerShell Script Block Logging plus supporting endpoint, authentication, and network telemetry. Document adjacent variants such as listener-only capture, hash-validation fan-out, or non-PowerShell relay/pass-the-hash alerts for detection follow-up.
Setup
editSetup
PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104). Setup instructions: https://ela.st/powershell-logging-setup
Rule query
editevent.category:process and host.os.type:windows and
powershell.file.script_block_text : (
("NTLMSSPNegotiate" and ("NegotiateSMB" or "NegotiateSMB2")) or
"4E544C4D53535000" or
"0x4e,0x54,0x4c,0x4d,0x53,0x53,0x50" or
"0x4e,0x54,0x20,0x4c,0x4d" or
"0x53,0x4d,0x42,0x20,0x32" or
"0x81,0xbb,0x7a,0x36,0x44,0x98,0xf1,0x35,0xad,0x32,0x98,0xf0,0x38"
) and
not file.directory : "C:\ProgramData\Microsoft\Windows Defender Advanced Threat Protection\Downloads"
Framework: MITRE ATT&CKTM
-
Tactic:
- Name: Credential Access
- ID: TA0006
- Reference URL: https://attack.mitre.org/tactics/TA0006/
-
Technique:
- Name: Adversary-in-the-Middle
- ID: T1557
- Reference URL: https://attack.mitre.org/techniques/T1557/
-
Sub-technique:
- Name: LLMNR/NBT-NS Poisoning and SMB Relay
- ID: T1557.001
- Reference URL: https://attack.mitre.org/techniques/T1557/001/
-
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: PowerShell
- ID: T1059.001
- Reference URL: https://attack.mitre.org/techniques/T1059/001/
-
Tactic:
- Name: Lateral Movement
- ID: TA0008
- Reference URL: https://attack.mitre.org/tactics/TA0008/
-
Technique:
- Name: Use Alternate Authentication Material
- ID: T1550
- Reference URL: https://attack.mitre.org/techniques/T1550/
-
Sub-technique:
- Name: Pass the Hash
- ID: T1550.002
- Reference URL: https://attack.mitre.org/techniques/T1550/002/