PowerShell Suspicious Script with Screenshot Capabilities

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

PowerShell Suspicious Script with Screenshot Capabilities

edit

Detects PowerShell script block content that uses CopyFromScreen with .NET bitmap classes to capture screenshots. Attackers use screen capture to collect on-screen information and credentials.

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:

Tags:

  • Domain: Endpoint
  • OS: Windows
  • Use Case: Threat Detection
  • Tactic: Collection
  • Resources: Investigation Guide
  • Data Source: PowerShell Logs

Version: 214

Rule authors:

  • Elastic

Rule license: Elastic License v2

Investigation guide

edit

Triage and analysis

Investigating PowerShell Suspicious Script with Screenshot Capabilities

Possible investigation steps

  • Does the alert-preserved script content indicate a bounded screenshot action or deliberate repeated screen collection?
  • Focus: the preserved script text on the alert and any associated file.path.
  • Implication: supports deliberate collection when the script loops, captures full desktops, or targets multiple monitors; weaker support when the content shows a single bounded capture tied to a recurring support or test action.
  • Does the reconstructed script add save, encode, archive, or transfer logic that changes risk?
  • Why: script block logging can split one script across multiple records; later fragments often reveal output paths, encoding, or transfer logic.
  • Focus: powershell.file.script_block_id, powershell.sequence, powershell.total, and powershell.file.script_block_length to rebuild adjacent fragments, then the reconstructed script body for output paths, image encoding, archive helpers, or remote destinations. !{investigate{"description":"","label":"Script block fragments for the same script","providers":[[{"excluded":false,"field":"powershell.file.script_block_id","queryType":"phrase","value":"{{powershell.file.script_block_id}}","valueType":"string"},{"excluded":false,"field":"host.id","queryType":"phrase","value":"{{host.id}}","valueType":"string"}]],"relativeFrom":"now-1h","relativeTo":"now"}}
  • Implication: staging becomes more likely when reconstruction shows image saves, compression, archiving, or transfer logic.
  • Can you recover the PowerShell process and explain how it was launched?
  • Focus: the matching process start event via process.pid and host.id, recovering process.command_line, process.parent.executable, process.parent.command_line, and process.Ext.session_info.logon_type. !{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"}}
  • Hint: if the process event cannot be found, keep later file and network review bounded to the same host and alert time.
  • Implication: supports unauthorized use when the process runs from user-writable paths, inherits an unusual parent, or lands in an unexpected session type.
  • Does the user-host pattern fit a recognized support, accessibility, or QA workflow?
  • Focus: the user.id and host.id pairing, the recovered process.parent.executable, 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-host pair has no recurring support or QA pattern, the launcher is new, or the host is used for privileged sessions.
  • Do file events show screenshot output, staging artifacts, or suspicious script provenance?
  • Focus: file events for the same process.entity_id, with attention to file.path, file.Ext.header_bytes, file.origin_url or file.Ext.windows.zone_identifier, and later reuse of a written path as process.executable.
  • Implication: staging is more likely when the script arrives from download locations, writes screenshots to user-writable paths, or produces files that later execute.
  • Do network events show transfer of captured images or related staging activity?
  • Focus: network events for the same process.entity_id, separating DNS lookup_result events (dns.question.name, dns.resolved_ip) from connection events (destination.ip, destination.port).
  • Implication: delivery risk increases when the process reaches rare external infrastructure, remote storage, or destinations named in the script. Missing network telemetry is unresolved, not benign.
  • Does the host or session context suggest privileged or sensitive on-screen data could have been exposed?
  • Why: the same capture script is far more consequential on admin workstations, jump hosts, or finance endpoints than on a lab box used for UI testing.
  • Focus: the recovered process.Ext.session_info.logon_type and the user.id/host.id pairing. For remote sessions, bridge process.Ext.authentication_id to authentication events for source.ip; if unavailable, treat origin as unresolved.
  • Implication: raise urgency when the visible desktop likely contained credentials, privileged consoles, or finance data.
  • If the local evidence stays suspicious, do related alerts suggest broader compromise?
  • Focus: related alerts for the same user.id and host.id in the last 48 hours to spot recurrence across hosts or same-host staging, archive helpers, or alternate capture routines. !{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 the same user repeats screenshot capture across hosts or the host shows precursor access or alternate capture routines; keep narrow when both views stay confined to one recognized launcher.
  • Escalate when capture scope, launch context, artifacts, network, or session sensitivity align on unauthorized screen collection; close only when all evidence supports a recognized benign workflow; if mixed or incomplete, preserve and escalate.

False positive analysis

  • Support, QA, accessibility, or testing workflows can legitimately trigger this rule. Confirm by matching the same process.executable, signer, and host.id pattern across prior alerts or against workflow records.
  • Before creating an exception, validate that the same user.id, host.id, file.path, and a stable powershell.file.script_block_text substring recur across prior alerts. Avoid exceptions on screenshot-related strings alone, user.name alone, or the host alone.

Response and remediation

  • If confirmed benign, reverse any temporary containment and document the confirmed workflow evidence: the stable user-host pairing, recovered launch chain, and bounded internal capture or transfer path. Create an exception only if the same user, host, and launch context recur consistently across prior alerts from this rule.
  • If suspicious but unconfirmed, preserve the reconstructed script content, recovered process.entity_id, written file.path artifacts, and any dns.question.name or destination.ip values linked to transfer. Apply reversible containment such as temporary egress restrictions or tighter monitoring on the exposed session. Escalate to host isolation only when capture, staging, 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, written file.path artifacts, and any confirmed dns.question.name or destination.ip values before initiating response actions. Use available endpoint response integrations to isolate the host and contain the affected account when capture scope, launch chain, artifacts, or delivery evidence shows unauthorized screen collection or transfer. If direct endpoint response is unavailable, escalate with the documented artifacts to the team that can act.
  • If linked dns.question.name, destination.ip, or transfer artifacts confirm screenshot delivery or staging, block the confirmed destination, channel, or automation path before cleanup and preserve any related cloud, messaging, or remote-storage identifiers needed for follow-on scoping.
  • If screenshots may have captured credentials, privileged sessions, or other sensitive on-screen data, follow the incident process for credential reset and access review for the exposed accounts or sessions, and review post-alert access from the same host or user for follow-on misuse.
  • After containment, review related users and hosts for the same powershell.file.script_block_text content, file.path pattern, or dns.question.name destinations before eradicating. Remove confirmed staged scripts, screenshot artifacts, and transfer helpers. Restrict the execution path, such as tightening PowerShell execution policies or script-path allowlists.
  • Retain PowerShell script block logging and related endpoint telemetry so the case remains auditable.

Setup

edit

Setup

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

edit
event.category:process and host.os.type:windows and
  powershell.file.script_block_text : (
    CopyFromScreen and
    ("System.Drawing.Bitmap" or "Drawing.Bitmap")
  ) and not user.id : "S-1-5-18"

Framework: MITRE ATT&CKTM