Potential PowerShell Obfuscation via String Reordering
editPotential PowerShell Obfuscation via String Reordering
editIdentifies PowerShell scripts that use string reordering and runtime reconstruction techniques as a form of obfuscation. These methods are designed to evade static analysis and bypass security protections such as the Antimalware Scan Interface (AMSI).
Rule type: esql
Rule indices: None
Severity: low
Risk score: 21
Runs every: 5m
Searches indices from: now-9m (Date Math format, see also Additional look-back time
)
Maximum alerts per execution: 100
References: None
Tags:
- Domain: Endpoint
- OS: Windows
- Use Case: Threat Detection
- Tactic: Defense Evasion
- Data Source: PowerShell Logs
Version: 2
Rule authors:
- Elastic
Rule license: Elastic License v2
Setup
editSetup
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
Rule query
editFROM logs-windows.powershell_operational* metadata _id, _version, _index | WHERE event.code == "4104" // Look for scripts with more than 500 chars that contain a related keyword | EVAL script_len = LENGTH(powershell.file.script_block_text) | WHERE script_len > 500 | WHERE powershell.file.script_block_text LIKE "*{0}*" // Replace string format expressions with 🔥 to enable counting the occurrence of the patterns we are looking for // The emoji is used because it's unlikely to appear in scripts and has a consistent character length of 1 | EVAL replaced_with_fire = REPLACE(powershell.file.script_block_text, """((\{\d+\}){2,}["']\s?-f|::Format[^\{]+(\{\d+\}){2,})""", "🔥") // Count how many patterns were detected by calculating the number of 🔥 characters inserted | EVAL count = LENGTH(replaced_with_fire) - LENGTH(REPLACE(replaced_with_fire, "🔥", "")) // Keep the fields relevant to the query, although this is not needed as the alert is populated using _id | KEEP count, replaced_with_fire, powershell.file.script_block_text, powershell.file.script_block_id, file.path, powershell.sequence, powershell.total, _id, _index, host.name, agent.id, user.id | WHERE count > 3
Framework: MITRE ATT&CKTM
-
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/
-
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/