Lesson 5 of 5 · 25 min read

Hunt-to-Detection Pipeline — Converting Findings into Rules

A hunt finding is evidence that an attacker behavior is observable in your environment. A hunt finding without a detection rule means the next attacker using the same technique goes undetected — you just got lucky once. The hunt-to-detection pipeline closes that gap: every confirmed finding becomes an automated rule within the same sprint.


Step 1: Extract the Behavioral Invariant

The hunt found a specific event. The rule should not target just that specific instance — it should target the behavioral pattern that event represents.

Example finding:

Time: 2026-05-18 02:14 UTC
Host: server-prod-07
Event: Sysmon Event 1 (Process Create)
  Image: C:\Windows\PSEXESVC.exe
  CommandLine: C:\Windows\PSEXESVC.exe
  ParentImage: C:\Windows\System32\services.exe
  User: SYSTEM
  IntegrityLevel: System

Question 1: What must be true for this to happen? — PsExec (or equivalent) was used to execute code remotely via SMB. The PSEXESVC.exe service is always created on the target host when PsExec connects.

Question 2: Would any legitimate tool also create PSEXESVC.exe? — PsExec is the primary tool. Sysinternals PSExec variants also use the same service name. A legitimate IT admin using PsExec for remote management would trigger this.

Behavioral invariant: PSEXESVC.exe process creation on any host = PsExec or equivalent lateral movement tool in use.


Step 2: Write the Initial Rule

title: PsExec Service Executable Created
id: 4b8f1a2c-3d4e-5f6a-7b8c-9d0e1f2a3b4c
status: experimental
description: |
  Detects creation of PSEXESVC.exe, the service executable installed by PsExec 
  on target hosts during remote execution. Derived from Hunt H-2026-023.
references:
  - https://docs.internal/hunts/H-2026-023
  - https://attack.mitre.org/techniques/T1021/002/
author: hunt-team
date: 2026/05/20
tags:
  - attack.lateral_movement
  - attack.t1021.002
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    Image|endswith: '\PSEXESVC.exe'
  filter_legitimate_admin:
    User|contains: 'SYSTEM'
    ParentImage|endswith: '\services.exe'
  condition: selection and not filter_legitimate_admin

falsepositives:
  - Legitimate IT admin use of PsExec for remote management
  - Automated deployment systems using PsExec-based remote execution

level: high

fields:
  - Image
  - CommandLine
  - ParentImage
  - User
  - ComputerName

Wait — the filter here is wrong. Legitimate PsExec also creates PSEXESVC.exe with SYSTEM/services.exe as parent. This filter would suppress ALL PSEXESVC.exe creation. Remove the filter and instead add a condition that focuses on the lateral movement context:

detection:
  selection:
    Image|endswith: '\PSEXESVC.exe'
  filter_known_admin_hosts:
    ComputerName|contains:
      - 'jumpbox'
      - 'admin-ws'
  condition: selection and not filter_known_admin_hosts

falsepositives:
  - IT administrators using PsExec from authorized jump boxes or admin workstations
  - Deployment automation that uses PsExec for remote installation

This is still imprecise. Document it as experimental and plan for tuning based on production FP data.


Step 3: Write TP and FP Fixtures from Hunt Data

The hunt finding IS the TP fixture:

// tests/windows/process_creation/psexesvc_creation-tp.json
[
  {
    "EventID": 1,
    "Image": "C:\\Windows\\PSEXESVC.exe",
    "CommandLine": "C:\\Windows\\PSEXESVC.exe",
    "ParentImage": "C:\\Windows\\System32\\services.exe",
    "User": "SYSTEM",
    "ComputerName": "server-prod-07",
    "IntegrityLevel": "System",
    "UtcTime": "2026-05-18 02:14:23.000"
  }
]

The FP fixture represents known-legitimate use:

// tests/windows/process_creation/psexesvc_creation-fp.json
[
  {
    "EventID": 1,
    "Image": "C:\\Windows\\PSEXESVC.exe",
    "CommandLine": "C:\\Windows\\PSEXESVC.exe",
    "ParentImage": "C:\\Windows\\System32\\services.exe",
    "User": "SYSTEM",
    "ComputerName": "admin-ws-01",
    "IntegrityLevel": "System",
    "UtcTime": "2026-05-19 09:00:00.000"
  }
]

The FP fixture tests that admin-ws-01 (an authorized jump box) is excluded correctly.


Step 4: Open the PR with Hunt Context

The PR description should tell the story of the finding:

## Detection Rule: PsExec Service Creation (T1021.002)

### Origin
Derived from Hunt H-2026-023 (SMB Lateral Movement Hunt), run 2026-05-20.

The hunt found one suspicious PsExec event:
- **Host:** server-prod-07 (Tier 1 production server)
- **Time:** 2026-05-18 02:14 UTC (off-hours)
- **User:** SYSTEM (via PSEXESVC.exe service)
- **Source:** Traced to ws-dev-04 (developer workstation, no prod access rights)
- **Status:** Escalated to IR — confirmed unauthorized lateral movement

### Rule design decisions
- Detection targets PSEXESVC.exe creation specifically (not PsExec.exe — which runs 
  on the source, not the target)
- Exclusion added for known admin jump boxes (admin-ws-01, admin-ws-02, jumpbox-*)
  where IT admins legitimately use PsExec for authorized remote management
- Status: experimental — expect FPs from any host where PsExec is legitimately used;
  tune based on production data in first week

### Tests
- TP fixture: from actual hunt finding (server-prod-07 event)
- FP fixture: synthetic event from admin-ws-01 (known-legitimate host)

### Hunt report
Full report: docs/hunts/H-2026-023.md

Step 5: Update the Coverage Matrix and Hunt Library

# Coverage matrix update
T1021.002 (SMB/Windows Admin Shares):
  Before: Gap (no rule)
  After: Covered (rule: psexesvc_creation.yml) — tested via hunt H-2026-023

# Hunt library entry
Hunt: H-2026-023 — SMB Lateral Movement
Last run: 2026-05-20
Detection created: proc_creation_psexesvc.yml
Coverage matrix: T1021.002 → Covered
Next scheduled run: 2026-07-20 (quarterly)

The Hunt-to-Detection Checklist

Before closing any hunt, verify each output:

□ Hunt report (TaHiTI format) committed to docs/hunts/
□ Sigma rule written for each high-confidence finding
□ TP fixture created from real hunt evidence
□ FP fixtures created for known-legitimate use cases
□ PR opened with hunt context in description
□ Coverage matrix updated (technique → Covered/Miscovered/Gap)
□ Baseline documentation updated
□ Telemetry gaps documented in the gap backlog
□ Hunt library entry updated with next run date
Security Datasets (Mordor)— OTRF