What must an empty threat hunt's write-up record for the negative to count as coverage later?
answer
- make the zero re-runnable by a stranger
- hypothesis, logic, sources, window, hosts
- three host numbers, not one
- retention bounds the range, not the time picker
- gaps beside the conclusion, not in an appendix
basics
~20 sRecord the hypothesis and technique identifiers, the exact logic, the sources it ran against, the date range bounded by real retention, the hosts in scope versus searched versus silent, and what a hit would have looked like.
solid answer
~50 sAn empty hunt is only worth what its scope statement is worth, so the write-up has to make the negative re-runnable and bounded. I record the hypothesis and the technique identifiers it maps to; the exact queries and the sources they ran against; the date range, bounded by what those sources actually retained rather than what the time picker offered; the host denominator — in scope, searched, and silent — with the silent ones named; what a hit would have looked like, so a reader can judge what would have been visible; and the variants the logic did not cover. Then the result, and the gaps stated next to the result rather than in an appendix. Six months later that record answers "was this ever looked for here, and how far did it reach?" A record saying "hunted ESXi persistence, no findings" answers nothing.
code
json · 12 lines{
"hunt_id": "HUNT-2026-041",
"hypothesis": "Actor with vCenter admin credentials enables SSH/ESXi Shell on hosts and runs commands locally",
"techniques": ["T1078", "T1021.004", "T1059.004"],
"sources": ["esxi:auth.log", "esxi:shell.log", "vcenter:vpxd.log"],
"window": { "requested_days": 90, "data_actually_retained_days": 14 },
"scope": { "hosts_in_cluster": 48, "hosts_forwarding": 37, "hosts_silent": 11 },
"queries": ["..."],
"expected_hit": "shell.log command execution on a host whose SSH service was enabled outside a change window",
"result": "no matching records",
"gaps": ["11 hosts never forwarded; no endpoint agent exists on ESXi", "vCenter-API-only variant not covered by the logic"]
}go deeper
Know that an empty hunt still gets written up, and be able to list what belongs in it: what you looked for, where, over what dates, and which hosts had no data at all.
You are expected to explain why each field bounds the claim — especially why retention, not the search range, sets the covered window, and why the count of silent hosts belongs in the record.
Show that you treat the write-up as re-runnable evidence: exact logic, source-level naming, and the expected-hit description that proves the query could have matched something.
Own the template and the norm that gaps sit beside conclusions. Decide what a hunt record must contain before it can be counted, and who reads it when a stakeholder asks whether something was ever looked for.
## Why the write-up is the product When a hunt finds something, the finding is the product and the write-up is administration. When a hunt finds nothing — which is most of the time — the write-up **is** the product. There is no artefact, no case, no timeline; there is only the record of what was searched. If that record is thin, the work evaporates, and a year later the same hypothesis gets hunted again from scratch by someone who could not tell what the last person covered. So the standard to write to is: **a competent stranger, six months from now, must be able to re-run this hunt and state its limits without asking you anything.** ## What goes in **The hypothesis, in behavioural terms.** Not "hunted for hypervisor compromise" but the actual proposition: an actor holding virtualisation-administrator credentials enables remote shell access on ESXi hosts and executes commands directly on them. A hypothesis you cannot disagree with is a hypothesis you cannot test. **Technique identifiers.** Map the hypothesis to the behaviours it covers — valid accounts, remote services over SSH, a Unix shell interpreter. Identifiers let a reader compare this hunt with other work without re-reading your prose. Say which sub-variants the logic covered, because "the technique" and "the one implementation described in the write-up I read" are not the same set. **The logic, verbatim.** The queries, exactly as executed, in whatever language your platform speaks. This is what makes the negative re-runnable and what lets a reviewer see that you filtered on a field that was actually populated. **The sources, named at source level.** "ESXi syslog" is too coarse; authentication records, shell command records and the vCenter agent log carry different things and fail independently. **The date range, bounded by real retention.** The number that belongs in the record is the period for which those sources actually held data, not the range the search interface let you select. A ninety-day picker over a fourteen-day stream silently returns nothing for the seventy-six days that never existed. **The host denominator, all three numbers.** Hosts in scope, hosts that delivered data and were therefore searched, and hosts that delivered nothing and were therefore not searched. The third number is the one people delete to make the report look better, and it is the most valuable line in the document. **What a hit would have looked like.** One or two lines describing the record you expected to see if the hypothesis were true. This lets a reader judge the sensitivity of the hunt, and it is the sanity check you should have run against your own logic before concluding. **The result, with its gaps in the same breath.** "No matching records" followed immediately by the sources, hosts and window. Never a bare conclusion with the caveats in an appendix. **Owner, date, and the follow-up asks.** The gaps you found are work for someone; name them as work rather than as observations. ## What it buys you - **Re-runnability.** Next quarter you re-execute the same logic over a wider host set and can say the answerability improved. - **A defensible answer to "was this looked for?"** with edges attached, which is what stops the negative being read as an assurance. - **A gap that has a home.** Eleven hosts outside the telemetry estate is a concrete engineering item, and the hunt record is where it was discovered. - **Reuse.** A colleague hunting an adjacent hypothesis inherits your source map and your knowledge of which hosts are silent, rather than rediscovering it. ## The failure shapes - **The one-liner.** "Hunted ESXi persistence — no findings." Unbounded, unverifiable, and it will be quoted back at you as proof of cleanliness. - **The scope-free zero.** Every technical detail present except the host denominator, so the reader assumes the whole cluster. - **The optimistic window.** The range recorded is the range searched, not the range retained. - **Caveats in the appendix.** Structurally the same as no caveats, because the summary is the only part that travels. - **Silent hosts removed from the denominator.** The number improves and the document starts lying.
- Your write-up says the hunt covered 90 days but the ESXi syslog stream retains 14. What do you change?I change the recorded range to fourteen days and say explicitly that the remaining seventy-six were unavailable, not clean. The searched range and the covered range are different numbers, and only the second is a claim. I would also raise the retention shortfall as a finding of the hunt, because it caps how strong any future negative on those sources can be.
- Why record what a hit would have looked like, when there was no hit?Because it is the only way a reader can judge the hunt's sensitivity, and the only way I can check my own logic. If I cannot describe the record that would have matched, I do not know that my query could have matched anything at all. It also lets the next person tighten or broaden the search without reverse-engineering my intent from the query text.
saying these in an interview costs you the question
- Records the conclusion but not the queries
- Reports one host number instead of three
- Puts scope caveats in an appendix
- Uses the search time picker as the covered range
- Writes the hypothesis as an untestable theme