[Rule Tuning] PowerShell Rules Revamp - 9 (#5706)

* [Rule Tuning] PowerShell Rules Revamp - 9

* .

* Update defense_evasion_posh_obfuscation_index_reversal.toml

* Update defense_evasion_posh_obfuscation_index_reversal.toml

* update disclaimer

* update tags
This commit is contained in:
Jonhnathan
2026-02-18 12:22:24 -03:00
committed by GitHub
parent 93d20b1233
commit 6d0471768f
5 changed files with 514 additions and 128 deletions
@@ -2,75 +2,84 @@
creation_date = "2025/04/14"
integration = ["windows"]
maturity = "production"
updated_date = "2025/12/09"
updated_date = "2026/02/09"
[rule]
author = ["Elastic"]
description = """
Identifies PowerShell scripts that use negative index ranges to reverse the contents of a string or array at runtime as
a form of obfuscation. This technique avoids direct use of reversal functions by iterating through array elements in
reverse order. These methods are designed to evade static analysis and bypass security protections such as the
Antimalware Scan Interface (AMSI).
Detects PowerShell scripts that uses negative index ranges (for example, $var[-1..0]) to reverse strings or arrays and
rebuild content at runtime. Attackers use index reversal to reconstruct hidden commands or payloads and evade static
analysis and AMSI.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "PowerShell Obfuscation via Negative Index String Reversal"
note = """ ## Triage and analysis
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.
> This guide was created by humans with the assistance of generative AI. While its contents have been manually curated to include the most valuable information, always validate assumptions and adjust procedures to match your internal runbooks and incident triage and response policies.
### Investigating PowerShell Obfuscation via Negative Index String Reversal
PowerShell, a powerful scripting language, can be exploited by adversaries using obfuscation techniques like negative index string reversal to evade detection. This method manipulates strings or arrays by iterating in reverse, bypassing static analysis tools. The detection rule identifies scripts with obfuscation patterns by analyzing script length and specific indexing patterns, flagging potential threats for further investigation.
This alert flags PowerShell script block content that uses negative index ranges to reverse strings or arrays and rebuild content at runtime. This pattern can be used to hide command text and reduce readability during review, so the primary goal is to recover the reconstructed content and determine what it does in the observed execution context.
### Possible investigation steps
#### Key alert fields to review
- Review the `powershell.file.script_block_text` to understand the script's intent and identify any suspicious or malicious behavior.
- Check the `host.name` and `user.id` fields to determine the affected system and user, assessing if they are high-value targets or have a history of similar alerts.
- Analyze the `file.path` to identify the location of the script and assess if it is in a common or suspicious directory.
- Investigate the `powershell.file.script_block_id` and `powershell.sequence` to trace the execution flow and determine if this script is part of a larger, potentially malicious sequence.
- Correlate the `agent.id` with other logs to see if there are additional related activities or alerts from the same endpoint.
- Examine the `count` of detected patterns to assess the level of obfuscation and potential threat severity.
- `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.
- `file.path`, `file.directory`, `file.name`: File-origin context when the script block is sourced from an on-disk file.
- `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.
- `Esql.script_block_tmp`: Transformed script block where detection patterns replace original content with a marker to support scoring/counting and quickly spot match locations.
- `Esql.script_block_pattern_count`: Count of matches for the detection pattern(s) observed in the script block content.
- `powershell.file.script_block_entropy_bits`: Shannon entropy of the script block. Higher values may indicate obfuscation.
- `powershell.file.script_block_surprisal_stdev`: Standard deviation of surprisal across the script block. Low values indicate uniform randomness. High values indicate mixed patterns and variability.
- `powershell.file.script_block_unique_symbols`: Count of distinct characters present in the script block.
- `powershell.file.script_block_length`: Script block length (size) context.
#### Possible investigation steps
- Review `powershell.file.script_block_text` and locate the reversal logic. Use `Esql.script_block_tmp` to quickly find match positions, then identify:
- The variable or array being reversed
- The reconstructed output (string, byte array, or command fragment)
- The sink where the output is used (for example, passed into a dynamic execution routine, used as a URL, or written to disk)
- Reconstruct the final value produced by the reversal. Focus on what the script is trying to rebuild (commands, URLs, file paths, registry paths, encoded blobs, or arguments) and record the recovered strings for scoping.
- If the script block is fragmented, pivot on `powershell.file.script_block_id` and use `powershell.sequence` and `powershell.total` to rebuild the full script in order. Reassess intent based on the complete content rather than a single fragment.
- Use `Esql.script_block_pattern_count` to prioritize reviews:
- Single-use reversal may be utility logic and requires context to judge
- Repeated reversal across a long script is more consistent with obfuscation wrappers
- Use script complexity signals to guide triage:
- High `powershell.file.script_block_entropy_bits` and high `powershell.file.script_block_unique_symbols` can indicate encoded or staged content
- Compare `powershell.file.script_block_surprisal_stdev` with the script content to determine whether the script mixes readable logic with high-randomness segments
- Validate execution context with `user.name`, `user.domain`, `user.id`, `host.name`, and `host.id`. Prioritize investigation when the user is unexpected for the host, the host is sensitive, or similar activity is new for that account.
- Review `file.path`, `file.directory`, and `file.name` (if present) to understand script origin. Treat unknown locations, new or renamed scripts, and ambiguous naming as higher risk, and check for additional script blocks tied to the same path.
- Scope related activity by searching for additional PowerShell script block events on the same `host.id` and `user.id` around `@timestamp`, and by pivoting on the same `powershell.file.script_block_id`. Look for:
- Follow-on script blocks with clearer (deobfuscated) commands
- Repeated use of similar reversal segments or reconstructed indicators
- If other endpoint telemetry is available, correlate activity on the same host and time window to identify what happened next (process launches, network connections, file writes, or other changes) and validate whether outcomes align with the reconstructed content.
### False positive analysis
- Scripts containing the keyword "GENESIS-5654" are known false positives and are automatically excluded from triggering alerts. Ensure that any legitimate scripts using this keyword are documented to prevent unnecessary investigations.
- Legitimate administrative scripts that use negative indexing for valid purposes may trigger false positives. Review these scripts and consider adding them to an exception list if they are frequently flagged but verified as non-malicious.
- Automated scripts generated by trusted software that use similar obfuscation patterns for performance or compatibility reasons can be excluded by identifying unique identifiers or patterns within these scripts and updating the exclusion criteria accordingly.
- Regularly update the exclusion list to include new patterns or identifiers from trusted sources as they are identified, ensuring that legitimate activities are not hindered by the detection rule.
- Collaborate with IT and security teams to maintain a list of known safe scripts and their characteristics, which can be referenced when analyzing potential false positives.
- Legitimate scripts may reverse arrays or strings for formatting, parsing, or testing. These cases typically remain readable end-to-end and do not rely on multiple layers of reconstruction to produce executable behavior.
- Developer utilities and automation tooling can include dense string manipulation. Validate whether the observed `file.path` and execution context (`user.name`, `host.name`) align with approved workflows and whether the same script content recurs consistently across expected hosts.
- If activity is confirmed benign, prefer context-based tuning using stable attributes visible in the alert (for example, consistent `file.path` and recognizable script content patterns) rather than suppressing the technique broadly.
### Response and remediation
- Isolate the affected host immediately to prevent further spread of potentially malicious scripts or unauthorized access.
- Terminate any suspicious PowerShell processes identified by the alert to halt ongoing obfuscation activities.
- Conduct a thorough review of the PowerShell script block text and related logs to identify any malicious payloads or commands executed.
- Remove any identified malicious scripts or files from the affected system to prevent re-execution.
- Reset credentials for any user accounts involved in the alert to mitigate potential unauthorized access.
- Escalate the incident to the security operations team for further analysis and to determine if additional systems are compromised.
- Update endpoint protection and monitoring tools to enhance detection capabilities for similar obfuscation techniques in the future.
- If the reconstructed content indicates malicious behavior, isolate the affected host to limit further execution and reduce the risk of lateral movement.
- Preserve evidence by retaining the full `powershell.file.script_block_text` and all related fragments grouped by `powershell.file.script_block_id`. Capture the reconstructed strings and relevant metadata (`powershell.sequence`, `powershell.total`, `Esql.script_block_pattern_count`) in case notes.
- Identify and contain the execution source. If an unauthorized on-disk script is referenced by `file.path`, remove or quarantine it and investigate how it was introduced using your standard incident response workflow.
- Investigate the associated account (`user.id`) for signs of compromise. Apply account controls (credential reset, session invalidation, privilege review) based on your procedures and observed scope.
- Hunt for additional exposure by pivoting on recovered indicators and on recurrence of the reversal technique across hosts and users. Remediate any additional impacted endpoints identified during scoping.
- After containment, improve preventative controls appropriate for your environment, such as restricting PowerShell usage to approved users/hosts and enhancing monitoring for obfuscation and dynamic execution patterns.
"""
risk_score = 21
rule_id = "9edd1804-83c7-4e48-b97d-c776b4c97564"
setup = """## Setup
The 'PowerShell Script Block Logging' logging policy must be enabled.
Steps to implement the logging policy with Advanced Audit Configuration:
```
Computer Configuration >
Administrative Templates >
Windows PowerShell >
Turn on PowerShell Script Block Logging (Enable)
```
Steps to implement the logging policy via registry:
```
reg add "hklm\\SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1
```
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 = "low"
tags = [
@@ -109,6 +118,7 @@ from logs-windows.powershell_operational* metadata _id, _version, _index
Esql.script_block_length,
Esql.script_block_tmp,
powershell.file.*,
file.name,
file.path,
powershell.sequence,
powershell.total,
@@ -116,6 +126,7 @@ from logs-windows.powershell_operational* metadata _id, _version, _index
_version,
_index,
host.name,
host.id,
agent.id,
user.id
@@ -124,6 +135,10 @@ from logs-windows.powershell_operational* metadata _id, _version, _index
// FP Patterns
| where not powershell.file.script_block_text like "*GENESIS-5654*"
| where file.name not like ("PSFzf.psm1", "Tenable_API_AssetLists_IPv6Seeder.ps1", "Utility.ps1")
// ESQL requires this condition, otherwise it only returns matches where file.name exists.
or file.name is null
'''
@@ -162,3 +177,21 @@ id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[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"
]
@@ -3,39 +3,134 @@ bypass_bbr_timing = true
creation_date = "2023/07/06"
integration = ["windows"]
maturity = "production"
updated_date = "2025/03/20"
updated_date = "2026/02/09"
[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies the use of Cmdlets and methods related to archive compression activities. Adversaries will often compress and
encrypt data in preparation for exfiltration.
Identifies PowerShell script block content that uses archive compression cmdlets or .NET compression classes (for
example, Compress-Archive, ZipFile, GZipStream, DeflateStream) to build compressed artifacts. Attackers compress or
package data to stage it for collection or exfiltration.
"""
from = "now-9m"
index = ["winlogbeat-*", "logs-windows.powershell*"]
language = "kuery"
license = "Elastic License v2"
name = "PowerShell Script with Archive Compression Capabilities"
note = """## Triage and analysis
> **Disclaimer**:
> This guide was created by humans with the assistance of generative AI. While its contents have been manually curated to include the most valuable information, always validate assumptions and adjust procedures to match your internal runbooks and incident triage and response policies.
### Investigating PowerShell Script with Archive Compression Capabilities
This alert identifies PowerShell script block content that references archive compression functionality. Matches can be driven by the `Compress-Archive` cmdlet or by .NET compression classes (for example, `IO.Compression.ZipFile`, `IO.Compression.ZipArchive`, `GZipStream`, `DeflateStream`, `BrotliStream`, `ZLibStream`) paired with compression configuration terms (for example, `CompressionLevel`, `CompressionMode`, `ZipArchiveMode`). Compression is common in legitimate automation, but it can also be used to package collected data for staging and potential exfiltration.
Prioritize understanding (1) who ran the script and where, (2) what data was targeted for compression, (3) where the resulting archive or compressed data was staged, and (4) whether there is follow-on activity consistent with collection or 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.
- `file.path`, `file.directory`, `file.name`: File-origin context when the script block is sourced from an on-disk file.
- `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.
- `Esql.script_block_tmp`: Transformed script block where detection patterns replace original content with a marker to support scoring/counting and quickly spot match locations.
- `Esql.script_block_pattern_count`: Count of matches for the detection pattern(s) observed in the script block content.
- `powershell.file.script_block_entropy_bits`: Shannon entropy of the script block. Higher values may indicate obfuscation.
- `powershell.file.script_block_surprisal_stdev`: Standard deviation of surprisal across the script block. Low values indicate uniform randomness. High values indicate mixed patterns and variability.
- `powershell.file.script_block_unique_symbols`: Count of distinct characters present in the script block.
- `powershell.file.script_block_length`: Script block length (size) context.
#### Possible investigation steps
- Establish initial context and priority:
- Identify the affected host and user (`host.name`, `host.id`, `user.name`, `user.domain`, `user.id`).
- Assess whether the user is expected to run PowerShell that creates archives on this host. Unexpected host-user pairings or rare activity on sensitive systems should be prioritized.
- Review the alert time in relation to known operational activity (for example, maintenance windows, support cases, backup or migration tasks).
- Quickly understand what matched:
- Review `Esql.script_block_tmp` to locate the matched compression indicators within the script block.
- Use `Esql.script_block_pattern_count` to understand whether the script contains repeated compression indicators (often seen in loops or multi-step staging).
- Review `powershell.file.script_block_text` to determine whether the activity is `Compress-Archive` usage, .NET compression usage, or both.
- Assess script complexity and likelihood of obfuscation:
- Review `powershell.file.script_block_length` to understand whether the script block is small and targeted or large and multi-purpose.
- Use `powershell.file.script_block_entropy_bits`, `powershell.file.script_block_surprisal_stdev`, and `powershell.file.script_block_unique_symbols` to triage for suspicious encoding/obfuscation:
- High entropy with low variability can indicate embedded encoded content.
- High variability can indicate a mix of readable logic and opaque data blobs.
- If metrics suggest obfuscation, prioritize deeper review and broader scoping for related script blocks from the same host and user.
- Reconstruct full script block content when fragmented:
- Pivot on `powershell.file.script_block_id` and collect all fragments for that ID.
- Order fragments by `powershell.sequence` and validate completeness using `powershell.total` when present.
- Re-review the reconstructed script to understand inputs, outputs, and any follow-on behavior.
- Identify what data is being compressed and where it is staged:
- In `powershell.file.script_block_text`, identify source paths, file selection logic (for example, recursion, wildcards, extension filters), and loops that suggest bulk collection vs a single archive operation.
- Identify the output archive name and destination directory (if specified). Focus on archives staged in user-writable or temporary directories, newly created staging folders, or remote locations.
- Determine whether compression produces an on-disk archive, in-memory compressed data, or both (for example, stream-based compression used with output streams or byte arrays).
- Determine script origin and delivery path:
- If `file.path`, `file.directory`, or `file.name` are present, assess whether the script origin aligns with expected administrative tooling for the host role.
- Review whether the script file appears newly introduced or recently modified relative to the alert time and whether similar scripts exist on other expected hosts.
- If file origin fields are absent, treat the activity as potentially interactive or remotely delivered and prioritize identifying the initiating process/source using adjacent endpoint telemetry.
- Correlate with adjacent host activity to validate intent and impact (as available):
- Process context:
- Identify the PowerShell host process associated with the script block and determine the parent process or initiation source near the alert time.
- Increase suspicion for unusual launch chains, unexpected automation context, or repeated executions by the same user across multiple hosts.
- File activity:
- Look for archive creation or modification events consistent with the output identified in the script block.
- Review whether the archive is renamed, moved, copied to shared locations, or deleted shortly after creation.
- Network activity:
- Review outbound connections from the same host following the suspected archive creation window, especially new or rare destinations, large transfers, or repeated connections shortly after staging.
- Authentication activity:
- Review nearby logon activity for the same user, including new logons to other hosts around the same time, which may indicate coordinated collection and staging.
- Assess prevalence and scope:
- Search for the same `file.path`/`file.name` or distinctive substrings from `powershell.file.script_block_text` across hosts to determine whether the behavior is isolated or widespread.
- Identify whether similar compression activity occurs across multiple hosts under the same user context or within a short time window.
### False positive analysis
- This activity can be benign when compression is used for routine operations such as packaging logs, diagnostics, backups, software deployment artifacts, or data migration.
- Benign activity is more likely when:
- The script origin (`file.path`/`file.directory`/`file.name`) aligns with approved administrative workflows and expected host roles.
- The compressed inputs are narrow and operationally relevant rather than broad user or shared data sets.
- Execution is consistent over time (repeatable cadence, consistent hosts, consistent users) and is not followed by suspicious file movement or unusual outbound network activity.
- Escalate for further review when:
- Script block characteristics suggest obfuscation or embedded opaque content (entropy and symbol distribution inconsistent with typical administrative scripts).
- Compression targets broad directories, multiple paths, or patterns suggestive of data harvesting.
- Archives are staged in unusual locations or closely followed by movement off-host, deletion, or network activity indicative of transfer.
### Response and remediation
- If malicious or suspicious activity is confirmed:
- Contain the affected host to prevent additional staging or transfer.
- Preserve evidence:
- Full `powershell.file.script_block_text` (reconstructed using `powershell.file.script_block_id`, `powershell.sequence`, and `powershell.total` when needed).
- `file.path`/`file.name` for any on-disk script source and the archive output path and filename identified in the script content.
- Host and user identifiers (`host.id`, `host.name`, `user.id`, `user.name`, `user.domain`).
- Identify potential data exposure:
- Determine what directories and file patterns were included and whether the archive was copied or transmitted externally.
- Expand scoping:
- Hunt for similar script block content and archive staging behavior across endpoints, especially under the same user context.
- Remediate root cause:
- Remove unauthorized scripts and staged archives.
- If credential misuse is suspected, reset impacted credentials and review recent account activity for additional misuse.
- If the activity is verified benign:
- Document the legitimate owner, purpose, and expected host/user scope for future triage.
- Consider adding operational context (for example, asset criticality, expected administrative accounts, or known script repositories) to reduce repeated investigation while preserving coverage for unexpected archive staging behavior.
"""
risk_score = 21
rule_id = "27071ea3-e806-4697-8abc-e22c92aa4293"
setup = """## Setup
The 'PowerShell Script Block Logging' logging policy must be enabled.
Steps to implement the logging policy with Advanced Audit Configuration:
```
Computer Configuration >
Administrative Templates >
Windows PowerShell >
Turn on PowerShell Script Block Logging (Enable)
```
Steps to implement the logging policy via registry:
```
reg add "hklm\\SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1
```
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 = "low"
tags = [
@@ -45,6 +140,7 @@ tags = [
"Tactic: Collection",
"Data Source: PowerShell Logs",
"Rule Type: BBR",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
@@ -76,45 +172,39 @@ not file.directory : (
"C:\Program Files\Microsoft Dependency Agent\plugins\lib" or
"C:\Program Files\WindowsPowerShell\Modules\icinga-powershell-framework\cache" or
"C:\ProgramData\Microsoft\Windows Defender Advanced Threat Protection\Downloads"
)
) and
not user.id : "S-1-5-18"
'''
[[rule.filters]]
[rule.filters.meta]
negate = true
[rule.filters.query.wildcard."file.path"]
case_insensitive = true
value = "?:\\\\ProgramData\\\\Microsoft\\\\Windows Defender Advanced Threat Protection\\\\Downloads\\\\*"
[[rule.filters]]
[[rule.filters]]
[rule.filters.meta]
negate = true
[rule.filters.query.wildcard."file.path"]
case_insensitive = true
value = "?:\\\\ProgramData\\\\Microsoft\\\\Windows Defender Advanced Threat Protection\\\\DataCollection\\\\*"
[[rule.filters]]
[[rule.filters]]
[rule.filters.meta]
negate = true
[rule.filters.query.wildcard."file.path"]
case_insensitive = true
value = "?:\\\\Program Files\\\\WindowsPowerShell\\\\Modules\\\\dbatools\\\\*\\\\optional\\\\Expand-Archive.ps1"
[[rule.filters]]
value = "?:\\\\Program Files\\\\WindowsPowerShell\\\\Modules\\\\*"
[rule.filters.meta]
negate = true
[rule.filters.query.wildcard."file.path"]
case_insensitive = true
value = "?:\\\\Program Files\\\\WindowsPowerShell\\\\Modules\\\\dbatools\\\\*\\\\optional\\\\Compress-Archive.ps1"
[[rule.filters]]
[rule.filters.meta]
negate = true
[rule.filters.query.wildcard."file.path"]
case_insensitive = true
value = "?:\\\\Program Files\\\\Azure\\\\StorageSyncAgent\\\\AFSDiag.ps1"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
@@ -145,3 +235,22 @@ id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[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"
]
@@ -3,38 +3,113 @@ bypass_bbr_timing = true
creation_date = "2025/04/16"
integration = ["windows"]
maturity = "production"
updated_date = "2025/12/17"
updated_date = "2026/02/09"
[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies PowerShell scripts with an abnormally high proportion of non-alphanumeric characters, often resulting from
encoding, string mangling, or dynamic code generation.
Identifies PowerShell script block content with an unusually high proportion of non-alphanumeric characters, often
produced by encoding, string mangling, or dynamic code generation. Attackers use special-character heavy obfuscation to
conceal payloads and hinder static analysis and AMSI.
"""
from = "now-9m"
language = "esql"
license = "Elastic License v2"
name = "Potential PowerShell Obfuscation via High Special Character Proportion"
note = """## Triage and analysis
> **Disclaimer**:
> This guide was created by humans with the assistance of generative AI. While its contents have been manually curated to include the most valuable information, always validate assumptions and adjust procedures to match your internal runbooks and incident triage and response policies.
### Investigating Potential PowerShell Obfuscation via High Special Character Proportion
This rule alerts on PowerShell Script Block Logging content where non-alphanumeric characters make up an unusually large share of the script text. This pattern is frequently produced by encoding, aggressive escaping, string mangling, or dynamic code generation intended to hinder inspection.
The alert includes scoring and script-shape fields that help distinguish benign embedded data from suspicious deobfuscation/execution logic. Treat the script block text as potentially untrusted content and focus on reconstructing the full script and identifying downstream behavior through correlation.
#### 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.
- `file.path`, `file.directory`, `file.name`: File-origin context when the script block is sourced from an on-disk file.
- `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.
- `Esql.script_block_tmp`: Transformed script block where detection patterns replace original content with a marker to support scoring/counting and quickly spot match locations.
- `Esql.script_block_ratio`: Proportion of the script block's characters that match the alert's target character set, divided by total script length (0-1).
- `Esql.script_block_pattern_count`: Count of matches for the detection pattern(s) observed in the script block content.
- `powershell.file.script_block_entropy_bits`: Shannon entropy of the script block. Higher values may indicate obfuscation.
- `powershell.file.script_block_surprisal_stdev`: Standard deviation of surprisal across the script block. Low values indicate uniform randomness. High values indicate mixed patterns and variability.
- `powershell.file.script_block_unique_symbols`: Count of distinct characters present in the script block.
- `powershell.file.script_block_length`: Script block length (size) context.
#### Possible investigation steps
- Establish scope and execution context:
- Review `@timestamp` to set an investigation window and identify preceding/follow-on activity.
- Identify the affected `host.id`/`host.name` and the executing `user.id`/`user.name`/`user.domain`.
- Determine whether the user/host pairing is expected for PowerShell usage in your environment and whether the account is privileged or widely used.
- Interpret the alert scoring and "shape" signals:
- Review `Esql.script_block_ratio` and `Esql.script_block_pattern_count` alongside `powershell.file.script_block_length` to understand how extreme the special-character density is.
- Use `Esql.script_block_tmp` to quickly assess whether the special characters cluster in a single region (for example, one embedded blob) or are distributed throughout the script (for example, pervasive mangling).
- Use `powershell.file.script_block_entropy_bits`, `powershell.file.script_block_unique_symbols`, and `powershell.file.script_block_surprisal_stdev` to guide prioritization:
- High entropy with many unique symbols commonly aligns with encoded/compressed/encrypted blobs embedded in the script.
- High special-character ratio with lower entropy can align with heavy escaping, string concatenation, or code generation.
- Low surprisal variability (low standard deviation) can indicate uniformly random-looking content typical of dense encoding.
- Reconstruct the full script block before making a determination:
- Pivot on `powershell.file.script_block_id` to collect all fragments for the script block.
- Reassemble fragments in order using `powershell.sequence` and confirm completeness using `powershell.total`.
- If fragments are missing, treat the visible content as incomplete and continue collection/scoping before concluding intent.
- Analyze `powershell.file.script_block_text` for intent and technique:
- Identify whether the content is primarily data (for example, long opaque strings) or executable logic (functions, control flow, and invocation).
- Look for common deobfuscation and dynamic execution patterns, such as:
- Decoding/decompression routines (for example, Base64 decoding, byte/char transformations, compression streams).
- Dynamic invocation or staged execution (for example, `Invoke-Expression`/`IEX`, reflection, `.Invoke()`, `Add-Type`).
- Retrieval of remote content or secondary payloads (for example, web request/client usage, download-and-execute flow).
- If the script includes clear indicators (domains, URLs, IP addresses, file paths, file names), capture them from the script text for pivoting and scoping.
- Determine provenance and expectedness using available file context:
- If `file.path`/`file.directory`/`file.name` are present, assess whether the location and naming align with known administrative scripts or approved automation.
- If file fields are absent, treat the activity as potentially interactive or in-memory and prioritize identifying what initiated PowerShell through adjacent host telemetry.
- Correlate with adjacent telemetry (as available in your environment) to confirm impact:
- Process activity on the same host and time window to determine the initiating process and whether PowerShell was launched indirectly.
- Network activity to identify outbound connections consistent with download, staging, or command-and-control behavior.
- File and registry activity to identify dropped artifacts or persistence-related changes.
- Authentication activity for the same `user.id` to identify suspicious logons or lateral movement preceding the script execution.
- Expand scope across the environment:
- Search for additional script block events on the same `host.id` and `user.id` near the alert time to identify staged execution (for example, decoding in one block, execution in another).
- Hunt for similar script content using stable substrings from `powershell.file.script_block_text`, and group by `file.name` or `file.path` when present to identify reuse.
### False positive analysis
- False positives are most likely when scripts embed or manipulate large non-code payloads (for example, serialized objects, structured data, certificates, or compressed content) or when tooling auto-generates scripts with heavy escaping and templating.
- Validate benign hypotheses by confirming a consistent execution pattern over time (recurring `host.id` and `user.id`), expected provenance (`file.path`/`file.name` when present), and script content that performs known administrative functions rather than decoding and executing newly generated code.
- Treat unexpected execution context (new user/host pairing) combined with high entropy and opaque content as higher risk, even if the script text does not immediately reveal its final payload.
### Response and remediation
- If malicious or suspicious activity is confirmed:
- Contain the affected host to prevent additional execution and lateral movement.
- Preserve evidence from the alert, including `powershell.file.script_block_text`, reconstructed fragments (if applicable), `powershell.file.script_block_id`, and the scoring fields (`Esql.script_block_ratio`, `Esql.script_block_pattern_count`, `powershell.file.script_block_entropy_bits`).
- Identify and remediate follow-on behavior discovered during correlation (downloaded payloads, dropped files, persistence changes, or suspicious network destinations).
- Scope the intrusion by searching for similar script content across the environment using stable substrings from `powershell.file.script_block_text`, and by pivoting on `user.id`, `host.id`, `file.path`, and `file.name`.
- If account compromise is suspected, reset credentials for the affected user and review other recent activity for that `user.id`.
- If the activity is determined benign:
- Document the responsible script or workflow, expected execution context, and typical frequency.
- Monitor for deviations such as new hosts, new users, or materially different script content that may indicate abuse of a legitimate mechanism.
"""
risk_score = 21
rule_id = "f9753455-8d55-4ad8-b70a-e07b6f18deea"
setup = """## Setup
The 'PowerShell Script Block Logging' logging policy must be enabled.
Steps to implement the logging policy with Advanced Audit Configuration:
```
Computer Configuration >
Administrative Templates >
Windows PowerShell >
Turn on PowerShell Script Block Logging (Enable)
```
Steps to implement the logging policy via registry:
```
reg add "hklm\\SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1
```
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 = "low"
tags = [
@@ -44,6 +119,7 @@ tags = [
"Tactic: Defense Evasion",
"Data Source: PowerShell Logs",
"Rule Type: BBR",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
@@ -82,6 +158,7 @@ from logs-windows.powershell_operational* metadata _id, _version, _index
_version,
_index,
host.name,
host.id,
agent.id,
user.id
@@ -130,3 +207,22 @@ id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[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,14 +2,14 @@
creation_date = "2023/07/06"
integration = ["windows"]
maturity = "production"
updated_date = "2025/03/20"
updated_date = "2026/02/09"
[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies the use of Cmdlets and methods related to Windows event log deletion activities. This is often done by
attackers in an attempt to evade detection or destroy forensic evidence on a system.
Identifies PowerShell script block content that clears Windows event logs using Clear-EventLog, Remove-EventLog, or
EventLogSession/EventLog Clear methods. Attackers clear local logs to evade detection and destroy forensic evidence.
"""
from = "now-119m"
index = ["winlogbeat-*", "logs-windows.powershell*"]
@@ -17,6 +17,76 @@ interval = "60m"
language = "kuery"
license = "Elastic License v2"
name = "PowerShell Script with Log Clear Capabilities"
note = """## Triage and analysis
> **Disclaimer**:
> This guide was created by humans with the assistance of generative AI. While its contents have been manually curated to include the most valuable information, always validate assumptions and adjust procedures to match your internal runbooks and incident triage and response policies.
### Investigating PowerShell Script with Log Clear Capabilities
This alert identifies PowerShell script block content associated with clearing Windows event logs through cmdlets or .NET methods. Clearing local logs can reduce forensic visibility and interrupt security monitoring. Because script block logging records executed content, confirm whether log clearing occurred and identify the broader activity that led to this action.
#### 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
- Analyze `powershell.file.script_block_text` to determine intent and scope:
- Identify the clearing technique used (for example, `Clear-EventLog`, `Remove-EventLog`, `EventLogSession.ClearLog`, or `Diagnostics.EventLog.Clear`).
- Extract referenced log names/channels and any values that indicate breadth (single log vs multiple logs, loops, or log enumeration).
- Note any remote targets, session objects, or hostnames that suggest log clearing on other systems.
- If `Remove-EventLog` is used, treat it as higher impact and determine whether it targets built-in logs or custom logs/event sources.
- Reconstruct full content when the script block is split:
- Pivot on `powershell.file.script_block_id` to collect all fragments.
- Order by `powershell.sequence` and confirm completeness using `powershell.total`.
- Use `powershell.file.script_block_length` to identify unusually large content that may include additional actions beyond log clearing.
- Establish execution context and likely origin:
- Review `user.name`, `user.domain`, and `user.id` to determine whether the account is expected to perform log maintenance and whether the timing is consistent with approved activity.
- Review `host.name` and `host.id` to determine whether the affected system is high value (for example, servers or shared systems) and to scope other alerts on the same host.
- If `file.path`, `file.directory`, or `file.name` are present, capture the script location/name and evaluate whether it aligns with known administrative scripts or automation.
- If file context is absent, treat the activity as inline or dynamically generated and prioritize identifying how PowerShell was launched (interactive session, scheduled execution, service, or parent process) using adjacent endpoint telemetry.
- Confirm whether logs were actually cleared and identify what was impacted:
- Review available Windows logging for records indicating event logs were cleared around `@timestamp`, and document which logs were affected.
- Look for gaps in event coverage or abrupt changes in event volume beginning at or shortly after the alert time on the same `host.id`.
- Correlate with adjacent activity around `@timestamp` (as available in your environment):
- Process execution: identify the PowerShell host process, its parent process, and any related automation that triggered the script.
- Authentication and remote access: identify new or unusual logons, session establishment, or privilege changes leading up to the event.
- Network activity: review connections consistent with remote administration or lateral movement preceding the log clearing.
- Additional PowerShell activity: review other script block events for the same `host.id` and `user.id` before and after the alert to identify precursor actions and follow-on cleanup.
- Scope across the environment:
- Search for the same or similar `powershell.file.script_block_text` patterns on other hosts to determine whether this is isolated behavior, shared tooling, or coordinated activity.
- Pivot on `user.id` to identify whether the same account performed similar activity on multiple hosts within a short time window.
### False positive analysis
- Authorized administrators may clear logs during troubleshooting, controlled testing, or specific maintenance procedures. Validate against change records, maintenance windows, and documented responsibilities for the account in `user.name`.
- Endpoint provisioning, imaging, or environment resets (for example, labs or short-lived systems) can include log clearing as part of baseline preparation. Validate whether `host.name` is part of an expected rebuild or reset workflow.
- Operational scripts may clear specific logs to address performance or retention constraints. Benign activity is more likely when `file.path` and `file.name` are from a controlled script repository and no additional suspicious activity is present for the same `user.id` and `host.id`.
### Response and remediation
- If activity is unauthorized or suspicious:
- Treat this as potential evidence destruction. Preserve remaining forensic data and collect relevant telemetry from the affected host.
- Preserve the full script content by capturing all fragments linked by `powershell.file.script_block_id` (use `powershell.sequence` and `powershell.total` for ordering) and retain it with the case record.
- Contain the involved account and host according to incident response procedures (for example, restrict access, reset credentials, and isolate the endpoint if required).
- Investigate for additional post-compromise activity on the same `host.id` and by the same `user.id`, prioritizing persistence, credential access, and lateral movement around the alert time.
- Assess logging resilience: verify critical logs are centrally forwarded and retained, and review access controls that allow event log clearing to ensure they are limited to necessary administrative roles.
- If activity is confirmed benign:
- Document the authorized workflow (who, what, where, and when), including expected `host.name`, `user.name`, and any associated script identifiers (`file.name`/`file.path`).
- Maintain monitoring for deviations from the approved pattern (unexpected accounts, hosts, timing, or expanded targeting) to reduce noise without losing coverage.
"""
references = [
"https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.eventlog.clear",
"https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.eventing.reader.eventlogsession.clearlog",
@@ -25,21 +95,8 @@ risk_score = 21
rule_id = "3d3aa8f9-12af-441f-9344-9f31053e316d"
setup = """## Setup
The 'PowerShell Script Block Logging' logging policy must be enabled.
Steps to implement the logging policy with Advanced Audit Configuration:
```
Computer Configuration >
Administrative Templates >
Windows PowerShell >
Turn on PowerShell Script Block Logging (Enable)
```
Steps to implement the logging policy via registry:
```
reg add "hklm\\SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1
```
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 = "low"
tags = [
@@ -49,6 +106,7 @@ tags = [
"Tactic: Defense Evasion",
"Data Source: PowerShell Logs",
"Rule Type: BBR",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
@@ -69,19 +127,20 @@ event.category:process and host.os.type:windows and
[[rule.filters]]
[rule.filters.meta]
negate = true
[rule.filters.query.wildcard."file.path"]
case_insensitive = true
value = "?:\\\\Windows\\\\system32\\\\WindowsPowerShell\\\\v1.0\\\\Modules\\\\Microsoft.PowerShell.Management\\\\*.psd1"
[[rule.filters]]
[[rule.filters]]
[rule.filters.meta]
negate = true
[rule.filters.query.wildcard."file.path"]
case_insensitive = true
value = "?:\\\\Program Files\\\\Microsoft Monitoring Agent\\\\Agent\\\\Health Service State\\\\Resources\\\\*\\\\M365Library.ps1"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
@@ -117,3 +176,22 @@ id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[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,14 +2,15 @@
creation_date = "2023/07/12"
integration = ["windows"]
maturity = "production"
updated_date = "2025/09/03"
updated_date = "2026/02/09"
[rule]
author = ["Elastic"]
building_block_type = "default"
description = """
Identifies the use of Cmdlets and methods related to remote execution activities using WinRM. Attackers can abuse WinRM
to perform lateral movement using built-in tools.
Identifies PowerShell script block content that queries Active Directory password policy settings using AD cmdlets, GPP
password helpers, or directory searcher attributes. Attackers collect password policy details to tune credential attacks
and target weak configurations.
"""
from = "now-119m"
index = ["winlogbeat-*", "logs-windows.powershell*"]
@@ -17,25 +18,74 @@ interval = "60m"
language = "kuery"
license = "Elastic License v2"
name = "PowerShell Script with Password Policy Discovery Capabilities"
note = """## Triage and analysis
> **Disclaimer**:
> This guide was created by humans with the assistance of generative AI. While its contents have been manually curated to include the most valuable information, always validate assumptions and adjust procedures to match your internal runbooks and incident triage and response policies.
### Investigating PowerShell Script with Password Policy Discovery Capabilities
This alert identifies PowerShell script block content consistent with querying Active Directory password policy settings, including default domain policy requirements, fine-grained password policies, or related directory attributes. Adversaries may use these details to tune password guessing attempts and prioritize targets; administrators may also collect this information for auditing and troubleshooting.
#### 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
- Review `powershell.file.script_block_text` and identify the discovery method:
- AD password policy cmdlets/functions such as `Get-ADDefaultDomainPasswordPolicy`, `Get-ADFineGrainedPasswordPolicy`, `Get-ADUserResultantPasswordPolicy`, `Get-DomainPolicy`, or `Get-PassPol`.
- Directory searcher patterns such as `defaultNamingContext`, `ActiveDirectory.DirectoryContext`, or `ActiveDirectory.DirectorySearcher`, and referenced properties/attributes like `.MinLengthPassword`, `.MinPasswordAge`, `.MaxPasswordAge`, `minPwdLength`, `minPwdAge`, `maxPwdAge`, or `msDS-PasswordSettings`.
- Helper function use that may attempt to access Group Policy Preference password data (for example, `Get-GPPPassword`).
- Determine scope and intent from the script content:
- Domain-wide enumeration vs querying a specific user/resultant policy.
- Enumeration of fine-grained policy objects (`msDS-PasswordSettings`), which can indicate targeted reconnaissance for weaker settings.
- Evidence of output collection (formatting, exporting, or writing results) that may support later use.
- Validate the execution context using `host.name`, `host.id`, `user.name`, `user.domain`, and `user.id`:
- Confirm the host is an expected location for administrative or audit activity (for example, an admin workstation or management server).
- Assess whether the account context aligns with expected job function and normal host access patterns.
- Determine script origin and how it was introduced when `file.path`, `file.directory`, or `file.name` are present:
- Validate that the script path and name align with approved tooling and standard locations for that host.
- Treat execution from user-writable or temporary locations, or from unfamiliar script names, as higher risk and scope for additional suspicious activity.
- Reconstruct the full script content when it is split across multiple events:
- Pivot on `powershell.file.script_block_id` and order by `powershell.sequence` to rebuild the full script (use `powershell.total` to confirm all fragments are present).
- Preserve the reconstructed content for case notes and scoping.
- Correlate with other activity from the same host and account near `@timestamp` (if available in your telemetry):
- Review additional PowerShell script block logs for related discovery, credential access attempts, or follow-on execution.
- Review process activity to determine how PowerShell was launched (parent process, service/automation context, or interactive use) and whether the launch source is expected for the user/host.
- Review network activity consistent with directory queries or access to domain infrastructure that may indicate broader reconnaissance.
- Review file activity for evidence of staged scripts/modules or stored output containing policy details.
- Review authentication activity for spikes in failed logons, account lockouts, or access to multiple hosts following the discovery.
- Scope and prevalence:
- Look for similar `powershell.file.script_block_text` content executed by the same `user.id` on other hosts to determine whether this is isolated or part of a wider discovery phase.
- Look for similar content on the same `host.id` from other users to identify shared tooling, automation, or a compromised host used to launch reconnaissance.
### False positive analysis
- Authorized identity and directory administration activities (for example, validating password policy requirements during audits, troubleshooting, or policy change reviews).
- Scheduled reporting or compliance workflows that periodically inventory default and fine-grained password policy settings.
- Support investigations that query resultant password policy for a specific user as part of account lifecycle management or lockout investigations.
### Response and remediation
- If the activity is unexpected or cannot be tied to an approved administrative task:
- Isolate the affected host to prevent further reconnaissance.
- Restrict or disable the involved account (`user.id`) and reset credentials according to incident response procedures.
- Preserve evidence, including the reconstructed `powershell.file.script_block_text`, associated `powershell.file.script_block_id` fragments, and any referenced scripts (`file.path`, `file.name`).
- Hunt for follow-on activity associated with password policy discovery, such as password guessing attempts, credential collection, and additional directory enumeration, using the same `user.id`, `host.id`, and timeframe.
- If the script content suggests access to Group Policy Preference password data, treat this as potential credential exposure and rotate any identified credentials and remediate insecure configurations.
- If the activity is confirmed benign:
- Document the approved use case (expected accounts, hosts, and script locations) to speed future triage.
- Apply least-privilege controls to limit where and by whom directory policy discovery can be performed while maintaining audit visibility.
"""
risk_score = 21
rule_id = "fe25d5bc-01fa-494a-95ff-535c29cc4c96"
setup = """## Setup
The 'PowerShell Script Block Logging' logging policy must be enabled.
Steps to implement the logging policy with Advanced Audit Configuration:
```
Computer Configuration >
Administrative Templates >
Windows PowerShell >
Turn on PowerShell Script Block Logging (Enable)
```
Steps to implement the logging policy via registry:
```
reg add "hklm\\SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1
```
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 = "low"
tags = [
@@ -46,6 +96,7 @@ tags = [
"Tactic: Execution",
"Data Source: PowerShell Logs",
"Rule Type: BBR",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
@@ -119,3 +170,22 @@ id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"
[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"
]