Potential PowerShell Obfuscation via Backtick-Escaped Variable Expansion
Detects PowerShell scripts that uses backtick-escaped characters inside ${} variable expansion (multiple backticks
between word characters) to reconstruct strings at runtime. Attackers use variable-expansion obfuscation to split
keywords, hide commands, and evade static analysis and AMSI.
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: Defense Evasion
- Data Source: PowerShell Logs
- Resources: Investigation Guide
Version: 7
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 rule identifies Windows PowerShell Script Block Logging events where backtick-escaped characters are embedded within ${} variable expansion. This technique can be used to split tokens and reconstruct variable names or keywords at runtime, reducing the effectiveness of simple string-based detections and content scanning.
Focus analysis on (1) who executed the script, (2) where it executed, (3) how much of the script is obfuscated, and (4) what the script ultimately does after deobfuscation. Higher Esql.script_block_pattern_count, elevated powershell.file.script_block_entropy_bits, and unexpected script origin (for example, unusual file.path) increase the likelihood of malicious intent.
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.
Validate execution scope and context:
- Review
host.name/host.idto understand where the script ran and whether the endpoint role makes this activity unexpected. - Review
user.name,user.domain, anduser.idto determine whether the account is expected to run PowerShell on this host and to identify any unusual account usage patterns in your environment. - If
file.path/file.name/file.directoryare present, determine whether the script appears to originate from an expected location (for example, a managed scripts directory) versus an unusual or user-writable location.
- Review
Reconstruct the complete script before interpreting intent:
- Pivot on
powershell.file.script_block_idand collect all related fragments. - Use
powershell.sequenceandpowershell.totalto verify you have the full set of fragments and to order them correctly. - Review the reconstructed
powershell.file.script_block_textfor staging behavior (for example, an initial deobfuscation routine followed by a second stage that performs the primary action).
- Pivot on
Locate the obfuscated variable expansions and normalize the content:
- Use
Esql.script_block_tmpto quickly identify the positions of suspicious${}expansions, then review the corresponding sections inpowershell.file.script_block_text. - Use
Esql.script_block_pattern_countto estimate how pervasive the obfuscation is. A higher count is more consistent with deliberate evasion than isolated escaping. - In the matched
${}segments, assess what the obfuscated expansion is intended to represent by mentally removing backtick escapes and looking for recognizable tokens (cmdlet/function names, variable names, or string literals) that the script is trying to hide.
- Use
Assess behavior indicated by the script content:
- Identify whether the script uses dynamic invocation patterns, such as building an invocation target at runtime or executing reconstructed strings.
- Look for decoding and deobfuscation constructs (string concatenation, character-by-character reconstruction, data transformation, decompression) that may reveal embedded or second-stage content.
- Extract and document any clear indicators contained in the script text (remote endpoints, file paths, registry paths, service/task names, or additional scripts referenced). Use these indicators to scope impact across hosts.
Use alert-side obfuscation metrics to prioritize and focus review:
- Compare
powershell.file.script_block_entropy_bits,powershell.file.script_block_unique_symbols, andpowershell.file.script_block_surprisal_stdevagainst what is typical in your environment for administrative scripts. - Treat scripts with high entropy and many unique symbols as higher risk, especially when combined with multiple obfuscated
${}expansions.
- Compare
Scope prevalence and recurrence:
- Search for other Script Block Logging events on the same
host.idanduser.idthat include similar backtick-escaped${}patterns. - Look for repeated occurrences of the same
file.name/file.pathacross multiple hosts, which may indicate a shared script or distributed execution. - If the script contains unique strings or indicators, use them to identify additional affected endpoints.
- Search for other Script Block Logging events on the same
- Legitimate scripts that implement complex string building or variable-name handling and happen to use backticks within
${}expansion (more common in developer tooling, templating, or edge-case input handling). - Auto-generated PowerShell produced by administrative automation that uses nonstandard escaping or runtime string construction.
When evaluating potential false positives, weigh consistency (same user.id, host.id, and file.path over time) against indicators of compromise (unexpected user/host pairing, high obfuscation density, high entropy, or evidence of follow-on actions).
If the activity is suspicious or confirmed malicious:
- Contain the affected endpoint to prevent additional execution and limit potential lateral movement.
- Preserve evidence from the alert, including the full reconstructed
powershell.file.script_block_text,powershell.file.script_block_id,powershell.sequence/powershell.total, and anyfile.path/file.namevalues. - If an on-disk source is indicated by
file.path, collect the referenced script and related files for review and remove or quarantine malicious artifacts according to your procedures. - Investigate for follow-on effects suggested by the script content (persistence, payload delivery, configuration changes) and remediate any identified artifacts.
- Review the impacted
user.idfor compromise, revoke active sessions as appropriate, and reset credentials based on your incident response policy. - Use extracted indicators and distinctive script fragments to hunt for additional affected hosts and users.
If the activity is verified benign:
- Document the legitimate script source, expected
file.path/file.name, and the normal execution context (user.id,host.id) to speed up future triage. - Monitor for deviations in execution context or significant changes in obfuscation metrics (for example, increased
Esql.script_block_pattern_countor higher entropy) that could indicate abuse of an otherwise legitimate script.
- Document the legitimate script source, expected
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, """\$\{(\w++`){2,}\w++\}""", "🔥")
// 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.name,
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
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/