Dynamic IEX Reconstruction via Method String Access
Detects PowerShell scripts that rebuilds IEX by converting method references to strings (for example, ''.IndexOf.ToString()) and extracting multiple indexed characters (for example, [n,n,n]). Attackers use method-string reconstruction to conceal dynamic execution and bypass static detections and AMSI.
Rule type: esql
Rule indices:
Rule Severity: low
Risk Score: 21
Runs every:
Searches indices from: now-9m
Maximum alerts per execution: 100
References:
Tags:
- Domain: Endpoint
- OS: Windows
- Use Case: Threat Detection
- Tactic: Defense Evasion
- Data Source: PowerShell Logs
- Resources: Investigation Guide
Version: 9
Rule authors:
- Elastic
Rule license: Elastic License v2
PowerShell Script Block Logging must be enabled to generate the events used by this rule (e.g., 4104). Setup instructions: https://ela.st/powershell-logging-setup
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.
This alert indicates PowerShell script block content that uses method-to-string conversion and indexed character extraction to assemble an execution primitive at runtime, commonly "IEX" (Invoke-Expression). This obfuscation technique can conceal dynamic execution intent and is often used to reduce obvious keywords in the script body.
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.
Establish execution context and scope:
- Review
host.nameandhost.idto identify the affected endpoint and its role/criticality. - Review
user.name,user.domain, anduser.idto determine whether the activity aligns with expected administrative or automation usage. - Review
file.path,file.directory, andfile.name(when present) to understand whether the script originated from an on-disk file. - Review
agent.idto pivot to other telemetry from the same endpoint and timeframe.
- Review
Validate what matched and how extensively it appears:
- Review
Esql.script_block_pattern_countto gauge how often the technique appears within the script block (higher counts can indicate heavier obfuscation). - Use
Esql.script_block_tmpto quickly locate the matched regions, then review the corresponding locations inpowershell.file.script_block_textfor the exact construct and nearby context. - Review
powershell.file.script_block_lengthalongsidepowershell.file.script_block_entropy_bits,powershell.file.script_block_surprisal_stdev, andpowershell.file.script_block_unique_symbolsto help distinguish isolated string tricks from broader obfuscation.
- Review
Reconstruct the full script block when content is split:
- Pivot on
powershell.file.script_block_idand order results bypowershell.sequence. - Use
powershell.totalto confirm you have all fragments before making a final assessment. - Preserve the reassembled content from
powershell.file.script_block_textfor follow-on analysis and scoping.
- Pivot on
Determine the reconstructed token and follow-on behavior:
- In
powershell.file.script_block_text, identify the method string being indexed and the associated index list (for example, [n,n,n]) to determine what characters are being assembled. - Identify how the reconstructed string is used (for example, invoked directly, assigned to a variable, or passed as an argument) and what content it ultimately executes.
- Capture any secondary artifacts referenced in the script content (for example, embedded payload strings, additional script blocks, or external resource locations) and use them to drive further correlation.
- In
Validate likely origin and initiating source:
- If
file.pathis present, validate whether the script location is expected for the user and host, and whether it appears in a user-writable location or a standard administrative tooling path. - If file origin fields are not present, the script may have been executed interactively or generated at runtime; rely on surrounding endpoint telemetry to identify the initiating process and any related activity.
- If
Correlate with adjacent activity to understand impact:
- Review other PowerShell script blocks on the same
host.idanduser.idaround the alert time to identify staging steps and any follow-on execution. - If process telemetry is available, identify the PowerShell process and its parent process that initiated execution, and check for suspicious child processes near the alert time.
- If network or file telemetry is available, look for downloads, outbound connections, and file writes temporally aligned with the script block execution and the content referenced within
powershell.file.script_block_text.
- Review other PowerShell script blocks on the same
Assess prevalence across the environment:
- Search for similar patterns (including stable substrings from
powershell.file.script_block_text) across other hosts and users. - Prioritize results with higher
Esql.script_block_pattern_countand higher obfuscation metrics to identify likely common tooling or shared payloads.
- Search for similar patterns (including stable substrings from
- PowerShell developers or automation teams may experiment with unconventional string manipulation, but method-string indexing to assemble execution primitives is uncommon in routine administration.
- Authorized security testing, malware analysis, or threat emulation activities can intentionally use this technique; validate against approved testing windows and operator accounts.
- Some script packaging or code protection approaches can introduce non-standard string operations; treat as benign only when the script origin (
file.path/file.name), execution context (user.id), and surrounding host activity support a known, approved workflow.
If malicious or suspicious activity is confirmed:
- Contain the affected host identified by
host.idto prevent additional execution and lateral movement. - Preserve evidence from the alert, including
powershell.file.script_block_text,powershell.file.script_block_id,powershell.sequence,powershell.total,file.path, andEsql.script_block_pattern_count. - Scope for related activity by searching for similar content patterns across the environment and identifying additional impacted hosts and accounts.
- If an on-disk script is involved (
file.pathpresent), collect the file for analysis and remove or quarantine it according to your incident handling process. - Review the associated account (
user.id) for additional suspicious activity and remediate credential exposure as appropriate (for example, reset credentials and review recent authentication activity).
- Contain the affected host identified by
If the activity is determined to be benign:
- Document the legitimate script source, expected hosts, and operator accounts for future triage.
- Reduce noise with narrowly scoped suppression using stable characteristics available in the alert (for example, consistent
file.pathand repeatable non-sensitive substrings inpowershell.file.script_block_text), while continuing to monitor for deviations.
from logs-windows.powershell_operational* metadata _id, _version, _index
| where event.code == "4104"
// Filter out smaller scripts that are unlikely to implement obfuscation using the patterns we are looking for
| eval Esql.script_block_length = length(powershell.file.script_block_text)
| where Esql.script_block_length > 500
// replace the patterns we are looking for with the 🔥 emoji to enable counting them
// The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1
| eval Esql.script_block_tmp = replace(
powershell.file.script_block_text,
"""(?i)['"]['"].(Insert|Normalize|Chars|substring|Remove|LastIndexOfAny|LastIndexOf|IsNormalized|IndexOfAny|IndexOf)[^\[]+\[\d+,\d+,\d+\]""",
"🔥"
)
// count how many patterns were detected by calculating the number of 🔥 characters inserted
| eval Esql.script_block_pattern_count = length(Esql.script_block_tmp) - length(replace(Esql.script_block_tmp, "🔥", ""))
// keep the fields relevant to the query, although this is not needed as the alert is populated using _id
| keep
Esql.script_block_pattern_count,
Esql.script_block_length,
Esql.script_block_tmp,
powershell.file.*,
file.path,
file.directory,
powershell.sequence,
powershell.total,
_id,
_version,
_index,
host.name,
host.id,
agent.id,
user.id
// Filter for scripts that match the pattern at least once
| where Esql.script_block_pattern_count >= 1
| where not (
file.directory like "C:\\\\Program Files\\\\WindowsPowerShell\\\\Modules\\\\Maester\\\\1.1.0*" or
file.directory like "C:\\\\Users\\\\*\\\\Documents\\\\WindowsPowerShell\\\\Modules\\\\Maester\\\\1.1.0*"
)
// ESQL requires this condition, otherwise it only returns matches where file.directory exists.
or file.directory is null
Framework: MITRE ATT&CK
Tactic:
- Name: Defense Evasion
- Id: TA0005
- Reference URL: https://attack.mitre.org/tactics/TA0005/
Technique:
- Name: Obfuscated Files or Information
- Id: T1027
- Reference URL: https://attack.mitre.org/techniques/T1027/
Technique:
- Name: Deobfuscate/Decode Files or Information
- Id: T1140
- Reference URL: https://attack.mitre.org/techniques/T1140/
Framework: MITRE ATT&CK
Tactic:
- Name: Execution
- Id: TA0002
- Reference URL: https://attack.mitre.org/tactics/TA0002/
Technique:
- Name: Command and Scripting Interpreter
- Id: T1059
- Reference URL: https://attack.mitre.org/techniques/T1059/
Sub Technique:
- Name: PowerShell
- Id: T1059.001
- Reference URL: https://attack.mitre.org/techniques/T1059/001/