Encoded PowerShell Command Execution
This query identifies PowerShell and pwsh executions that pass a Base64-encoded command via -EncodedCommand (or any of its accepted prefixes such as -e, -ec, -enc), decodes the payload inline and enriches the result with the executing user. Encoded commands are a common obfuscation technique used by malware loaders, offensive frameworks and living-off-the-land attacks.
#event_simpleName=ProcessRollup2 ImageFileName=/\\(powershell|pwsh)\.exe$/i
| replace("\\^", with="", field=CommandLine, as=cmd)
| cmd=/\s[-\/]e(c|nc?[a-z]*)?\s+(?<b64>[A-Za-z0-9+\/=]{16,})/i
| decoded := base64Decode(b64, charset="UTF-16LE")
| join({#event_simpleName=UserIdentity}, field=[aid, AuthenticationId], include=[UserName], mode=left)
| table([aid, UserName, ParentImageFileName, ImageFileName, CommandLine, decoded])This query uses CrowdStrike Query Language (CQL) to detect and decode encoded PowerShell commands:
-
Event Filtering:
#event_simpleName=ProcessRollup2 ImageFileName=/\\(powershell|pwsh)\.exe$/i- Searches ProcessRollup2 events for Windows PowerShell (powershell.exe) and PowerShell 7 (pwsh.exe), case-insensitive -
Caret Normalisation:
replace("\\^", with="", field=CommandLine, as=cmd)- Removescmd.execaret escapes (e.g.-e^n^c) into a working copycmd, so obfuscated parameter names are matched without listing every caret position in the regex. The originalCommandLineis kept untouched for the output. -
Parameter Matching:
cmd=/\s[-\/]e(c|nc?[a-z]*)?\s+(?<b64>[A-Za-z0-9+\/=]{16,})/i- PowerShell accepts any unambiguous prefix of-EncodedCommand. The pattern matches-e,-ec,-enc,-encoded,-encodedcommandand the/parameter prefix, while excluding-ex/-ep(ExecutionPolicy) - Captures the following Base64 argument into the fieldb64 -
Payload Decoding:
decoded := base64Decode(b64, charset="UTF-16LE")- PowerShell encodes commands as UTF-16LE. Decoding inline saves the round trip to an external tool during triage -
User Context:
join({#event_simpleName=UserIdentity}, field=[aid, AuthenticationId], include=[UserName], mode=left)- Enriches results with the executing user. The key is[aid, AuthenticationId]because logon IDs are only unique per host.mode=leftkeeps hits even when no matching UserIdentity event exists in the search window -
Output:
table([aid, UserName, ParentImageFileName, ImageFileName, CommandLine, decoded])- Displays the parent process, the original command line and the decoded payload for analysis
