EDR rules-as-code from attack patterns
TL;DR: Detection engineering turns red-team tradecraft into running rules. The pipeline: study an attack technique → identify telemetry signals it must produce → write a rule (Sigma, KQL, Splunk SPL, EDR-vendor DSL) → tune for false positives → land in CI alongside the rule corpus. The goal isn’t to alert on every attack — it’s to alert deterministically on attack patterns the team has chosen to detect. Companion to purple-team-feedback-loop and ir-from-source-signals.
The four-step pipeline
- Technique selection — usually MITRE ATT&CK technique IDs (T1059, T1003, T1078…).
- Telemetry mapping — which sensor produces which event.
- Rule authoring — Sigma (vendor-neutral) → translate per platform.
- Tuning + deploy — ship via git, measure FP rate, decommission stale rules.
Step 1 — pick attacks worth detecting
Not every attack technique merits a rule. Triage:
| High-value | Low-value |
|---|---|
| Used by adversaries against your sector | Rare in the wild |
| Hard to bypass without changing approach | Cosmetic; trivial bypass |
| Telemetry is reliable | Requires log sources you don’t have |
| Low false-positive ceiling | Generates 1000 events/day baseline |
Pull adversary profiles from MITRE ATT&CK Navigator for your sector (FIN6, APT29, Conti, etc.). Map their techniques; prioritise.
Step 2 — telemetry mapping
For each technique, list the events that must fire when the attack runs.
T1059.001 — PowerShell:
- Sysmon EventID 1 (process create) with
Image=powershell.exeorpwsh.exe. - Sysmon EventID 10 (process access) on lsass.exe.
- Windows EventID 4104 (PowerShell ScriptBlock logging).
- Windows EventID 800/4103 (module/pipeline logging).
If you don’t have ScriptBlock logging enabled, that detection class won’t work. Confirm before writing.
Step 3 — write the rule in Sigma
Sigma is vendor-neutral; translates to Splunk SPL, Elastic EQL/KQL, Microsoft KQL, CrowdStrike LogScale, etc.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
title: PowerShell with suspicious encoded command
id: 1a2b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6
status: experimental
description: Detects PowerShell invocations with -EncodedCommand and base64 payloads
references:
- https://attack.mitre.org/techniques/T1059/001/
author: detection-eng-team
date: 2026/06/05
tags:
- attack.execution
- attack.t1059.001
logsource:
product: windows
category: process_creation
detection:
selection_img:
Image|endswith:
- '\powershell.exe'
- '\pwsh.exe'
selection_cmd:
CommandLine|contains:
- ' -enc '
- ' -EncodedCommand '
- ' -ec '
condition: selection_img and selection_cmd
falsepositives:
- DevOps tooling that uses encoded commands
level: medium
Translate:
1
2
sigma convert -t splunk powershell-encoded.yml
sigma convert -t kql powershell-encoded.yml
Step 4 — tune for false positives
A rule with > 1 FP/day per host is a rule the team will mute.
Steps:
- Run the rule in audit mode (no alert; collect matches) for one week.
- Review every match. Tag as TP, FP, or “informational”.
- Add exception clauses to push FP-rate below threshold.
- Promote to alert mode.
1
2
3
4
5
filter:
CommandLine|contains:
- 'DevopsScript.ps1' # known good
- 'ScheduledTask=BackupJob' # known good
condition: selection_img and selection_cmd and not filter
Storage and rollout
Rules live in git, like code:
1
2
3
4
5
6
7
8
9
10
11
12
detection-rules/
README.md
CONTRIBUTING.md
rules/
execution/
t1059-001-powershell-encoded.yml
t1059-003-cmd-suspicious.yml
credential-access/
t1003-001-lsass-dump.yml
...
tests/
t1059-001-test-events.json
CI:
sigma checkvalidates syntax.- Unit tests with synthetic events confirm rule matches what it should.
- Conversion to platform DSL produces artefacts uploaded to SIEM/EDR via API.
- Rule deprecation requires PR + review.
Common detection categories
| Category | Anchor events |
|---|---|
| Credential dumping (LSASS) | Sysmon 10 access to lsass.exe with GrantedAccess=0x1010 |
| Mimikatz | command-line containing sekurlsa::logonpasswords / known PE imports |
| Persistence via Run keys | Sysmon 13 (registry value set) on HKLM\...\Run |
| WMI persistence | Sysmon 19/20/21 on EventSubscription |
| Scheduled-task creation | Windows 4698 |
| LOLBin abuse | process create with parent / arg / hash patterns |
| AMSI bypass | PowerShell 4104 with known patterns; AMSI failure events |
| ASR rule triggered | Defender 1121/1122 |
Detection-as-code anti-patterns
- Detection by hash — adversary recompiles, bypass.
- Detection by ImageFileName — adversary renames
mimikatz.exetoupdate.exe. - Detection by command-line literal — adversary changes case, encoding, splits string.
- Detection on a single event — single events get tuned out; chain multiple correlations.
Better:
- Behavioural — LSASS access by a non-system process.
- Frequency — N events of type X within Y minutes.
- Anomaly — process spawns child it’s never spawned in the baseline.
- Sequence — process A spawns process B which writes file C, all within seconds.
Atomic Red Team integration
Atomic Red Team (Red Canary) provides MITRE-aligned per-technique tests:
1
2
3
git clone https://github.com/redcanaryco/atomic-red-team
cd atomic-red-team/atomics/T1059.001
# follow tests; each test should trigger your rule
CI loop: nightly, run a subset of atomics in a controlled VM; verify rules fire; alert if any expected fire is missing.
SOC handoff
For each rule, document:
- What it detects — plain-English description.
- What an analyst should do first — runbook link.
- Common false-positive patterns — context for triage.
- Severity rationale — why it’s a “high”, not a “medium”.
- Owner — team or person to ping.
Without these, the SOC ignores or auto-closes alerts; the rule “works” but produces no IR value.
Bridging to the red team
The purple-team loop (purple-team-feedback-loop):
- Red team runs technique.
- Detection team observes detection (or non-detection).
- Detection team writes/updates rule.
- Red team verifies bypass technique still works (or finds new variant).
- Repeat.
This is how mature programmes evolve. The OSEP-shaped attack chain (osep-full-chain-walkthrough) maps directly to a detection backlog.
Anti-detection by the red team
For OSEP-style operations:
- Read your customer’s published detection-rule corpus (if any).
- Identify the assumptions each rule makes (image name, command-line shape, parent process).
- Pick a technique that violates none of the assumptions.
The red team’s job in detection-mature orgs is not finding a bug — it’s finding a technique without a rule. Detection engineering’s job is shrinking that gap.