Potential PowerShell Obfuscation via Invalid Escape Sequences

edit
A newer version is available. Check out the latest documentation.

Potential PowerShell Obfuscation via Invalid Escape Sequences

edit

Identifies PowerShell scripts that use invalid escape sequences as a form of obfuscation. This technique introduces backticks (`) between characters in a way that does not correspond to valid PowerShell escape sequences, breaking up strings and bypassing pattern-based detections while preserving execution logic. This is 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
  • Resources: Investigation Guide

Version: 5

Rule authors:

  • Elastic

Rule license: Elastic License v2

Investigation guide

edit
## Triage and analysis

Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.

Investigating Potential PowerShell Obfuscation via Invalid Escape Sequences

PowerShell, a powerful scripting language in Windows environments, can be exploited by adversaries using obfuscation techniques to evade detection. By inserting invalid escape sequences, attackers can obscure malicious scripts, bypassing static analysis and security tools like AMSI. The detection rule identifies such obfuscation by analyzing script patterns, specifically targeting unusual backtick usage, to flag potential threats.

Possible investigation steps

  • Review the powershell.file.script_block_text field to understand the context and content of the script block that triggered the alert. Look for patterns of invalid escape sequences and assess whether they appear intentionally obfuscated.
  • Examine the file.name and file.path fields to determine the origin and location of the script. This can help identify whether the script is part of a legitimate application or potentially malicious.
  • Check the host.name and agent.id fields to identify the affected system and the agent responsible for logging the event. This information is crucial for understanding the scope of the potential threat.
  • Analyze the user.id field to ascertain which user executed the script. This can provide insights into whether the user has a history of executing suspicious scripts or if their account may be compromised.
  • Investigate the powershell.file.script_block_id and powershell.sequence fields to trace the execution sequence and correlate it with other related script blocks, which may reveal additional obfuscation or malicious activity.
  • Assess the count field to evaluate the extent of obfuscation detected. A higher count may indicate more aggressive obfuscation techniques, warranting further scrutiny.

False positive analysis

  • Scripts from Visual Studio Code’s PowerShell extension may trigger false positives due to its shell integration. To handle this, exclude scripts containing the pattern "$([char]0x1b)]633" from detection.
  • PowerShell modules with names starting with "TSS_" may be flagged incorrectly. Exclude these by adding a condition to ignore files matching the pattern "TSS_*.psm1".
  • Legitimate scripts that use backticks for formatting or other non-obfuscation purposes might be detected. Review such scripts and, if verified as safe, add them to an exception list based on their script block ID or file path.
  • Regularly update the exclusion list to reflect changes in legitimate script usage patterns, ensuring that new false positives are addressed promptly.

Response and remediation

  • Isolate the affected host immediately to prevent lateral movement and further execution of potentially malicious scripts. Disconnect the host from the network and disable remote access.
  • Analyze the script block text and file path to identify the source and nature of the obfuscated script. Determine if the script is part of a larger attack or if other systems are affected.
  • Remove or quarantine the identified malicious script and any associated files from the host. Ensure that all remnants of the obfuscated code are eliminated to prevent re-execution.
  • Conduct a thorough scan of the host using updated antivirus and antimalware tools to detect and remove any additional threats or indicators of compromise.
  • Review and update PowerShell execution policies and security settings to restrict the execution of scripts with invalid escape sequences. Implement stricter controls to prevent similar obfuscation techniques.
  • Escalate the incident to the security operations center (SOC) or relevant cybersecurity team for further investigation and monitoring. Provide detailed logs and findings to assist in understanding the scope and impact of the threat.
  • Implement enhanced logging and monitoring for PowerShell activities across the network to detect and respond to similar obfuscation attempts promptly. Use the identified patterns to refine detection capabilities.

Setup

edit

Setup

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

edit
from logs-windows.powershell_operational* metadata _id, _version, _index
| where event.code == "4104" and powershell.file.script_block_text like "*`*"

// 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, """[A-Za-z0-9_-]`(?![rntb]|\r|\n|\d)[A-Za-z0-9_-]""", "🔥")

// 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_tmp,
    powershell.file.script_block_text,
    powershell.file.script_block_id,
    file.name,
    file.directory,
    file.path,
    powershell.sequence,
    powershell.total,
    _id,
    _index,
    host.name,
    agent.id,
    user.id

// Filter for scripts that match the pattern at least 10 times
| where Esql.script_block_pattern_count >= 10

| where file.name not like "TSS_*.psm1"
  // ESQL requires this condition, otherwise it only returns matches where file.name exists.
  or file.name is null

// VSCode Shell integration
| where not powershell.file.script_block_text like "*$([char]0x1b)]633*"

| where not file.directory == "C:\\Program Files\\MVPSI\\JAMS\\Agent\\Temp"
  // ESQL requires this condition, otherwise it only returns matches where file.directory exists.
  or file.directory is null

Framework: MITRE ATT&CKTM