Potential PowerShell Obfuscation via Character Array Reconstruction

edit
IMPORTANT: This documentation is no longer updated. Refer to Elastic's version policy and the latest documentation.

Potential PowerShell Obfuscation via Character Array Reconstruction

edit

Identifies PowerShell scripts that use character arrays and runtime string reconstruction as a form of obfuscation. This technique breaks strings into individual characters, often using constructs like char[] with index-based access or joining logic. 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
  • Resources: Investigation Guide

Version: 3

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 Character Array Reconstruction

PowerShell, a powerful scripting language, is often targeted by adversaries for obfuscation to bypass security measures. By reconstructing strings from character arrays, attackers evade static analysis and detection. The detection rule identifies scripts using such obfuscation by searching for patterns indicative of character array manipulation, thus flagging potential threats for further investigation.

Possible investigation steps

  • Review the powershell.file.script_block_text field to understand the content and intent of the script, focusing on the obfuscated parts indicated by the presence of the "char" keyword and the 🔥 character.
  • Examine the file.path and host.name fields to determine the origin and location of the script execution, which can provide context about the environment and potential risk.
  • Check the user.id and agent.id fields to identify the user and agent responsible for executing the script, which can help assess whether the activity is expected or suspicious.
  • Analyze the powershell.file.script_block_id and powershell.sequence fields to trace the execution sequence and correlate it with other related script blocks, providing a broader view of the script’s behavior.
  • Investigate the count field to assess the extent of obfuscation, as a higher count may indicate more complex or extensive obfuscation techniques being used.

False positive analysis

  • Scripts used for legitimate administrative tasks may use character arrays for performance optimization or to handle special characters. Review the script’s purpose and context to determine if it aligns with known administrative functions.
  • PowerShell scripts from trusted sources or vendors might use character arrays for legitimate obfuscation to protect intellectual property. Verify the script’s origin and check for digital signatures or hashes to confirm authenticity.
  • Automated scripts generated by development tools or frameworks could include character array manipulation as part of their standard output. Identify and whitelist these tools if they are commonly used in your environment.
  • Security tools or monitoring solutions might use character arrays in their scripts for legitimate purposes. Cross-reference with known security software and consider excluding these from the detection rule if they are verified as safe.
  • Regularly update the exclusion list to include new trusted scripts or tools as they are introduced into the environment, ensuring that legitimate activities are not flagged as false positives.

Response and remediation

  • Isolate the affected host immediately to prevent further spread of potentially malicious scripts or unauthorized access.
  • Terminate any suspicious PowerShell processes identified by the alert to halt ongoing obfuscation activities.
  • Conduct a thorough review of the script block text and associated logs to identify any malicious payloads or commands executed.
  • Remove any identified malicious scripts or files from the affected system to prevent re-execution.
  • Reset credentials for any user accounts involved in the alert to mitigate potential credential compromise.
  • Update endpoint protection and ensure that AMSI and other security features are fully enabled and configured to detect similar threats.
  • Escalate the incident to the security operations center (SOC) for further analysis and to determine if additional systems are affected.

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"

// Filter for scripts that contain the "char" keyword using MATCH, boosts the query performance
| where powershell.file.script_block_text : "char"

// 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,
    """(char\[\]\]\(\d+,\d+[^)]+|(\s?\(\[char\]\d+\s?\)\+){2,})""",
    "🔥"
)

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

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

Framework: MITRE ATT&CKTM