[Rule Tuning] Windows High-Severity Rules Revamp - 1 (#5899)
* [Rule Tuning] Windows High-Severity Rules Revamp - 1 * ++ * Guide compression * ++ * revert unit test removal * Apply suggestion from @w0rk3r * Update command_and_control_headless_browser.toml --------- Co-authored-by: shashank-elastic <91139415+shashank-elastic@users.noreply.github.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
creation_date = "2021/10/19"
|
||||
integration = ["windows"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/03/24"
|
||||
updated_date = "2026/03/30"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
@@ -11,90 +11,13 @@ Detects PowerShell script block content that invokes microphone capture routines
|
||||
Adversaries may use audio recording to surveil users or capture sensitive conversations for theft or extortion.
|
||||
"""
|
||||
from = "now-9m"
|
||||
index = ["winlogbeat-*", "logs-windows.powershell*"]
|
||||
index = ["logs-windows.powershell*", "winlogbeat-*"]
|
||||
language = "kuery"
|
||||
license = "Elastic License v2"
|
||||
name = "PowerShell Suspicious Script with Audio Capture Capabilities"
|
||||
note = """## Triage and analysis
|
||||
|
||||
> **Disclaimer**:
|
||||
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
|
||||
|
||||
### Investigating PowerShell Suspicious Script with Audio Capture Capabilities
|
||||
|
||||
This alert indicates PowerShell script block content associated with microphone recording or Windows multimedia audio capture routines. Because audio capture can expose sensitive conversations, prioritize investigation when the activity is unexpected for the user, host, or time of day, or when the script suggests local staging or external transfer.
|
||||
|
||||
#### Key alert fields to review
|
||||
|
||||
- `user.name`, `user.domain`, `user.id`: Account execution context for correlation, prioritization, and scoping.
|
||||
- `host.name`, `host.id`: Host execution context for correlation, prioritization, and scoping.
|
||||
- `powershell.file.script_block_text`: Script block content that matched the detection logic.
|
||||
- `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`: Script block metadata to pivot to other fragments or reconstruct full script content when split across multiple events.
|
||||
- `file.path`, `file.directory`, `file.name`: File-origin context when the script block is sourced from an on-disk file.
|
||||
- `powershell.file.script_block_length`: Script block length (size) context.
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- Establish alert context and ownership:
|
||||
- Identify the execution context using `user.name`, `user.domain`, and `user.id`, and the impacted endpoint using `host.name` and `host.id`.
|
||||
- If `file.path` or `file.name` is populated, note the script origin and whether the location is expected for administrative scripts.
|
||||
|
||||
- Analyze `powershell.file.script_block_text` for capability and intent:
|
||||
- Determine whether the script enumerates devices, starts/stops recording, sets recording duration, or saves output.
|
||||
- Capture any referenced output paths, filenames, or extensions (for example, `.wav`) that may indicate where audio was written.
|
||||
- Look for higher-risk patterns in the same content, such as dynamic unmanaged API access (for example, `Add-Type` with `DllImport`), obfuscation, looping/retry logic, or cleanup routines (delete after save/upload).
|
||||
- Note any embedded remote destinations, credentials, or upload logic if present to support containment and scoping.
|
||||
|
||||
- Reconstruct full script content when the script block is split:
|
||||
- Pivot on `powershell.file.script_block_id` for the same endpoint and time window.
|
||||
- Rebuild the full content by ordering fragments with `powershell.sequence` and validating completeness with `powershell.total` before drawing conclusions from a single fragment.
|
||||
- Review nearby script blocks from the same `user.id` and `host.id` to identify configuration, helper functions, or follow-on actions not present in the matching fragment.
|
||||
|
||||
- Validate execution chain and likely launch method (if additional telemetry is available):
|
||||
- Correlate the alert time on `host.name` with process execution telemetry to identify the PowerShell host process and its parent process.
|
||||
- Assess whether the parent process and timing are consistent with expected user/admin activity on that host.
|
||||
- If the script content indicates remote execution, scheduled execution, or automation, review surrounding activity for corroborating evidence (repeated runs, multiple hosts, or multiple users).
|
||||
|
||||
- Assess evidence of audio collection and data handling:
|
||||
- If the script indicates an output location, correlate with file activity around `@timestamp` to identify newly created or modified files that could contain recorded audio.
|
||||
- Review `file.path` and `file.name` (when present) for suspicious or deceptive naming and whether the same artifact appears on multiple endpoints.
|
||||
- If the script references encoding or compression, consider that audio may be staged as non-audio file types; use distinctive filenames or directories from the script content to guide searches.
|
||||
|
||||
- Identify possible exfiltration or secondary objectives:
|
||||
- Review the script content for staging steps (chunking, encoding, archiving) and any explicit network transfer logic.
|
||||
- If remote destinations are present in the script content, correlate with network telemetry for outbound connections from the same host near the alert time and evaluate whether transfer volume and timing are consistent with audio data movement.
|
||||
|
||||
- Scope and prevalence:
|
||||
- Search for the same function names, API strings, or distinctive substrings from `powershell.file.script_block_text` across other endpoints to identify reuse.
|
||||
- Check whether the same `user.id` is associated with similar script blocks on multiple hosts, or whether multiple users on the same `host.id` exhibit similar activity.
|
||||
- If `file.name` is populated, look for the same filename and path patterns elsewhere to determine distribution.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Benign scripts typically show consistent script content and stable provenance (reused script name/path and predictable execution patterns). Unexpected users, ad hoc locations, or one-off executions on user workstations increase suspicion.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If malicious or unauthorized audio capture is suspected:
|
||||
- Contain the endpoint to prevent further collection and reduce the risk of data loss.
|
||||
- Preserve evidence: the full reconstructed script content (all fragments), related PowerShell events in the same time window, and any identified output or staging artifacts.
|
||||
- If audio files are discovered, handle them as potentially sensitive data per your incident response and privacy procedures.
|
||||
- Identify any remote destinations from the script content and take network containment actions appropriate for your environment.
|
||||
- Scope for related activity using `user.id`, `host.id`, and distinctive content from `powershell.file.script_block_text` to identify other affected endpoints or users.
|
||||
- Assess the associated account for compromise and take account-level containment actions (credential reset, session revocation, access review) when misuse is confirmed.
|
||||
|
||||
- If confirmed benign:
|
||||
- Document the business purpose, script owner, and expected execution scope (accounts, hosts, and schedule).
|
||||
- If the activity is legitimate but creating operational noise, add rule exceptions with narrowly scoped constraints based on stable attributes (consistent script content patterns, known script file path/name, and expected executing accounts) rather than broadly suppressing audio-related indicators.
|
||||
"""
|
||||
references = ["https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Get-MicrophoneAudio.ps1"]
|
||||
risk_score = 73
|
||||
rule_id = "2f2f4939-0b34-40c2-a0a3-844eb7889f43"
|
||||
setup = """## 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
|
||||
"""
|
||||
severity = "high"
|
||||
tags = [
|
||||
"Domain: Endpoint",
|
||||
@@ -126,6 +49,132 @@ event.category:process and host.os.type:windows and
|
||||
)
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating PowerShell Suspicious Script with Audio Capture Capabilities
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- Does the preserved script content show live microphone capture logic 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 recording routines, output paths, duration controls, or upload logic; carries less weight when the text is clearly inert example material, documentation, or recognized test content with no adjacent execution evidence.
|
||||
|
||||
- Does reconstructing the full script reveal staging, timers, cleanup, or transfer behavior that changes urgency?
|
||||
- Why: script block logging can split one script across multiple records; later fragments often reveal save locations, loop logic, or exfiltration.
|
||||
- Focus: `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`, and `powershell.file.script_block_length` to rebuild adjacent fragments, then the reconstructed content for output paths, encoding steps, remote destinations, or cleanup logic. $investigate_0
|
||||
- Implication: supports active collection when reconstruction shows repeated capture loops, hidden staging paths, compression, upload, persistence, or cleanup after collection.
|
||||
|
||||
- Does the user-host pairing fit recognized accessibility testing, media tooling, or security assessment?
|
||||
- Focus: the `user.id` and `host.id` pairing, whether the host role or asset classification supports microphone access, and any prior alert recurrence from this rule for the same pairing and launcher.
|
||||
- Implication: escalate when the user has no recurring pattern of audio access, the host handles privileged or sensitive workflows, or the timing falls outside scheduled testing.
|
||||
|
||||
- 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_1
|
||||
- Hint: if the process event cannot be found, keep later file and network review bounded to the same host and alert time rather than assuming a wider process scope.
|
||||
- Implication: supports concern when the recovered process is launched by a document, browser, chat client, scheduled task, remote session, or user-writable script path.
|
||||
|
||||
- Do file events from the same process show recorded audio or staging artifacts?
|
||||
- Focus: file events for the same `process.entity_id`, with attention to `file.path`, `file.extension`, `file.Ext.header_bytes`, and `file.Ext.original.path` when media files or archives are renamed for staging.
|
||||
- Implication: supports active collection when media files, deceptive extensions, archives, or renamed payloads appear in user-writable or hidden paths, or when written artifacts are later executed or uploaded.
|
||||
|
||||
- Do network events show outbound transfer or second-stage behavior from the same process?
|
||||
- Focus: network events for the same `process.entity_id`, separating `dns.question.name` / `dns.resolved_ip` from `destination.ip` / `destination.port`.
|
||||
- Implication: suggests follow-on transfer when the same process or host reaches rare public destinations, cloud storage, or messaging services. Missing network telemetry is unresolved, not benign.
|
||||
|
||||
- If the local evidence stays suspicious, do related alerts or repeated script-block activity suggest broader compromise?
|
||||
- Focus: related alerts for the same `user.id` to find repeated collection, execution, or defense-evasion activity. $investigate_2
|
||||
- Hint: compare related alerts for the same `host.id` and repeated preserved script substrings on this asset to look for persistence, repeated collection, follow-on staging, or renamed audio-capture variants. $investigate_3
|
||||
- Implication: suggests broader compromise when either view shows collection, execution, defense-evasion, persistence, or transfer activity; stays localized when alerts are confined to the known script and host with no repeated collection or follow-on staging.
|
||||
|
||||
- Escalate when script intent, launch context, artifacts, or network activity align on active collection; close only when all evidence supports a recognized benign workflow; if mixed or incomplete, preserve and escalate.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Accessibility, QA, or red-team activity can legitimately trigger this rule. Confirm that the script content, writer identity, and host all belong to an authorized workflow.
|
||||
- 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 audio API strings alone, `user.name` alone, or the host alone.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If confirmed benign, reverse any temporary containment and document the script content, recovered launch chain, user-host scope, and any benign file 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`, related `file.path` artifacts, and any `dns.question.name` or `destination.ip` values linked to transfer. Apply reversible containment such as temporary destination blocking or session restrictions. Escalate to host isolation only when active collection 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 (preferred over process termination for initial containment when the asset can tolerate it), then block confirmed malicious destinations and scripts. If direct endpoint response is unavailable, escalate with the documented artifacts to the team that can act. If the captured audio may have exposed sensitive conversations or privileged sessions, initiate access review for the affected accounts.
|
||||
- If recorded audio files or staging archives are identified, preserve them according to privacy and evidence-handling requirements. Review related users and hosts for the same `powershell.file.script_block_text` content, `file.path` pattern, or `dns.question.name` destinations before eradicating. Then remove the artifacts and any persistence or automation identified during reconstruction or host-scoping.
|
||||
- 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.
|
||||
"""
|
||||
|
||||
setup = """## 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.investigation_fields]
|
||||
field_names = [
|
||||
"@timestamp",
|
||||
"user.name",
|
||||
"user.id",
|
||||
"user.domain",
|
||||
"powershell.file.script_block_text",
|
||||
"powershell.file.script_block_id",
|
||||
"powershell.sequence",
|
||||
"powershell.total",
|
||||
"file.path",
|
||||
"file.directory",
|
||||
"file.name",
|
||||
"process.pid",
|
||||
"host.name",
|
||||
"host.id",
|
||||
"powershell.file.script_block_length"
|
||||
]
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Script block fragments for the same script"
|
||||
description = ""
|
||||
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"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Process events for the PowerShell instance"
|
||||
description = ""
|
||||
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"
|
||||
|
||||
[[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"
|
||||
@@ -175,21 +224,3 @@ reference = "https://attack.mitre.org/techniques/T1120/"
|
||||
id = "TA0007"
|
||||
name = "Discovery"
|
||||
reference = "https://attack.mitre.org/tactics/TA0007/"
|
||||
[rule.investigation_fields]
|
||||
field_names = [
|
||||
"@timestamp",
|
||||
"user.name",
|
||||
"user.id",
|
||||
"user.domain",
|
||||
"powershell.file.script_block_text",
|
||||
"powershell.file.script_block_id",
|
||||
"powershell.sequence",
|
||||
"powershell.total",
|
||||
"file.path",
|
||||
"file.directory",
|
||||
"file.name",
|
||||
"process.pid",
|
||||
"host.name",
|
||||
"host.id",
|
||||
"powershell.file.script_block_length"
|
||||
]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
creation_date = "2021/10/15"
|
||||
integration = ["windows"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/01/26"
|
||||
updated_date = "2026/03/30"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
@@ -11,98 +11,16 @@ Detects PowerShell script block content that references Win32 keylogging primiti
|
||||
low-level input hooks. Adversaries use keylogging to capture credentials and other sensitive user input.
|
||||
"""
|
||||
from = "now-9m"
|
||||
index = ["winlogbeat-*", "logs-windows.powershell*"]
|
||||
index = ["logs-windows.powershell*", "winlogbeat-*"]
|
||||
language = "kuery"
|
||||
license = "Elastic License v2"
|
||||
name = "PowerShell Keylogging Script"
|
||||
note = """## Triage and analysis
|
||||
|
||||
> **Disclaimer**:
|
||||
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
|
||||
|
||||
### Investigating PowerShell Keylogging Script
|
||||
|
||||
This alert indicates that PowerShell Script Block Logging recorded code referencing Win32 API functions commonly used to capture keystrokes or register low-level keyboard or mouse hooks. These primitives are frequently used by offensive tooling and custom implants to collect credentials and other sensitive input.
|
||||
|
||||
#### Key alert fields to review
|
||||
|
||||
- `user.name`, `user.domain`, `user.id`: Account execution context for correlation, prioritization, and scoping.
|
||||
- `host.name`, `host.id`: Host execution context for correlation, prioritization, and scoping.
|
||||
- `powershell.file.script_block_text`: Script block content that matched the detection logic.
|
||||
- `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`: Script block metadata to pivot to other fragments or reconstruct full script content when split across multiple events.
|
||||
- `file.path`, `file.directory`, `file.name`: File-origin context when the script block is sourced from an on-disk file.
|
||||
- `powershell.file.script_block_length`: Script block length (size) context.
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- Identify the execution scope and prioritize response:
|
||||
- Review `host.name` and `host.id` to understand where the activity occurred and whether the asset is high value.
|
||||
- Review `user.name`, `user.domain`, and `user.id` to determine the executing account and whether the activity is expected for that user.
|
||||
- Use `@timestamp` to establish when the script block executed and to anchor a timeline for related activity on the same host.
|
||||
|
||||
- Analyze the script block content for intent and capability:
|
||||
- Review `powershell.file.script_block_text` and note which capability is present:
|
||||
- Key state polling: `GetAsyncKeyState`, `NtUserGetAsyncKeyState`, `GetKeyboardState`.
|
||||
- Input hooking: `SetWindowsHookEx`, `SetWindowsHookExA`, `SetWindowsHookExW`, or `NtUserSetWindowsHookEx` with hook constants like `WM_KEYBOARD_LL`, `WH_KEYBOARD_LL`, or `WH_MOUSE_LL`, and hook flow indicators such as `LowLevelKeyboardProc` or `CallNextHookEx`.
|
||||
- Foreground window context capture often used to label keystrokes: `GetForegroundWindow`, `GetWindowTextA`, `GetWindowTextW`.
|
||||
- Commodity keylogging functions or modules: `Get-Keystrokes`.
|
||||
- Determine whether the script block only defines helper functions or actively invokes hook registration or polling loops (higher confidence of active collection).
|
||||
- Look for common interop patterns used to call Win32 APIs from PowerShell (for example, `Add-Type`, `DllImport`, or embedded C#) and for logic that maps virtual key codes to readable output.
|
||||
- Identify any referenced output handling within the script text (for example, file writes, buffering, encoding, or remote transmission routines) and capture those strings for scoping.
|
||||
|
||||
- Reconstruct the full script when content is split across multiple events:
|
||||
- If `powershell.total` is greater than 1 or the content appears truncated, collect all events that share the same `powershell.file.script_block_id`.
|
||||
- Rebuild the script by ordering fragments using `powershell.sequence` until the expected `powershell.total` is reached.
|
||||
- If expected sequences are missing, widen the time range around `@timestamp` to account for ingestion delays or gaps before concluding reconstruction.
|
||||
- Preserve the fully reconstructed script text as evidence and for further scoping.
|
||||
|
||||
- Determine the source of the script and how it was introduced:
|
||||
- If `file.path` and `file.name` are present, treat the script as file-backed and assess whether the location and name are consistent with approved tooling and change control.
|
||||
- Prioritize review when `file.path` suggests a user-writable or transient location, or when `file.name` is unusual for your environment.
|
||||
- If file origin fields are not present, treat the execution as inline or dynamically generated and focus on surrounding PowerShell activity from the same `user.id` and `host.id` around `@timestamp`.
|
||||
- Correlate the alert time on the same host with available process telemetry to identify the PowerShell host process and its parent process, then evaluate whether the execution chain aligns with expected administrative behavior.
|
||||
|
||||
- Check for evidence of collection, staging, or downstream actions:
|
||||
- Within `powershell.file.script_block_text`, identify any referenced output locations, file names, or remote destinations that could indicate where captured input is stored or transmitted.
|
||||
- Review nearby endpoint file and network telemetry (if available) for unexpected file creation/modification in user-writable locations and unusual outbound connections following the alert time.
|
||||
- Review authentication telemetry around the alert time to understand which accounts may have been exposed on the affected host during the suspected collection window.
|
||||
- Look for repeated executions from the same `host.id` and `user.id` over time, which can indicate persistence or scheduled collection.
|
||||
|
||||
- Scope for additional executions and impacted hosts:
|
||||
- Search for other alerts or script block events that match the same `powershell.file.script_block_id`, the same `file.name`, or distinctive substrings from `powershell.file.script_block_text` across the environment.
|
||||
- Identify whether the same `user.id` executed similar script blocks on multiple hosts or whether multiple users are affected on the same host, which may indicate broader compromise.
|
||||
- If multiple hosts show the same file-backed script (`file.name` and `file.path`), determine whether it is a legitimate deployment versus unauthorized propagation.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Some legitimate PowerShell automation may reference low-level input or window APIs for specialized use cases such as accessibility utilities, kiosk or lab automation, macro/hotkey tooling, or authorized security testing.
|
||||
- False positives are more likely when the script is part of a known internal toolkit with a documented business purpose, runs on a limited and expected host scope, and lacks evidence of sustained collection loops or output handling.
|
||||
- Treat as higher risk when the script content includes continuous polling or hook registration combined with logic that records, formats, stores, or prepares data for transmission, or when the activity occurs on user workstations outside of expected maintenance windows.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If the activity is unauthorized or suspicious:
|
||||
- Contain the host to prevent further input collection and limit follow-on actions.
|
||||
- Preserve evidence from the alert, including the complete `powershell.file.script_block_text` reconstructed via `powershell.file.script_block_id`, `powershell.sequence`, and `powershell.total`, and any associated `file.path` and `file.name` values.
|
||||
- Use the script content to extract any indicators (for example, output file names, remote destinations, or unique strings) and scope for related activity on other hosts.
|
||||
- Assume potential credential exposure on the affected host and follow incident response procedures for credential reset, session revocation, and review of privileged access activity during the suspected collection window.
|
||||
- Remediate the initial access path and remove any persistence or secondary payloads identified during correlation, including removing unauthorized scripts referenced by `file.path`.
|
||||
|
||||
- If the activity is confirmed benign:
|
||||
- Document the legitimate script or tool, expected operators (`user.id`), and expected host scope (`host.id`).
|
||||
- Apply narrowly scoped tuning based on stable, repeatable identifiers (for example, specific `file.path` and expected accounts) to reduce recurring noise while maintaining coverage for unauthorized keylogging behavior.
|
||||
"""
|
||||
references = [
|
||||
"https://github.com/EmpireProject/Empire/blob/master/data/module_source/collection/Get-Keystrokes.ps1",
|
||||
"https://github.com/MojtabaTajik/FunnyKeylogger/blob/master/FunnyLogger.ps1",
|
||||
]
|
||||
risk_score = 73
|
||||
rule_id = "bd2c86a0-8b61-4457-ab38-96943984e889"
|
||||
setup = """## 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
|
||||
"""
|
||||
severity = "high"
|
||||
tags = [
|
||||
"Domain: Endpoint",
|
||||
@@ -132,46 +50,72 @@ event.category:process and host.os.type:windows and
|
||||
)
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
[[rule.threat.technique]]
|
||||
id = "T1056"
|
||||
name = "Input Capture"
|
||||
reference = "https://attack.mitre.org/techniques/T1056/"
|
||||
[[rule.threat.technique.subtechnique]]
|
||||
id = "T1056.001"
|
||||
name = "Keylogging"
|
||||
reference = "https://attack.mitre.org/techniques/T1056/001/"
|
||||
### Investigating PowerShell Keylogging Script
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- 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.
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0009"
|
||||
name = "Collection"
|
||||
reference = "https://attack.mitre.org/tactics/TA0009/"
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
[[rule.threat.technique]]
|
||||
id = "T1059"
|
||||
name = "Command and Scripting Interpreter"
|
||||
reference = "https://attack.mitre.org/techniques/T1059/"
|
||||
[[rule.threat.technique.subtechnique]]
|
||||
id = "T1059.001"
|
||||
name = "PowerShell"
|
||||
reference = "https://attack.mitre.org/techniques/T1059/001/"
|
||||
- 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`, and `powershell.file.script_block_length` to 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.id` and `host.id` pairing, 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.
|
||||
|
||||
[[rule.threat.technique]]
|
||||
id = "T1106"
|
||||
name = "Native API"
|
||||
reference = "https://attack.mitre.org/techniques/T1106/"
|
||||
- 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_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.
|
||||
|
||||
- Do file events show keystroke logs, staged archives, or renamed artifacts?
|
||||
- Focus: file events for the same `process.entity_id`, with attention to `file.path`, `file.extension`, `file.Ext.header_bytes`, and `file.Ext.original.path` when 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.
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0002"
|
||||
name = "Execution"
|
||||
reference = "https://attack.mitre.org/tactics/TA0002/"
|
||||
- Do network events show credential exfiltration, webhook delivery, or remote staging?
|
||||
- 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: suggests exfiltration when the process reaches rare public destinations, messaging or webhook services, or cloud storage. Missing network telemetry is unresolved, not benign.
|
||||
|
||||
- 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_id` was recovered, bridge to `winlog.event_data.TargetLogonId` for session origin (`source.ip`, `winlog.event_data.AuthenticationPackageName`). Also check post-alert 4624 or 4648 events on the same `host.id` for accounts that do not match the alert user.
|
||||
- Hint: "4648" explicit-credential events do not use `winlog.event_data.TargetLogonId`; search `winlog.event_data.SubjectLogonId` instead.
|
||||
- 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.id` to find repeated collection or defense-evasion activity. $investigate_2
|
||||
- Hint: compare related alerts for the same `host.id` for 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.
|
||||
|
||||
- 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.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Accessibility, kiosk, security-testing, or malware-analysis 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 hook-function strings alone, `user.name` alone, or the host alone.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- 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`, related `file.path` artifacts, any `dns.question.name` or `destination.ip` values 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`, written `file.path` artifacts, any confirmed `dns.question.name` or `destination.ip` values, 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_text` content, `file.path` pattern, or `dns.question.name` destinations 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.
|
||||
"""
|
||||
|
||||
setup = """## 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.investigation_fields]
|
||||
field_names = [
|
||||
@@ -192,3 +136,87 @@ field_names = [
|
||||
"powershell.file.script_block_length"
|
||||
]
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Script block fragments for the same script"
|
||||
description = ""
|
||||
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"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Process events for the PowerShell instance"
|
||||
description = ""
|
||||
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"
|
||||
|
||||
[[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 = "T1056"
|
||||
name = "Input Capture"
|
||||
reference = "https://attack.mitre.org/techniques/T1056/"
|
||||
[[rule.threat.technique.subtechnique]]
|
||||
id = "T1056.001"
|
||||
name = "Keylogging"
|
||||
reference = "https://attack.mitre.org/techniques/T1056/001/"
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0009"
|
||||
name = "Collection"
|
||||
reference = "https://attack.mitre.org/tactics/TA0009/"
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
[[rule.threat.technique]]
|
||||
id = "T1059"
|
||||
name = "Command and Scripting Interpreter"
|
||||
reference = "https://attack.mitre.org/techniques/T1059/"
|
||||
[[rule.threat.technique.subtechnique]]
|
||||
id = "T1059.001"
|
||||
name = "PowerShell"
|
||||
reference = "https://attack.mitre.org/techniques/T1059/001/"
|
||||
|
||||
[[rule.threat.technique]]
|
||||
id = "T1106"
|
||||
name = "Native API"
|
||||
reference = "https://attack.mitre.org/techniques/T1106/"
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0002"
|
||||
name = "Execution"
|
||||
reference = "https://attack.mitre.org/tactics/TA0002/"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
creation_date = "2021/10/19"
|
||||
integration = ["windows"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/01/26"
|
||||
updated_date = "2026/03/30"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
@@ -11,108 +11,13 @@ Detects PowerShell script block content that uses CopyFromScreen with .NET bitma
|
||||
Attackers use screen capture to collect on-screen information and credentials.
|
||||
"""
|
||||
from = "now-9m"
|
||||
index = ["winlogbeat-*", "logs-windows.powershell*"]
|
||||
index = ["logs-windows.powershell*", "winlogbeat-*"]
|
||||
language = "kuery"
|
||||
license = "Elastic License v2"
|
||||
name = "PowerShell Suspicious Script with Screenshot Capabilities"
|
||||
note = """## Triage and analysis
|
||||
|
||||
> **Disclaimer**:
|
||||
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
|
||||
|
||||
### Investigating PowerShell Suspicious Script with Screenshot Capabilities
|
||||
|
||||
This rule identifies PowerShell scripts that includes screenshot collection logic using `CopyFromScreen` together with bitmap classes. This pattern is commonly used to capture the interactive desktop and may indicate collection of sensitive on-screen data (for example, application content, authentication prompts, or remote session activity).
|
||||
|
||||
Prioritize alerts on endpoints used for privileged administration or sensitive workflows, and alerts tied to accounts that do not typically run interactive PowerShell automation.
|
||||
|
||||
#### Key alert fields to review
|
||||
|
||||
- `user.name`, `user.domain`, `user.id`: Account execution context for correlation, prioritization, and scoping.
|
||||
- `host.name`, `host.id`: Host execution context for correlation, prioritization, and scoping.
|
||||
- `powershell.file.script_block_text`: Script block content that matched the detection logic.
|
||||
- `powershell.file.script_block_id`, `powershell.sequence`, `powershell.total`: Script block metadata to pivot to other fragments or reconstruct full script content when split across multiple events.
|
||||
- `file.path`, `file.directory`, `file.name`: File-origin context when the script block is sourced from an on-disk file.
|
||||
- `powershell.file.script_block_length`: Script block length (size) context.
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- Establish alert scope and execution context:
|
||||
- Identify the affected system using `host.name` and `host.id`. Determine if the host is expected to have an interactive desktop session for the associated user at the time of the alert.
|
||||
- Identify the initiating account using `user.name`, `user.domain`, and `user.id`. Assess whether the account is a typical interactive user for the host and whether the activity aligns with the user role.
|
||||
- Review the alert time (`@timestamp`) and determine whether the timing aligns with normal business operations for the user and host.
|
||||
|
||||
- Review and interpret the script block content:
|
||||
- Examine `powershell.file.script_block_text` to understand what is being captured:
|
||||
- Identify whether the capture targets the full screen or a specific region (for example, use of coordinates and dimensions passed into `CopyFromScreen`).
|
||||
- Identify whether capture is repeated (for example, loops, timers, repeated invocations) which may indicate ongoing collection.
|
||||
- Identify any logic that targets specific monitors, window bounds, or desktop layout.
|
||||
- Determine how captured images are handled:
|
||||
- Look for references indicating local image creation or saving (for example, image format usage such as PNG/JPEG/BMP, file extensions, or save routines).
|
||||
- Look for encoding/staging behavior (for example, Base64 conversion, compression, or in-memory serialization) that could facilitate transfer.
|
||||
- Note any referenced paths, filenames, or remote destinations embedded in the script, and capture unique strings for scoping and hunting.
|
||||
|
||||
- Reconstruct full script logic when split across events:
|
||||
- Use `powershell.file.script_block_id` to collect all related fragments.
|
||||
- Order fragments using `powershell.sequence` and validate completeness using `powershell.total`.
|
||||
- Re-review the reconstructed script for supporting capabilities beyond capture (for example, environment checks, staging, cleanup, or transfer logic).
|
||||
- Use `powershell.file.script_block_length` to help identify unusually large or complex script blocks that may warrant deeper review.
|
||||
|
||||
- Identify script source and provenance:
|
||||
- If `file.path`, `file.directory`, or `file.name` are present, treat the script as file-backed:
|
||||
- Validate whether the location is expected for administrative or support scripts in your environment.
|
||||
- Collect the referenced file for review and compare it to known-good versions or approved repositories where applicable.
|
||||
- If file fields are not present, treat the activity as potentially inline or dynamically generated:
|
||||
- Pay close attention to download, decode, or dynamic compilation patterns visible in `powershell.file.script_block_text`.
|
||||
|
||||
- Scope for related PowerShell activity using available pivots:
|
||||
- On the same `host.id` and `user.id`, review surrounding script blocks near the alert time to identify related actions (for example, staging, transfer preparation, or artifact cleanup).
|
||||
- Search for similar `powershell.file.script_block_text` patterns across other hosts to determine prevalence and potential lateral spread.
|
||||
- If `file.name` or `file.path` are present, search for additional execution of the same script file across the environment.
|
||||
|
||||
- Correlate with adjacent telemetry to determine initiation and outcomes:
|
||||
- Using `host.id`, `host.name`, `user.id`, and the alert time window, correlate with available endpoint and security telemetry to identify:
|
||||
- How PowerShell was initiated (interactive use vs. application-driven execution) and whether there is an unusual execution chain.
|
||||
- Evidence of screenshot artifacts being written, moved, archived, or deleted, especially in locations referenced in `powershell.file.script_block_text`.
|
||||
- Any outbound communication or data movement that could indicate transfer of captured images or related content.
|
||||
|
||||
- Assess potential impact:
|
||||
- Determine whether the host and user context suggests access to sensitive information that could have been exposed via screenshots.
|
||||
- If screenshot artifacts are identified, preserve copies and metadata for exposure assessment and downstream response actions.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Legitimate scenarios may include authorized troubleshooting, remote support workflows, UI testing, or automation that captures screenshots.
|
||||
- Validate benign explanations by confirming that the involved `user.name`/`user.id` and `host.name`/`host.id` align with expected operational ownership and that the script content in `powershell.file.script_block_text` matches known, approved implementations.
|
||||
- File-backed scripts with stable, approved locations (`file.path`/`file.name`) and consistent content are more likely to be benign. Inline or frequently changing script content, especially with staging or transfer logic, should be treated as higher risk even if screenshot capture is a documented capability.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If the activity is confirmed malicious or remains suspicious after triage:
|
||||
- Contain the affected host to limit further collection and potential data transfer.
|
||||
- Preserve evidence:
|
||||
- Export and retain all related script block fragments for the same `powershell.file.script_block_id` and reconstruct the full script using `powershell.sequence` and `powershell.total`.
|
||||
- Collect any file-backed script referenced by `file.path`/`file.name`, along with any identified screenshot output paths from `powershell.file.script_block_text`.
|
||||
- Scope and eradicate:
|
||||
- Hunt for the same screenshot capture indicators across the environment using distinctive strings from `powershell.file.script_block_text`, as well as the involved `user.id` and `file.name` (if present).
|
||||
- Review correlated telemetry for signs of staging or transfer and identify any additional affected hosts or accounts.
|
||||
- Credential and access hygiene:
|
||||
- If screenshots may have captured credentials or privileged activity, follow your incident response process for credential reset and access review for the involved account(s).
|
||||
- Review access to sensitive systems from the affected host and user context during the relevant time window.
|
||||
|
||||
- If the activity is confirmed benign:
|
||||
- Document the legitimate business process, script ownership, and expected execution scope (approved users, hosts, and typical timing).
|
||||
- Ensure the script source is controlled (when `file.path`/`file.name` are present) and that execution is limited to authorized accounts and systems.
|
||||
- Continue monitoring for deviations in script content or execution context using the same pivots (`host.id`, `user.id`, and distinctive content in `powershell.file.script_block_text`).
|
||||
"""
|
||||
references = ["https://docs.microsoft.com/en-us/dotnet/api/system.drawing.graphics.copyfromscreen"]
|
||||
risk_score = 73
|
||||
rule_id = "959a7353-1129-4aa7-9084-30746b256a70"
|
||||
setup = """## 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
|
||||
"""
|
||||
severity = "high"
|
||||
tags = [
|
||||
"Domain: Endpoint",
|
||||
@@ -133,36 +38,71 @@ event.category:process and host.os.type:windows and
|
||||
) and not user.id : "S-1-5-18"
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
[[rule.threat.technique]]
|
||||
id = "T1113"
|
||||
name = "Screen Capture"
|
||||
reference = "https://attack.mitre.org/techniques/T1113/"
|
||||
### Investigating PowerShell Suspicious Script with Screenshot Capabilities
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0009"
|
||||
name = "Collection"
|
||||
reference = "https://attack.mitre.org/tactics/TA0009/"
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
[[rule.threat.technique]]
|
||||
id = "T1059"
|
||||
name = "Command and Scripting Interpreter"
|
||||
reference = "https://attack.mitre.org/techniques/T1059/"
|
||||
[[rule.threat.technique.subtechnique]]
|
||||
id = "T1059.001"
|
||||
name = "PowerShell"
|
||||
reference = "https://attack.mitre.org/techniques/T1059/001/"
|
||||
- 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_0
|
||||
- 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_1
|
||||
- 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.
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0002"
|
||||
name = "Execution"
|
||||
reference = "https://attack.mitre.org/tactics/TA0002/"
|
||||
- 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_2 $investigate_3
|
||||
- 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 = """## 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.investigation_fields]
|
||||
field_names = [
|
||||
@@ -183,3 +123,78 @@ field_names = [
|
||||
"powershell.file.script_block_length"
|
||||
]
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Script block fragments for the same script"
|
||||
description = ""
|
||||
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"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Process events for the PowerShell instance"
|
||||
description = ""
|
||||
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"
|
||||
|
||||
[[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 = "T1113"
|
||||
name = "Screen Capture"
|
||||
reference = "https://attack.mitre.org/techniques/T1113/"
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0009"
|
||||
name = "Collection"
|
||||
reference = "https://attack.mitre.org/tactics/TA0009/"
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
[[rule.threat.technique]]
|
||||
id = "T1059"
|
||||
name = "Command and Scripting Interpreter"
|
||||
reference = "https://attack.mitre.org/techniques/T1059/"
|
||||
[[rule.threat.technique.subtechnique]]
|
||||
id = "T1059.001"
|
||||
name = "PowerShell"
|
||||
reference = "https://attack.mitre.org/techniques/T1059/001/"
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0002"
|
||||
name = "Execution"
|
||||
reference = "https://attack.mitre.org/tactics/TA0002/"
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
creation_date = "2025/08/20"
|
||||
integration = ["endpoint", "windows", "sentinel_one_cloud_funnel", "crowdstrike"]
|
||||
maturity = "production"
|
||||
updated_date = "2026/03/24"
|
||||
updated_date = "2026/03/30"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
description = """
|
||||
Identifies DNS queries to commonly abused Top Level Domains by common LOLBINs or executable running from world writable
|
||||
Identifies DNS queries to commonly abused Top Level Domains by common LOLBINs or executables running from world writable
|
||||
directories or unsigned binaries. This behavior matches on common malware C2 abusing less formal domain names.
|
||||
"""
|
||||
from = "now-9m"
|
||||
@@ -22,35 +22,6 @@ index = [
|
||||
language = "eql"
|
||||
license = "Elastic License v2"
|
||||
name = "Network Activity to a Suspicious Top Level Domain"
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Network Activity to a Suspicious Top Level Domain
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- Investigate the process execution chain (parent process tree) for unknown processes or malicious scripts.
|
||||
- Review if the domain reputation and the frequency of network activities as well as any download/upload activity.
|
||||
- Verify if the executed process is persistent on the host like common mechanisms Startup folder, task or Run key.
|
||||
- Investigate other alerts associated with the user/host during the past 48 hours.
|
||||
- Extract this communication's indicators of compromise (IoCs) and use traffic logs to search for other potentially compromised hosts.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Trusted domain from an expected process running in the environment.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- Initiate the incident response process based on the outcome of the triage.
|
||||
- Isolate the involved host to prevent further post-compromise behavior.
|
||||
- Immediately block the identified indicators of compromise (IoCs).
|
||||
- Implement any temporary network rules, procedures, and segmentation required to contain the attack.
|
||||
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
|
||||
- Update firewall rules to be more restrictive.
|
||||
- Reimage the host operating system or restore the compromised files to clean versions.
|
||||
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
|
||||
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
|
||||
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
|
||||
"""
|
||||
references = ["https://www.cybercrimeinfocenter.org/top-20-tlds-by-malicious-phishing-domains"]
|
||||
risk_score = 73
|
||||
rule_id = "e516bf56-d51b-43e8-91ec-9e276331f433"
|
||||
@@ -63,7 +34,6 @@ tags = [
|
||||
"Resources: Investigation Guide",
|
||||
"Data Source: Elastic Endgame",
|
||||
"Data Source: Elastic Defend",
|
||||
"Data Source: Windows Security Event Logs",
|
||||
"Data Source: SentinelOne",
|
||||
"Data Source: Crowdstrike",
|
||||
"Data Source: Sysmon",
|
||||
@@ -75,15 +45,147 @@ query = '''
|
||||
network where host.os.type == "windows" and dns.question.name != null and
|
||||
(
|
||||
process.name : ("MSBuild.exe", "mshta.exe", "wscript.exe", "powershell.exe", "pwsh.exe", "msiexec.exe", "rundll32.exe",
|
||||
"bitsadmin.exe", "InstallUtil.exe", "python.exe", "regsvr32.exe", "dllhost.exe", "node.exe",
|
||||
"bitsadmin.exe", "InstallUtil.exe", "python.exe", "regsvr32.exe", "dllhost.exe", "node.exe", "curl.exe",
|
||||
"java.exe", "javaw.exe", "*.pif", "*.com", "*.scr") or
|
||||
(?process.code_signature.trusted == false or ?process.code_signature.exists == false) or
|
||||
?process.code_signature.subject_name : ("AutoIt Consulting Ltd", "OpenJS Foundation", "Python Software Foundation") or
|
||||
?process.executable : ("?:\\Users\\*.exe", "?:\\ProgramData\\*.exe")
|
||||
?process.executable : (
|
||||
"?:\\Users\\Public\\*.exe", "?:\\ProgramData\\*.exe", "?:\\Users\\*\\Downloads\\*.exe",
|
||||
"\\Device\\HarddiskVolume*\\Users\\Public\\*.exe", "\\Device\\HarddiskVolume*\\ProgramData\\*.exe", "\\Device\\HarddiskVolume*\\Users\\*\\Downloads\\*.exe"
|
||||
)
|
||||
) and
|
||||
dns.question.name regex """.*\.(top|buzz|xyz|rest|ml|cf|gq|ga|onion|monster|cyou|quest|cc|bar|cfd|click|cam|surf|tk|shop|club|icu|pw|ws|online|fun|life|boats|store|hair|skin|motorcycles|christmas|lol|makeup|mom|bond|beauty|biz|live|work|zip|country|accountant|date|party|science|loan|win|men|faith|review|racing|download|host)"""
|
||||
dns.question.name regex """.*\.(top|buzz|xyz|rest|ml|cf|gq|ga|onion|monster|cyou|quest|cc|bar|cfd|click|cam|surf|tk|shop|club|icu|pw|ws|online|fun|life|boats|store|hair|skin|motorcycles|christmas|lol|makeup|mom|bond|beauty|biz|live|work|zip|country|accountant|date|party|science|loan|win|men|faith|review|racing|download|host|zone)""" and
|
||||
|
||||
not process.executable : (
|
||||
"?:\\ProgramData\\Microsoft\\Windows Defender\\platform\\*\\*.exe",
|
||||
"\\Device\\HarddiskVolume*\\ProgramData\\Microsoft\\Windows Defender\\platform\\*\\*.exe"
|
||||
)
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Network Activity to a Suspicious Top Level Domain
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- Does the alert-local DNS result and domain shape fit the process role?
|
||||
- Focus: the alert's `event.action`, `dns.question.name`, `dns.Ext.status`, and `dns.resolved_ip`; use "lookup_result" for resolved IPs and "lookup_requested" for failed or request-only lookups.
|
||||
- Implication: concern rises when the name is algorithmic, newly introduced for that tool, or resolves to unrelated external infrastructure; weaker when the lookup fails immediately or the domain matches a known vendor pattern for that process, but a failed lookup alone does not clear the process. `.onion` lookups signal Tor hidden-service resolution -- treat these as elevated concern and look for Tor binaries or proxy configuration.
|
||||
|
||||
- Is the alerting binary the expected tool in the expected install context?
|
||||
- Focus: `process.executable`, `process.code_signature.subject_name`, `process.code_signature.trusted`, and `process.pe.original_file_name`.
|
||||
- Implication: more concerning when the binary is unsigned, renamed, user-writable, or inconsistent with its usual signer. Identity alone does not clear the DNS behavior.
|
||||
|
||||
- Does the command line and launch chain fit a legitimate workflow?
|
||||
- Focus: `process.command_line`, `process.parent.executable`, and `process.parent.command_line`.
|
||||
- Implication: more concerning if a document, script, or unexpected launcher started the process, or if the arguments look staged or evasive.
|
||||
|
||||
- Does the same process resolve the domain and then communicate with the returned infrastructure?
|
||||
- Why: a suspicious DNS lookup carries more weight when the same process reuses the returned IPs for follow-on connections or transfer behavior in the same window.
|
||||
- Focus: process-scoped "lookup_result" and connection events on the same `host.id`, using `dns.resolved_ip` to bridge `dns.question.name` to `destination.ip`; treat `destination.as.organization.name` as ownership context rather than a verdict. $investigate_2
|
||||
- Hint: if the transform returns no results, broaden to host-scoped network events around the alert time.
|
||||
- Implication: escalate when the same process repeatedly resolves the domain, connects to the returned IPs, or shows suspicious transfer patterns; lower suspicion when activity is limited to a one-off lookup with no matching connection behavior. Missing follow-on network telemetry is unresolved, not benign.
|
||||
|
||||
- Do file events or child processes from the same process chain show download-and-execute or artifact staging?
|
||||
- Focus: same-host file and process activity around the alert time, scoped to the alert's `process.entity_id`, with attention to `file.path`, `file.origin_url`, `file.Ext.windows.zone_identifier`, and later `process.executable` reuse of a written path.
|
||||
- Hint: if file coverage is missing, keep the artifact review bounded to the same host, lineage, and alert window rather than treating the lookup as harmless.
|
||||
- Implication: staging risk rises when the chain writes scripts, archives, or executables to user-writable paths and later runs them.
|
||||
|
||||
- Does the same process chain pivot to direct-IP traffic, lookalike domains, or TLD rotation that this rule would miss?
|
||||
- Why: attackers often keep the same process chain but swap to a nearby domain, a different abusive TLD, or direct-IP egress after the first lookup.
|
||||
- Focus: reuse the process-scoped network results from the prior step to look for direct `destination.ip` connections with no preceding DNS, sibling `dns.question.name` values under different TLDs, or repeated reuse of the same `dns.resolved_ip` across multiple domains. $investigate_2
|
||||
- Implication: escalate when the process shifts from the flagged lookup to direct-IP traffic, nearby domain variants, or fast domain and TLD rotation on the same infrastructure; lower suspicion when surrounding DNS stays limited to one recognized vendor domain family with no adjacent variant traffic.
|
||||
|
||||
- If the local DNS, process, or artifact evidence stays suspicious or unresolved, does related alert history show this DNS pattern is isolated or part of broader compromise?
|
||||
- Focus: related alerts for the same `host.id` and `user.id` in the last 48 hours to test whether the same lineage, domain family, or follow-on activity recurs on the asset or follows the user across hosts.
|
||||
- $investigate_0
|
||||
- $investigate_1
|
||||
- Implication: broaden scope when the host or user view shows repeated suspicious lineage, related delivery or persistence alerts, or reuse of the same infrastructure on other assets; keep scope narrow when the pattern stays confined to one recognized workflow with no contradictory evidence.
|
||||
|
||||
- Escalate when DNS fit, process context, follow-on communication, artifacts, or variant traffic point to unauthorized C2 or delivery; close only when all evidence aligns with a recognized benign workflow; if mixed or incomplete, preserve and escalate.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Software distribution, developer tooling, or security-testing workflows can legitimately query less common TLDs. Confirm by matching the same `process.executable`, `process.code_signature.subject_name`, `dns.question.name` family, and `host.id` across prior alerts or against workflow records.
|
||||
- Before creating an exception, build on `process.executable`, `process.code_signature.subject_name`, the `dns.question.name` family, and `host.id` or `user.id`. Avoid exceptions on the TLD alone, `process.name` alone, or `host.id` alone.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If confirmed benign, reverse any temporary containment and document the `process.executable`, `process.code_signature.subject_name`, `process.parent.command_line`, `dns.question.name` family, and bounded `host.id` or `user.id` scope that proved the workflow. Create an exception only if that same pattern recurs consistently across prior alerts from this rule.
|
||||
- If suspicious but unconfirmed, first preserve `dns.question.name`, `dns.resolved_ip`, connected `destination.ip` values, the alert's `process.entity_id`, `process.command_line`, `process.parent.command_line`, and any staged `file.path` values. Then apply reversible containment such as temporary DNS or egress blocks for the observed infrastructure or heightened monitoring on `host.id`. Escalate to host isolation only if the preserved evidence shows likely follow-on communication or staging and the asset role can tolerate stronger containment.
|
||||
- If confirmed malicious, document the alert's `process.entity_id`, `process.command_line`, `process.parent.command_line`, written `file.path` artifacts, and connected `dns.question.name` or `destination.ip` infrastructure before initiating response actions. Prefer endpoint isolation as the first containment step; if direct endpoint response is unavailable, escalate with the preserved artifact set to the team that can isolate the host. Block the confirmed malicious domains and direct-IP destinations before terminating processes or deleting files.
|
||||
- After containment, review other `host.id` and `user.id` alerts for the same `dns.question.name`, `destination.ip`, or `process.executable` pattern before deleting artifacts or restoring access. Then eradicate staged binaries, scripts, and any persistence or proxy changes identified during the file or variant review, and remediate the entry path that allowed the suspicious process to run. If the same suspicious window includes credential, admin-tool, or remote-session alerts, review those sessions for follow-on misuse and reset exposed credentials when the evidence supports compromise.
|
||||
"""
|
||||
|
||||
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)
|
||||
- [SentinelOne Cloud Funnel](https://ela.st/sentinel-one-cloud-funnel)
|
||||
- [Sysmon Event ID 3 - Network Connection](https://ela.st/sysmon-event-3-setup)
|
||||
"""
|
||||
|
||||
[rule.investigation_fields]
|
||||
field_names = [
|
||||
"@timestamp",
|
||||
"host.name",
|
||||
"host.id",
|
||||
"user.name",
|
||||
"user.id",
|
||||
"process.name",
|
||||
"process.executable",
|
||||
"process.entity_id",
|
||||
"process.pid",
|
||||
"process.code_signature.subject_name",
|
||||
"process.code_signature.trusted",
|
||||
"dns.question.name",
|
||||
"dns.resolved_ip",
|
||||
"event.action",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Network activity for the alerting process"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ 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" },
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
creation_date = "2024/05/10"
|
||||
integration = ["endpoint", "windows", "system", "m365_defender", "sentinel_one_cloud_funnel", "crowdstrike"]
|
||||
maturity = "production"
|
||||
updated_date = "2025/09/11"
|
||||
updated_date = "2026/03/30"
|
||||
|
||||
[rule]
|
||||
author = ["Elastic"]
|
||||
description = """
|
||||
Identifies the use of a browser to download a file from a remote URL and from a suspicious parent process. Adversaries
|
||||
may use browsers to avoid ingress tool transfer restrictions.
|
||||
Identifies headless browser execution from a suspicious parent process with arguments consistent with scripted retrieval. Adversaries use browsers because they are trusted, signed binaries that proxy and application-control policies allow through, bypassing restrictions on direct download tools.
|
||||
"""
|
||||
from = "now-9m"
|
||||
index = [
|
||||
@@ -25,30 +24,6 @@ index = [
|
||||
language = "eql"
|
||||
license = "Elastic License v2"
|
||||
name = "Potential File Download via a Headless Browser"
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Potential File Download via a Headless Browser
|
||||
|
||||
- Investigate the process execution chain (parent process tree).
|
||||
- Investigate the process network and file events.
|
||||
- Identify the user account that performed the action and whether it should perform this kind of action.
|
||||
- Contact the account owner and confirm whether they are aware of this activity.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- Initiate the incident response process based on the outcome of the triage.
|
||||
- Isolate the involved host to prevent further post-compromise behavior.
|
||||
- If the triage identified malware, search the environment for additional compromised hosts.
|
||||
- Implement temporary network rules, procedures, and segmentation to contain the malware.
|
||||
- Stop suspicious processes.
|
||||
- Immediately block the identified indicators of compromise (IoCs).
|
||||
- Inspect the affected systems for additional malware backdoors like reverse shells, reverse proxies, or droppers that attackers could use to reinfect the system.
|
||||
- Remove and block malicious artifacts identified during triage.
|
||||
- Investigate credential exposure on systems compromised or used by the attacker to ensure all compromised accounts are identified. Reset passwords for these accounts and other potentially compromised credentials, such as email, business systems, and web services.
|
||||
- Run a full antimalware scan. This may reveal additional artifacts left in the system, persistence mechanisms, and malware components.
|
||||
- Determine the initial vector abused by the attacker and take action to prevent reinfection through the same vector.
|
||||
- Using the incident response data, update logging and audit policies to improve the mean time to detect (MTTD) and the mean time to respond (MTTR).
|
||||
"""
|
||||
references = ["https://lolbas-project.github.io/lolbas/Binaries/Msedge/"]
|
||||
risk_score = 73
|
||||
rule_id = "5f2f463e-6997-478c-8405-fb41cc283281"
|
||||
@@ -75,7 +50,7 @@ query = '''
|
||||
process where host.os.type == "windows" and event.type == "start" and
|
||||
process.name : ("chrome.exe", "msedge.exe", "brave.exe", "browser.exe", "dragon.exe", "vivaldi.exe") and
|
||||
process.args : "--headless*" and
|
||||
process.args : ("--disable-gpu", "--dump-dom", "*http*", "data:text/html;base64,*") and
|
||||
process.args : ("--dump-dom", "*http*", "data:text/html;base64,*") and
|
||||
process.parent.name :
|
||||
("cmd.exe", "powershell.exe", "wscript.exe", "cscript.exe", "mshta.exe", "conhost.exe", "msiexec.exe",
|
||||
"explorer.exe", "rundll32.exe", "winword.exe", "excel.exe", "onenote.exe", "hh.exe", "powerpnt.exe", "forfiles.exe",
|
||||
@@ -86,6 +61,125 @@ process where host.os.type == "windows" and event.type == "start" and
|
||||
)
|
||||
'''
|
||||
|
||||
note = """## Triage and analysis
|
||||
|
||||
### Investigating Potential File Download via a Headless Browser
|
||||
|
||||
#### Possible investigation steps
|
||||
|
||||
- What headless pattern does the command line express, and is the browser the installed product?
|
||||
- Why: this rule fires on three distinct retrieval patterns -- remote URL fetch, inline base64 HTML decode ("data:text/html;base64"), or DOM dump ("--dump-dom") -- and each requires different follow-on evidence.
|
||||
- Focus: `process.command_line` and `process.working_directory` to identify the retrieval pattern and output destination; confirm the browser is the installed product via `process.executable`, `process.code_signature.subject_name`, and `process.code_signature.trusted`.
|
||||
- Implication: retrieval intent is stronger when the command line targets external content, decodes base64, or redirects output to unusual paths, especially when the browser is unsigned, portable, or renamed; more explainable when the arguments match a rendering or automation workflow and the browser is the standard signed installation.
|
||||
|
||||
- Does the parent, ancestry, and user-host pattern explain why a browser is being driven headlessly?
|
||||
- Why: the same browser arguments mean different things when launched by a web-rendering service than when launched by a script host, Office application, or interactive shell.
|
||||
- Focus: `process.parent.executable`, `process.parent.command_line`, `process.Ext.ancestry`, and `process.Ext.session_info.logon_type`; also check whether `user.id` and `host.id` fit a role where headless browser automation is expected.
|
||||
- Implication: more concerning if launched by a script host, Office process, MSI, WMI, or an unexpected interactive session, or when the user-host pair should not be running headless browsers; more explainable if the ancestry resolves to a recognized rendering service or automation component for that host role.
|
||||
|
||||
- Do network events show the browser reaching destinations consistent with the claimed workflow?
|
||||
- Focus: same-host network events scoped to the alert's `process.entity_id`, using `dns.resolved_ip` to bridge `dns.question.name` to `destination.ip` and treating `destination.as.organization.name` as ownership context rather than a verdict. $investigate_2
|
||||
- Hint: if `process.entity_id` is not available, stay on the same `host.id` and alert window and use `dns.question.name`, `dns.resolved_ip`, and `destination.ip` to test whether the browser likely reached the fetched content.
|
||||
- Implication: delivery risk increases when the browser reaches rare public destinations or infrastructure unrelated to the workflow, or when another process connects to an exposed debugging port; risk falls when destinations align with recognized internal services or known automation targets. Missing network telemetry is unresolved, not benign.
|
||||
|
||||
- Do file events or child processes from the browser show downloaded, decoded, or staged artifacts?
|
||||
- Focus: file events scoped to `process.entity_id` (`file.path`, `file.origin_url`, `file.Ext.windows.zone_identifier`, `file.Ext.header_bytes`), child process activity, and later `process.executable` reuse of a written path.
|
||||
- Implication: more likely delivery when the browser writes scripts, executables, archives, or decoded content to user-writable or deceptive paths, spawns child processes, or the artifact later appears in execution telemetry; less concerning when output stays in a renderer cache or report directory with no suspicious reuse.
|
||||
|
||||
- If the local browser, destination, or artifact evidence stays suspicious or unresolved, does related alert history show isolated automation or broader download activity on this user or host?
|
||||
- Focus: related alerts for `host.id` and `user.id` in the last 48 hours, checking for sibling transfer tools, non-headless browser automation, or reuse of the same destinations across hosts.
|
||||
- $investigate_0
|
||||
- $investigate_1
|
||||
- Implication: broaden when the same user or host shows repeated delivery behavior across hosts or through sibling tools; keep narrow when both alert views stay within one recognized automation component.
|
||||
|
||||
- Escalate when browser identity, command line, destinations, artifacts, or alert scope point to unauthorized headless retrieval or staging; close only when all evidence aligns with a recognized automation workflow; if mixed or incomplete, preserve and escalate.
|
||||
|
||||
### False positive analysis
|
||||
|
||||
- Server-side rendering, web testing, QA, or browser automation can legitimately start a headless browser with retrieval arguments. Confirm when `process.executable`, `process.parent.executable`, and the `dns.question.name` or `destination.ip` pattern all align with one automation component and no staged artifacts diverge from that workflow. If automation records are unavailable, require the same browser, parent, and destination pattern to recur across prior alerts.
|
||||
- Before creating an exception, build on `process.executable`, `process.parent.executable`, `process.code_signature.subject_name`, and `host.id` or `user.id`. Avoid exceptions on `process.name` alone, the "--headless" flag alone, or `host.id` alone.
|
||||
|
||||
### Response and remediation
|
||||
|
||||
- If confirmed benign, reverse any temporary containment and document the `process.executable`, `process.parent.executable`, `process.command_line`, destination pattern from `dns.question.name` or `destination.ip`, and recurring `user.id` / `host.id` scope that proved the workflow. Create an exception only if that same pattern recurs consistently across prior alerts from this rule.
|
||||
- If suspicious but unconfirmed, first preserve the alert's `process.entity_id`, `process.command_line`, related `file.path` outputs, `file.origin_url` provenance, and any linked `dns.question.name`, `dns.resolved_ip`, or `destination.ip` values. Then apply reversible containment such as temporary egress blocks or tighter monitoring of the affected `user.id` or `host.id`. Escalate to host isolation only when the browser, network, or artifact evidence shows material delivery or staging risk.
|
||||
- If confirmed malicious, document the alert's `process.entity_id`, `process.command_line`, `process.parent.command_line`, written `file.path` artifacts, `process.hash.sha256`, and confirmed `dns.question.name` or `destination.ip` values before initiating response actions. Prefer endpoint isolation as the first containment step, weighing the host's role before isolating critical infrastructure such as servers, domain controllers, or build systems. If direct endpoint response is unavailable, escalate with the preserved artifact set to the team that can act.
|
||||
- After containment, review other `host.id` and `user.id` alerts for the same `dns.question.name`, `destination.ip`, or `process.executable` pattern before deleting artifacts or restoring access. Then block the malicious destinations and downloaded artifact hashes identified during the investigation, eradicate the scripts, archives, browsers, or persistence artifacts uncovered during the artifact and scope review, and remediate the launcher, automation component, or execution-control gap that allowed the headless browser to retrieve content.
|
||||
"""
|
||||
|
||||
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.name",
|
||||
"host.id",
|
||||
"user.name",
|
||||
"user.id",
|
||||
"user.domain",
|
||||
"process.entity_id",
|
||||
"process.executable",
|
||||
"process.command_line",
|
||||
"process.pe.original_file_name",
|
||||
"process.parent.executable",
|
||||
"process.parent.command_line",
|
||||
"process.code_signature.subject_name",
|
||||
"process.code_signature.trusted",
|
||||
"process.working_directory",
|
||||
"process.hash.sha256",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
||||
[[transform.investigate]]
|
||||
label = "Network activity for the alerting process"
|
||||
description = ""
|
||||
providers = [
|
||||
[
|
||||
{ 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" },
|
||||
{ excluded = false, field = "event.category", queryType = "phrase", value = "network", valueType = "string" }
|
||||
]
|
||||
]
|
||||
relativeFrom = "now-1h"
|
||||
relativeTo = "now"
|
||||
|
||||
[[rule.threat]]
|
||||
framework = "MITRE ATT&CK"
|
||||
@@ -94,9 +188,7 @@ id = "T1105"
|
||||
name = "Ingress Tool Transfer"
|
||||
reference = "https://attack.mitre.org/techniques/T1105/"
|
||||
|
||||
|
||||
[rule.threat.tactic]
|
||||
id = "TA0011"
|
||||
name = "Command and Control"
|
||||
reference = "https://attack.mitre.org/tactics/TA0011/"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user