A vendor report names OAuth consent persistence — how do you turn it into a testable hunt hypothesis?
answer
- the report is about the world
- make it a claim about your tenant
- name the record, then the killing result
- grants are state, not only events
- agree the no before you query
basics
~20 sRestate the report's technique as a claim about your own tenant, name the record that would carry it — the identity provider's consent and delegated permission-grant entries — and fix the result that would kill the claim before querying anything.
solid answer
~50 sThe report is a claim about the world; a hypothesis has to be a claim about my tenant. So I rewrite it: "a third-party application holds a delegated mail-read scope in our tenant, granted by consent, that is not on our sanctioned integration list." Then I name the observation surface — the identity provider's consent and delegated permission-grant records, which carry the application identifier, the scopes granted, who consented, and whether the consent covered one user or the whole tenant. No endpoint telemetry is involved. Then, with the intel analyst who brought me the report, I write the kill condition: every grant in the population resolves to an application we own or contract for, with scopes matching its documented purpose. That is the sentence worth arguing about, because it is the one that decides whether the hunt can end.
code
json · 7 lines{
"clientId": "8e2f...",
"resourceId": "0a77...",
"consentType": "Principal",
"principalId": "b41c...",
"scope": "Mail.Read offline_access"
}go deeper
Know that a vendor report is not itself a hunt. Be able to restate its technique as one sentence about your own environment and point at the log that would carry it.
Expect to write the skeleton on a whiteboard: behaviour, population and window, observable, kill condition. Explain why an artefact-level condition is weaker than a behavioural one.
Demonstrate the judgment that keeps the hunt decidable: insisting on a stated no before querying, and knowing a consent record proves authorization was granted, not that data moved.
Own how intelligence becomes work. Reports arrive faster than a small team can hunt, so the standard that a report is actionable only once someone writes a falsifiable claim is what stops the backlog turning into a reading list.
## The gap the report leaves A vendor report tells you that somebody, somewhere, was persisted against using a technique. That is not something your telemetry can disprove — your tenant has no opinion about what happened at another company. The hunter's job is to translate it into a claim about **this** estate, and the translation always produces the same four-part skeleton: | Part | For this report | |---|---| | Behaviour | A third-party application holds a delegated mail-read scope granted by consent | | Population + window | Every delegated grant currently present in the tenant, plus every consent recorded in the audit window | | Observable | The identity provider's consent and delegated permission-grant records | | Kill condition | Every grant resolves to an application on the sanctioned integration list, with scopes matching its purpose | If the report cites a technique identifier such as `T1528` (Steal Application Access Token), treat the identifier as a **label for the behaviour**, not as content. It tells you what to write in the first row; it does not write the other three. ## Why this behaviour is worth hunting A consent grant is an authorization that lives beside the password rather than inside it. The application holds its own token material, so resetting the user's password does not remove the grant, and the application keeps whatever scope it was given. That property is exactly why the technique appears in persistence write-ups, and it is why the hypothesis is about *state that exists now*, not only about an event that happened once. ## State versus events — the mistake that hollows out the hunt The audit log is a **stream of events**: a consent was recorded at a point in time. The grant list is **state**: which applications hold which scopes right now. A grant created before your audit window still exists as state today, and a hunt that queries only the event stream will not see it. So the population has two halves — the current grant inventory and the consent events in the window — and the hypothesis should say so. This is a scoping decision, not a retention question; you make it when you write the claim. ## What the record proves, and what it does not A delegated permission grant tells you that consent for those scopes was recorded for that application, by that principal, at one-user or tenant-wide scope. It does **not** tell you that the application ever exercised the scope — whether any mail was actually read is a different source and a different question. It also says nothing about credential theft: consent is given by a user who authenticated normally. Candidates who read a grant record as evidence of data access are making a direction-of-claim error, and interviewers listen for it. ## Two kill conditions that do not work *"No evidence of malicious application consent is found."* Unfalsifiable — *malicious* is the very property under test, so nothing settles it and the hunt never ends. *"No application with the client identifier from the report appears."* Decidable, but it is an artefact lookup rather than a hunt, and it is dead the moment the adversary registers a different application. It also inherits everything wrong with the report's specific infrastructure, which may already be burned. The workable condition names a **checkable property over a stated population**: every grant resolves to something on a list you maintain. Note that this makes the sanctioned-application list part of the hypothesis — and if the list is stale, the hunt discovers that first, which is a useful by-product rather than a failure. ## The argument with the intel analyst This is where the framing is really done. The analyst who brought the report wants the report's claim tested; the hunter needs a claim a query can decide. The productive move is to ask the question in the negative: *what result would you accept as a no?* If the analyst cannot name one, the hunt cannot be scheduled, and saying that plainly is more useful than starting a search that will never conclude. Usually the objection turns out to be about **population** — the analyst thinks the scope is too narrow — and that is fixable by widening the population while keeping the condition crisp, rather than by leaving the hunt open-ended. ## When there is no report at all The same skeleton works from a crown-jewel asset. Start at the thing worth stealing, ask what someone who wanted it would have to do, list the paths, and pick the path whose observable you actually collect. That last filter matters: a beautiful hypothesis about a behaviour nothing records is a collection requirement, not a hunt. ## In the interview Expect to be handed a report summary and asked to produce the hypothesis on the spot. Say the four parts in order, say which telemetry you would *not* need, and finish with the kill condition — interviewers are listening for whether you volunteer the stopping rule without being prompted.
- The report names a technique but no domains and no hashes. Does that make it unhuntable?It makes it more huntable, not less. A behaviour survives the adversary changing infrastructure; an artefact does not. Rewrite the technique as the observable it must produce in your tenant — a consent recorded for an application outside the sanctioned set — and hunt that. The absence of artefacts only means the claim cannot be collapsed into a lookup, which was never the goal.
- You have no report at all, only a crown-jewel mailbox. Where does the hypothesis come from?Start at the asset and work outwards: what would someone who wanted that mailbox do, and which of those paths leaves a record we hold? A delegated mail-read grant is one path; an application permission granted tenant-wide rather than per-user is another. Pick the path whose observable you actually collect, then write the same skeleton — behaviour, population, observable, kill condition.
- The intel analyst will not commit to a kill condition. How do you resolve it?Ask it in the negative: what result would you accept as a no? If no result would, the claim is not a hypothesis and the hunt cannot be scheduled — worth saying plainly rather than starting anyway. In practice the objection is usually that the population is too narrow, which you fix by widening the population while keeping the condition sharp.
saying these in an interview costs you the question
- Hunts the report's domains and hashes instead of the behaviour
- Adopts the report's claim without restating it about the tenant
- Queries only new consent events, missing grants already in place
- Reads a recorded consent grant as proof mail was read
- Leaves the kill condition to be decided after results arrive