Engineer a PowerShell Detection

Build and validate Sigma detections for encoded PowerShell using Event 4688.

Introduction

30 Second Summary

Security teams can face countless alerts during a shift. A noisy rule buries meaningful activity beneath routine work.

In this project, you will build a behavioral detection for encoded Windows PowerShell commands. You will test the rule against Windows Event 4688 telemetry before analyzing the evidence with Chainsaw.

What You'll Build

Your finished lab shows a tuned Sigma rule catching the encoded PowerShell test while ordinary PowerShell activity stays out of the results.

By the end of this project, you'll have:

  • A reproducible test lab where you generate ordinary PowerShell activity plus Base64-encoded PowerShell activity using only the harmless Get-Date command.
  • A clear noise comparison showing the broad rule matching routine activity while the tuned rule keeps its focus on encoded commands.
  • An analyst-ready detection package with reproducible tests plus triage guidance plus false-positive analysis plus documented limitations plus a MITRE ATT&CK mapping.
  • Secret Mission: extend the same test-and-tune workflow to detect hidden-window PowerShell execution.

Are there any prerequisites?

You need a Windows 10 or Windows 11 computer with local administrator access. You also need permission to change local audit policy.

The test runs only Get-Date. You do not need malware or offensive tools.

Before We Start

Before the hands-on work begins, lock in the behavior you are investigating. You are detecting Windows PowerShell execution that uses -EncodedCommand because encoding can obscure execution intent from a SOC analyst.

Set Up Telemetry and Chainsaw

A detection only works when its required telemetry exists. You need to prove that Windows records process command lines before you build a rule around them.

In this step, you will prepare Windows PowerShell for the lab. You will enable command-line data in Security Event 4688. You will also install Chainsaw so you can analyze the evidence later.

In this step, get ready to:
  • Create the local detection lab workspace.
  • Enable process-creation auditing with command-line capture.
  • Install Chainsaw 2.16.5 with its pinned event-log mapping.
Prepare the local workspace

Your lab needs one predictable location for scripts, rules, exported logs, results, and tools. An elevated PowerShell session also gives you the permissions required to change the local audit settings.

  • Press the Windows key to open Windows search.
  • Type Windows PowerShell into the search box.
  • Right-click the Windows PowerShell search result.
  • Select Run as administrator.
  • Approve the Windows permission prompt.

The elevated window gives the audit-policy commands permission to change system settings.

  • Verify the prescribed Windows PowerShell environment by running this command:
powershell.exe -NoProfile

What does this command do?

  • The command starts a child Windows PowerShell session.
  • The -NoProfile parameter skips profile scripts that could change the test environment.

You should see a fresh PowerShell prompt in the same window. This confirms that the Windows PowerShell executable is available.

  • Verify the prescribed text editor by running this command:
notepad.exe

What does this command prove?

The command starts Windows Notepad. You will use this built-in editor for the project files.

  • Close Windows Notepad after its empty document opens.
  • Press Windows logo key+E to open File Explorer.
  • Enter C:\ in the File Explorer address bar.
  • Select New from the File Explorer toolbar.
  • Select Folder.
  • Name the new folder DetectionLab.
  • Open C:\DetectionLab.

The rest of the project stays inside C:\DetectionLab. This keeps your evidence separate from unrelated files.

  • Create scripts inside C:\DetectionLab with the same folder control.
  • Create rules inside C:\DetectionLab.
  • Create logs inside C:\DetectionLab.
  • Create results inside C:\DetectionLab.
  • Create tools inside C:\DetectionLab.

You should now see five folders inside C:\DetectionLab.

  • Create naive inside C:\DetectionLab\rules.
  • Create tuned inside C:\DetectionLab\rules.
  • Create stretch inside C:\DetectionLab\rules.
  • Create chainsaw inside C:\DetectionLab\tools.

Why separate these folders?

The naive folder holds the deliberately broad rule. The tuned folder holds the refined rule.

The stretch folder is reserved for the optional challenge. The logs folder keeps raw evidence separate from detection results.

Your workspace is ready. File Explorer should show the complete folder structure without any rule or script files yet.

Enable process command-line telemetry

Security Event 4688 records successful process creation. The detection needs its Process Command Line field because the PowerShell parameter appears there.

Why enable two settings?

Process Creation auditing generates Event 4688 records. Command-line capture fills those records with the arguments used to start each process.

Both settings must be active for the later Sigma rule to inspect PowerShell parameters.

  • Return to the elevated Windows PowerShell session from earlier.
  • Enable successful Process Creation auditing by running this command:
Auditpol.exe /set /subcategory:{0CCE922B-69AE-11D9-BED3-505054503030} /success:enable

What does this command change?

The subcategory GUID identifies Process Creation independently of the Windows display language. Success auditing tells Windows to record processes that start successfully.

You should see confirmation that the audit-policy change completed.

Command-line capture is useful, but it deserves care. Future command-line arguments can be recorded in plain text.

  • Keep passwords and secrets out of commands while command-line capture is enabled.
  • Enable the Event 4688 command-line field by running this command:
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v "ProcessCreationIncludeCmdLine_Enabled" /t REG_DWORD /d 1 /f

What does this registry value control?

  • The ProcessCreationIncludeCmdLine_Enabled value controls whether process arguments are added to Event 4688.
  • The REG_DWORD data value 1 enables that collection.

You should see confirmation that the registry value was added or updated.

  • Generate a harmless process-creation event by running this command:
powershell.exe -NoProfile -Command "Get-Date"

What does this test generate?

The command starts a child Windows PowerShell process that only displays the current date. Windows should record the executable plus its arguments in Event 4688.

You should see the current date in the terminal. That output confirms the harmless child process completed.

Before you query the Security log, do you expect the new event to include the full command line or only the process name?

  • Inspect the five newest Event 4688 records by running this command:
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4688} -MaxEvents 5 | Format-List TimeCreated,Id,Message

What does this query show?

  • The filter reads Event 4688 records from the Windows Security log.
  • The result includes the timestamp and the full event message for each recent process.
  • The message exposes the Process Command Line field needed by your detection.

You should find a recent Event 4688 for the harmless date test. Its Process Command Line field should be populated.

Missing the command line?

  • Confirm that you ran both configuration commands from the elevated Windows PowerShell session.
  • Run the harmless date test again so its event appears among the five newest records.
  • Check the event message for the Process Command Line field.

Still stuck? Help me diagnose why Process Command Line is empty in my Windows Security Event 4688 records.

Install Chainsaw and verify the lab

Chainsaw reads Windows event-log evidence and applies Sigma rules without a separate server. This lab pins the executable plus its mapping to the same release so the analysis stays reproducible.

Why Chainsaw for this lab?

A full SIEM requires ingestion and indexing before you can test a rule. Chainsaw hunts the local EVTX evidence directly.

That shorter loop keeps your attention on telemetry quality and detection logic.

First, check the project-owned executable path. A missing-file result is expected when Chainsaw has not been installed before.

  • Check the Chainsaw version at the required path by running this command:
C:\DetectionLab\tools\chainsaw\chainsaw.exe --version

How should I use this result?

The result tells you whether the pinned executable is already present. Choose the tab that matches what your terminal shows.

✔️ I see version 2.16.5

Good result. The required Chainsaw executable is already in the project-owned path.

  • Keep C:\DetectionLab\tools\chainsaw\chainsaw.exe in place.
  • Continue below to install the pinned mapping file.

ⓧ I see a different version

The lab uses Chainsaw v2.16.5 with a mapping from the same release. Replace the existing executable so both pieces stay aligned.

  • Open the official Chainsaw release page for v2.16.5.
  • Download chainsaw_x86_64-pc-windows-msvc.zip from the release assets.
  • Open your Downloads folder in File Explorer.
  • Extract the archive with File Explorer's Extract All... control.

The archive may contain more than one item. You only need the executable for this project-owned tools folder.

  • Locate chainsaw.exe inside the extracted contents.
  • Cut chainsaw.exe in File Explorer.
  • Navigate to C:\DetectionLab\tools\chainsaw.
  • Paste the executable into the folder.
  • Approve the replacement of the existing executable.

ⓧ Command not found

The project-owned executable has not been installed yet. Download the pinned Windows archive from the official repository.

  • Open the official Chainsaw release page for v2.16.5.
  • Download chainsaw_x86_64-pc-windows-msvc.zip from the release assets.
  • Open your Downloads folder in File Explorer.
  • Extract the archive with File Explorer's Extract All... control.

The extracted folder contains the executable that performs the local event-log hunts.

  • Locate chainsaw.exe inside the extracted contents.
  • Cut chainsaw.exe in File Explorer.
  • Navigate to C:\DetectionLab\tools\chainsaw.
  • Paste the executable into the folder.

Did endpoint protection flag the download?

Endpoint protection may flag Chainsaw because forensic tools and bundled detection content can trigger heuristic scanning. Keep endpoint protection enabled.

  • Verify that the archive came from the official release page linked above.
  • Verify that the mapping comes from the official pinned repository link below.

Need help reviewing the warning? Help me assess a Microsoft Defender warning for the official Chainsaw v2.16.5 download without disabling endpoint protection globally.

Chainsaw also needs a mapping that connects Sigma fields such as CommandLine to the fields inside Windows event records.

  • Create mappings inside C:\DetectionLab\tools\chainsaw with File Explorer.
  • Open the pinned Chainsaw mapping file in your browser.
  • Use your browser's page-saving control to save the file as C:\DetectionLab\tools\chainsaw\mappings\sigma-event-logs-all.yml.
  • Confirm that sigma-event-logs-all.yml appears inside the mappings folder in File Explorer.

The executable and mapping now come from the same pinned release. Your later hunts can interpret Event 4688 fields consistently.

  • Refresh the harmless process event before the final checks by running this command:
powershell.exe -NoProfile -Command "Get-Date"

Why refresh the event?

The fresh child process keeps the relevant Event 4688 near the top of the Security log. This makes the final five-event query easier to inspect.

Before you run the final checks, do you expect all three prerequisites to pass together?

  • Verify the audit policy, recent process telemetry, and Chainsaw version by running these commands:
Auditpol.exe /get /subcategory:{0CCE922B-69AE-11D9-BED3-505054503030}
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4688} -MaxEvents 5 | Format-List TimeCreated,Id,Message
C:\DetectionLab\tools\chainsaw\chainsaw.exe --version

What should these checks prove?

  • The audit-policy check confirms that Success auditing is enabled for Process Creation.
  • The event query shows a recent Event 4688 with a populated Process Command Line field.
  • The Chainsaw version check prints 2.16.5.

That is the foundation in place. Windows is recording the process detail your rules need, and Chainsaw can read the evidence in the next step.

One of the final checks failed?

  • Return to the elevated Windows PowerShell session if the audit or Security-log checks report a permission problem.
  • Confirm that chainsaw.exe is directly inside C:\DetectionLab\tools\chainsaw if the version check cannot start.
  • Confirm that the mapping filename ends in .yml if File Explorer shows an unexpected text-file extension.

Still blocked? Help me diagnose which Windows telemetry or Chainsaw setup check failed.

Your collection and analysis foundation is ready. Next, you will generate controlled PowerShell activity and watch an overbroad detection match too much of it.

Build a Noisy First Detection

Your Windows Security auditing now captures complete process command lines in Event 4688. That evidence proves what Windows PowerShell actually ran.

A rule that matches every PowerShell command recreates alert fatigue. This step lets you experience that noisy baseline before you tune it.

In this step, get ready to:
  • Create a controlled test generator plus an intentionally broad detection rule.
  • Generate ordinary PowerShell activity plus encoded PowerShell activity.
  • Test the naive rule against exported Security log evidence.
Create the controlled test files

A controlled comparison needs one ordinary command plus one encoded command. A Sigma rule gives Chainsaw a portable description of the behavior to find.

  • Switch back to Windows Notepad from earlier.
  • Start a blank document for the test generator.

You should see an empty editing area ready for the script.

  • Use Notepad's save dialog to save the document as C:\DetectionLab\scripts\generate-test-events.ps1.
  • Confirm the document title shows generate-test-events.ps1.
  • Add the ordinary child-process test by pasting this code:
Write-Host 'Generating ordinary PowerShell activity...'
powershell.exe -NoProfile -Command "Get-Date"

What does this first test do?

  • The first line labels the ordinary activity in your PowerShell output.
  • The second line starts a child PowerShell process that runs the harmless Get-Date command.
  • Save C:\DetectionLab\scripts\generate-test-events.ps1.
  • Test the ordinary section from the administrator PowerShell session by running:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\DetectionLab\scripts\generate-test-events.ps1

What does this command prove?

This starts the saved script in a fresh Windows PowerShell process. The temporary Bypass policy lets this controlled script run without changing the system-wide execution policy.

You should see Generating ordinary PowerShell activity... followed by the current date. That output proves the first child process completed safely.

Script not running?

  • Confirm that Notepad saved the file with the .ps1 extension.
  • Check that the file sits inside C:\DetectionLab\scripts.
  • Make sure you are running the command from the administrator PowerShell session.

Still stuck? Help me diagnose why the PowerShell test script does not run.

  • Return to generate-test-events.ps1 in Notepad.
  • Add the encoded child-process test below the ordinary test by pasting:
Write-Host 'Generating encoded PowerShell activity...'
$command = "Get-Date"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
powershell.exe -NoProfile -EncodedCommand $encodedCommand

How is the encoded test created?

  • The $command variable holds the same harmless date command used by the ordinary test.
  • The $bytes variable holds the command as UTF-16LE bytes.
  • The $encodedCommand variable holds the Base64 text accepted by -EncodedCommand.
  • The final line starts a second child process with that encoded command.
  • Save C:\DetectionLab\scripts\generate-test-events.ps1.
  • Return to File Explorer from earlier.
  • Navigate to C:\DetectionLab\scripts.

You should see generate-test-events.ps1 listed in the folder.

✔️ Awesome, I've got everything!

Great. Your generator now contains the ordinary test plus the encoded test.

ⓧ I'd like to double check the full code

Write-Host 'Generating ordinary PowerShell activity...'
powershell.exe -NoProfile -Command "Get-Date"

Write-Host 'Generating encoded PowerShell activity...'
$command = "Get-Date"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
powershell.exe -NoProfile -EncodedCommand $encodedCommand

What should you compare?

Check the order of the ordinary section plus the encoded section. Confirm that the encoded section passes $encodedCommand to the final child process.

  • Switch back to Windows Notepad.
  • Start a blank document for the naive rule.

You should see a fresh editing area separate from the generator script.

  • Use Notepad's save dialog to save the document as C:\DetectionLab\rules\naive\powershell_any.yml.
  • Confirm the document title shows powershell_any.yml.
  • Define the broad PowerShell detection by pasting this rule:
title: Any Windows PowerShell Command Line
id: 0f0c2d86-2bfa-43c8-9c6a-d7e3f5480e19
status: experimental
description: Detects any process creation command line that contains powershell.exe to demonstrate an intentionally noisy baseline.
references:
    - https://attack.mitre.org/techniques/T1059/001/
author: NextWork Learner
date: 2026-09-19
tags:
    - attack.execution
    - attack.t1059.001
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        CommandLine|contains: 'powershell.exe'
    condition: selection
falsepositives:
    - Routine administration, automation, software deployment, and troubleshooting that use Windows PowerShell.
level: low

What does this rule evaluate?

  • The process_creation log source tells Chainsaw to evaluate Windows process-creation events.
  • The CommandLine|contains selection searches each mapped command line for the powershell.exe fragment.
  • The low severity describes a notable result that is rarely an incident by itself.
  • Save C:\DetectionLab\rules\naive\powershell_any.yml.
  • Return to File Explorer.
  • Navigate to C:\DetectionLab\rules\naive.

You should see powershell_any.yml listed beside no extra .txt extension.

✔️ Awesome, I've got everything!

Your naive Sigma rule is saved in the folder that Chainsaw searches in this step.

ⓧ I'd like to double check the full code

title: Any Windows PowerShell Command Line
id: 0f0c2d86-2bfa-43c8-9c6a-d7e3f5480e19
status: experimental
description: Detects any process creation command line that contains powershell.exe to demonstrate an intentionally noisy baseline.
references:
    - https://attack.mitre.org/techniques/T1059/001/
author: NextWork Learner
date: 2026-09-19
tags:
    - attack.execution
    - attack.t1059.001
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        CommandLine|contains: 'powershell.exe'
    condition: selection
falsepositives:
    - Routine administration, automation, software deployment, and troubleshooting that use Windows PowerShell.
level: low

What should you compare?

Check the YAML indentation beneath logsource plus detection. Confirm that the file ends with level: low.

Rule file missing or misnamed?

  • Confirm that the file is inside C:\DetectionLab\rules\naive.
  • Remove any hidden .txt extension from the filename.
  • Match the four-space indentation shown beneath each nested YAML key.

Need help? Help me compare my naive Sigma rule with the expected YAML structure.

Generate and export the evidence

The generator creates a known comparison pair using the same harmless command. The only meaningful difference is how each child process receives that command.

Before you run the generator, predict whether it will display one date or two.

  • Run the complete generator from the administrator PowerShell session with this command:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\DetectionLab\scripts\generate-test-events.ps1

What happens during this run?

The script starts one ordinary child process. It then starts one encoded child process using the Base64 value built from the same Get-Date command.

You should first see Generating ordinary PowerShell activity... followed by a date. You should then see Generating encoded PowerShell activity... followed by another date.

Both harmless child processes completed successfully. Their process-creation events now give the rule two behaviors to evaluate.

Only seeing one date?

  • Confirm that the encoded section appears beneath the ordinary section in generate-test-events.ps1.
  • Check that $encodedCommand uses the same capitalization in its assignment plus its final command.
  • Compare each bracket plus parenthesis with the complete script.

Still stuck? Help me find why the encoded PowerShell child process does not display a date.

An EVTX export freezes the current Security log evidence into one local file. Both rule versions can later analyze that same evidence.

  • Export the Security log to the lab by running this command:
wevtutil epl Security C:\DetectionLab\logs\security.evtx /ow:true

What does this export do?

The command copies the local Security channel into security.evtx. The /ow:true option replaces an older export at that path.

  • Return to File Explorer.
  • Navigate to C:\DetectionLab\logs.

You should see security.evtx in the folder. That file contains the process events created by your tests.

EVTX file not appearing?

  • Confirm that your PowerShell window still has administrator access.
  • Check that C:\DetectionLab\logs exists.
  • Run the export command again after closing any program that has locked the existing file.

Need help? Help me diagnose why the Security log export was not created.

Hunt the noisy baseline

A Chainsaw hunt applies the naive rule to every mapped process-creation event in the exported evidence. This is the moment that tests whether one executable-name fragment provides enough context.

Before you run the hunt, predict how selective a rule with one command-line fragment will be.

  • Run the naive Chainsaw hunt against the exported Security log with this command:
C:\DetectionLab\tools\chainsaw\chainsaw.exe hunt C:\DetectionLab\logs\security.evtx -s C:\DetectionLab\rules\naive --mapping C:\DetectionLab\tools\chainsaw\mappings\sigma-event-logs-all.yml --metadata

What does this hunt combine?

  • The EVTX path supplies the evidence collected from the Security log.
  • The -s path supplies the naive Sigma rule.
  • The --mapping path connects Sigma's process fields to Windows event fields.
  • The --metadata flag includes additional rule details in the hunt output.

The results include the encoded child process. They also include ordinary PowerShell activity.

You have proved the important failure in the first design. The rule recognizes PowerShell usage without distinguishing the behavior that deserves investigation.

  • Compare the command lines shown in the matching results.
  • Locate the match created by the ordinary child process.
  • Locate the match created by the encoded child process.

Both tests appear under the same low-severity rule. That visible overlap is the noisy baseline you need before tuning.

No matches in the hunt?

  • Confirm that both dates appeared before you exported the Security log.
  • Check that security.evtx was exported after the generator ran.
  • Confirm that the rule file remains inside C:\DetectionLab\rules\naive.

Still no matches? Help me trace why Chainsaw does not match my PowerShell test events.

Your baseline now proves that executable-name matching alone creates noise. Next, you will narrow the behavior while preserving the encoded test match.

Tune and Validate the Behavior

Your broad Sigma rule caught the encoded test. It also caught routine Windows PowerShell activity.

That noisy baseline recreates alert fatigue. You will tune the rule against the same EVTX evidence so Chainsaw can isolate the encoded behavior.

In this step, get ready to:
  • Create a tuned Sigma rule that requires the executable fragment plus the encoded-command fragment.
  • Run the tuned Chainsaw hunt against the existing EVTX evidence.
  • Inspect the raw event context for triage details.
Create the tuned rule

A behavioral rule becomes more useful when its conditions describe the behavior under review. This version requires the PowerShell executable plus the encoded-command parameter.

Using the same evidence keeps the comparison fair. Only the rule logic changes.

  • Press the Windows key to open Windows search.
  • Enter Notepad in the search field.
  • Press Enter to open Windows Notepad.
  • Create a blank document from Notepad's file menu.
  • Paste the tuned rule into the blank document:
title: Encoded Windows PowerShell Command
id: c5d0f5dc-3b19-4c51-a862-47a2e4a9f8f2
status: experimental
description: Detects Windows PowerShell process creation with the EncodedCommand parameter.
references:
    - https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe
    - https://attack.mitre.org/techniques/T1059/001/
author: NextWork Learner
date: 2026-09-19
tags:
    - attack.execution
    - attack.t1059.001
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        CommandLine|contains|all:
            - 'powershell.exe'
            - '-EncodedCommand'
    condition: selection
falsepositives:
    - Legitimate administration or software deployment that submits Base64-encoded PowerShell commands.
level: medium

What does this rule change?

  • The CommandLine|contains|all selection requires every listed fragment. A match must include the executable identity plus the encoded behavior.
  • The two tags connect the detection to MITRE ATT&CK technique T1059.001.
  • The level: medium value marks the result for more frequent manual review than the level: low baseline.
  • The false-positive note preserves legitimate administration as a possible explanation.
  • Use Notepad's save control to enter C:\DetectionLab\rules\tuned\encoded_powershell.yml as the file name.
  • Choose the file-type option that preserves the .yml extension.
  • Complete the save.
  • Confirm Notepad's title bar shows encoded_powershell.yml.
  • Compare CommandLine|contains|all with the naive rule's CommandLine|contains selection.
  • Compare level: medium with the naive rule's level: low value.

Tuned rule saved with the wrong format?

  • If the title bar ends with .txt, save the file again with a file-type option that preserves the .yml extension.
  • If the indentation shifted during pasting, replace the document with the complete reference below.

Still stuck? Help me check why my tuned Sigma rule is not saving as a YAML file.

✔️ Awesome, I've got everything!

Your tuned file now requires the PowerShell executable fragment plus the encoded-command fragment.

ⓧ I'd like to double check the full code

The current cumulative project files are shown below for comparison.

Write-Host 'Generating ordinary PowerShell activity...'
powershell.exe -NoProfile -Command "Get-Date"

Write-Host 'Generating encoded PowerShell activity...'
$command = "Get-Date"
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
powershell.exe -NoProfile -EncodedCommand $encodedCommand
title: Any Windows PowerShell Command Line
id: 0f0c2d86-2bfa-43c8-9c6a-d7e3f5480e19
status: experimental
description: Detects any process creation command line that contains powershell.exe to demonstrate an intentionally noisy baseline.
references:
    - https://attack.mitre.org/techniques/T1059/001/
author: NextWork Learner
date: 2026-09-19
tags:
    - attack.execution
    - attack.t1059.001
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        CommandLine|contains: 'powershell.exe'
    condition: selection
falsepositives:
    - Routine administration, automation, software deployment, and troubleshooting that use Windows PowerShell.
level: low
title: Encoded Windows PowerShell Command
id: c5d0f5dc-3b19-4c51-a862-47a2e4a9f8f2
status: experimental
description: Detects Windows PowerShell process creation with the EncodedCommand parameter.
references:
    - https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe
    - https://attack.mitre.org/techniques/T1059/001/
author: NextWork Learner
date: 2026-09-19
tags:
    - attack.execution
    - attack.t1059.001
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        CommandLine|contains|all:
            - 'powershell.exe'
            - '-EncodedCommand'
    condition: selection
falsepositives:
    - Legitimate administration or software deployment that submits Base64-encoded PowerShell commands.
level: medium

Extra for Experts: How Does All Change Matching?

Sigma list values normally behave as alternatives. The all modifier makes every value mandatory for this field.

Measure the tuning result

A saved rule still needs evidence-based validation. The tuned hunt tests the new conditions against the exported Security log from earlier.

  • Switch back to the elevated Windows PowerShell session from earlier.

Before you run the hunt, do you expect one focused match pattern or the same broad result set from the naive rule?

  • Apply the tuned rule to the existing evidence by running this command:
C:\DetectionLab\tools\chainsaw\chainsaw.exe hunt C:\DetectionLab\logs\security.evtx -s C:\DetectionLab\rules\tuned --mapping C:\DetectionLab\tools\chainsaw\mappings\sigma-event-logs-all.yml --metadata

What does this hunt test?

  • The hunt command applies the Sigma rule in the tuned folder to the existing Security log export.
  • The --mapping option connects Sigma's process-creation fields to Windows Event 4688 data.
  • The --metadata option includes additional rule details in the result.
  • Compare every returned command line with the two controlled child commands.
  • Record a pass only if the encoded test appears while the ordinary child command is absent.

You should see the encoded child process in the results. The ordinary powershell.exe -NoProfile -Command "Get-Date" child process should be absent.

That is the tuning win: your rule now isolates the behavior that deserves review.

Tuned hunt missing the expected match?

  • Confirm the tuned rule is saved at C:\DetectionLab\rules\tuned\encoded_powershell.yml.
  • Confirm the selection uses CommandLine|contains|all with separate powershell.exe and -EncodedCommand values.
  • Confirm the hunt points to the existing C:\DetectionLab\logs\security.evtx evidence.

Still stuck? Help me diagnose why my tuned Chainsaw hunt is missing the encoded PowerShell event.

Connect the match to triage

A detection result becomes analyst-ready when it points back to source telemetry. Raw Windows Security Event 4688 context gives the match investigative meaning.

The command line shows the behavior under review. The other event fields show who launched it plus when it happened.

Before you search, which event details do you expect to be visible behind the alert?

  • Search the raw evidence for the encoded-command parameter by running this command:
C:\DetectionLab\tools\chainsaw\chainsaw.exe search EncodedCommand -i C:\DetectionLab\logs\security.evtx

What does this search reveal?

  • The search command looks for EncodedCommand inside the raw EVTX evidence.
  • The -i option makes the string search case-insensitive.
  • The result exposes the event data behind the tuned Sigma match.
  • Find the result whose Process Command Line contains powershell.exe.
  • Confirm the same Process Command Line contains -EncodedCommand.
  • Identify the account associated with the process event.
  • Identify the parent process that launched PowerShell.
  • Identify the timestamp attached to the process event.

The matching raw record should show a populated Process Command Line containing powershell.exe plus -EncodedCommand.

You should also see an account plus a parent process. The timestamp anchors the activity in time.

You have now traced a tuned alert back to the exact process event that created it.

Raw search missing the encoded event?

  • Confirm the search points to C:\DetectionLab\logs\security.evtx.
  • Confirm the search term is exactly EncodedCommand.
  • Confirm the exported evidence is the same file that produced the tuned hunt result.

Still stuck? Help me find the encoded PowerShell event in my exported EVTX evidence.

Your tuned rule now separates encoded PowerShell from the ordinary test. Next up, you will package the evidence plus triage guidance into an analyst-ready project.

Package an Analyst-Ready Detection

Your tuned Sigma rule now separates the encoded test from ordinary Windows PowerShell activity. Another analyst still needs enough context to reproduce the result.

An analyst-ready package gives that analyst a reproducible path. It states the evidence requirements up front.

It also records the triage path. Its limitations keep a behavioral lead from becoming an unsupported verdict.

In this step, get ready to:
  • Create README.md as the analyst handoff.
  • Capture sanitized validation evidence from both hunts.
  • Rerun the workflow to confirm the tuned rule's result.
Create the analyst README

Your README connects the behavior to MITRE ATT&CK T1059.001. It also names Security Event 4688 as the telemetry source.

The test matrix keeps the broad result beside the tuned result. This makes the reduction in noise visible.

  • Press the Windows key to open the Windows search bar.
  • Type Windows Notepad into the search bar.
  • Select Windows Notepad from the search results.
  • Use Notepad's save control to save the blank document as C:\DetectionLab\README.md.
  • Paste the detection hypothesis, telemetry requirements, and test matrix into C:\DetectionLab\README.md using this block:
# Windows PowerShell Detection Engineering Lab

## Detection hypothesis

Encoded PowerShell deserves analyst review because adversaries may abuse PowerShell for execution and ATT&CK documents encoded PowerShell use under T1059.001. Encoding is not proof of malicious intent, so this rule is a behavioral lead rather than a verdict.

## Telemetry

- Source: Windows Security log
- Event: 4688, A new process has been created
- Required field: Process Command Line
- Test tool: Chainsaw 2.16.5 with its pinned `sigma-event-logs-all.yml` mapping
- Rule format: Sigma specification 2.1.0

## Test matrix

| Test activity | Naive rule | Tuned rule |
| --- | --- | --- |
| `powershell.exe -NoProfile -Command "Get-Date"` | Match | No match |
| `powershell.exe -NoProfile -EncodedCommand <UTF-16LE Base64>` | Match | Match |

How does this frame the detection?

  • The hypothesis frames encoded PowerShell as review-worthy behavior without declaring it malicious.
  • The telemetry section names the evidence required for the rule to work.
  • The matrix shows which activity each rule should match.
  • Save C:\DetectionLab\README.md.
  • Scroll to the Test matrix section in Notepad.

You should see that the ordinary command matches only the naive rule. The encoded command matches both rules.

Does the matrix look misaligned?

Confirm that every table row starts and ends with a vertical bar. Keep each test activity on one line.

Still stuck? Help me fix the Markdown table in my detection README.

  • Place the reproduction steps, triage questions, and ATT&CK mapping directly below the test matrix using this block:
## Reproduce

1. Run `powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\DetectionLab\scripts\generate-test-events.ps1`.
2. Run `wevtutil epl Security C:\DetectionLab\logs\security.evtx /ow:true`.
3. Run the naive and tuned Chainsaw hunts documented in the project guide.

## Triage questions

1. Which account created the process?
2. What is the complete command line and what does the encoded content decode to?
3. Which parent process launched PowerShell?
4. Is the activity associated with approved administration or deployment tooling?
5. What happened immediately before and after this process creation?

## ATT&CK mapping

- Tactic: Execution
- Technique: T1059.001, Command and Scripting Interpreter: PowerShell

How does this support an investigation?

  • The reproduction steps turn the test into a repeatable workflow.
  • The triage questions guide the analyst from the alert to its surrounding context.
  • The ATT&CK section maps the behavior to the Execution tactic.
  • Save C:\DetectionLab\README.md.
  • Read each question in the Triage questions section.

You should see prompts covering the account, command line, parent process, approved use, and surrounding activity.

Missing investigation context?

Compare the five numbered questions with the raw event fields you inspected earlier. Each question should point to evidence available during triage.

Need help? Help me check whether my triage questions cover the useful Event 4688 context.

  • Finish C:\DetectionLab\README.md by placing this block below the ATT&CK mapping:
## False positives

Legitimate administrators and software deployment systems may use `-EncodedCommand` to avoid complex quoting. Validate the user, parent process, host role, timing, and decoded command before escalating.

## Limitations

- The rule detects a documented command-line parameter, not malicious intent.
- PowerShell can be invoked indirectly through its underlying .NET automation interfaces without launching `powershell.exe`.
- Renamed binaries or other PowerShell hosts are outside this rule's scope.
- An attacker can avoid this exact parameter, so this rule is one layer of coverage rather than complete PowerShell detection.

## Safe handling

Do not publish the raw Security EVTX file. It may contain usernames and unrelated command lines. Publish the rules, test script, sanitized screenshots, and this README instead.

Why document the blind spots?

False-positive guidance tells an analyst what legitimate activity needs validation. The limitations define which PowerShell behavior remains outside this rule's coverage.

Safe handling keeps the raw EVTX evidence local because unrelated command lines can contain sensitive information.

  • Save C:\DetectionLab\README.md.
  • Scroll from the detection hypothesis to the safe handling section.

You should see a complete path from the detection idea to its operational limits.

Is a section missing?

Compare your heading order with the full-file reference below. Check that False positives appears before Limitations.

Still unsure? Help me compare my detection README with the required section order.

✔️ Awesome, I've got everything!

Great. Double check that you saved C:\DetectionLab\README.md after adding every section.

ⓧ I'd like to double check the full code

  • Compare your complete C:\DetectionLab\README.md with this reference:
# Windows PowerShell Detection Engineering Lab

## Detection hypothesis

Encoded PowerShell deserves analyst review because adversaries may abuse PowerShell for execution and ATT&CK documents encoded PowerShell use under T1059.001. Encoding is not proof of malicious intent, so this rule is a behavioral lead rather than a verdict.

## Telemetry

- Source: Windows Security log
- Event: 4688, A new process has been created
- Required field: Process Command Line
- Test tool: Chainsaw 2.16.5 with its pinned `sigma-event-logs-all.yml` mapping
- Rule format: Sigma specification 2.1.0

## Test matrix

| Test activity | Naive rule | Tuned rule |
| --- | --- | --- |
| `powershell.exe -NoProfile -Command "Get-Date"` | Match | No match |
| `powershell.exe -NoProfile -EncodedCommand <UTF-16LE Base64>` | Match | Match |

## Reproduce

1. Run `powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\DetectionLab\scripts\generate-test-events.ps1`.
2. Run `wevtutil epl Security C:\DetectionLab\logs\security.evtx /ow:true`.
3. Run the naive and tuned Chainsaw hunts documented in the project guide.

## Triage questions

1. Which account created the process?
2. What is the complete command line and what does the encoded content decode to?
3. Which parent process launched PowerShell?
4. Is the activity associated with approved administration or deployment tooling?
5. What happened immediately before and after this process creation?

## ATT&CK mapping

- Tactic: Execution
- Technique: T1059.001, Command and Scripting Interpreter: PowerShell

## False positives

Legitimate administrators and software deployment systems may use `-EncodedCommand` to avoid complex quoting. Validate the user, parent process, host role, timing, and decoded command before escalating.

## Limitations

- The rule detects a documented command-line parameter, not malicious intent.
- PowerShell can be invoked indirectly through its underlying .NET automation interfaces without launching `powershell.exe`.
- Renamed binaries or other PowerShell hosts are outside this rule's scope.
- An attacker can avoid this exact parameter, so this rule is one layer of coverage rather than complete PowerShell detection.

## Safe handling

Do not publish the raw Security EVTX file. It may contain usernames and unrelated command lines. Publish the rules, test script, sanitized screenshots, and this README instead.
Capture sanitized validation evidence

Screenshots can prove that the broad rule was noisy. They can also expose unrelated activity from the Security log.

Keep only the rows needed to show the test result. Your raw C:\DetectionLab\logs\security.evtx file stays local.

  • Switch back to the administrator Windows PowerShell session from earlier.
  • Recreate the broad-rule result by running this command:
C:\DetectionLab\tools\chainsaw\chainsaw.exe hunt C:\DetectionLab\logs\security.evtx -s C:\DetectionLab\rules\naive --mapping C:\DetectionLab\tools\chainsaw\mappings\sigma-event-logs-all.yml --metadata

What does this evidence prove?

The naive rule looks for any command line containing powershell.exe. Its output demonstrates why routine administration creates noise.

You should see matches for ordinary PowerShell activity. You should also see the encoded test.

Keep sensitive details private

  • Remove usernames that identify a person.
  • Remove machine names that identify your device.
  • Remove unrelated command lines from other activity.
  • Crop the broad-rule output to the relevant test rows.
  • Capture the sanitized broad-rule result.
  • Recreate the tuned-rule result by running this command:
C:\DetectionLab\tools\chainsaw\chainsaw.exe hunt C:\DetectionLab\logs\security.evtx -s C:\DetectionLab\rules\tuned --mapping C:\DetectionLab\tools\chainsaw\mappings\sigma-event-logs-all.yml --metadata

What should the tuned evidence show?

The tuned rule requires both powershell.exe and -EncodedCommand in the same command line. The ordinary child command should be absent from these results.

You should see the encoded child process in the tuned output. You should not see the ordinary Get-Date child command.

  • Crop the tuned-rule output to the encoded test row.
  • Capture the sanitized tuned-rule result.
Reproduce the final result

Repeatability tests whether the same workflow produces the same detection outcome. A second successful run turns your package into reusable evidence.

  • Generate a fresh ordinary test and a fresh encoded test by running this command:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\DetectionLab\scripts\generate-test-events.ps1

What does the generator create?

The script launches one ordinary child process. It launches a second child process with -EncodedCommand.

Both child processes run Get-Date. The test contains no malicious payload.

You should see two dates in Windows PowerShell. That confirms both controlled test activities completed.

Did one of the dates fail to appear?

Confirm that C:\DetectionLab\scripts\generate-test-events.ps1 still contains the ordinary command and the encoded command from the earlier step.

Need help? Help me diagnose why my PowerShell test generator did not display both dates.

  • Refresh the exported Security log by running this command:
wevtutil epl Security C:\DetectionLab\logs\security.evtx /ow:true

What does this export capture?

This overwrites the existing project export with current Security log evidence. The refreshed file now contains the latest controlled process events.

Windows PowerShell should return to the prompt without an error. Your local C:\DetectionLab\logs\security.evtx evidence is ready for the final hunt.

Before you run the final hunt, which of the two child commands do you expect the tuned rule to match?

  • Run the tuned rule against the refreshed evidence with this command:
C:\DetectionLab\tools\chainsaw\chainsaw.exe hunt C:\DetectionLab\logs\security.evtx -s C:\DetectionLab\rules\tuned --mapping C:\DetectionLab\tools\chainsaw\mappings\sigma-event-logs-all.yml --metadata

What makes this the final check?

The hunt uses the refreshed evidence with the same tuned rule. It also uses the pinned mapping from Chainsaw 2.16.5.

The result tests the detection logic without changing the evidence format or analysis tool.

You should see the encoded child process match. The ordinary powershell.exe -NoProfile -Command "Get-Date" child process should be absent.

Does the final hunt show the wrong result?

Confirm that the hunt points to C:\DetectionLab\rules\tuned. A path to the naive rule recreates the noisy result.

Confirm that the mapping path ends with sigma-event-logs-all.yml.

Still stuck? Help me compare my final Chainsaw hunt with the expected tuned command.

That's the package finished. Another analyst can now reproduce the encoded test from your README.

Secret mission

Detect Hidden PowerShell

Extend your Event 4688 workflow to hidden-window PowerShell execution. You will create a second behavioral rule, generate a harmless test event, and prove that Chainsaw can detect it.

Clean Up Your Resources

Clean Up Your Resources

Everything you built lives on your Windows computer, so there are no ongoing costs. The options below cover keeping the lab, pausing detailed collection, or removing the workspace.

Resources you used:

  • The Windows Security auditing setting that creates successful Event 4688 Process Creation records.
  • The Process Command Line capture setting that adds command-line arguments to future Event 4688 records.
  • The C:\DetectionLab workspace containing your test script, three Sigma rules, README.md, validation evidence, Chainsaw 2.16.5, the pinned mapping, and the local EVTX export.

Keep everything running

No action is needed. Choose this option if you want to test more PowerShell behaviors against the same local lab.

  • Retain the C:\DetectionLab workspace for future rule tuning.
  • Leave Process Creation success auditing enabled.
  • Leave Process Command Line capture enabled.
  • Avoid entering passwords or secrets on command lines because those arguments are logged in plain text.

Your rules, evidence, and test workflow remain ready for another detection experiment.

Pause - I'll come back to this later

This option keeps every lab file while stopping Process Command Line capture for future Event 4688 records.

  • Switch back to the administrator Windows PowerShell session from earlier.
  • Pause future command-line capture by running this command:
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v "ProcessCreationIncludeCmdLine_Enabled" /t REG_DWORD /d 0 /f

What Does This Command Change?

The registry value becomes 0. This setting stops populating the Process Command Line field in future Event 4688 records.

Existing Windows Security log entries remain unchanged.

  • Confirm that PowerShell reports a completed registry update.
  • Leave Process Creation success auditing in its current state.
  • Keep the C:\DetectionLab workspace in place.

Command-line capture is now paused while your detection files remain available.

Registry Change Rejected?

If Windows refuses the registry change, confirm that you returned to the administrator PowerShell session from earlier.

Ask for help with this permission issue.

Delete - I don't want to use this again

This option returns the lab to its pre-project audit state before the local workspace is removed. Deleting the workspace permanently removes your reusable rules and evidence from C:\DetectionLab.

  • Copy any sanitized portfolio files you want to keep to a location outside C:\DetectionLab.
  • Switch back to the administrator Windows PowerShell session from earlier.
  • Stop future command-line capture by running this command:
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Audit" /v "ProcessCreationIncludeCmdLine_Enabled" /t REG_DWORD /d 0 /f

What Does This Command Change?

The registry value becomes 0. This setting stops populating the Process Command Line field in future Event 4688 records.

Existing Windows Security log entries remain unchanged.

  • Confirm that PowerShell reports a completed registry update.

Registry Change Rejected?

If Windows refuses the registry change, confirm that the PowerShell session still has local administrator access.

Ask for help restoring this setting.

The Process Creation audit policy has an environment-specific starting value. Restore the state that your computer used before this project.

  • Press the Windows key to open search.
  • Type Local Security Policy.
  • Select Local Security Policy from the results.
  • Locate Audit Process Creation.
  • Restore Audit Process Creation to its pre-project Success or No Auditing state.
  • Close Local Security Policy.
  • Leave the Windows Security log intact.

Keep the Security Log

The project export at C:\DetectionLab\logs\security.evtx disappears with the workspace. The system-wide Windows Security log remains in place because this project does not require clearing it.

The remaining project data sits inside C:\DetectionLab.

  • Close the administrator Windows PowerShell window from earlier.
  • Press the Windows key to open search.
  • Type File Explorer.
  • Select File Explorer from the results.
  • Enter C:\ in the address bar.
  • Select the DetectionLab folder.
  • Press the Delete key.
  • Confirm the deletion.

You've cleared the local lab while preserving the system-wide Windows Security log. You should no longer see DetectionLab under C:\.

Nice Work!

Nice Work!

You made it! You built a Windows PowerShell detection lab from native Security Event 4688 telemetry.

Your evidence shows how a broad rule creates noise. Your tuned logic catches the encoded test while excluding ordinary activity.

You've learned how to:

  • Built native process telemetry around Security Event 4688. You generated harmless ordinary PowerShell activity. You also generated encoded PowerShell activity using Get-Date.
  • Experienced alert fatigue with the broad Sigma rule. You refined its behavioral detection logic to require powershell.exe together with -EncodedCommand. Chainsaw confirmed that the ordinary test no longer matched.
  • Mapped the behavior to MITRE ATT&CK T1059.001. Your README.md contains triage questions. It documents false positives. It records detection limitations. Reproduction commands make the package repeatable.
  • Completed the optional Secret Mission by extending the lab to hidden-window PowerShell. You created a stretch rule requiring powershell.exe, -WindowStyle, and Hidden. You generated a harmless hidden-window event. Chainsaw confirmed the rule matched it.

Ready to quiz yourself?