How to Threat Hunt: Hypothesis-Driven Hunting, Step by Step
A working method for threat hunting: where hypotheses come from, the data you need before you start, the reduce-and-triage loop, a worked DNS beacon hunt, and how a hunt becomes a detection rule.
Every alert in your queue represents a detection that worked. Threat hunting is the discipline of going after the intrusions that produced no alert at all, which means it starts from the assumption that the tooling you already bought missed something.
That assumption has to be turned into something testable before it becomes work. "Go look for evil" is a mood. "An implant on a workstation is beaconing over DNS TXT records to a domain nobody else in the estate resolves" is a claim you can accept or reject in an afternoon with a query and a time window. This guide is the method for producing claims of the second kind and running them to a conclusion.
What a hunt actually is
A hunt is a scheduled, human-led search through telemetry for attacker activity, structured around a hypothesis and bounded by a data source, a host population and a time window. Three properties define it.
It is proactive. Nothing triggers it except the plan. That is the whole difference from working the alert queue, and it is why hunting finds dwell time that alerting missed.
It is falsifiable. The hypothesis has to be phrased so that a specific query result would disprove it. A claim that cannot come back empty cannot come back at all.
It ends in an artifact. An incident ticket, a detection rule, a tuning change, or a written negative result with the query attached. A hunt that ends in a conversation gets run again from zero next quarter.
MITRE's TTP-Based Hunting paper frames the same thing as hunting behaviours rather than indicators: hashes and IP addresses rotate cheaply, while the way an attacker executes code, persists and calls home changes slowly because it is bound to how the operating system works. Hunting the behaviour is what makes a hunt survive the attacker changing infrastructure.
If your team has telemetry centralised and can run its own queries, you can hunt. The commonly cited maturity ladder runs from an organisation that only consumes vendor alerts, through following other people's hunt procedures, to creating and finally automating its own, which is where machine learning in security starts to matter. Most teams that think they are too immature to hunt are already at the "can run our own queries" rung and have simply never scheduled the time.
Data comes before hypotheses
The fastest way to waste a week is to design an elegant hunt against telemetry you do not collect. Check the shelf before you plan the meal.
Five families of telemetry carry almost every hunt worth running: process creation with full command lines, DNS queries, network flow or proxy records, authentication events, and writes to autostart locations. Each one decides which hypotheses you can even state. Without command lines there is no LOLBin hunt; without DNS logs there is no beacon hunt; without flow records there is no interval analysis.
Which Windows and Sysmon events supply them, and which auditing is off until you turn it on, is the subject of Windows event IDs for security. The one trap worth repeating here: 4688 does not record command lines until you enable it in Group Policy, and a hunt that depends on arguments will return clean results on a fleet that never captured them. Clean results from missing data look exactly like clean results from a clean network.
Two coverage questions belong in every hunt plan. Which hosts are actually reporting? Compare the distinct host count in your telemetry against your asset inventory before you conclude anything; a hunt across 480 of 610 workstations is a hunt with a 130-machine blind spot. How far back does the data go? An intrusion can begin weeks before anyone thinks to look, so a 7-day retention window will happily tell you the environment is quiet.
Where hypotheses come from
Three generators, and a healthy programme uses all three.
Intelligence-driven
You read an advisory or an ATT&CK technique and ask whether the same behaviour exists in your estate. CISA's joint guidance on living-off-the-land techniques (AA24-038A) is a good example of an input that converts directly into hunts, because it describes what the activity looks like in logs. The technique catalogue itself is covered in the MITRE ATT&CK framework; use it as a menu of hypotheses rather than a checklist to work through in order.
A good intelligence-driven hypothesis names the technique and the observable together: "T1218.011 rundll32 is being used to execute a DLL from a user-writable path, which would appear in Sysmon 1 as a rundll32 command line containing AppData or Temp."
Baseline-driven
You look at the shape of your own data and hunt the outliers. This is where stack counting earns its keep: group a field, count occurrences, sort ascending, and read the bottom of the list. Rare is a far better starting population than common, and plenty of rare things are benign.
Crown-jewel driven
Start from what an attacker wants (the domain controllers, the code-signing box, the finance file share, the backup server) and work backwards through the access path. "Who has authenticated interactively to the backup server in 90 days, and is every one of those accounts expected?" is a hunt that takes an hour and occasionally ends a career.
The loop
Six steps, in order. The discipline is in doing them in order.
- State the hypothesis. One sentence, naming the behaviour, the population and the evidence that would show it.
- Scope. Data source, host population, time window. Write these down because they define what your negative result actually covers.
- Reduce. Get from millions of events to a set a human can read. Volume thresholds, shape filters, stack counting, then known-good exclusions in that order.
- Triage. Look at what survived, with enough context to explain each row. Every row gets a verdict.
- Close out. Incident, detection rule, tuning change, or documented negative.
- Feed back. Every exclusion you wrote is a fact about your environment. Every gap you hit is a logging ticket.
Step 3 is where hunts are won or lost.
Excluding your EDR vendor's domains, your backup agent and your patch tool at the top of the query feels efficient and quietly makes those the safest places in your network to hide. Filter on behaviour first, look at the volume of what you are about to exclude, then exclude by exact match with a reason recorded next to each entry.
A worked hunt: DNS beaconing
A worked illustration, with figures chosen to show the arithmetic of the loop rather than taken from a published case.
Hypothesis: an implant on a workstation is using DNS to reach its operator, encoding data in subdomain labels and receiving instructions in TXT answers. Population: 480 reporting workstations. Data: Sysmon event 22 (DNS query) plus the internal resolver's query log. Window: 30 days. Which signals separate a tunnel from ordinary resolution, and why each one alone convicts nobody, is the subject of DNS tunneling. The hunt borrows that signal set and spends its effort on the reduction.
The funnel:
| Stage | Filter applied | Remaining |
|---|---|---|
| Raw | Sysmon 22 across 480 hosts, 30 days | 21,437,912 events |
| Group | Distinct registrable domains | 61,240 domains |
| Volume | More than 200 queries from a single host | 388 domains |
| Shape | Mean subdomain label length over 30 characters | 41 domains |
| Entropy | Mean Shannon entropy of the label above 3.5 bits per character | 14 domains |
| Known-good | Remove vendor telemetry, AV lookup and CDN domains, by exact match | 7 domains |
| Triage | Analyst review of the survivors | 1 domain |
Six of the seven survivors explained themselves quickly: two email security products doing reputation lookups, one licence-check service, and three subdomains of a SaaS product that encodes a session ID into the hostname. Those went onto the exclusion list with a note.
The seventh was cdn-metrics-sync[.]net. It appeared only in the final six days of the window and produced 8,203 queries in that time, all from one host (WKS-4471), all TXT, mean label length 52 characters, mean interval 63.2 seconds with roughly 12 percent jitter around it, and answers between 210 and 240 bytes. No other host in the estate had ever resolved it.
Three follow-up queries turned that into an incident:
- What made the query? The Sysmon 22
Imagefield namedC:\Users\j.rahman\AppData\Local\Programs\Notes\notes.exe, unsigned, in a path no software inventory knew about. - How did it get there? Sysmon 1 showed the binary first executing at the start of that six-day run, with
outlook.exetwo links up the parent chain. - Did it arrange to stay? Sysmon 13 showed a registry write to
HKCU\Software\Microsoft\Windows\CurrentVersion\Run\NotesSyncninety seconds after first execution, which is the standard pattern described in malware persistence techniques.
Interval regularity is the tell that generalises across channels, and why jitter fails to hide it is covered in command and control, with the profile-driven version in Cobalt Strike.
Stack counting, the technique behind step 3
The reduction above used domain-level aggregation. The same move applied to process arguments is the single highest-yield hunting technique on Windows, and it needs no threat intelligence at all. Group by a normalised command line, count, sort ascending.
Thirty days of rundll32.exe executions across the same 480 hosts:
| Normalised command line | Hosts | Executions |
|---|---|---|
rundll32.exe shell32.dll,Control_RunDLL <cpl> | 402 | 18,904 |
rundll32.exe printui.dll,PrintUIEntry <args> | 96 | 1,120 |
rundll32.exe davclnt.dll,DavSetCookie <host> <url> | 3 | 6 |
rundll32.exe C:\Users\<user>\AppData\Local\Temp\ui.dat,Start | 1 | 2 |
The top of that list is the operating system doing its job. The bottom two rows are the hunt. DavSetCookie means a WebDAV fetch, which is worth explaining on three machines. A DLL executed from Temp with a non-standard extension on exactly one host is the row you open first. Neither required knowing an attacker's infrastructure, only knowing that rarity plus a user-writable path is a combination worth a human minute. Which signed binaries carry that risk, and the tradecraft that abuses them, is living off the land.
Normalisation matters here. Lowercase the path, replace GUIDs, usernames, PIDs and hex strings with placeholders, and strip volatile arguments. Without that, a thousand unique command lines that are really one behaviour will sit at the rare end of your stack and bury the actual outlier.
Hunting, alert triage, incident response and red teaming
These get conflated in job descriptions. They differ in what starts them and what they produce.
| Threat hunting | Alert triage | Incident response | Red teaming | |
|---|---|---|---|---|
| Trigger | A hypothesis on a schedule | A detection firing | A confirmed incident | An engagement scope |
| Input | Bulk telemetry | A single alert with context | Everything about one intrusion | Objectives and rules of engagement |
| Output | Detections, gaps, occasional incidents | Verdict on that alert | Containment and recovery | A report of what was reachable |
| Time frame | Days, planned | Minutes, reactive | Hours to weeks, urgent | Weeks, scheduled |
| Success looks like | Better coverage next month | Correct verdicts, fast | Short dwell time, clean recovery | Findings the defenders can act on |
The handoff that matters most runs left to right in the first two columns. A hunt that confirms a compromise stops being a hunt at that moment and becomes an incident, which is the domain of incident response. Resist the urge to keep pulling threads once you know something is live: capture volatile evidence and hand over.
Turning a hunt into a detection
This is the step that compounds. A hunt found once; a detection finds forever, cheaply.
Write down seven things when you promote a hunt:
- The query, in the SIEM's own language, runnable without you.
- The data source and the fields it depends on, so a logging change that breaks it is traceable.
- The exclusions, each with a reason and a date.
- The expected volume, measured by running the tuned query over historical data.
- The ATT&CK technique ID, so coverage can be mapped.
- The responder action, written for someone at 3am with no context.
- The failure condition: what change in the environment would make this rule stop working.
Volume decides the format. Take the DNS hunt above: the entropy-and-length rule on its own returned 41 domains a month, roughly ten a week for a rule with a low hit rate. Combined with the per-host volume threshold and the exclusion list, the tuned version returned three hits over the same 30 days of history, all from the one incident. Three a month with a clear responder action ships as an alert. Forty-one is a scheduled hunt that a human reviews weekly.
Before you ship a detection, run it over the last 30 to 90 days of stored data. That gives you a measured false-positive rate in your environment for free, and it occasionally finds an intrusion that predates the hunt. A rule shipped without a backtest is a guess about volume, and volume is what determines whether anyone will still be reading its output in a month.
Failure modes
The unfalsifiable hypothesis. "Hunt for ransomware precursors" cannot come back empty because it never defined what a hit looks like. Name the behaviour and the field it appears in.
Hunting the matrix top to bottom. ATT&CK has hundreds of techniques and working them in order spends your best analysts on techniques irrelevant to your platform mix. Pick by what an attacker in your estate would plausibly do.
Hunting the tool's demo. If every hunt maps to a feature your vendor showcased, you are testing the product rather than the environment.
The blind spot mistaken for a clean result. Missing hosts, unenabled auditing and short retention all produce empty result sets. Report coverage alongside every finding: "no matches across 480 of 610 workstations, 30 days".
Attackers who know the hunt. Implants deliberately degrade the signals hunts rely on: long sleep intervals to defeat interval analysis, domain fronting to look ordinary, and packing to defeat static checks. Sandbox-aware and obfuscated samples are covered in sandbox evasion and malware obfuscation. The counter is to hunt properties an attacker must keep in order to work at all: something must execute, something must persist, something must call home.
No write-up. Two analysts, three months apart, running the same hunt from scratch because the first one left nothing behind, is the most common way hunting programmes stall.
Alert-queue creep. Once hunters are good at triage they get handed the queue, and the schedule quietly evaporates. Protect hunting time on the roster or it stops happening.
Measuring a hunting programme
The wrong metric is incidents found. Most hunts correctly find nothing, and a team measured on incidents will drift toward hunting the things it already knows are noisy so it has something to report.
Measure instead:
- Detections shipped per quarter, with their measured false-positive rate.
- Visibility gaps found and closed, counted as log sources fixed and hosts brought into coverage.
- Coverage of techniques relevant to your estate, tracked against ATT&CK, and honest about what "covered" means.
- Time from hypothesis to conclusion, which tells you whether your data platform is usable.
- Reruns, meaning how many previous hunts can be re-executed today by someone who did not write them.
Where to start
Five hunts, in this order, that need only telemetry most estates already have.
- New services and scheduled tasks. Stack 7045 and 4698 for 30 days and read the rarest entries. Low volume, high meaning, and the same ground that both persistence and lateral movement cross.
- Rare parent-child process pairs. Stack parent and child image names from Sysmon 1. Office applications spawning script hosts sit at the bottom of that list.
- Autostart writes. Sysmon 13 on Run keys, plus Sysmon 11 for executables written to Startup folders, joined back to the creating process.
- Outbound destinations resolved by exactly one host. Cheap, uses DNS or proxy logs alone, and catches early-stage implants before the operator settles in.
- Console and RDP logons to servers by accounts that have never logged on to them before. 4624 with Logon Type 2 (interactive at the console) and Logon Type 10 (RemoteInteractive, meaning RDP), differenced against a 90-day baseline.
Each produces a stack you can read in an hour and an exclusion list you will reuse in every later hunt.
The verdict
Threat hunting is worth the headcount when three conditions hold: you centralise telemetry with weeks of retention, you can query it yourself, and you protect scheduled time for it. Without those, hunting becomes an aspiration written into a job title while the person does alert triage full time.
The return arrives as detections rather than as discoveries. A team that runs a hunt a fortnight and converts the good ones into tested rules ends the year with two dozen behavioural detections built for its own environment, a documented map of what it cannot see, and analysts who know their estate well enough to recognise wrong when it appears. The occasional live intrusion found along the way is a bonus on top of that.
Related guides
Sources & further reading
- TTP-Based Hunting (MITRE)
- MITRE ATT&CK (MITRE)
- NIST SP 800-92: Guide to Computer Security Log Management (NIST)
- Identifying and Mitigating Living Off the Land Techniques (AA24-038A) (CISA, NSA, FBI)
- Sysmon, Sysinternals Documentation (Microsoft)