Purple-Team Weekly Loop¶
Summary
Instead of a generic beginner curriculum, use the blue-team stack you already have — Splunk, Zeek, Suricata, Arkime, Velociraptor — and learn one MITRE ATT&CK technique per week: understand it as the attacker, run it in a lab, find every trace it leaves, write the detection, and finish with a one-page note. After a year that is ~50 techniques you can explain from both sides.
The loop¶
flowchart LR
A[1. Understand<br/>attacker view] --> B[2. Execute<br/>in the lab]
B --> C[3. Host evidence<br/>Event Logs + Sysmon]
C --> D[4. Endpoint collection<br/>Velociraptor]
D --> E[5. Network evidence<br/>Zeek / Suricata / Arkime]
E --> F[6. Detection<br/>Splunk SPL]
F --> G[7. Map & write up<br/>ATT&CK + 1-page note]
G -.next week.-> A
| Day | Step | Output |
|---|---|---|
| 1 | Read the ATT&CK page and 1–2 procedure examples; read this site's page for the technique | 5-line explanation of why the technique works |
| 2 | Execute in the lab (manually and/or with Atomic Red Team) — snapshot the VM first | Exact commands + timestamps |
| 3 | Find the host evidence: Security, Sysmon, PowerShell, System logs; registry/file artifacts | List of event IDs and fields that show it |
| 4 | Collect with Velociraptor; check network side in Zeek/Suricata/Arkime | Artifact names, pcap/log evidence |
| 5 | Write and tune the SPL; test it against noise (run normal admin activity too) | Saved search + false-positive notes |
| 6–7 | Write the one-page note (template below); list visibility gaps | Note committed to this site |
Worked example — week 1: T1059.001 PowerShell¶
1 · Understand (attacker view)¶
PowerShell is a full scripting language with direct access to .NET and the Windows API, installed on every modern Windows host. Attackers use it to download and run code in memory (IEX (New-Object Net.WebClient).DownloadString(...)), to hide commands with -EncodedCommand (Base64 of UTF-16LE text), and to run without a profile or window (-nop -w hidden). See PowerShell cradles for the full attacker side.
2 · Execute in the lab (harmless payload)¶
# Build an encoded command for a harmless action
$cmd = 'Write-Output "purple-test"; Get-Process | Select-Object -First 3'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($cmd)
$b64 = [Convert]::ToBase64String($bytes)
# Run it the way an attacker would (hidden window, no profile, encoded)
powershell.exe -nop -w hidden -enc $b64
# Optional: same idea through Atomic Red Team (list tests first, pick a benign one)
Invoke-AtomicTest T1059.001 -ShowDetailsBrief
Before running, make sure these are on in the lab: Script Block Logging (GPO Administrative Templates › Windows Components › Windows PowerShell › Turn on PowerShell Script Block Logging), process creation with command line (4688), and Sysmon.
3 · Host evidence¶
| Source | Event | What you will see |
|---|---|---|
| Sysmon | 1 — process created | Image=...\powershell.exe, CommandLine contains -enc, ParentImage (who launched it) |
| Security | 4688 — process created | Same as above, only if "Include command line in process creation events" is enabled |
| PowerShell/Operational | 4104 — script block logged | The decoded script text — attackers can encode the command line, but 4104 records what actually ran |
| PowerShell/Operational | 4103 — module logging | Pipeline/command details (if module logging enabled) |
| Windows PowerShell (classic) | 400 / 600 | Engine start with HostApplication = full command line — useful because it exists even on old systems |
4 · Splunk detection — line by line¶
index=botsv3 sourcetype="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventID=1 Image="*\\powershell.exe"
| where match(CommandLine, "(?i)\s-(e|en|enc|enco|encod|encode|encoded|encodedcommand)\s")
| rex field=CommandLine "(?i)-e\w*\s+(?<b64>[A-Za-z0-9+/=]{20,})"
| table _time, host, User, ParentImage, CommandLine, b64
index=botsv3 sourcetype=... EventID=1— Sysmon process-creation events.Image="*\\powershell.exe"— only PowerShell processes (*= anything before,\\= one backslash).where match(CommandLine, "...")— keep command lines with any abbreviation of-EncodedCommand(PowerShell accepts-e,-en,-enc… all of them).(?i)makes the regex case-insensitive.rex field=CommandLine "...(?<b64>...)"— extract the Base64 blob into a new field calledb64so you can decode it.table— show only the columns you need.
Result:
| _time | host | User | ParentImage | CommandLine | b64 |
|---|---|---|---|---|---|
| 2026-10-07 21:04:11 | LAB-WIN10 | LAB\analyst | C:\Windows\explorer.exe | powershell.exe -nop -w hidden -enc VwByAGkAdABlAC0A... |
VwByAGkAdABlAC0A... |
Then confirm what actually ran from the script-block log:
index=botsv3 sourcetype="XmlWinEventLog:Microsoft-Windows-PowerShell/Operational" EventCode=4104
| search ScriptBlockText="*purple-test*" OR ScriptBlockText="*DownloadString*" OR ScriptBlockText="*FromBase64String*"
| table _time, host, ScriptBlockText
EventCode=4104— script block logging: the decoded text of the script.search ScriptBlockText="*...*"— look for our test marker plus two classic attacker keywords.- The result shows
Write-Output "purple-test"; Get-Process | Select-Object -First 3in plain text — proof that 4104 defeats the encoding.
5 · Velociraptor¶
| Artifact | Why |
|---|---|
Windows.EventLogs.PowershellScriptblock |
Pulls 4104 events from the endpoint even if they never reached the SIEM |
Windows.System.Powershell.PSReadline |
Interactive command history (ConsoleHost_history.txt) per user |
Windows.Forensics.Prefetch |
Proves POWERSHELL.EXE executed and when (workstations) — see Prefetch |
See Velociraptor for running hunts.
6 · Network side¶
- Zeek
http.log: if the script downloads over HTTP, the defaultuser_agentcontainsWindowsPowerShell—zeek-cut ts id.orig_h host uri user_agent < http.log | grep -i powershell. -
Suricata — a local rule for the same idea:
-
Arkime:
http.user-agent == *PowerShell*to pull the sessions and download the pcap. - Over HTTPS you will not see the user agent — look at JA3/JA4 and the destination instead (Zeek SSL).
7 · The one-page note (template)¶
# T1059.001 — PowerShell
**Why it works:** built-in, trusted, runs .NET in memory; -enc hides intent.
**Lab commands:** powershell -nop -w hidden -enc <b64> (2026-10-07 21:04, LAB-WIN10)
**Host evidence:** Sysmon 1 / 4688 (command line), 4104 (decoded script), 400 (HostApplication)
**Endpoint collection:** Velociraptor PowershellScriptblock, PSReadline, Prefetch
**Network evidence:** Zeek http.log UA "WindowsPowerShell"; Suricata sid 1000001
**Detection:** [SPL saved search name] — FP: SCCM/Intune scripts using -enc
**ATT&CK:** T1059.001 (Execution)
**Gaps:** 4104 not forwarded on servers; no TLS inspection
Suggested order of techniques¶
Each row links to the page on this site that already holds the attacker and detection detail.
| Week | Technique | ATT&CK | Page |
|---|---|---|---|
| 1 | PowerShell / command interpreters | T1059.001 | PowerShell cradles |
| 2 | Scheduled Task | T1053.005 | Persistence |
| 3 | Windows Service | T1543.003 | Persistence |
| 4 | Registry Run keys | T1547.001 | Persistence |
| 5 | NTLM & Pass-the-Hash | T1550.002 | Pass-the-Hash |
| 6 | Kerberos & Kerberoasting | T1558.003 | Kerberoasting |
| 7 | Credential dumping (LSASS) | T1003.001 | LSASS dumping |
| 8 | SAM / NTDS extraction | T1003.002/.003 | SAM & NTDS |
| 9 | SMB / PsExec | T1021.002 | PsExec & SMB |
| 10 | RDP | T1021.001 | RDP |
| 11 | WMI | T1047 | WMI & WinRM |
| 12 | WinRM | T1021.006 | WMI & WinRM |
| 13 | LOLBins (certutil, mshta, rundll32) | T1218, T1105 | LOLBins |
| 14 | Phishing → user execution | T1566, T1204 | Phishing delivery |
| 15 | Web shell | T1505.003 | Web shell playbook |
| 16 | HTTP(S) C2 & beaconing | T1071.001 | Beaconing & C2 |
| 17 | DNS C2 / tunnelling | T1071.004 | Zeek dns.log |
| 18 | Process injection | T1055 | Process injection |
| 19 | UAC bypass | T1548.002 | UAC bypass |
| 20 | Token impersonation | T1134 | Token & Potato |
| 21 | LLMNR poisoning & NTLM relay | T1557.001 | LLMNR & NTLM relay |
| 22 | DCSync | T1003.006 | DCSync |
| 23 | Impair defenses & log clearing | T1562, T1070.001 | Impair defenses |
| 24 | Exfiltration over web services | T1567 | Data exfiltration playbook |
After week 24, chain them: run weeks 14 → 1 → 2 → 7 → 9 → 16 → 24 as one intrusion and investigate it end to end as a case.
References¶
- MITRE ATT&CK — T1059.001 PowerShell
- Atomic Red Team — small, documented tests per ATT&CK technique
- Microsoft — about_Logging_Windows (script block logging)
- Pages: Roadmap · 24-month curriculum · Hunting patterns