PowerShell Keylogging Script
Detects PowerShell script block content that references Win32 keylogging primitives such as key state polling or low-level input hooks. Adversaries use keylogging to capture credentials and other sensitive user input.
Rule type: query
Rule indices:
- logs-windows.powershell*
- winlogbeat-*
Rule Severity: high
Risk Score: 73
Runs every:
Searches indices from: now-9m
Maximum alerts per execution: 100
References:
- https://github.com/EmpireProject/Empire/blob/master/data/module_source/collection/Get-Keystrokes.ps1
- https://github.com/MojtabaTajik/FunnyKeylogger/blob/master/FunnyLogger.ps1
Tags:
- Domain: Endpoint
- OS: Windows
- Use Case: Threat Detection
- Tactic: Collection
- Resources: Investigation Guide
- Data Source: PowerShell Logs
Version: 219
Rule authors:
- Elastic
Rule license: Elastic License v2
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
Does the preserved script content show active keylogging intent rather than inert reference text?
- Focus: the preserved script text on the alert and any associated
file.path. - Implication: supports concern when the content invokes polling loops, hook registration, window-labeling routines, output formatting, or commodity functions such as "Get-Keystrokes"; carries less weight when the text is clearly documentation, training content, or inert reference with no adjacent execution evidence.
- Focus: the preserved script text on the alert and any associated
Does reconstructing the full script reveal logging, labeling, staging, or transmission behavior that changes urgency?
- Why: script block logging can split one script across multiple records; later fragments often reveal output paths, timer loops, or exfiltration.
- Focus:
powershell.file.script_block_id,powershell.sequence,powershell.total, andpowershell.file.script_block_lengthto rebuild adjacent fragments, then the reconstructed content for foreground-window labeling, output files, archives, remote destinations, or cleanup logic. $investigate_0 - Implication: supports active collection when reconstruction shows continuous polling, registered hooks, keystroke formatting, saved logs, compression, upload logic, or cleanup after collection.
Does the user-host pairing fit recognized accessibility tooling, kiosk automation, or security assessment?
- Focus: the
user.idandhost.idpairing, whether the host role supports input-capture tooling, and any prior alert recurrence for the same pairing and launcher. - Hint: if workflow documentation is unavailable, require the same pairing and launcher to recur across prior alerts.
- Implication: escalate when the user has no recurring pattern of input capture, the host handles privileged workflows, or the timing falls outside scheduled testing.
- Focus: the
Can you recover the PowerShell process and explain how it was launched?
- Focus: the matching process start event via
process.pidandhost.id, recoveringprocess.command_line,process.parent.executable,process.parent.command_line, andprocess.Ext.session_info.logon_type. $investigate_1 - Hint: if the process event cannot be found, keep later file, network, and authentication review bounded to the same host and alert time.
- Implication: supports unauthorized use when the recovered process is launched by a document, browser, chat client, scheduled task, remote session, or user-writable script path.
- Focus: the matching process start event via
Do file events show keystroke logs, staged archives, or renamed artifacts?
- Focus: file events for the same
process.entity_id, with attention tofile.path,file.extension,file.Ext.header_bytes, andfile.Ext.original.pathwhen logs or archives are renamed for staging. - Implication: supports active collection when log files, archives, or renamed artifacts appear in user-writable or hidden paths, or when header bytes do not match the visible extension.
- Focus: file events for the same
Do network events show credential exfiltration, webhook delivery, or remote staging?
- Focus: network events for the same
process.entity_id, separating DNSlookup_resultevents (dns.question.name,dns.resolved_ip) from connection events (destination.ip,destination.port). - Implication: suggests exfiltration when the process reaches rare public destinations, messaging or webhook services, or cloud storage. Missing network telemetry is unresolved, not benign.
- Focus: network events for the same
Do authentication events show the session came from an unusual origin or that captured credentials were reused?
- Why: keylogging becomes higher priority when post-capture authentication shows new logons or explicit-credential use that could reflect captured input being used.
- Focus: if
process.Ext.authentication_idwas recovered, bridge towinlog.event_data.TargetLogonIdfor session origin (source.ip,winlog.event_data.AuthenticationPackageName). Also check post-alert 4624 or 4648 events on the samehost.idfor accounts that do not match the alert user. - Hint: "4648" explicit-credential events do not use
winlog.event_data.TargetLogonId; searchwinlog.event_data.SubjectLogonIdinstead. - Implication: suggests captured-input abuse when the session has an unexpected origin or when later logons show new remote, privileged, or explicit-credential activity.
If the local evidence stays suspicious, do related alerts suggest broader compromise?
- Focus: related alerts for the same
user.idto find repeated collection or defense-evasion activity. $investigate_2 - Hint: compare related alerts for the same
host.idfor persistence, repeated collection, or renamed input-capture variants. $investigate_3 - Implication: broaden when either view shows collection, defense-evasion, persistence, or transfer activity outside the expected workflow; keep the case local when surrounding alerts stay confined to one recognized workflow.
- Focus: related alerts for the same
Escalate when script intent, launch context, artifacts, network, or authentication evidence align on unauthorized input capture; close only when all evidence supports a recognized benign workflow; if mixed or incomplete, preserve and escalate.
- Accessibility, kiosk, security-testing, or malware-analysis workflows can legitimately trigger this rule. Confirm by matching the same
process.executable, signer, andhost.idpattern across prior alerts or against workflow records. - Before creating an exception, validate that the same
user.id,host.id,file.path, and a stablepowershell.file.script_block_textsubstring recur across prior alerts. Avoid exceptions on hook-function strings alone,user.namealone, or the host alone.
- If confirmed benign, reverse any temporary containment and document the script content, recovered launch chain, user-host scope, and any benign artifact or destination pattern that proved the confirmed workflow. Create an exception only if the same workflow recurs consistently across prior alerts from this rule.
- If suspicious but unconfirmed, preserve the reconstructed script content, recovered
process.entity_id, relatedfile.pathartifacts, anydns.question.nameordestination.ipvalues linked to transfer, and authentication events around the alert. Apply reversible containment such as session restrictions or temporary destination blocking. Escalate to host isolation only when active collection, credential reuse, or transfer evidence is strong and the host role can tolerate it. Avoid destructive cleanup until scope is clearer. - If confirmed malicious, document the recovered
process.entity_id,process.command_line,process.parent.executable, writtenfile.pathartifacts, any confirmeddns.question.nameordestination.ipvalues, and logon session details before initiating response actions. Prefer host isolation over process termination for initial containment when the asset can tolerate it, then contain affected accounts, block malicious destinations and scripts, and terminate recovered processes only after evidence capture. - If keystroke logs, archives, or staging artifacts are identified, preserve them as sensitive evidence. Review related users and hosts for the same
powershell.file.script_block_textcontent,file.pathpattern, ordns.question.namedestinations before eradicating. Then remove the artifacts and any persistence or automation identified during reconstruction or host-scoping. - If follow-on authentication review suggests captured credentials were used, prioritize credential resets for the affected user and any additional accounts identified during the post-alert authentication timeline, then hunt for related sessions or privilege changes on the same host and other assets.
- After containment, restrict the execution path that allowed the script to run, such as tightening PowerShell execution policies or script-path allowlists. Retain PowerShell script block logging and related endpoint telemetry.
event.category:process and host.os.type:windows and
(
powershell.file.script_block_text : (GetAsyncKeyState or NtUserGetAsyncKeyState or GetKeyboardState or "Get-Keystrokes") or
powershell.file.script_block_text : (
(SetWindowsHookEx or SetWindowsHookExA or SetWindowsHookExW or NtUserSetWindowsHookEx) and
(
GetForegroundWindow or GetWindowTextA or GetWindowTextW or "WM_KEYBOARD_LL" or "WH_MOUSE_LL" or
"WH_KEYBOARD_LL" or "LowLevelKeyboardProc" or "CallNextHookEx"
)
)
) and not user.id : "S-1-5-18" and
not powershell.file.script_block_text : (
"sentinelbreakpoints" and "Set-PSBreakpoint"
)
Framework: MITRE ATT&CK
Tactic:
- Name: Collection
- Id: TA0009
- Reference URL: https://attack.mitre.org/tactics/TA0009/
Technique:
- Name: Input Capture
- Id: T1056
- Reference URL: https://attack.mitre.org/techniques/T1056/
Sub Technique:
- Name: Keylogging
- Id: T1056.001
- Reference URL: https://attack.mitre.org/techniques/T1056/001/
Framework: MITRE ATT&CK
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/
Technique:
- Name: Native API
- Id: T1106
- Reference URL: https://attack.mitre.org/techniques/T1106/