PowerShell - Detecting Attacks

PowerShell is a powerful tool for system administration — but it's also a favorite target for attackers. Its deep integration with Windows allows adversaries to execute commands, exfiltrate data, and persist in the environment without triggering traditional antivirus systems.

In this article, we'll explore how to detect PowerShell-based attacks, why it's essential, and best practices for securing and monitoring PowerShell activity. Code examples are provided to help you start building detection and defense scripts.


Why Detect PowerShell Attacks

Attackers often abuse PowerShell for:

  • Living off the land — using built-in tools to avoid detection.
  • Fileless attacks — running code in memory to evade antivirus.
  • Credential harvesting — extracting secrets from memory or system files.
  • Command-and-control — downloading and executing payloads remotely.

Because PowerShell is a legitimate tool, security controls must distinguish authorized administration from malicious usage. That's where monitoring, logging, and detection logic become essential.


Enabling Logging for Detection

1. PowerShell Script Block Logging

This captures all commands and code blocks executed in PowerShell sessions — even obfuscated or dynamically generated ones.

# Enable Script Block Logging
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" `
  -Name "EnableScriptBlockLogging" -Value 1 -Force

2. Module and Transcription Logging

Transcription records full session transcripts and module logging tracks which PowerShell modules are loaded.

# Enable Module Logging
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging" `
  -Name "EnableModuleLogging" -Value 1 -Force
 
# Enable Transcription
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription" `
  -Name "EnableTranscripting" -Value 1 -Force

After enabling these, monitor logs in:

Event Viewer → Applications and Services Logs → Microsoft → Windows → PowerShell → Operational

Detecting Suspicious Activity with PowerShell

Example 1: Detect Base64-Encoded Commands

Attackers often use Base64-encoded payloads to hide commands. You can scan the event logs for suspicious patterns:

Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" |
  Where-Object { $_.Message -match "Base64" -or $_.Message -match "frombase64string" } |
  Select-Object TimeCreated, Id, Message

Example 2: Detect Downloads from the Internet

Look for use of Invoke-WebRequest, Invoke-Expression, or DownloadString—these are common in malware staging.

Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" |
  Where-Object { $_.Message -match "Invoke-WebRequest|Invoke-Expression|DownloadString" } |
  Select-Object TimeCreated, Id, Message

Example 3: Alert on Suspicious Encoded Command Line

Monitor command-line executions for suspicious PowerShell launches:

Get-WinEvent -LogName "Security" -FilterXPath "*[EventData[@Name='CommandLine']]" |
  Where-Object { $_.Message -match "powershell.exe" -and $_.Message -match "-enc" } |
  Select-Object TimeCreated, Message

Best Practices for PowerShell Attack Detection

  1. Restrict PowerShell usage

    • Use Constrained Language Mode for non-admin users:

      $ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"
    • Disable older PowerShell versions (v2) which lack logging.

  2. Centralize logs

    • Forward PowerShell logs to a SIEM (like Splunk, Sentinel, or ELK).
    • Correlate events across systems for anomaly detection.
  3. Monitor administrative activity

    • Detect new PowerShell remoting sessions and credential-related modules like Mimikatz.
  4. Use AMSI (Antimalware Scan Interface)

    • AMSI scans PowerShell content before execution; ensure it's not disabled.

      Get-ItemProperty "HKLM:\Software\Microsoft\AMSI" -ErrorAction SilentlyContinue
  5. Alert on known offensive tools

    • Watch for patterns or signatures of PowerShell Empire, Covenant, or Metasploit.
  6. Baseline normal usage

    • Identify what legitimate PowerShell activity looks like in your environment.
    • Use deviations from the baseline to trigger alerts.

Example: Automated Monitoring Script

Here's a simplified detection script that continuously checks for suspicious PowerShell usage:

# Monitor PowerShell logs for suspicious patterns
$suspiciousPatterns = "Invoke-WebRequest|DownloadString|frombase64string|-enc"
 
while ($true) {
    $events = Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" -MaxEvents 50 |
        Where-Object { $_.Message -match $suspiciousPatterns }
 
    foreach ($event in $events) {
        Write-Host "⚠ Suspicious PowerShell activity detected at $($event.TimeCreated)"
        Write-Host $event.Message
    }
 
    Start-Sleep -Seconds 30
}

This script can be enhanced to send alerts via email, Slack, or webhook.


🔐 Tip: Combine PowerShell logging with endpoint detection solutions and continuous security awareness to maintain strong defense posture.


Summary

PowerShell is both a powerful administrative tool and a common attacker weapon. By enabling proper logging, scanning event logs, and enforcing security policies, you can detect and mitigate PowerShell-based threats before they cause harm.

Key takeaways:

  • Enable all PowerShell logging features.
  • Regularly monitor logs for suspicious patterns.
  • Use central SIEM correlation and AMSI protection.
  • Educate administrators on safe PowerShell usage.