Detection rules › Elastic

Potential PowerShell Obfuscation via String Reordering

Author
Elastic
Source
upstream

Detects PowerShell scripts that uses format placeholders like "{0}{1}" with the -f operator or ::Format to reorder strings at runtime. Attackers use format-based reconstruction to hide commands or payload strings and evade static analysis and AMSI.

MITRE ATT&CK coverage

TacticTechniques
ExecutionT1059 Command and Scripting Interpreter, T1059.001 Command and Scripting Interpreter: PowerShell
Defense EvasionT1027 Obfuscated Files or Information, T1027.010 Obfuscated Files or Information: Command Obfuscation, T1140 Deobfuscate/Decode Files or Information

Event coverage

ProviderEvent IDTitle
PowerShell4104Creating Scriptblock text (MessageNumber of MessageTotal).

Stages and Predicates

Stage 1: esql:from

Stage 2: esql:where

powershell.file.script_block_text:"{0}"

Stage 3: esql:eval

Stage 4: esql:where

Esql.script_block_length > 500

Stage 5: esql:eval

Stage 6: esql:eval

Stage 7: esql:keep

Stage 8: esql:where

Esql.script_block_pattern_count >= 5

Stage 9: esql:where

(not file.directory:"C:\\\\Program Files\\\\WindowsPowerShell\\\\Modules\\\\icinga-powershell-framework\\\\cache" or not file.directory:*)

Stage 10: esql:where

not (powershell.file.script_block_text:"$s.BranchBehindStatusSymbol.Text" and powershell.file.script_block_text:"GitBranchStatus")

Stage 11: esql:where

not ((powershell.file.script_block_text:"$local:Bypassed" or powershell.file.script_block_text:"origPSExecutionPolicyPreference") and (powershell.file.script_block_text:":::::\\\\\\\\windows\\\\\\\\sentinel" or powershell.file.script_block_text:"sentinelbreakpoints"))

Exclusions

Top-level NOT(...) conjuncts — predicates this rule actively suppresses.

StageFieldKindExcluded values
1ScriptBlockTextmatch$s.BranchBehindStatusSymbol.Text
2ScriptBlockTextmatchGitBranchStatus
1ScriptBlockTextmatch$local:Bypassed
2ScriptBlockTextmatchorigPSExecutionPolicyPreference
3ScriptBlockTextmatch:::::\\\\windows\\\\sentinel
4ScriptBlockTextmatchsentinelbreakpoints

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
Esql.script_block_lengthgt
  • 500 corpus 6 (elastic 6)
Esql.script_block_pattern_countge
  • 5
powershell.file.script_block_textwildcard
  • *{0}*

Neighbors

Stricter alternatives (narrower than this rule)

The rules below may be useful if you find the current rule is too noisy / lacks specificity.