﻿---
title: Potential Malicious PowerShell Based on Alert Correlation
description: Identifies PowerShell script blocks linked to multiple distinct PowerShell detections via the same ScriptBlock ID, indicating compound suspicious behavior...
url: https://www.elastic.co/elastic/docs-builder/docs/2848/reference/security/prebuilt-rules/rules/windows/execution_posh_malicious_script_agg
products:
  - Elastic Security
---

# Potential Malicious PowerShell Based on Alert Correlation
Identifies PowerShell script blocks linked to multiple distinct PowerShell detections via the same ScriptBlock ID,
indicating compound suspicious behavior. Attackers often chain obfuscation, decoding, and execution within a single
script block.
**Rule type**: esql
**Rule indices**:
**Rule Severity**: high
**Risk Score**: 73
**Runs every**: 
**Searches indices from**: `now-9m`
**Maximum alerts per execution**: 100
**References**:
**Tags**:
- Domain: Endpoint
- OS: Windows
- Use Case: Threat Detection
- Tactic: Execution
- Rule Type: Higher-Order Rule
- Resources: Investigation Guide

**Version**: 4
**Rule authors**:
- Elastic

**Rule license**: Elastic License v2

## Investigation guide


## 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 Malicious PowerShell Based on Alert Correlation

This alert groups multiple PowerShell-related detections that reference the same ScriptBlock identifier. When several independent detections fire on a single script block, it often indicates a single execution chain combining multiple suspicious behaviors. Treat the contributing alerts as the primary evidence and use this correlation to prioritize investigation and scoping.
Investigation goals:
- Identify affected endpoints and users by pivoting to the contributing alerts.
- Recover the complete script content associated with the ScriptBlock identifier and understand its intent.
- Identify follow-on behavior (process, network, persistence) and scope the activity across the environment.


#### Key alert fields to review

- `Esql.script_block_id`: The ScriptBlock identifier used to correlate multiple alerts.
- `Esql.kibana_alert_rule_name_count_distinct`: The number of distinct PowerShell-related rule names that contributed to the correlation.
- `Esql.kibana_alert_rule_name_values`: The contributing rule names; use this list to quickly understand what detection logic was triggered.
- `Esql._id_values`: The contributing alert document IDs; pivot to these source alerts for full context and supporting evidence.


#### Possible investigation steps

- Understand what drove the correlation:
  - Review `Esql.kibana_alert_rule_name_count_distinct` to gauge overall confidence and urgency.
- Review `Esql.kibana_alert_rule_name_values` and group the contributing detections by behavior (for example, obfuscation/encoding, suspicious execution, network retrieval, or persistence-related activity). Use this grouping to decide what evidence is most important to validate first.
- Pivot to the contributing alerts and capture execution context:
  - Use `Esql._id_values` to open each contributing alert and collect the affected host and user context, along with the earliest and latest timestamps across the set.
- Confirm the contributing alerts represent the same ScriptBlock ID and are not unrelated alerts that happen to share similar message content.
- Identify whether the activity is limited to a single endpoint or appears on multiple endpoints. Multiple endpoints can indicate script reuse, distribution, or remote execution.
- Reconstruct the full script block content:
  - Using `Esql.script_block_id`, locate all available records (alerts and/or underlying telemetry referenced by the contributing alerts) tied to the same identifier.
- If the script content is split across multiple fragments, reconstruct it in the correct order before assessing intent.
- Identify any decoded/deobfuscated output that the script generates during execution and capture it as evidence for scoping.
- Assess intent and capability based on the recovered script:
  - Look for evidence of staged execution, such as multiple layers of decoding, dynamic code generation, or invocation of additional code.
- Identify indicators that can be used for scoping (for example, external destinations, file locations, created services, or suspicious child process activity referenced by the contributing alerts).
- Correlate with adjacent activity during the same timeframe:
  - Process activity: check for unusual parent-child relationships involving PowerShell and unexpected child processes following the script block execution.
- Network activity: review outbound connections and DNS activity that align with the execution window, especially first-time or rare destinations.
- File and registry activity: look for payload staging, configuration changes, or persistence artifacts created near the execution window.
- Authentication activity: review for suspicious logons or account changes that coincide with the script execution, especially if activity spans multiple endpoints.
- Scope and hunt for additional occurrences:
  - Search for other alerts containing the same `Esql.script_block_id` to determine if the script was reused or executed repeatedly.
- Use indicators and behaviors observed in the contributing alerts to identify related activity in other alerts and telemetry sources, and establish first-seen/last-seen boundaries.


### False positive analysis

- Legitimate administrative automation can produce multiple detections if it uses dynamic script generation, embedded encoded content, or downloads content at runtime. Validate whether the affected hosts, users, and timing align with an approved maintenance activity.
- If the same ScriptBlock content repeatedly maps to a known benign workflow, document the expected behavior and tune upstream detections to better distinguish that workflow, rather than suppressing this correlation rule.


### Response and remediation

- If the activity is confirmed or strongly suspected to be malicious:
  - Contain impacted endpoints to prevent additional execution and follow-on actions.
- Restrict, reset, or rotate credentials for involved accounts as appropriate, especially for privileged or shared accounts.
- Remove identified artifacts and persistence mechanisms (for example, suspicious services or dropped binaries) and remediate any affected systems.
- Block or monitor indicators identified from the contributing alerts (external destinations, file locations, or other observable artifacts) to prevent reinfection and support hunting.
- Validation and recovery:
  - Use `Esql.script_block_id` and the contributing alert set in `Esql._id_values` to verify that the activity has ceased and to identify any additional impacted endpoints.
- Continue monitoring for recurrence of the same ScriptBlock ID or the contributing behaviors to confirm remediation effectiveness.
- Post-incident:
  - Preserve the recovered script content and the full set of contributing alerts as evidence.
- Identify and address the initial execution mechanism indicated by the contributing alerts and improve preventative controls and logging coverage to reduce recurrence.


## Rule Query

```esql
from .alerts-security.* metadata _id

// Filter for PowerShell related alerts
| where kibana.alert.rule.name like "*PowerShell*"

// as alerts don't have non-ECS fields, parse the script block ID using grok
| grok message "ScriptBlock ID: (?<Esql.script_block_id>.+)"
| where Esql.script_block_id is not null

// keep relevant fields for further processing
| keep kibana.alert.rule.name, Esql.script_block_id, _id

// count distinct alerts and filter for matches above the threshold
| stats
    Esql.kibana_alert_rule_name_count_distinct = count_distinct(kibana.alert.rule.name),
    Esql.kibana_alert_rule_name_values = values(kibana.alert.rule.name),
    Esql._id_values = values(_id)
  by Esql.script_block_id

// Apply detection threshold
| where Esql.kibana_alert_rule_name_count_distinct >= 5
```

**Framework:** MITRE ATT&CK
- Tactic:
  - Name: Execution
- Id: TA0002
- Reference URL: [[https://attack.mitre.org/tactics/TA0002/](https://attack.mitre.org/tactics/TA0002/)](https://attack.mitre.org/tactics/TA0002/)
- Technique:
  - Name: Command and Scripting Interpreter
- Id: T1059
- Reference URL: [[https://attack.mitre.org/techniques/T1059/](https://attack.mitre.org/techniques/T1059/)](https://attack.mitre.org/techniques/T1059/)
- Sub Technique:
  - Name: PowerShell
- Id: T1059.001
- Reference URL: [[https://attack.mitre.org/techniques/T1059/001/](https://attack.mitre.org/techniques/T1059/001/)](https://attack.mitre.org/techniques/T1059/001/)