Hypothesis-Driven Hunting
A threat hunt is a claim about the world — "an actor performed this behavior in this
environment, and if so, these artifacts exist in these logs" — subjected to a test
that could refute it. It is not running a block of IOC searches and seeing what lights
up. The difference is the whole discipline: a hunt with no stated refutation condition
cannot fail, and a search that cannot fail has not learned anything when it returns
empty. It has produced the feeling of coverage, which is worse than no hunt, because
someone will now report the environment as clean.
Two failure modes, and the second is the quiet, dangerous one:
- Grep-for-evil. A pile of IOC queries with no hypothesis behind them. A hit is a
"maybe" you cannot interpret (the IOC is stale, shared, or benign), and a miss means
nothing at all — you did not define what a miss would rule out.
- Absence-as-proof. Treating "the hunt found no evidence" as "there is no adversary."
A null result is bounded entirely by the data you queried, its retention, and its
coverage. "Not present in these logs, for this window, at this fidelity" is the honest
claim; "not present" is a lie the hunt is not entitled to tell.
Composes with the library:
- abductive-engineering — the hunt hypothesis is an abduction; the query is its deduced consequence; the result is the induction
- falsifiable-testing — a hunt with no defined refutation is a test that cannot fail; state the failing case first
- detection-engineering — a behavior a hunt confirms becomes a detection requirement, closing the loop
- dual-use-behavior-adjudication — a hit is a lead to adjudicate against baseline and context, never a verdict
- claim-provenance-discipline — the hunt's coverage and null result must travel, so "clean" carries its own caveats
- honest-degradation — the meaning of a null is capped by data coverage; say what the hunt could not see
Step 1 — Abduce a behavior, not a keyword
Start from a hypothesis about what an adversary did, framed so it has observable
consequences. "Hunt for evil" is not a hypothesis; "an actor that gained a foothold on
a workstation moved laterally to a server using WMI" is. The behavior is the object;
the artifacts are the evidence you will go looking for.
Ground it in something: a threat-intel report about an actor's TTPs, a gap a
purple-team-exercise exposed, an anomaly from another hunt, or a "what would I do
from here" walk of assume-breach-modeling. A hypothesis with a reason behind it is
worth testing; a random IOC list is not.
Step 2 — Deduce the observable consequence and where it must live
If the hypothesis is true, what must exist, and in which data source? This is the
deductive step, and it is where most hunts are quietly unfalsifiable — the hunter never
names what a true instance would actually look like, so any result can be rationalized.
- WMI lateral movement → process-creation events for
wmiprvse.exe spawning children
on the target, network flows on 135/DCOM, auth events for the source account. Name the
fields, the log source, the time window.
- State the base rate up front: WMI is also how a hundred legitimate management
tools operate (link
dual-use-behavior-adjudication). If the expected artifact is
common, the hunt is a lead-generator, not a detector, and you should know that before
you run it.
Step 3 — State the refutation condition before you query
Write down, in advance: what result would refute the hypothesis, and what a null result
would and would not prove. This single act converts a sweep into a test.
- "If WMI lateral movement occurred in this window, I expect ≥1
wmiprvse child-process
event on the server tier. Absence in process-creation logs that we confirm were
ingesting for this window refutes the specific behavior for hosts with that logging
— and says nothing about hosts where the log was off."
- The precommitment matters because after you see the data, every result looks
explicable. Deciding the failing case first is what stops you from moving the goalposts
(the Eco's-razor discipline: a result that fits too neatly is a prompt to check
coverage, not to declare victory).
Step 4 — Run, then interpret a hit as a lead and a null as bounded
- A hit is a lead, not a finding. Hand it to
dual-use-behavior-adjudication: is this
WMI use the adversary or the patch-management server doing its job? A hunt that stops at
"found WMI activity, escalating as compromise" reproduces the false-MALICE error.
- A null is bounded by coverage. Before writing "clean," establish: were those logs
actually ingesting for the whole window? What is the retention — did the window predate
it? What fidelity — sampled netflow, disabled command-line logging? The honest output is
"no evidence of this behavior in these sources over this window," with the blind
spots named (
honest-degradation). A null over logs that were off is not a null; it is
an unrun hunt.
Step 5 — Bank the result regardless of outcome, and close the loop
A hunt that finds nothing still produced knowledge, but only if it is recorded so the
next person can trust or re-run it:
- Log the hypothesis, the queries, the data coverage, and the result — so "we hunted
for WMI lateral movement and found none, over these sources for this window" is an
auditable, repeatable claim, not a vibe (
claim-provenance-discipline). Six months
later this is the difference between "we checked" and "someone remembers checking."
- Confirmed behavior → detection. If the hunt found real adversary activity, the
behavior is now a
detection-engineering requirement: build the rule with its benign
twin so the next occurrence is caught automatically instead of re-hunted.
- A refined or refuted hypothesis is a result. "The behavior was not present, but the
hunt revealed we have zero command-line logging on the server tier" is often more
valuable than the hunt itself — it is the next work.
The one-line test
If you cannot state, before running a single query, what result would prove your
hypothesis wrong and what a clean result would leave unknown, you are not hunting —
you are sweeping, and a sweep that comes back empty has told you only that you swept.
1---2name: hypothesis-driven-hunting3description: Hypothesis-Driven Hunting4---56# Hypothesis-Driven Hunting78A threat hunt is a claim about the world — "an actor performed *this behavior* in *this9environment*, and if so, *these artifacts* exist in *these logs*" — subjected to a test10that could refute it. It is not running a block of IOC searches and seeing what lights11up. The difference is the whole discipline: a hunt with no stated refutation condition12cannot fail, and a search that cannot fail has not learned anything when it returns13empty. It has produced the *feeling* of coverage, which is worse than no hunt, because14someone will now report the environment as clean.1516Two failure modes, and the second is the quiet, dangerous one:1718- **Grep-for-evil.** A pile of IOC queries with no hypothesis behind them. A hit is a19 "maybe" you cannot interpret (the IOC is stale, shared, or benign), and a miss means20 nothing at all — you did not define what a miss would rule out.21- **Absence-as-proof.** Treating "the hunt found no evidence" as "there is no adversary."22 A null result is bounded entirely by the data you queried, its retention, and its23 coverage. "Not present in these logs, for this window, at this fidelity" is the honest24 claim; "not present" is a lie the hunt is not entitled to tell.2526Composes with the library:2728- **abductive-engineering** — the hunt hypothesis is an abduction; the query is its deduced consequence; the result is the induction29- **falsifiable-testing** — a hunt with no defined refutation is a test that cannot fail; state the failing case first30- **detection-engineering** — a behavior a hunt confirms becomes a detection *requirement*, closing the loop31- **dual-use-behavior-adjudication** — a hit is a lead to adjudicate against baseline and context, never a verdict32- **claim-provenance-discipline** — the hunt's coverage and null result must travel, so "clean" carries its own caveats33- **honest-degradation** — the meaning of a null is capped by data coverage; say what the hunt could not see3435---3637## Step 1 — Abduce a behavior, not a keyword3839Start from a hypothesis about what an adversary *did*, framed so it has observable40consequences. "Hunt for evil" is not a hypothesis; "an actor that gained a foothold on41a workstation moved laterally to a server using WMI" is. The behavior is the object;42the artifacts are the evidence you will go looking for.4344Ground it in something: a threat-intel report about an actor's TTPs, a gap a45`purple-team-exercise` exposed, an anomaly from another hunt, or a "what would I do46from here" walk of `assume-breach-modeling`. A hypothesis with a reason behind it is47worth testing; a random IOC list is not.4849---5051## Step 2 — Deduce the observable consequence and where it must live5253If the hypothesis is true, *what must exist, and in which data source*? This is the54deductive step, and it is where most hunts are quietly unfalsifiable — the hunter never55names what a true instance would actually look like, so any result can be rationalized.5657- WMI lateral movement → process-creation events for `wmiprvse.exe` spawning children58 on the target, network flows on 135/DCOM, auth events for the source account. Name the59 fields, the log source, the time window.60- State the **base rate** up front: WMI is also how a hundred legitimate management61 tools operate (link `dual-use-behavior-adjudication`). If the expected artifact is62 common, the hunt is a lead-generator, not a detector, and you should know that before63 you run it.6465---6667## Step 3 — State the refutation condition before you query6869Write down, in advance: *what result would refute the hypothesis, and what a null result70would and would not prove.* This single act converts a sweep into a test.7172- "If WMI lateral movement occurred in this window, I expect ≥1 `wmiprvse` child-process73 event on the server tier. Absence in *process-creation logs that we confirm were74 ingesting for this window* refutes the specific behavior *for hosts with that logging*75 — and says nothing about hosts where the log was off."76- The precommitment matters because after you see the data, every result looks77 explicable. Deciding the failing case first is what stops you from moving the goalposts78 (the Eco's-razor discipline: a result that fits too neatly is a prompt to check79 coverage, not to declare victory).8081---8283## Step 4 — Run, then interpret a hit as a lead and a null as bounded8485- **A hit is a lead, not a finding.** Hand it to `dual-use-behavior-adjudication`: is this86 WMI use the adversary or the patch-management server doing its job? A hunt that stops at87 "found WMI activity, escalating as compromise" reproduces the false-MALICE error.88- **A null is bounded by coverage.** Before writing "clean," establish: were those logs89 actually ingesting for the whole window? What is the retention — did the window predate90 it? What fidelity — sampled netflow, disabled command-line logging? The honest output is91 "no evidence of *this behavior* in *these sources* over *this window*," with the blind92 spots named (`honest-degradation`). A null over logs that were off is not a null; it is93 an unrun hunt.9495---9697## Step 5 — Bank the result regardless of outcome, and close the loop9899A hunt that finds nothing still produced knowledge, but only if it is recorded so the100next person can trust or re-run it:101102- **Log the hypothesis, the queries, the data coverage, and the result** — so "we hunted103 for WMI lateral movement and found none, over these sources for this window" is an104 auditable, repeatable claim, not a vibe (`claim-provenance-discipline`). Six months105 later this is the difference between "we checked" and "someone remembers checking."106- **Confirmed behavior → detection.** If the hunt found real adversary activity, the107 behavior is now a `detection-engineering` requirement: build the rule with its benign108 twin so the next occurrence is caught automatically instead of re-hunted.109- **A refined or refuted hypothesis is a result.** "The behavior was not present, but the110 hunt revealed we have zero command-line logging on the server tier" is often more111 valuable than the hunt itself — it is the next work.112113---114115## The one-line test116117If you cannot state, before running a single query, what result would prove your118hypothesis *wrong* and what a clean result would leave *unknown*, you are not hunting —119you are sweeping, and a sweep that comes back empty has told you only that you swept.