The best way to learn Sigma is to write a rule from scratch for a real technique. This lesson walks through the complete process: from ATT&CK technique → detection requirement → Sigma rule → conversion → validation.
Technique: T1059.001 — Command and Scripting Interpreter: PowerShell
Specific behavior: Encoded command execution via -EncodedCommand (or abbreviations)
Step 1: Understand the Technique
From ATT&CK T1059.001:
- PowerShell can execute code passed as a Base64-encoded string via
-EncodedCommand(or-ec,-en,-e) - Adversaries use this to obfuscate their commands and bypass simple string-matching rules
- The encoded command is decoded by PowerShell before execution
What we want to detect: PowerShell launched with an encoded command flag, indicating likely obfuscation attempt.
What we DON’T want to detect: Legitimate PowerShell scripts that happen to use encoded commands (some admin tools do this).
Step 2: Identify the Data Source
ATT&CK T1059.001 data sources:
- Process: Process Creation → Sysmon Event 1 or Windows 4688 with CommandLine
- Script: Script Execution → PowerShell Event 4104 (Script Block Logging)
Choice: Use process creation — wider deployment, catches the invocation even if ScriptBlock logging is disabled.
Logsource in Sigma:
logsource:
category: process_creation
product: windows
Step 3: Write the Selection Block
The attacker runs something like:
powershell.exe -NoP -sta -NonI -W Hidden -Enc SGVsbG8gV29ybGQ=
The discriminating field: Image ends with powershell.exe AND CommandLine contains an encoding flag.
detection:
selection_img:
Image|endswith:
- '\powershell.exe'
- '\pwsh.exe' # PowerShell 7
selection_encoded:
CommandLine|contains:
- ' -enc '
- ' -EncodedCommand '
- ' -e '
Wait — -e is a partial match. Remove-Item -e would match. Use more specific patterns:
selection_encoded:
CommandLine|contains:
- ' -enc '
- ' -EncodedCommand '
- ' -enco '
- '/e ' # slash variant
- '/enc '
- '/EncodedCommand '
Still imperfect — -e followed by anything matches. Better: require that after -e there’s a base64-looking string. But regex in Sigma can be fragile. Let’s stick with the common variants and document the limitation.
Step 4: Add a False Positive Filter
Legitimate use cases:
- Microsoft Endpoint Configuration Manager (SCCM) uses encoded PowerShell during client deployment
- Some remote management tools send encoded commands to ensure safe transport
- Chocolatey (Windows package manager) uses encoded commands in its scripts
filter_legitimate:
ParentImage|contains:
- '\ccmexec.exe' # SCCM client
- '\ccmsetup.exe' # SCCM setup
CommandLine|contains:
- 'chocolatey'
Condition: selection_img and selection_encoded and not filter_legitimate
Step 5: Write the Complete Rule
title: PowerShell Encoded Command Execution
id: 8ef91d92-abad-4a3e-8e74-7e0a5e9f0e31
status: test
description: Detects PowerShell launched with an encoded command argument, often used to obfuscate malicious payloads
references:
- https://attack.mitre.org/techniques/T1059/001/
- https://ss64.com/ps/powershell.html
author: TDL Detection Team
date: 2024/03/15
modified: 2024/03/15
tags:
- attack.execution
- attack.t1059.001
- attack.defense_evasion
- attack.t1027
logsource:
category: process_creation
product: windows
detection:
selection_img:
Image|endswith:
- '\powershell.exe'
- '\pwsh.exe'
selection_encoded:
CommandLine|contains:
- ' -enc '
- ' -EncodedCommand '
- ' -enco '
- ' /enc '
- ' /EncodedCommand '
filter_sccm:
ParentImage|contains:
- '\ccmexec.exe'
- '\ccmsetup.exe'
condition: (selection_img and selection_encoded) and not filter_sccm
falsepositives:
- SCCM/ConfigMgr client (filtered)
- Some legitimate administrative scripts using encoded commands for safe transport
- Remote management tools (Ansible, Puppet) that use encoded commands
level: medium
fields:
- Image
- CommandLine
- ParentImage
- User
- ComputerName
Step 6: Convert and Test
# Convert to Elastic ECS
sigma convert -t elasticsearch -p ecs-windows \
powershell-encoded-command.yml
# Output:
# (process.executable:(*\\powershell.exe OR *\\pwsh.exe) AND process.command_line:(*\ \-enc\ * OR *\ \-EncodedCommand\ * OR *\ \-enco\ * OR *\ \/enc\ * OR *\ \/EncodedCommand\ *)) AND NOT (process.parent.executable:(*\\ccmexec.exe* OR *\\ccmsetup.exe*))
# Convert to SPL
sigma convert -t splunk -p sysmon \
powershell-encoded-command.yml
# Output:
# (Image IN ("*\powershell.exe","*\pwsh.exe") (CommandLine="* -enc *" OR CommandLine="* -EncodedCommand *" OR CommandLine="* -enco *" OR CommandLine="* /enc *" OR CommandLine="* /EncodedCommand *")) NOT (ParentImage IN ("*\ccmexec.exe*","*\ccmsetup.exe*"))
Validation test:
# Generate a test command that should trigger the rule
$encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes('Write-Host "test"'))
powershell.exe -EncodedCommand $encoded
Verify the alert fires. Then verify it doesn’t fire for:
# Non-encoded PowerShell (should NOT alert)
powershell.exe -Command "Write-Host 'hello'"
Sigma rule: PowerShell Encoded Command— SigmaHQ
EVTX-ATTACK-SAMPLES— GitHub