EventMonitor/EventProcessors/PowerShellEvents.ps1
|
# ── PowerShell Security Events Processor ────────────────────────────────────── # Monitors PowerShell script block logging for detecting PowerShell-based attacks. # Event ID: 4104 (Script Block Logging) # # Requires: Group Policy > Computer Configuration > Administrative Templates > # Windows Components > Windows PowerShell > Turn on PowerShell Script Block Logging # # Reference: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_logging_windows <# .SYNOPSIS Collects PowerShell script block execution events within the time window. .DESCRIPTION Event 4104 captures the actual PowerShell code being executed, which is critical for detecting obfuscated attacks, fileless malware, and living-off-the-land techniques. Only logs scripts flagged as suspicious by the PowerShell engine (ScriptBlockLogging level 'Warning') to reduce noise, unless all script block logging is desired. #> function Get-PowerShellEvents { [CmdletBinding()] param( [Parameter(Mandatory)] [string]$sessionId, [Parameter(Mandatory)] [DateTime]$StartTime ) try { $events = Read-WindowsEvents -EventId 4104 -LogName 'Microsoft-Windows-PowerShell/Operational' -StartTime $StartTime foreach ($evt in $events) { # Properties: [0]MessageNumber [1]MessageTotal [2]ScriptBlockText [3]ScriptBlockId [4]Path $props = New-EventProperties -SessionId $sessionId -EventType 'Alert' -Severity 'Medium' $props['ScriptBlockId'] = "$($evt.Properties[3].Value)" $props['ScriptPath'] = "$($evt.Properties[4].Value)" $props['MessageNumber'] = "$($evt.Properties[0].Value)" $props['MessageTotal'] = "$($evt.Properties[1].Value)" # Script block text can be very large — truncate for telemetry $scriptText = "$($evt.Properties[2].Value)" if ($scriptText.Length -gt 4000) { $scriptText = $scriptText.Substring(0, 4000) + '...[truncated]' } $props['ScriptBlockText'] = $scriptText Send-LogAnalyticsConnectEvents ` -eventName '4104 PowerShell Script Block' -Properties $props -sendEvent $evt } } catch { Write-EMLog -Message "Get-PowerShellEvents: $($_.Exception.Message)" -Level Error TrackException -ErrorRecord $_ ` -Properties (New-ErrorProperties -SessionId $sessionId -FunctionName 'Get-PowerShellEvents') } } |