The Ops Atlas xOps School

Security & Compliance Ambiguous / not standardised Sources verified

ThreatOps

ThreatOps is an unstandardised label. This page uses it for running threat intelligence and threat hunting as one operation: priority intelligence requirements steer what is collected and analysed, and testable hypotheses steer hunts whose findings change defences.

Key takeaways

  • ThreatOps has no standard definition. Vendors use it for an intelligence-driven blocking service, a managed threat-hunting team and a gamified hunting-training programme. This page uses it for intelligence and hunting run as one operation.
  • Start from a short list of priority intelligence requirements (PIRs), each answering one question for one decision. Intelligence nobody asked for is rarely acted on.
  • IP addresses and hashes are cheap for an adversary to change; behaviours (TTPs) cost far more. Give indicators an expiry date and spend analyst time higher up the Pyramid of Pain.
  • A hunt is a testable hypothesis with a scope and a time box. A hunt that finds nothing still succeeds if you are confident you would have seen the activity.
  • Measure effects, not effort: detections created, gaps closed, PIRs answered and decisions changed, not reports written or indicators ingested.
  • Share with TLP 2.0 labels over STIX 2.1 and TAXII 2.1, and check the legal basis where you operate. In the US, check the current sunset date of the Cybersecurity Information Sharing Act of 2015 protections before relying on them.
  • Many organisations should consume intelligence and buy hunting rather than build both. An in-house programme is worth building only when telemetry, data retention and people who act on findings already exist.

ThreatOps, as this page uses the word, is the operation that turns knowledge about adversaries into changed defences. Threat intelligence answers questions decision-makers asked in advance, called priority intelligence requirements (PIRs). Threat hunting tests written hypotheses against your own telemetry for activity that automated detection missed. Both feed detection requests, patch priorities, incident escalations and briefs that change decisions.

NIST defines threat intelligence as “Threat information that has been aggregated, transformed, analyzed, interpreted, or enriched to provide the necessary context for decision-making processes.”[1] Splunk’s PEAK framework defines hunting as “any manual or machine-assisted process intended to find security incidents missed by an organization’s automated detection systems.”[2] ThreatOps runs both as a service with requirements, owners, records and measures.

Who this page is for. Beginners, CTI analysts and hunters, SOC and detection leads who receive the outputs, and leaders deciding whether to build, buy or skip.

Aspect Summary
Goal Defences and decisions that change because of what is known about adversaries
Primary users CTI analysts, threat hunters, SOC and detection leads, CISOs and risk owners
In scope PIRs, source evaluation, analysis and reporting, IOCs versus TTPs, ATT&CK mapping, STIX/TAXII and threat intelligence platforms (TIPs), hunting, sharing through ISACs with TLP
Out of scope Production detection engineering (DetectionOps), alert triage (SOC Ops), incident handling (ResponseOps), vulnerability prioritisation (VulnerabilityOps)
Prerequisites Security telemetry you can query, retained long enough to look back; a team that can act on findings
Key outputs PIR register, intelligence products, hunt records, detection requests, expiring indicator sets, shared reports
Term status Ambiguous label over established practices

Three failures recur without such an operation.

Intelligence without a customer. Teams subscribe to feeds and forward news. FIRST’s CTI SIG (special interest group) says PIRs exist to provide decision-quality information “versus simply ‘reporting the news’”.[3] Without requirements, nobody can say which feed or report was worth its cost.

Indicators treated as intelligence. An IP address or file hash is cheap for the adversary to replace. In David Bianco’s Pyramid of Pain, “the amount of pain you cause an adversary depends on the types of indicators you are able to make use of”.[4] Some adversaries leave few indicators at all. In the 2024 joint advisory on Volt Typhoon, CISA, NSA, FBI and partners wrote that “Conventional IOCs associated with the malicious activity are generally lacking”, and reported indications of footholds kept “for at least five years”.[5]

Waiting for alerts. Mandiant’s M-Trends 2026, based on its own investigations, reports: “Global median dwell time rose to 14 days from 11 days”, and a median of 122 days for cyber-espionage and North Korean IT-worker incidents.[6] Those figures describe Mandiant’s caseload, not every organisation, but they explain proactive search. NIST SP 800-53 Rev. 5 offers hunting as an optional control (RA-10): a capability to “Search for indicators of compromise in organizational systems” and to “Detect, track, and disrupt threats that evade existing controls”.[7]

Without ThreatOps With ThreatOps
Feeds pushed straight into blocking, never expired Indicators rated, labelled, alert-only by default, expiring
Hunting is “searching around” when someone has time Hunts are written hypotheses with scope, time box and record
Findings end in a chat thread Findings become detection requests, gap tickets or incidents

The name. The NIST CSRC glossary returns no results for “threatops”.[8] Vendors use it in at least three senses:

  1. An intelligence-driven blocking service. Centripetal (2022) defines ThreatOps as “the process of operationalizing threat intelligence to shield against all known and emerging attacks”, combining automatic blocking with human hunters.[9]
  2. A managed-hunting team brand. A marketplace listing for Huntress’s managed detection and response (MDR) service calls its human threat hunters “The Huntress ThreatOps team”.[10]
  3. A gamified hunting-training programme. SentinelOne’s ThreatOps (2020–2026) is an “industrial-scale gamified platform” for hunting practice, run by its solutions engineers and also used in sales evaluations.[11]

The spaced phrase “threat operations” is a separate case: platform vendors use it loosely, as in ThreatQuotient’s “We believe the foundation of threat operations is people.”[12] None of these is a community standard, so this page classifies the label as ambiguous and adopts one reading.

What else it is not.

  • Not a feed subscription. Feeds are raw collection; FIRST’s early-stage guidance uses them for “flagging/alerting but not automated blocking”.[13]
  • Not threat modelling. Modelling an application’s design belongs to DevSecOps; ThreatOps feeds it adversary knowledge.
  • Not the SOC. Triage and 24×7 monitoring belong to SOC Ops; a hunter escalates and does not run the incident.

The vocabulary comes from government intelligence; the cyber practice formed through public papers and standards:

Year Milestone
2011 Hutchins, Cloppert and Amin, Intelligence-Driven Computer Network Defense: the intrusion kill chain; atomic, computed and behavioural indicators[14]
2013 Diamond Model of Intrusion Analysis (adversary, infrastructure, capability, victim)[15]; Bianco’s Pyramid of Pain[4]
2015 Sqrrl hunting reference model and Hunting Maturity Model (HMM)[2][16]
2016, 2018 NIST SP 800-150 on cyber threat information sharing;[17] CSF 1.1 outcome ID.RA-2: CTI “is received from information sharing forums and sources”[18]
2018 TaHiTI hunting methodology, Dutch Payments Association (as described by Bianco)[2]
2021 STIX 2.1 and TAXII 2.1 approved as OASIS Standards[19][20]
2022 TLP 2.0 authoritative from August 2022[21]
2023 PEAK hunting framework (Splunk SURGe)[2]
2024 NIST CSF 2.0 keeps it as ID.RA-02 and adds DE.AE-07: CTI integrated into the analysis of adverse events[22]
2026 CTI-CMM 1.3 (January); ATT&CK v20 (13 October)[23][24]
Term Meaning on this page Example
PIR Priority intelligence requirement. FIRST’s criteria: “ask only one question”, focus on “a specific fact, event, or activity”, support “a single decision”[25] “Is any group exploiting our VPN product family this quarter?”
Strategic, operational, tactical intelligence Audience levels: leaders; security managers; analysts and tools. FIRST adds “technical” at the bottom[26] Board brief; hunt plan; watchlist
IOC Indicator of compromise: an observable such as an IP, domain or hash 203.0.113.50 seen in a phishing wave
TTP Tactics, techniques and procedures: how an adversary operates Flooding a user with MFA prompts
Pyramid of Pain Indicator types ordered by how much it costs the adversary when you deny them[4] Hashes at the bottom, TTPs at the top
MITRE ATT&CK A knowledge base of adversary tactics and techniques “based on real-world observations”[27] T1621 MFA Request Generation
STIX 2.1 / TAXII 2.1 OASIS standards: a JSON language for CTI, and an HTTPS API to exchange it[19][20] An Indicator object served from a TAXII Collection
TIP Threat intelligence platform: stores, scores, links and distributes intelligence MISP, OpenCTI
TLP Traffic Light Protocol 2.0 labels: TLP:RED (named recipients only), TLP:AMBER (recipient’s organisation and clients, need to know; TLP:AMBER+STRICT = the organisation only), TLP:GREEN (the community), TLP:CLEAR (no limit)[21] TLP:AMBER+STRICT
Hunt (hypothesis-driven) A testable supposition checked against data; PEAK describes it with ABLE: Actor, Behavior, Location, Evidence[28] “A crew is pushing MFA prompts at finance staff”
Baseline hunt Learn what normal looks like, then examine deviations[2] Rare parent–child process pairs
Retro-hunt (sweep) Search past data for newly published indicators Advisory hashes over 90 days of endpoint data
ISAC Information Sharing and Analysis Center, usually sector-based[29] A financial-sector ISAC
Diamond Model An intrusion event has four linked features (adversary, infrastructure, capability, victim); analysts pivot from one to the others[15] Malware → its command-and-control (C2) domain and IP → other hosts calling that IP
RFI Request for information: a one-off question outside the PIR register “Is this phishing kit linked to a known crew?”
Data acronyms SIEM: security information and event management; EDR: endpoint detection and response; IdP: identity provider; ASN: autonomous system number (an IP’s network); OSINT: open-source intelligence Lab 2

Mental model: two loops and a pyramid. The intelligence loop decides what matters; the hunt loop checks whether it is happening here; the pyramid decides how durable the defence will be.

The Atlas divides security operations by the flow of work; SecOps is the hub.

Figure 1. Where ThreatOps sits in the security-operations flow
data for huntsdetection requestexploitation intelalertslive findinglessons, IOCspatternsSecDataOps: telemetryThreatOps: requirements,intel, huntsDetectionOps:detectionsVulnerabilityOpsSOC Ops: triageResponseOps:incidents
Diagram source (Mermaid)
flowchart TB
  SD["SecDataOps: telemetry"]
  TO["ThreatOps: requirements,<br/>intel, hunts"]
  DO["DetectionOps:<br/>detections"]
  VO["VulnerabilityOps"]
  SOC["SOC Ops: triage"]
  RO["ResponseOps:<br/>incidents"]
  SD -->|"data for hunts"| TO
  TO -->|"detection request"| DO
  TO -->|"exploitation intel"| VO
  DO -->|"alerts"| SOC
  TO -->|"live finding"| RO
  RO -.->|"lessons, IOCs"| TO
  SOC -.->|"patterns"| TO
  VO ~~~ RO
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef neutral fill:#f1f4f6,stroke:#5b7a87,color:#122029
  class TO core
  class SD,DO,VO,SOC,RO neutral

Text equivalent: SecDataOps supplies telemetry to ThreatOps. ThreatOps sends detection requests to DetectionOps, exploitation intelligence to VulnerabilityOps and live findings to ResponseOps; DetectionOps alerts go to SOC Ops. Dotted feedback edges: ResponseOps returns lessons and new indicators, SOC Ops returns recurring patterns that become hunt topics.

Neighbour ThreatOps owns The neighbour owns
DetectionOps PIRs, hypotheses, hunt findings, the detection request Writing, testing, deploying and tuning production detections
SOC Ops Proactive search without an alert Alert queues, triage, shifts and SLAs
ResponseOps Scoping hunts and intelligence during incidents Containment, eradication, evidence, notification
VulnerabilityOps Exploitation intelligence for your estate Prioritising and tracking fixes (CISA’s KEV catalogue of exploited CVEs, EPSS exploit-probability scores, SLAs)
SecDataOps Stating which data the hunts need Collecting, parsing and retaining it

No official ThreatOps manifesto exists; this charter is this Atlas’s proposal.

Mission. Reduce adversaries’ time and room in our environment by deciding what to look for, looking, and turning what we learn into defences that run without us.

Principles.

  1. Requirements first. Every product and hunt traces to a PIR or a named stakeholder’s question. FIRST: PIRs “are not infinite, they must be limited and well-scoped to key decision points”; “Less is more.”[3]
  2. Climb the pyramid. Use atomic indicators quickly and let them expire; invest analyst time in behaviours.[4]
  3. Hypotheses are testable and time-boxed. A hunt states what would prove or disprove it, where, and in which data.[28]
  4. Every hunt ends in an artefact: a detection request, gap ticket, escalation, or a record that the activity would have been visible.[30]
  5. Say how sure you are. Each judgement carries a probability word and a confidence level, as FIRST recommends.[31]
  6. Share by default within the label. Use TLP; remove personal data the recipient does not need.
  7. Automation for volume, people for judgement. Assessments, PIR changes, attribution and blocking have a named human owner. Anyone on call may remove a blocking indicator at once and must record it; the CTI lead reviews within an hour.

Non-goals. Building a library of every actor; running production detections; operating the incident; buying every feed.

Block Minimum viable form
PIR register A reviewed table of 5–8 PIRs with owners and review dates
Collection plan A source list with A–F and 1–6 ratings[32]
Knowledge store A TIP (MISP, OpenCTI) or, early on, a version-controlled repository
Analytic standard Probability word plus confidence; assumptions listed; peer review for products leaving the team
Hunt programme One recorded hunt a fortnight
Dissemination paths Brief for leaders, ticket for engineers, STIX/TAXII for tools
Sharing agreements ISAC membership, TLP policy, legal sign-off

Analytic rigour. Analysts tend to settle on the first explanation that fits. The US government’s tradecraft primer counters this with structured techniques: a key assumptions check lists what a judgement rests on; analysis of competing hypotheses (ACH) tests each piece of evidence against every plausible explanation, aiming to disprove rather than confirm.[33] Use ACH for contested judgements such as attribution; evidence that fits every hypothesis decides nothing.

Small organisations combine these roles; in an early programme FIRST calls the CTI analyst role “typically a secondary duty”.[13] One accountable owner per activity is what matters.

Activity CTI lead Analyst or hunter Detection engineering SOC or IR lead CISO, risk owners
Set and review PIRs R C I C A
Rate sources, manage feeds A R I I I
Write intelligence products A R I C I
Run a hunt A R C I I
Escalate live malicious activity I R I A I
Build the production detection C C A/R C I
Allow a feed to auto-block C C R C A
Share outside the organisation A R I C I

R = responsible, A = accountable, C = consulted, I = informed. Legal and privacy (not shown) are consulted on PIRs, source terms and every external share.

Lifecycle: the intelligence loop and the hunt loop

Link to section “Lifecycle: the intelligence loop and the hunt loop”

FIRST’s CTI SIG settled on a six-step cycle: “Direction, Collection, Processing, Analysis, Dissemination, Feedback (Review)”.[34] PEAK structures each hunt as Prepare, Execute and Act, with knowledge feeding every phase.[2]

Figure 2. The intelligence loop and the hunt loop
revise PIRshunt topicsinternal intelDirection: PIRsCollectionProcessingAnalysisDisseminationFeedbackHunt loop (PEAK):topic and hypothesisPrepare: scope, dataExecute: analyseAct: record, hand off
Diagram source (Mermaid)
flowchart TB
  D1["Direction: PIRs"] --> C1["Collection"]
  C1 --> P1["Processing"]
  P1 --> A1["Analysis"]
  A1 --> S1["Dissemination"]
  S1 --> F1["Feedback"]
  F1 -->|"revise PIRs"| D1
  A1 -->|"hunt topics"| H1["Hunt loop (PEAK):<br/>topic and hypothesis"]
  H1 --> H2["Prepare: scope, data"]
  H2 --> H3["Execute: analyse"]
  H3 --> H4["Act: record, hand off"]
  H4 -->|"internal intel"| C1
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef decision fill:#fdf3e3,stroke:#c9800f,color:#122029
  class D1,C1,P1,A1,S1,F1 core
  class H1,H2,H3,H4 decision

Text equivalent: The intelligence loop runs Direction (PIRs), Collection, Processing, Analysis, Dissemination and Feedback, which revises the PIRs. Analysis sends hunt topics into the hunt loop (orange nodes, PEAK): topic and hypothesis, Prepare (scope, data), Execute (analyse) and Act (record, hand off), which returns internal intelligence to Collection.

Day 0, 1 and 2. Day 0 agrees PIRs, data access and sharing rules; Day 1 delivers first products and hunts; Day 2 is reviews (Operating model and governance), expiry and measurement (Metrics and KPIs).

Cadence Forum Inputs Decisions
Daily (15 min) Intelligence triage New advisories, ISAC posts, RFIs Retro-hunt or not; owner
Weekly Hunt planning Backlog, PIR gaps, incidents, data gaps Next hunts and time boxes
Monthly Outputs review with detection and SOC leads Detection requests, gaps, feed precision Detection priorities; feeds to drop
Quarterly PIR review with stakeholders Feedback, threat changes, metrics Retire, add or rewrite PIRs; budget

FIRST’s PIR guidance quotes the line “If PIRs don’t change, you’re fighting the plan and not the enemy”.[3] Requests for information. Stakeholders also send one-off RFIs; CTI-CMM treats them as an input to detection engineering and an output of hunting.[23] Log each (see Templates); a recurring RFI is a PIR candidate.

Escalation rule: a hunter who sees likely malicious activity escalates at once to the incident process (PEAK’s “Escalate Critical Findings” step) and keeps hunting only with the incident lead’s agreement.[28] Incident scoping. During an incident, ResponseOps asks ThreatOps to find every foothold and to hunt again until a cycle finds nothing new; the incident lead sets priorities, and queries and results are evidence.

A ThreatOps architecture is mostly data handling with two trust boundaries: untrusted intelligence in, sensitive intelligence out.

Figure 3. Reference architecture: from sources to defences and back out
ConsumersExternal, untrustedISAC andgov feedsCommercialintelAdvisories,OSINTInternal:incidents, huntsTIP: rate,expire, labelSIEM, EDRwatchlistsHunt backlogVulnerabilityOpsLeadershipbriefsSharing gateto partners
Diagram source (Mermaid)
flowchart LR
  subgraph IN["External, untrusted"]
    direction TB
    S1["ISAC and<br/>gov feeds"]
    S2["Commercial<br/>intel"]
    S3["Advisories,<br/>OSINT"]
  end
  S4["Internal:<br/>incidents, hunts"]
  TIP["TIP: rate,<br/>expire, label"]
  subgraph OUT["Consumers"]
    direction TB
    O1["SIEM, EDR<br/>watchlists"]
    O2["Hunt backlog"]
    O3["VulnerabilityOps"]
    O4["Leadership<br/>briefs"]
  end
  GATE["Sharing gate<br/>to partners"]
  S1 --> TIP
  S2 --> TIP
  S3 --> TIP
  S4 --> TIP
  TIP --> O1
  TIP --> O2
  TIP --> O3
  TIP --> O4
  TIP --> GATE
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef risk fill:#fbeceb,stroke:#b4332b,color:#122029
  classDef neutral fill:#f1f4f6,stroke:#5b7a87,color:#122029
  class TIP core
  class GATE risk
  class S1,S2,S3,S4,O1,O2,O3,O4 neutral

Text equivalent: Three external, untrusted sources (ISAC and government feeds, commercial intelligence, advisories and open sources) and one internal source (own incidents and hunts) flow into a threat intelligence platform that rates, expires and labels them. It feeds SIEM and EDR watchlists, the hunt backlog, VulnerabilityOps and leadership briefs. Anything leaving the organisation passes a sharing gate on its way to partners.

Component Design choice and trade-off
Inbound connectors Prefer TAXII 2.1 where offered; CISA’s AIS, for example, expects a TAXII 2.1 client[35]
Watchlists Alert-only by default; blocking only for feeds with measured precision
Sharing gate Enforces TLP, strips unneeded personal data, records approvals; slower beats unrecorded

Alternatives. A small team can start with a version-controlled repository instead of a TIP; for bought hunting, see When to use.

Figure 4. From trigger to closed hunt, with exception paths
noyesnoyesnoyesnoyesTrigger: advisory, PIRor incident lessonRelevantto a PIR?Log, close,review PIRsRetro-hunt any indicators,set expiryWrite hypothesis(ABLE)Dataavailable?Gap ticketto SecDataOpsHunt withintime boxBaseline hunt:new data sourcea PIR needsMaliciousactivity?Would we haveseen it?Escalate toResponseOpsDetection requestto DetectionOpsRecord hunt,update PIR
Diagram source (Mermaid)
flowchart TB
  T["Trigger: advisory, PIR<br/>or incident lesson"] --> Q1{"Relevant<br/>to a PIR?"}
  Q1 -->|"no"| L["Log, close,<br/>review PIRs"]
  Q1 -->|"yes"| R["Retro-hunt any indicators,<br/>set expiry"]
  R --> H["Write hypothesis<br/>(ABLE)"]
  H --> Q2{"Data<br/>available?"}
  Q2 -->|"no"| G["Gap ticket<br/>to SecDataOps"]
  Q2 -->|"yes"| X["Hunt within<br/>time box"]
  B["Baseline hunt:<br/>new data source<br/>a PIR needs"] --> X
  X --> Q3{"Malicious<br/>activity?"}
  Q3 -->|"no"| Q4{"Would we have<br/>seen it?"}
  Q3 -->|"yes"| E["Escalate to<br/>ResponseOps"]
  Q4 -->|"no"| G
  Q4 -->|"yes"| DR["Detection request<br/>to DetectionOps"]
  E --> DR
  DR --> REC["Record hunt,<br/>update PIR"]
  G --> REC
  classDef decision fill:#fdf3e3,stroke:#c9800f,color:#122029
  classDef risk fill:#fbeceb,stroke:#b4332b,color:#122029
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  class Q1,Q2,Q3,Q4 decision
  class E,G risk
  class T,B,R,H,X,DR,REC,L core

Text equivalent: A trigger (advisory, PIR or incident lesson) that matches no PIR is logged and closed, and the PIRs reviewed. A matching trigger leads to a retro-hunt of any indicators it supplies, with expiry dates, then an ABLE hypothesis. Without data, a gap ticket goes to SecDataOps; otherwise the hunt runs in its time box. A new data source a PIR needs enters there as a baseline hunt, with no hypothesis. Malicious activity is escalated to ResponseOps and yields a detection request. If nothing is found: would it have been visible? No means a gap ticket; yes means a detection request to DetectionOps. Every path ends with the hunt recorded and the PIR updated.

Acceptance criteria for “done”. The record states hypothesis, data and time range searched, queries, verdict and artefacts, so a reviewer who was not on the hunt can rerun it.

Practice Trigger Owner Done when
Write and review PIRs Quarterly; major change CTI lead with stakeholders One question, decision, owner and review date each
Rate sources New feed or contact; quarterly Analyst Every source has an A–F rating and a use note
Handle indicators Indicator received Analyst, automated in the TIP No active atomic indicator without an expiry date
Retro-hunt Credible advisory matching a PIR Hunter Searched window stated; hits escalated
Hypothesis hunt Backlog item Hunter Verdict plus at least one artefact
Baseline hunt New data source[36] Hunter Normal described well enough to define “abnormal”
Write a product PIR due, significant event Analyst; peer reviewer Decision owner confirms it answers the PIR
Share Finding useful to peers Analyst; approver Approval recorded; personal data checked

Three details that are easy to get wrong.

  • Source evaluation. FIRST recommends rating source reliability from A (“Reliable”) to E, with F for “Cannot be judged”, and the information from 1 (“Confirmed”) to 5, with 6 for “Cannot be judged”. Its example rates a trusted provider’s new experimental feed “A3”: good source, untested information.[32]
  • Indicator lifecycle. STIX makes valid_until optional, and without it “there is no constraint on the latest time for which the Indicator is valid”.[19] Set it yourself: short for IPs, longer for domains, longest for behavioural detections, and record why.
  • Estimative language. FIRST recommends the NATO Words of Estimative Probability (WEP; for example “Likely” for 60–90%) and confidence levels (High, Moderate, Low), used for each judgement “but not in the same sentence”.[31]
Figure 5. The Pyramid of Pain as a handling policy
TTPs: hunt and detectbehaviourTools: detect tool use, shareanalysisHost and network artifacts:huntDomains: alert, expire inweeksIP addresses: alert, expire indaysHash values: match; blockonly via the policy gateLegend: teal = analyst time;grey = automated, expiring;higher = costlier for theadversary
Diagram source (Mermaid)
flowchart TB
  P6["TTPs: hunt and detect behaviour"]
  P5["Tools: detect tool use, share analysis"]
  P4["Host and network artifacts: hunt"]
  P3["Domains: alert, expire in weeks"]
  P2["IP addresses: alert, expire in days"]
  P1["Hash values: match; block only via the policy gate"]
  P6 --- P5
  P5 --- P4
  P4 --- P3
  P3 --- P2
  P2 --- P1
  P1 ~~~ L["Legend: teal = analyst time;<br/>grey = automated, expiring;<br/>higher = costlier for the adversary"]
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef neutral fill:#f1f4f6,stroke:#5b7a87,color:#122029
  classDef legend fill:#ffffff,stroke:#c9d6da,color:#122029
  class P6,P5,P4 core
  class P3,P2,P1 neutral
  class L legend

Text equivalent: Bianco’s six levels, top to bottom, with suggested handling: TTPs (hunt and detect behaviour), tools (detect tool use, share analysis), host and network artifacts (hunt), domains (alert, expire in weeks), IP addresses (alert, expire in days), hash values (match; block only through the policy gate below). Higher levels cost the adversary more to change. Teal levels get analyst time; grey levels are automated and expire. The handling is this Atlas’s suggestion, not Bianco’s.

Name Kind What it gives ThreatOps
NIST SP 800-53 Rev. 5 RA-10, PM-16, PM-16(1), RA-3(3) Optional: RA-10 and RA-3(3) are in no SP 800-53B baseline; PM-16 and PM-16(1) are organisation-level programme controls[37] Hunting; a threat awareness programme with “a cross-organization information-sharing capability”; automated sharing[7]
NIST CSF 2.0 ID.RA-02, DE.AE-07 Framework outcomes Receiving CTI; integrating it into the analysis of adverse events[22]
NIS2 Article 29 EU law (through national transposition) Voluntary exchange of IOCs, “adversarial tactics, threat-actor-specific information” within communities[38]
STIX 2.1, TAXII 2.1 OASIS Standards (2021) Exchange format and API[19][20]
TLP 2.0 FIRST standard (2022) Sharing labels[21]
MITRE ATT&CK v20 Knowledge base Shared vocabulary for behaviour; 15 Enterprise tactics and 227 techniques (October 2026)[24]
Kill chain, Diamond Model, Pyramid of Pain Analytic models Phases, pivots and indicator value[14][15][4]
PEAK; Sqrrl model; TaHiTI Hunting frameworks Hunt types, phases, deliverables[2]
FIRST CTI curriculum; CTI-CMM Practitioner guidance and maturity model PIRs, source ratings, uncertainty language; stakeholder-based maturity[3][23]

ATT&CK’s FAQ says “Tactics are unordered and may not all occur in a single intrusion”, unlike the kill chain’s ordered phases.[39] And the catalogue changes: v20 lists “Stealth” (TA0005) and a separate “Defense Impairment” tactic (TA0112), so coverage maps that say “Defense Evasion” need re-mapping.[40]

Choose by job, not brand; checked October 2026.

Job Representative options Strengths Watch-outs
Store, correlate and share intelligence MISP (open source; 2.5.x, October 2026; security releases are frequent, so track the release feed)[41] Correlation, sightings, ATT&CK galaxies, sharing groups, STIX import and export, REST API[42] Community sync needs governance
Model knowledge as a graph OpenCTI (Filigran): Community Edition under Apache 2.0, Enterprise Edition under a separate licence[43] Knowledge schema based on STIX 2; connectors to MISP and ATT&CK Check which features are Enterprise-only
Government and sector sharing CISA AIS (no cost; TAXII 2.1)[35]; ISACs[29] Sector-relevant, often early Eligibility, terms of use, sharing obligations
Behaviour catalogue ATT&CK STIX data and TAXII server[27][44] Machine-readable, versioned The public TAXII server allows 50 requests per 10 minutes per IP
Hunt data and analysis Your SIEM, EDR, data lake, notebooks Where the evidence is Retention and field quality decide what a hunt can prove

Selection criteria. Expiry, confidence and TLP per object; lossless STIX 2.1 import and export; scriptability; who maintains it when the champion leaves. Keep PIRs and hunt records in a format you own.

Automate the volume work: pulling feeds, de-duplication, enrichment, expiry and watchlist updates. In FIRST’s mature stage, repeatable processes are heavily automated and people work “from TTPs level and above”.[26] Language models can draft summaries, extract indicators and suggest ATT&CK mappings; treat their output as an unrated source, check it against the original, and never let a model assign confidence or TLP. Evaluating and governing such tools is covered in AIOps for Security.

For an illustrative mid-size company (one CTI analyst, one part-time hunter, a SIEM, EDR and an IdP), two artefacts carry most of the design: the PIR register and the indicator policy.

Example status: YAML syntax-checked by the Atlas validator; not executed (these are configuration records, not programs).

# pir-register.yaml - one question, one decision, one owner per PIR (illustrative)
version: 2026-Q4
review_by: 2027-01-15
pirs:
  - id: PIR-01
    question: >-
      Is any intrusion set exploiting remote-access products we expose
      (VPN, virtual desktops) against organisations in our sector this quarter?
    decision: Emergency patching or isolation of exposed remote-access services
    decision_owner: Head of Infrastructure
    level: operational
    sources: [SECTOR-ISAC, CISA-AIS, VENDOR-ADVISORIES, OWN-EDGE-LOGS]
    outputs: [retro-hunt, exploitation intel to VulnerabilityOps, brief]
    review: monthly
  - id: PIR-02
    question: >-
      Are identity-focused extortion crews targeting our help desk or MFA,
      and would our current telemetry show it?
    decision: Help-desk identity verification and MFA method policy
    decision_owner: CISO
    level: operational
    sources: [SECTOR-ISAC, ATTACK-V20, IDP-LOGS, HELPDESK-TICKETS]
    outputs: [hypothesis hunts, detection requests, gap tickets]
    review: quarterly
  - id: PIR-03
    question: >-
      Which threat developments in the next 12 months should change our
      security investment plan?
    decision: Annual security budget allocation
    decision_owner: Executive risk committee
    level: strategic
    sources: [SECTOR-ISAC, VENDOR-ANNUAL-REPORTS, GOVERNMENT-ADVISORIES]
    outputs: [semi-annual strategic brief]
    review: semi-annual
# indicator-policy.yaml - local defaults; tune with measured precision (illustrative)
default_action: alert            # blocking is the exception, not the default
expiry_days:                     # sets STIX valid_until when the source gave none
  ipv4-addr: 14
  domain-name: 60
  url: 30
  file-hash-sha256: 365
block_allowed_when:
  source_reliability_in: [A, B]
  information_credibility_in: [1, 2]
  feed_precision_90d_min: 0.9    # confirmed-malicious hits / investigated hits
  not_on_allowlists: [cdn-ranges, cloud-provider-ranges, partner-ranges]
unlabelled_inbound_treated_as: TLP:AMBER   # local policy, not part of TLP
revert:                          # a blocking feed is a production control
  allowed_by: anyone-on-call     # remove the indicator first, ask later
  record: [who, when, indicator, feed, reason]
  reviewed_by: cti-lead
  review_within_hours: 1
review:
  stale_indicator_report: weekly
  owner: cti-lead

The blocking rule follows FIRST’s staging: early programmes alert rather than block; later ones may block from automatic feeds “if appropriate”, and “Careful consideration is required”.[13][45] The gate covers every type, hashes included: a feed can list a legitimate admin tool. The 0.9 threshold and expiry periods are illustrative; set yours from your own hit data.

The labs need only a laptop, cost nothing and touch no production system. All were executed on 2026-10-16 and again on 2026-10-17 (Python 3.8.10, SQLite 3.31.1), except the optional TAXII step of Lab 3.

Lab 1 (beginner): turn a PIR into a ranked hunt backlog with ATT&CK data

Link to section “Lab 1 (beginner): turn a PIR into a ranked hunt backlog with ATT&CK data”

Objective: rank the techniques that PIR-02’s intrusion sets are publicly known to use, so the first hunts target shared behaviour. Prerequisites: Python 3.8 or later, internet access, about 60 MB of disk and 300 MB of memory (peak measured: 280 MB). Cost and risk: none.

  1. Download the Enterprise ATT&CK v20.0 bundle (STIX 2.1) from MITRE’s repository (commands below).[27] The pinned file keeps the output reproducible; the unversioned enterprise-attack.json always holds the latest release.
  2. Save the script below as hunt_backlog.py.
  3. Run it with the ATT&CK group IDs for Scattered Spider (G1015), LAPSUS$ (G1004) and Akira (G1024).
  4. Replace the IDs with the groups your own PIR names, and keep the output with the PIR record.
BASE=https://raw.githubusercontent.com/mitre-attack/attack-stix-data/master
curl -L -o enterprise-attack-20.0.json \
  "$BASE/enterprise-attack/enterprise-attack-20.0.json"
python3 hunt_backlog.py enterprise-attack-20.0.json G1015 G1004 G1024

Example status: executed on 2026-10-16 and 2026-10-17 against ATT&CK v20.0 (bundle modified 2026-10-13).

"""Rank ATT&CK techniques by how many priority groups use them.

Usage: python3 hunt_backlog.py enterprise-attack-20.0.json G1015 G1004 G1024
"""
import json
import sys
from collections import defaultdict


def attack_id(obj):
    for ref in obj.get("external_references", []):
        if ref.get("source_name") == "mitre-attack":
            return ref.get("external_id")
    return None


def active(obj):
    return not obj.get("revoked") and not obj.get("x_mitre_deprecated")


def main(path, group_ids):
    with open(path, encoding="utf-8") as fh:
        objects = json.load(fh)["objects"]
    by_id = {o["id"]: o for o in objects}
    version = next(o["x_mitre_version"] for o in objects
                   if o["type"] == "x-mitre-collection")
    groups = {o["id"]: o for o in objects
              if o["type"] == "intrusion-set" and active(o)
              and attack_id(o) in group_ids}
    missing = set(group_ids) - {attack_id(g) for g in groups.values()}
    if missing:
        sys.exit(f"Unknown or deprecated group IDs: {sorted(missing)}")

    users = defaultdict(set)  # technique STIX id -> group names
    for rel in objects:
        if (rel["type"] == "relationship" and active(rel)
                and rel["relationship_type"] == "uses"
                and rel["source_ref"] in groups
                and rel["target_ref"].startswith("attack-pattern--")):
            tech = by_id.get(rel["target_ref"])
            if tech and active(tech):
                users[tech["id"]].add(groups[rel["source_ref"]]["name"])

    rows = []
    for tid, names in users.items():
        tech = by_id[tid]
        tactics = sorted(p["phase_name"] for p in tech.get("kill_chain_phases", []))
        rows.append((len(names), attack_id(tech), tech["name"], tactics))
    rows.sort(key=lambda r: (-r[0], r[1]))

    print(f"ATT&CK Enterprise v{version}; groups: "
          + ", ".join(sorted(g["name"] for g in groups.values())))
    print(f"{len(rows)} distinct techniques; "
          f"{sum(1 for r in rows if r[0] == len(groups))} used by all groups")
    for count, tid, name, tactics in rows[:12]:
        more = f" +{len(tactics) - 1}" if len(tactics) > 1 else ""
        print(f"{count}/{len(groups)}  {tid:<10} {name[:38]:<38} {tactics[0]}{more}")


if __name__ == "__main__":
    if len(sys.argv) < 3:
        sys.exit(__doc__)
    main(sys.argv[1], set(sys.argv[2:]))

Expected output (verified by execution; counts change with each ATT&CK release):

ATT&CK Enterprise v20.0; groups: Akira, LAPSUS$, Scattered Spider
92 distinct techniques; 2 used by all groups
3/3  T1078      Valid Accounts                         initial-access +3
3/3  T1133      External Remote Services               initial-access +1
2/3  T1003.003  NTDS                                   credential-access
2/3  T1018      Remote System Discovery                discovery
2/3  T1021.001  Remote Desktop Protocol                lateral-movement
2/3  T1059.001  PowerShell                             execution
2/3  T1068      Exploitation for Privilege Escalation  privilege-escalation
2/3  T1069.002  Domain Groups                          discovery
2/3  T1078.004  Cloud Accounts                         initial-access +3
2/3  T1087.002  Domain Account                         discovery
2/3  T1090      Proxy                                  command-and-control
2/3  T1098.003  Additional Cloud Roles                 persistence +1

+3 means three more tactics. Validation: open T1133 on attack.mitre.org; its procedure examples include all three groups. Limits: only direct group links count, not links through software or campaigns: T1098.005 Device Registration (Lab 2) reaches Scattered Spider only through campaign C0027, so it is missing here.[46] Troubleshooting: “Unknown or deprecated group IDs” (exit code 1) means a typo or a revoked group. Teardown: delete the files.

Lab 2 (intermediate): run a hypothesis-driven hunt on sign-in logs

Link to section “Lab 2 (intermediate): run a hypothesis-driven hunt on sign-in logs”

Objective: test a written hypothesis, then act on the result. Prerequisites: Python 3 with its built-in sqlite3; the synthetic file below (documentation IP ranges, invented users). Cost and risk: none; never copy real sign-in logs to a laptop without approval.

Hypothesis, in PEAK’s ABLE form:[28] Actor: identity-focused extortion crews (PIR-02). Behavior: MFA push flooding (ATT&CK T1621) until the user approves, then registering a new MFA method (T1098.005 Device Registration). Location: the workforce IdP. Evidence: IdP sign-in and audit events: a burst of mfa_denied, then success from a network (ASN) new for that user, then mfa_method_added within an hour. PEAK advises hunting “one or two pieces” of behaviour at a time, not a whole attack chain;[28] this hypothesis chains exactly two.

  1. Save the data as signins.csv and the script as hunt_mfa.py.
  2. Run python3 hunt_mfa.py signins.csv.
  3. Run again with --min-denials 1 and explain the extra row.
  4. Act: write a detection request for the HIGH pattern (template in Templates) and a reset-and-verify task for the LEAD.
ts,user,event,src_ip,asn
2026-10-01T08:02:00Z,amara,success,198.51.100.10,64500
2026-10-01T08:05:00Z,li,success,198.51.100.11,64500
2026-10-02T08:01:00Z,amara,success,198.51.100.10,64500
2026-10-02T09:15:00Z,jonas,success,198.51.100.12,64500
2026-10-03T08:03:00Z,li,success,198.51.100.11,64500
2026-10-14T02:10:00Z,li,mfa_denied,203.0.113.50,64511
2026-10-14T02:11:00Z,li,mfa_denied,203.0.113.50,64511
2026-10-14T02:13:00Z,li,mfa_denied,203.0.113.50,64511
2026-10-14T02:16:00Z,li,mfa_denied,203.0.113.50,64511
2026-10-14T02:19:00Z,li,success,203.0.113.50,64511
2026-10-14T02:24:00Z,li,mfa_method_added,203.0.113.50,64511
2026-10-14T07:58:00Z,amara,mfa_denied,198.51.100.10,64500
2026-10-14T07:59:00Z,amara,success,198.51.100.10,64500
2026-10-15T11:00:00Z,jonas,mfa_denied,192.0.2.77,64499
2026-10-15T11:01:00Z,jonas,mfa_denied,192.0.2.77,64499
2026-10-15T11:02:00Z,jonas,mfa_denied,192.0.2.77,64499
2026-10-15T11:30:00Z,jonas,success,198.51.100.12,64500

Example status: executed on 2026-10-16 with the synthetic data above.

"""Hunt: MFA flooding (T1621), sign-in from a new network, new MFA method (T1098.005).

Usage: python3 hunt_mfa.py signins.csv [--min-denials 3] [--window-min 15]
"""
import argparse
import csv
import sqlite3

QUERY = """
WITH bursts AS (
  SELECT d.user, MAX(d.ts) AS last_denial, COUNT(*) AS denials, d.asn
  FROM ev d
  WHERE d.event = 'mfa_denied'
  GROUP BY d.user, d.asn, strftime('%Y-%m-%dT%H', d.ts)
  HAVING COUNT(*) >= :min_denials
     AND (julianday(MAX(d.ts)) - julianday(MIN(d.ts))) * 1440 <= :window
)
SELECT b.user, b.denials, s.ts AS success_ts, s.src_ip, s.asn,
       NOT EXISTS (SELECT 1 FROM ev h
                   WHERE h.user = b.user AND h.event = 'success'
                     AND h.asn = s.asn AND h.ts < b.last_denial) AS new_asn,
       EXISTS (SELECT 1 FROM ev m
               WHERE m.user = b.user AND m.event = 'mfa_method_added'
                 AND m.ts BETWEEN s.ts
                     AND strftime('%Y-%m-%dT%H:%M:%SZ', s.ts, '+60 minutes'))
         AS method_added
FROM bursts b
JOIN ev s ON s.user = b.user AND s.event = 'success' AND s.asn = b.asn
 AND s.ts > b.last_denial
 AND s.ts <= strftime('%Y-%m-%dT%H:%M:%SZ', b.last_denial, '+30 minutes')
ORDER BY s.ts;
"""

# Bursts with no later success from that network: someone else may hold the password.
UNANSWERED = """
WITH bursts AS (
  SELECT user, asn, MAX(ts) AS last_denial, COUNT(*) AS denials
  FROM ev WHERE event = 'mfa_denied'
  GROUP BY user, asn, strftime('%Y-%m-%dT%H', ts)
  HAVING COUNT(*) >= :min_denials
     AND (julianday(MAX(ts)) - julianday(MIN(ts))) * 1440 <= :window
)
SELECT b.user, b.denials, b.last_denial, b.asn FROM bursts b
WHERE NOT EXISTS (SELECT 1 FROM ev s WHERE s.user = b.user AND s.event = 'success'
                  AND s.asn = b.asn AND s.ts > b.last_denial)
ORDER BY b.last_denial;
"""


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("csv_path")
    ap.add_argument("--min-denials", type=int, default=3)
    ap.add_argument("--window-min", type=int, default=15)
    args = ap.parse_args()
    db = sqlite3.connect(":memory:")
    db.execute("CREATE TABLE ev (ts TEXT, user TEXT, event TEXT, src_ip TEXT, asn TEXT)")
    with open(args.csv_path, newline="", encoding="utf-8") as fh:
        rows = [(r["ts"], r["user"], r["event"], r["src_ip"], r["asn"])
                for r in csv.DictReader(fh)]
    db.executemany("INSERT INTO ev VALUES (?, ?, ?, ?, ?)", rows)
    params = {"min_denials": args.min_denials, "window": args.window_min}
    hits = db.execute(QUERY, params).fetchall()
    print(f"{len(rows)} events loaded; {len(hits)} candidate(s)")
    for user, denials, ts, ip, asn, new_asn, added in hits:
        rating = "HIGH" if new_asn and added else "MEDIUM" if new_asn else "LOW"
        print(f"{rating:<6} user={user} denials={denials} success={ts} asn={asn} "
              f"new_net={bool(new_asn)} new_mfa={bool(added)}")
    for user, denials, last, asn in db.execute(UNANSWERED, params):
        print(f"LEAD   user={user} denials={denials} last={last} asn={asn} "
              "(password likely known)")


if __name__ == "__main__":
    main()

Expected output (verified by execution):

17 events loaded; 1 candidate(s)
HIGH   user=li denials=4 success=2026-10-14T02:19:00Z asn=64511 new_net=True new_mfa=True
LEAD   user=jonas denials=3 last=2026-10-15T11:02:00Z asn=64499 (password likely known)

With --min-denials 1 a third row appears, LOW user=amara denials=1 …: one denied prompt, then a normal sign-in from her usual network, the noise a production rule must not alert on.

Validation: the HIGH row matches the hypothesis. The LEAD row is a finding the hypothesis did not predict: jonas denied three pushes from an unfamiliar network. If your IdP sends a push only after a correct password (check this), someone else probably knows it. Carrying it to production: the KQL sketch below runs the same logic on Microsoft Entra ID sign-in and audit logs.[47][48][49][50][51] Other IdPs log equivalents. Troubleshooting: bursts are grouped by clock hour, so one spanning an hour boundary splits; production logic uses sliding windows. Limits: flooding from one network and signing in from another is missed by design. Teardown: delete the files.

Example status: KQL sketch, not executed; names checked against Microsoft’s documentation on 2026-10-17; check one TargetResources record’s layout before trusting the last join.

// Lab 2 hypothesis on Microsoft Entra ID logs in a Log Analytics workspace. Not executed.
// SigninLogs.ResultType: "0" = success; "500121" = "User didn't complete the MFA prompt"
// (denial reasons include "user declined the authentication"). 500121 also "often
// appears if the user hasn't completed setting up MFA": users still registering can
// match all three signals, so exclude onboarding accounts before alerting.
// AuditLogs.OperationName "User registered security info" = an MFA method was added.
let bursts = SigninLogs
  | where TimeGenerated > ago(30d) and ResultType == "500121"
  | summarize denials = count(), first_denial = min(TimeGenerated),
              last_denial = max(TimeGenerated)
      by UserPrincipalName, AutonomousSystemNumber, bin(TimeGenerated, 1h)
  | where denials >= 3 and last_denial - first_denial <= 15m;
let successes = SigninLogs
  | where TimeGenerated > ago(90d) and ResultType == "0"
  | project UserPrincipalName, AutonomousSystemNumber, IPAddress,
            success_ts = TimeGenerated;
let first_seen = successes
  | summarize first_success = min(success_ts)
      by UserPrincipalName, AutonomousSystemNumber;
let methods_added = AuditLogs
  | where OperationName in ("User registered security info",
                            "User registered all required security info")
  | extend UserPrincipalName = tostring(TargetResources[0].userPrincipalName)
  | project UserPrincipalName, method_added = TimeGenerated;
bursts
| join kind=inner successes on UserPrincipalName, AutonomousSystemNumber
| where success_ts between (last_denial .. last_denial + 30m)
| join kind=inner first_seen on UserPrincipalName, AutonomousSystemNumber
| extend new_net = first_success > first_denial   // no earlier success from this ASN
| join kind=leftouter methods_added on UserPrincipalName
| extend added = method_added between (success_ts .. success_ts + 60m)
| summarize mfa_adds = countif(added)
    by UserPrincipalName, denials, success_ts, IPAddress, AutonomousSystemNumber, new_net
| extend new_mfa = mfa_adds > 0
| order by success_ts asc

A real precedent for the third signal: FireEye’s chief executive told US House committees in 2021 that the company found its intrusion after “a peculiar alert indicating that one of our employee’s accounts had registered a second phone” for two-factor codes; the employee had not.[52] An alert, not a hunt, but the signal works when its benign rate is known and the check (ask the user) is cheap.

Lab 3 (intermediate): package a finding for sharing and read from a TAXII server

Link to section “Lab 3 (intermediate): package a finding for sharing and read from a TAXII server”

Objective: express the Lab 2 finding as a STIX 2.1 bundle labelled with TLP 2.0, check it before sharing, and optionally query a public TAXII 2.1 server. Prerequisites: Python 3; curl. Risk: sharing real data needs the approval described in Quality, security, privacy and compliance.

Why TLP 2.0 needs an extension. STIX 2.1 defines markings for the older TLP labels only: “Other instances of tlp-marking MUST NOT be used or created”.[19] TLP 2.0 labels use an extension from the OASIS CTI committee’s common-objects repository; the bundle uses its TLP:GREEN object.[53] It shares the IP (short valid_until) and links it by STIX ID to the two behaviours, T1621 and T1098.005, which the receiver resolves against its own ATT&CK copy. Its confidence of 70 is STIX’s value for Admiralty credibility 2, “Probably True” (Appendix A), the same 1–6 scale FIRST uses to rate information.[19] Side effect: created_by_ref plus a Sighting whose where_sighted_refs names your own identity tells every recipient that your organisation was targeted; anonymise or omit them when that matters.

  1. Save the bundle as finding.json and the checker as check_bundle.py; run python3 check_bundle.py finding.json.
  2. Delete the valid_until line from the indicator and run again; the check must fail.
  3. Optional: list the collections on MITRE’s ATT&CK TAXII 2.1 server (command below).[44] It may refuse requests (rate limit, HTTP 503); the offline equivalent is the Lab 1 bundle.
curl -H 'Accept: application/taxii+json;version=2.1' \
  https://attack-taxii.mitre.org/api/v21/collections/

Example status: JSON syntax-checked; both checks executed on 2026-10-16 and 2026-10-17; the bundle was not sent anywhere.

{
  "type": "bundle",
  "id": "bundle--2ec35eb0-cc59-4fef-8af4-b6f947df006a",
  "objects": [
    {
      "type": "marking-definition",
      "spec_version": "2.1",
      "id": "marking-definition--bab4a63c-aed9-4cf5-a766-dfca5abac2bb",
      "created": "2022-10-01T00:00:00.000Z",
      "name": "TLP:GREEN",
      "extensions": {
        "extension-definition--60a3c5c5-0d10-413e-aab3-9e08dde9e88d": {
          "extension_type": "property-extension",
          "tlp_2_0": "green"
        }
      }
    },
    {
      "type": "identity",
      "spec_version": "2.1",
      "id": "identity--8fbe50f4-ab4f-4990-aa78-f4d363562898",
      "created": "2026-10-16T10:00:00.000Z",
      "modified": "2026-10-16T10:00:00.000Z",
      "name": "Example Corp CTI team",
      "identity_class": "organization"
    },
    {
      "type": "indicator",
      "spec_version": "2.1",
      "id": "indicator--2382283f-9d2e-4e23-82f1-8296bd9ad321",
      "created_by_ref": "identity--8fbe50f4-ab4f-4990-aa78-f4d363562898",
      "created": "2026-10-16T10:00:00.000Z",
      "modified": "2026-10-16T10:00:00.000Z",
      "name": "Source of MFA push flood against a workforce IdP",
      "description": "Seen once; low durability. Prefer the behaviour (T1621).",
      "indicator_types": ["malicious-activity"],
      "pattern": "[ipv4-addr:value = '203.0.113.50']",
      "pattern_type": "stix",
      "valid_from": "2026-10-14T02:10:00Z",
      "valid_until": "2026-10-28T02:10:00Z",
      "confidence": 70,
      "object_marking_refs": [
        "marking-definition--bab4a63c-aed9-4cf5-a766-dfca5abac2bb"
      ]
    },
    {
      "type": "relationship",
      "spec_version": "2.1",
      "id": "relationship--f9bc48c8-ca32-4c85-bcfe-ae59ed839bd6",
      "created": "2026-10-16T10:00:00.000Z",
      "modified": "2026-10-16T10:00:00.000Z",
      "relationship_type": "indicates",
      "source_ref": "indicator--2382283f-9d2e-4e23-82f1-8296bd9ad321",
      "target_ref": "attack-pattern--954a1639-f2d6-407d-aef3-4917622ca493",
      "object_marking_refs": [
        "marking-definition--bab4a63c-aed9-4cf5-a766-dfca5abac2bb"
      ]
    },
    {
      "type": "relationship",
      "spec_version": "2.1",
      "id": "relationship--3d0b8c52-1f7e-4c1a-9a55-6b2f0e9c7d41",
      "created": "2026-10-16T10:00:00.000Z",
      "modified": "2026-10-16T10:00:00.000Z",
      "relationship_type": "indicates",
      "source_ref": "indicator--2382283f-9d2e-4e23-82f1-8296bd9ad321",
      "target_ref": "attack-pattern--7decb26c-715c-40cf-b7e0-026f7d7cc215",
      "object_marking_refs": [
        "marking-definition--bab4a63c-aed9-4cf5-a766-dfca5abac2bb"
      ]
    },
    {
      "type": "sighting",
      "spec_version": "2.1",
      "id": "sighting--6753e044-c34e-4297-a036-644cc381c0f8",
      "created_by_ref": "identity--8fbe50f4-ab4f-4990-aa78-f4d363562898",
      "created": "2026-10-16T10:00:00.000Z",
      "modified": "2026-10-16T10:00:00.000Z",
      "first_seen": "2026-10-14T02:10:00Z",
      "last_seen": "2026-10-14T02:24:00Z",
      "count": 1,
      "sighting_of_ref": "indicator--2382283f-9d2e-4e23-82f1-8296bd9ad321",
      "where_sighted_refs": ["identity--8fbe50f4-ab4f-4990-aa78-f4d363562898"],
      "object_marking_refs": [
        "marking-definition--bab4a63c-aed9-4cf5-a766-dfca5abac2bb"
      ]
    }
  ]
}
"""Minimal pre-share checks for a STIX 2.1 bundle (not a full validator)."""
import json
import sys

REQUIRED = {
    "indicator": ["pattern", "pattern_type", "valid_from"],
    "relationship": ["relationship_type", "source_ref", "target_ref"],
    "sighting": ["sighting_of_ref"],
}
TLP2_EXT = "extension-definition--60a3c5c5-0d10-413e-aab3-9e08dde9e88d"

bundle = json.load(open(sys.argv[1], encoding="utf-8"))
ids = {o["id"] for o in bundle["objects"]}
problems = []
for obj in bundle["objects"]:
    for prop in REQUIRED.get(obj["type"], []):
        if prop not in obj:
            problems.append(f"{obj['id']}: missing {prop}")
    if obj["type"] not in ("marking-definition", "identity"):
        refs = obj.get("object_marking_refs", [])
        if not any(r in ids for r in refs):
            problems.append(f"{obj['id']}: no TLP marking in bundle")
    if obj["type"] == "marking-definition" and TLP2_EXT not in obj.get("extensions", {}):
        problems.append(f"{obj['id']}: not a TLP 2.0 marking")
    if obj["type"] == "indicator" and "valid_until" not in obj:
        problems.append(f"{obj['id']}: atomic indicator without valid_until")
external = sorted({o.get("target_ref") for o in bundle["objects"]
                   if o.get("target_ref") and o["target_ref"] not in ids})
print(f"{len(bundle['objects'])} objects; {len(problems)} problem(s)")
for p in problems:
    print("PROBLEM", p)
for ref in external:
    print("EXTERNAL", ref, "(resolve against ATT&CK)")
sys.exit(1 if problems else 0)

Expected output (verified by execution). Step 1:

6 objects; 0 problem(s)
EXTERNAL attack-pattern--7decb26c-715c-40cf-b7e0-026f7d7cc215 (resolve against ATT&CK)
EXTERNAL attack-pattern--954a1639-f2d6-407d-aef3-4917622ca493 (resolve against ATT&CK)

Step 2 prints PROBLEM indicator--2382283f-…: atomic indicator without valid_until and exits with code 1. Step 3 (dated observations, not expected output): one request on 2026-10-16 returned HTTP 200 with three collections; later requests on 2026-10-16 and 2026-10-17 returned HTTP 503. Troubleshooting: MITRE rate-limits the server, suggests the bundles for heavier use and requires a valid Accept header.[44] Validation: before any real share, a second person checks the TLP label, personal data and approval record. Teardown: delete the files.

Case 1 is sourced; cases 2–4 are illustrative.

1. Living off the land (sourced). The February 2024 Volt Typhoon advisory listed indicators and linked a TLP:CLEAR STIX file from the accompanying malware analysis report. It warned that many organisations lack the baselines needed for “behavior analytics, anomaly detection, and proactive hunting”.[5] Illustrative response: a utility retro-hunts the STIX indicators, then writes baseline hunts for admin tools used from unusual hosts. Pitfall: declaring “not affected” after an IOC sweep alone.

2. Identity-led extortion (illustrative). M-Trends 2026 reports voice phishing as the second most common initial infection vector (11%) in Mandiant’s investigations.[6] A retailer’s CISO sets PIR-02; Lab 1 ranks the shared techniques and Lab 2 tests the MFA-flooding hypothesis. The hunt finds no intrusion but shows that help-desk tickets do not record the requester’s verified identity: a gap ticket and a process change for IdentityOps. Success: the MFA detection in production. Pitfall: reading ATT&CK group data as a forecast.

3. Exploitation intelligence for patching (illustrative). An ISAC post (TLP:AMBER) reports exploitation of a VPN appliance before a patch exists. ThreatOps confirms the exposure, retro-hunts the indicators, and hands VulnerabilityOps a dated note: “exploited in our sector; we run 3 exposed units”. VulnerabilityOps owns priority and deadline; PatchOps owns the rollout. Pitfall: forwarding the post to a supplier outside the organisation’s clients, which TLP:AMBER does not allow.

4. Strategic brief (illustrative). For PIR-03 the brief follows the template: a bottom line with a probability word, confidence in a separate sentence, one recommendation. Success: the risk committee funds a specific control. Pitfall: actor names and no recommendation.

The CTI-CMM authors observe that “most organizations develop metrics that measure level of effort or throughput” rather than impact;[23] PEAK says the same of hunting: count “twelve new automated detections”, not “nine hunts”.[16] The set below is this Atlas’s proposal, built on PEAK’s measures and CTI-CMM’s example metrics.

KPI Formula Data source Pitfall
PIR coverage PIRs with at least one product or hunt in the period ÷ active PIRs PIR register, product log Easy to game with thin products
Intelligence-to-action rate Products followed by a recorded decision or change ÷ products disseminated Product log, stakeholder feedback Needs consumers to record actions
Hunt conversion rate Hunts producing at least one detection created or updated ÷ hunts completed Hunt records, detection repository Rewards easy hunts; read with the next KPI
Gap closure rate Gaps closed ÷ gaps reported (data, visibility, misconfiguration) Gap tickets Other teams close them; track age
Indicator hygiene Active atomic indicators with an expiry ÷ active atomic indicators TIP Absurd periods defeat it
Feed precision Confirmed-malicious hits ÷ investigated hits, per feed, 90 days Watchlist hits, triage outcomes Small samples; shared hosting inflates false hits

Review indicator hygiene weekly; hunt conversion, gap closure and feed precision monthly; the rest quarterly.

Worked calculation (illustrative quarter). PIR coverage: 5 of 6 PIRs had a product or hunt, 5 ÷ 6 = 83%. Intelligence-to-action: 14 of 40 products led to a recorded action, 35%. Hunt conversion: 5 of 12 hunts created or updated a detection, 42%. Gap closure: 4 of 9, 44%. Feed precision: 18 confirmed of 120 investigated hits, 15%. Reading: coverage is healthy; most products change nothing, so ask consumers why and cut unused ones; hunting improves detection; the feed, far below the 0.9 threshold, stays alert-only and is a cancellation candidate.

Vanity metrics. Indicators ingested, reports published, hunts started and “ATT&CK coverage” percentages. PEAK warns that “not everything in ATT&CK is intended to be turned into a detection”.[16]

  • Analytic quality. Use FIRST’s source ratings and uncertainty language, check key assumptions, and peer-review every product that leaves the team.
  • Operational security. FIRST advises discussing any interaction with underground sources with company lawyers.[32] Use dedicated, non-attributable infrastructure for adversary-facing research.
  • Sharing labels. TLP labels (see the glossary) tell recipients how far they may share, but “TLP is not a formal classification scheme”: binding terms come from your sharing agreement, and the source may add restrictions.[21]
  • Personal data. Indicators can contain personal data (email addresses, user names, IPs). Share only what the recipient needs; data-protection law varies by jurisdiction (see PrivacyOps).
  • Legal basis for sharing. NIS2 Article 29 has EU Member States enable voluntary sharing within communities and require essential and important entities to notify their competent authority when joining or leaving one; details depend on national transposition.[38] In the US, the Congressional Research Service summarises the Cybersecurity Information Sharing Act of 2015 as giving antitrust and liability protections for authorised sharing and requiring personal information to be removed; its provisions run to 11 December 2026 (CRS, 3 September 2026), so check their status.[54] Involve LegalOps before the first external share.
  • Evidence. A hunt that becomes an incident follows ResponseOps evidence rules from then on.

The main cost drivers are people, data retention and paid intelligence. Retention can be the hidden one: a retro-hunt looks back only as far as telemetry is kept, the long-dwell cases in The problem it solves exceed 90 days, and a retention increase fills forward (see the judgement call). Price retention per data source with SecDataOps and keep longer only the sources your PIRs need. Feeds should be renewed on measured precision and on how often they answered a PIR. People: the illustrative plan assumes a part-time hunter finishes a hunt a fortnight; when data must first be gathered and cleaned (PEAK’s “Gather Data” and “Pre-Process Data” steps), that pace drops, so data quality is a capacity lever.[28]

Quarterly, sample five hunt records and rerun one; check that escalations reached ResponseOps and detection requests reached DetectionOps; list expired indicators still on watchlists; ask each PIR owner whether the last product changed a decision. Risk signals: a PIR register unchanged for two quarters, no data-gap tickets (nobody checks visibility), and blocking rules whose source nobody can name.

Symptom Likely cause Diagnosis Remediation
Products not read No PIR; wrong audience Ask three consumers what they did with the last one Bottom line plus recommendation; retire unused ones
Watchlist alerts mostly benign Old or shared-infrastructure IOCs Hit age and hosting type per feed Expire, allowlist, demote the feed
Hunts produce nothing Vague hypotheses or missing data Read the last five hunt records Rewrite in ABLE form; raise gap tickets
Findings sit unbuilt No detection-engineering intake Age of open detection requests Intake SLA with DetectionOps
Sharing stalls Unclear approval, fear of liability Time from request to approval Pre-approved sharing classes

Worked runbook: a feed indicator blocks a shared IP (illustrative)

Link to section “Worked runbook: a feed indicator blocks a shared IP (illustrative)”

Situation. At 09:10 the checkout page fails for some customers. Firewall logs show denies from a rule fed by a commercial indicator list; the blocked address belongs to a content-delivery network (CDN) that served a malicious domain weeks ago.

  1. Contain (on-call engineer, minutes). Remove the indicator from the block list; charter principle 7 and the policy’s revert block pre-authorise this without the CTI lead. Record who, when, which indicator and why.
  2. Stop recurrence (CTI lead, within the hour). Switch the feed to alert-only; check its other indicators for shared hosting.
  3. Diagnose. Record source rating, first-seen date, valid_until (none was set) and the feed’s 90-day precision; check the CDN allowlist (not maintained).
  4. Recover and communicate. Confirm recovery with the service owner; report through IncidentOps as an availability incident caused by a security control.
  5. Prevent. Enforce expiry on import, refresh allowlists from providers’ published ranges, apply the precision gate, put blocking feeds under change control, and track “blocks reverted” monthly.
  • “More feeds, more protection.” Every feed adds triage load and false blocks; measure precision before adding another.
  • Attribution theatre. Attribute only when the name changes a defence, a response or a legal step.
  • The heat-map goal. A green ATT&CK matrix measures mapping effort, not protection; the tactics are not even a sequence.[39]
  • Hunting as SOC overflow. Hunters on the alert queue means no hunting; fix SOC Ops capacity.
  • Myth: sharing is risky, so share nothing. TLP labels, pre-approved sharing classes and legal frameworks such as NIS2 Article 29 exist to make sharing manageable.[21][38]

Build it when you have queryable telemetry with history, people who act on findings, stakeholders willing to set PIRs, and a reason to search proactively: a targeted sector, a selected control such as RA-10, or intrusions found late in the past.

Do not build it yet when the basics are missing: without endpoint or identity telemetry a hunter has nothing to search; with an unhandled alert queue, findings join the backlog. FIRST notes “it may be best to stay in stage 1 and outsource more advanced activities”.[55] Alternatives: your sector’s ISAC, government advisories, and managed hunting whose findings come back to you. A bought service must include response to what it finds, or a named internal owner for its findings, plus a route for its detection requests and gap tickets into your teams; otherwise bought findings stall like in-house ones. Hidden responsibilities: legal review of sharing, retention costs, the detection work hunts create, and stakeholder time for PIRs.

Figure 6. Should we build, buy, go lean or fix data first?
noyesnoyesnoyesnoyesTelemetry kept90+ days?Fix data first;meanwhile triage advisories,hunt recent dataOwner forfindings?Buy hunting withresponse included;name a findings ownerStakeholdersset PIRs?Lean: advisories,retro-hunts, ISACTargeted, orhunting required?Build: PIRs, TIP,hunt programme
Diagram source (Mermaid)
flowchart TB
  Q1{"Telemetry kept<br/>90+ days?"}
  Q1 -->|"no"| A1["Fix data first;<br/>meanwhile triage advisories,<br/>hunt recent data"]
  Q1 -->|"yes"| Q2{"Owner for<br/>findings?"}
  Q2 -->|"no"| A2["Buy hunting with<br/>response included;<br/>name a findings owner"]
  Q2 -->|"yes"| Q3{"Stakeholders<br/>set PIRs?"}
  Q3 -->|"no"| A3["Lean: advisories,<br/>retro-hunts, ISAC"]
  Q3 -->|"yes"| Q4{"Targeted, or<br/>hunting required?"}
  Q4 -->|"no"| A3
  Q4 -->|"yes"| A4["Build: PIRs, TIP,<br/>hunt programme"]
  A1 ~~~ Q2
  A2 ~~~ Q3
  A3 ~~~ Q4
  classDef decision fill:#fdf3e3,stroke:#c9800f,color:#122029
  classDef risk fill:#fbeceb,stroke:#b4332b,color:#122029
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  class Q1,Q2,Q3,Q4 decision
  class A1,A2 risk
  class A3,A4 core

Text equivalent: four questions down the left, exits to the right. Telemetry kept 90 days or more? If not, fix data first with SecDataOps and meanwhile triage advisories and hunt recent data (the “wait” exit). Someone owns acting on findings? If not, buy hunting that includes response, keep intelligence alert-only and name an internal owner for findings. Stakeholders will set PIRs? If not, run lean: advisories, retro-hunts, ISAC. Targeted sector, or hunting required by contract or a selected control? If not, stay lean; if yes, build PIRs, a TIP and a hunt programme. The 90-day threshold is illustrative.

This is the Atlas’s model, not an official one, aligned with FIRST’s three stages,[55] the Hunting Maturity Model (HMM0–HMM4) as PEAK presents it,[16] and CTI-CMM levels CTI0 (Pre-Foundational) to CTI3 (Leading).[23] Thresholds are proposals.

Level Observable behaviour Exit criteria Roughly aligns with
0 Absent Indicators copied from news; no owner A named owner and a triage log CTI0; HMM0
1 Consuming Feeds and advisories triaged, alert-only; CTI as a secondary duty Source register; every atomic indicator expires FIRST Stage 1; CTI1
2 Requirements-driven Reviewed PIR register; TIP; retro-hunts within days of credible advisories PIR coverage ≥ 80% for two quarters; intelligence-to-action measured FIRST Stage 2; CTI1–CTI2
3 Hunting programme Written hunts on a cadence; detection requests and gap tickets tracked Hunt conversion and gap closure reported monthly HMM2, PEAK’s minimum for most hunting organisations
4 Intelligence-led Internal intelligence shared; novel hunts; most hunts become detections; decisions cite products Stakeholders can name decisions changed by intelligence FIRST Stage 3; HMM3–HMM4; CTI2–CTI3
Window Actions Milestone and measure
Days 1–30 Name the owner; draft five PIRs; source register; all feeds alert-only with expiry; join the sector ISAC PIR register approved; all atomic indicators expiring
Days 31–60 Agree templates with DetectionOps; Lab 1 for PIR-02; two recorded hunts; escalation and sharing rules with ResponseOps and Legal First detection request accepted
Days 61–90 Choose a TIP; first strategic brief; monthly outputs review; measure feed precision First KPI report; one feed renewed or cancelled on evidence

Quick start

  • One accountable owner and a backup
  • Five to eight PIRs, each with a decision owner and review date
  • Every feed rated and alert-only until its precision is measured
  • Escalation path to the incident lead tested once

Hunt readiness

  • Hypothesis written in ABLE form and linked to a PIR
  • Data sources confirmed present for the time range
  • Time box agreed; reviewer named
  • Record template opened before the first query

Sharing preflight

  • TLP label chosen and correct for every object
  • Personal data removed unless the recipient needs it
  • Approval recorded; legal basis known for this community
  • Atomic indicators carry valid_until
  • Decided whether created_by_ref or where_sighted_refs may reveal who was targeted; anonymise or omit if so

Quarterly review

  • Every PIR confirmed, rewritten or retired with its owner
  • Indicators past expiry removed from watchlists
  • Feeds compared on precision and PIR answers
  • One archived hunt rerun by someone else

Template status: plain-text forms; adapt the fields to your ticketing system.

HUNT RECORD                                   ID: HUNT-2026-041   PIR: PIR-02
Hypothesis (ABLE)
  Actor:     identity-focused extortion crews
  Behavior:  MFA push flooding (T1621), then new MFA method (T1098.005)
  Location:  workforce IdP
  Evidence:  IdP sign-in and audit logs, 90 days
Scope and time box:  all workforce users; 3 working days
Data checked:        sources, fields, time range actually available
Queries:             link to repository commit
Verdict:             confirmed / refuted / inconclusive (why)
Would we have seen it?  yes / no (gap ticket ID)
Artefacts:           detection request, gap tickets, incident ID, brief
Reviewer and date:
DETECTION REQUEST                              To: DetectionOps   From: ThreatOps
Behaviour and ATT&CK ID:   T1621, then T1098.005 (new MFA method) within 60 min
Why now:                   PIR-02; hunt HUNT-2026-041
Logic sketch:              >= 3 denials in 15 min, success from a new ASN (Lab 2 KQL)
Test data:                 synthetic file and one real true positive (if any)
Expected benign matches:   single denials; travel; new phones; users finishing MFA setup
Suggested response:        verify with user out of band; revoke sessions
Priority and due date:
RFI LOG                                     ID: RFI-2026-017   Requester: Head of Payments
Question:         Is the phishing kit in ticket SEC-4412 linked to a known crew?
Due:              2026-10-20                   Related PIR: PIR-02 (none = PIR candidate?)
Answer and date:  probability word + confidence; sources rated A-F, 1-6
Recurring?        yes / no; if yes, propose a PIR at the quarterly review
INTELLIGENCE BRIEF                             PIR: PIR-03     TLP:AMBER+STRICT
Bottom line:      one sentence with a probability word (e.g. "likely")
Confidence:       high / moderate / low, in a separate sentence, with reason
What we recommend: the decision you want and its owner
Key judgements:   2 to 4, each with its evidence and sources (rating A-F, 1-6)
What would change our view:
Gaps:
Option Suits Strength Weakness
Consume only (ISAC, advisories, AIS) Small teams, low targeting Cheap, sector-relevant No validation in your own data
Managed hunting or MDR (alone or with in-house PIRs and briefs) Telemetry but no hunters Expertise and coverage hours Hunts may not follow your PIRs; without an internal owner and handoff contract, findings never become your detections
In-house ThreatOps Targeted sectors, mature data Context, PIR fit, detections you own People, retention, legal and tooling cost

Is ThreatOps a job title or a team? Some vendors name teams that way, such as Huntress’s ThreatOps team, but there is no common job family; the usual roles are CTI analyst and threat hunter.

Do we need a threat intelligence platform? Not on day one; see Alternatives under Reference architecture.

Should we auto-block indicators from feeds? Only from feeds with high measured precision, with expiry, allowlists and a fast manual override (see the worked runbook).

How is hunting different from searching for IOCs? A retro-hunt checks known indicators; a hunt tests a behaviour hypothesis that may have no indicators at all, as in the Volt Typhoon case.[5]

Can a two-person team do this? Yes, at Levels 1–2 with occasional hunts, outsourcing the rest (see When to use).

  • Adversaries using AI. ATT&CK v20 adds “AI-focused and AI-enabled Techniques in Enterprise”, so hunt backlogs will include them.[24]
  • Autonomous hunting claims are vendor marketing until evaluated as AIOps for Security describes; PEAK’s model-assisted hunts (M-ATH) use machine learning but keep a hunter in charge.[2]
  • Standards gaps. TAXII 2.1 reserves Channels (push sharing) but does not specify them,[20] and TLP 2.0 needs a STIX extension (Lab 3).
  • Maturity measurement. CTI-CMM 1.3’s roadmap planned version 2.0 for Q3 2026; on 2026-10-17 the site still offered 1.3.[23]
Stage Focus Practice
Prerequisites Log sources, SIEM queries, basic networking and identity SOC Ops, SecDataOps
One day Pyramid of Pain, ATT&CK structure, TLP Lab 1 with your sector’s groups
One week PIRs, source ratings, WEP and confidence Write three PIRs and one brief; Lab 2
30 days PEAK hunt types; STIX and TAXII Two recorded hunts; Lab 3; one detection request
Advanced Diamond Model pivoting, baseline and model-assisted hunts, metrics A quarterly PIR review and KPI report
Topic Remember
Label Ambiguous; the practices (CTI and hunting) are established
Start Five to eight PIRs with decision owners
Indicators Rate, label, alert-only, expire
Hunts ABLE hypothesis, time box, record, artefact
Outputs Detection requests, gap tickets, escalations, briefs
Standards STIX 2.1, TAXII 2.1, TLP 2.0, ATT&CK v20
Metrics PIR coverage, intelligence-to-action, hunt conversion, gap closure, feed precision
Watch-outs Feed hoarding, heat-map goals, unrecorded hunts, unexamined sharing law

A judgement call: a second feed or a hunter?

Link to section “A judgement call: a second feed or a hunter?”

Situation (illustrative). A 2,000-person insurer has one CTI analyst, a SIEM with 30 days of retention, EDR on all endpoints and budget for one option: a second commercial feed wired to auto-block, or a part-time hunter plus SIEM retention raised to 180 days for identity and EDR data.

The case for the feed. It is fast to deploy, produces visible numbers, and blocks known-bad infrastructure.

The case for the hunter. The insurer’s PIRs centre on identity-led extortion (use case 2): valid accounts, few durable indicators, so another feed adds little. But retention fills forward: raised today, it holds about 90 days of history after three months and 180 after six, assuming nothing older survives elsewhere. Until then, “were we already hit?” reaches back only 30 days.

Assumptions that decide it. Detection engineering can absorb about two requests a month; the current feed’s precision is unknown; identity hypotheses such as Lab 2’s need weeks of data, not months. Without detection capacity the hunter’s findings stall and the choice reverses, with managed hunting as a stopgap.

Decision. Raise retention now, the “fix data first” branch of the decision framework; meanwhile start the hunter on hypothesis and baseline hunts over recent data, and measure the current feed’s precision for 90 days. Why the attractive option can be wrong: an auto-blocking feed raises activity metrics, adds outage risk (see the runbook) and does nothing for the top PIR. Uncertainty: the first 90-day retro-hunt is possible around month 3, the first 180-day one at month 6; review then, not at week 6.

After this page you should be able to: explain why the label is ambiguous; write a PIR that meets FIRST’s three criteria; place an indicator on the Pyramid of Pain and choose its handling; write an ABLE hypothesis and test competing ones; package a finding with TLP 2.0 in STIX 2.1; and choose between building, buying, going lean and fixing data first.

A stakeholder asks for “everything about ransomware”. What do you do?

Turn it into PIRs that each ask one question for one decision, with an owner and a review date: for example “Which initial access methods are ransomware affiliates using against our sector this quarter?”

An ISAC shares 300 IP addresses at TLP:AMBER. How do you handle them?

Rate them, load them alert-only with a short valid_until, retro-hunt across retention, and share onward only within your organisation and its clients, on a need-to-know basis.

A three-day hunt for DNS tunnelling found nothing. Was it a failure?

Not if the record shows the DNS data covered the scope and the method would have revealed tunnelling: a confident negative, ideally with a detection request. Incomplete data means a gap ticket.

Two analysts disagree: is a login burst an intrusion or a broken script? How do you settle it?

List all hypotheses, check the assumptions behind each, then score every piece of evidence against all of them (ACH). Evidence that fits both decides nothing; look for evidence only one explains, such as a new ASN or a new MFA method.

Which KPI best shows that intelligence matters to the business, and why is it hard?

Intelligence-to-action rate: the share of products followed by a recorded decision or change. It is hard because consumers must record what they did; agree that when the PIR is written.

“ThreatOps” is a weak label for strong practices: vendors stretch it at least three ways and standards bodies do not define it. The work underneath is well documented: ask the right questions, judge sources, say how sure you are, test hypotheses against your own data, and turn each answer into a defence that outlives the hunt. Value shows when PIR owners can name a decision that intelligence changed and the detection library holds rules that began as hunts. If you cannot yet act on findings, consume, buy and fix your data first.

Each line gives the date the source was last opened. The evidence ledger (research/threatops-ledger.md) maps claims to sources and records what could not be fetched.

Further reading: the full FIRST CTI SIG curriculum.

Changelog

  • 2026-10-16 — First version: term status set to ambiguous (matrix proposed niche; see ledger section A); research, labs executed and diagrams by the managing author. Independent review pending.
  • 2026-10-17 — Review r1 revision: vendor senses, SP 800-53 baselines and retention lead time corrected; ACH, RFIs, incident scoping and T1098.005 added; labs re-run; repetition cut.
  • 2026-10-17 — Review r1, second pass: Figures 1, 2 and 6 redrawn for phones; decision tree reconciled with When to use; revert authority for blocks; Entra KQL sketch; TLP labels, acronyms, RFI log; widest tables narrowed; dated facts out of the takeaways.
  • 2026-10-17, post-score polish: 500121 MFA-setup caveat (KQL sketch, detection request); baseline-hunt entry in Figure 4; NIS2 text re-checked; restatements cut.

  1. threat intelligence (glossary term) — NIST CSRC Glossary, definition from SP 800-150. Checked 2026-10-16. ↩︎

  2. Introducing the PEAK Threat Hunting Framework — David Bianco, Splunk, 2023-04-18. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  3. Priority Intelligence Requirement (PIR) — FIRST CTI SIG curriculum. Checked 2026-10-17. ↩︎ ↩︎ ↩︎ ↩︎

  4. The Pyramid of Pain — David J. Bianco, 2013-03-01, updated 2014-01-17. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  5. AA24-038A: PRC State-Sponsored Actors Compromise and Maintain Persistent Access to U.S. Critical Infrastructure — CISA, NSA, FBI and partners, 2024-02-07. Checked 2026-10-17. ↩︎ ↩︎ ↩︎

  6. M-Trends 2026: Data, Insights, and Strategies From the Frontlines — Jurgen Kutscher, Google Cloud (Mandiant), 2026-03-23. Checked 2026-10-16. ↩︎ ↩︎

  7. SP 800-53 Rev. 5 catalog (OSCAL JSON, release 5.2.0): RA-10, PM-16, RA-3(3) — NIST, updated 2026-05-11. Checked 2026-10-16. ↩︎ ↩︎

  8. Glossary search for “threatops” — NIST CSRC, no results. Checked 2026-10-16. ↩︎

  9. How to Defeat Ransomware with ThreatOps — Lauren Farrell, Centripetal, 2022-03-22. Checked 2026-10-16. ↩︎

  10. Huntress — AppDirect marketplace listing, vendor-supplied text, undated. Checked 2026-10-17. ↩︎

  11. 5 Years of SentinelOne ThreatOps — Ryan O’Grady, SentinelOne, 2026-10-09. Checked 2026-10-17. ↩︎

  12. Company — ThreatQuotient, undated. Checked 2026-10-17. ↩︎

  13. CTI Maturity model – Stage 1 — FIRST CTI SIG. Checked 2026-10-16. ↩︎ ↩︎ ↩︎

  14. Intelligence-Driven Computer Network Defense Informed by Analysis of Adversary Campaigns and Intrusion Kill Chains — Hutchins, Cloppert and Amin, Lockheed Martin, 2011. Checked 2026-10-16. ↩︎ ↩︎

  15. The Diamond Model of Intrusion Analysis — Caltagirone, Pendergast and Betz, 2013. Checked 2026-10-17. ↩︎ ↩︎ ↩︎

  16. Measuring Hunting Success with PEAK — David Bianco, Splunk, 2023-08-02. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎

  17. SP 800-150, Guide to Cyber Threat Information Sharing — Johnson et al., NIST, October 2016. Checked 2026-10-16. ↩︎

  18. Framework for Improving Critical Infrastructure Cybersecurity, Version 1.1 — NIST, 2018-04-16 (ID.RA-2, p. 26). Checked 2026-10-17. ↩︎

  19. STIX Version 2.1 — OASIS Standard, 2021-06-10. Checked 2026-10-17. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  20. TAXII Version 2.1 — OASIS Standard, 2021-06-10. Checked 2026-10-16. ↩︎ ↩︎ ↩︎ ↩︎

  21. Traffic Light Protocol (TLP) — Version 2.0 — FIRST, authoritative from August 2022. Checked 2026-10-17. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  22. The NIST Cybersecurity Framework (CSF) 2.0 — NIST CSWP 29, 2024-02-26. Checked 2026-10-16. ↩︎ ↩︎

  23. CTI-CMM Version 1.3 — DeBolt, Connor, Beckwith et al., January 2026 (PDF linked from the site). Checked 2026-10-17. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  24. Updates – October 2026 (ATT&CK v20) — MITRE ATT&CK, 2026-10-13. Checked 2026-10-16. ↩︎ ↩︎ ↩︎

  25. Machine and Human Analysis Techniques (and Intelligence Cycle) — FIRST CTI SIG curriculum. Checked 2026-10-17. ↩︎

  26. CTI Maturity model – Stage 3 — FIRST CTI SIG. Checked 2026-10-16. ↩︎ ↩︎

  27. attack-stix-data — MITRE, ATT&CK in STIX 2.1. Checked 2026-10-17. ↩︎ ↩︎ ↩︎

  28. Hypothesis-Driven Hunting with the PEAK Framework — David Bianco, Splunk, 2023-05-08. Checked 2026-10-17. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  29. About ISACs — National Council of ISACs. Checked 2026-10-16. ↩︎ ↩︎

  30. Turning Hunts Into Detections with PEAK — David Bianco, Splunk, 2023-07-26. Checked 2026-10-16. ↩︎

  31. Communicating Uncertainties in CTI Reporting — FIRST CTI SIG curriculum. Checked 2026-10-17. ↩︎ ↩︎

  32. Source Evaluation and Information Reliability — FIRST CTI SIG curriculum. Checked 2026-10-17. ↩︎ ↩︎ ↩︎

  33. A Tradecraft Primer: Structured Analytic Techniques for Improving Intelligence Analysis — US Government (CIA), March 2009. Checked 2026-10-17. ↩︎

  34. Methods and Methodology — FIRST CTI SIG curriculum. Checked 2026-10-17. ↩︎

  35. Automated Indicator Sharing (AIS) — CISA. Checked 2026-10-16. ↩︎ ↩︎

  36. Baseline Hunting with the PEAK Framework — David Bianco, Splunk, 2023-07-11. Checked 2026-10-17. ↩︎

  37. SP 800-53B, Control Baselines for Information Systems and Organizations — NIST, 2020 (release 5.2.0, August 2025, baselines unchanged). Checked 2026-10-17. ↩︎

  38. Directive (EU) 2022/2555 (NIS2), Article 29 — EUR-Lex, 2022. Checked 2026-10-16. ↩︎ ↩︎ ↩︎

  39. ATT&CK FAQ — MITRE ATT&CK. Checked 2026-10-16. ↩︎ ↩︎

  40. Enterprise tactics — MITRE ATT&CK, v20. Checked 2026-10-16. ↩︎

  41. MISP Open Source Threat Intelligence Platform — MISP project; news lists 2.5.x security releases (October 2026). Checked 2026-10-17. ↩︎

  42. MISP features and functionalities — MISP project. Checked 2026-10-16. ↩︎

  43. OpenCTI — Filigran, GitHub README. Checked 2026-10-16. ↩︎

  44. TAXII 2.1 API User Guide — MITRE ATT&CK Workbench TAXII server. Checked 2026-10-17. ↩︎ ↩︎ ↩︎

  45. CTI Maturity model – Stage 2 — FIRST CTI SIG. Checked 2026-10-16. ↩︎

  46. Account Manipulation: Device Registration (T1098.005) — MITRE ATT&CK v20. Checked 2026-10-17. ↩︎

  47. Azure Monitor Logs reference: SigninLogs — Microsoft Learn, 2026-08-27. Checked 2026-10-17. ↩︎

  48. How to troubleshoot sign-in errors — Microsoft Learn, 2024-11-11. Checked 2026-10-17. ↩︎

  49. Sign-in event details for Microsoft Entra multifactor authentication — Microsoft Learn, 2025-06-24. Checked 2026-10-17. ↩︎

  50. Azure Monitor Logs reference: AuditLogs — Microsoft Learn, 2026-08-27. Checked 2026-10-17. ↩︎

  51. Microsoft Entra audit log activity reference — Microsoft Learn, 2025-03-25. Checked 2026-10-17. ↩︎

  52. Prepared Statement of Kevin Mandia, CEO of FireEye — US House Committees on Oversight and Reform and on Homeland Security, 2021-02-26. Checked 2026-10-16. ↩︎

  53. TLP 2.0 extension definition — OASIS CTI TC, cti-stix-common-objects repository. Checked 2026-10-16. ↩︎

  54. The Cybersecurity Information Sharing Act of 2015: Expiring Provisions (IF12959) — Congressional Research Service, updated 2026-09-03 (EveryCRSReport copy). Checked 2026-10-16. ↩︎

  55. Program maturity stages — FIRST CTI SIG. Checked 2026-10-16. ↩︎ ↩︎

Related Ops

DetectionOps

DetectionOps is a rare label for detection engineering run like software delivery: detections are written as code from threat-informed requirements, tested, peer-reviewed, deployed through a pipeline, measured in production, tuned and retired.

SOC Ops

SOC Ops is running a security operations centre as a dependable service: turning alerts into timely, recorded decisions through tiers, playbooks, SIEM and SOAR, shift handover, metrics and sourcing choices that people can sustain around the clock.

ResponseOps

In this Atlas, ResponseOps is security incident response run as an operational capability: contain an active adversary, preserve evidence, evict and recover cleanly, and meet notification duties. The label itself is not a standard term.

VulnerabilityOps

VulnerabilityOps (usually "VulnOps") runs vulnerability management as a continuous flow: decide what must be fixed by when from exploitation evidence and asset exposure, hand dated work to owners, verify every fix, and keep remediation capacity ahead of arrivals.

SecOps

SecOps is an ambiguous label. Here it means the working contract between security and IT operations: agreed hardening baselines, one owned remediation queue with deadlines, governed exceptions and joint metrics. Others use it for SOC work or a Google product.

SecDataOps

SecDataOps is the engineering and governance of security telemetry: onboarding log sources, parsing and normalising them to a schema, enriching, routing and tiering them, and retaining them so that detections, investigations and audits have complete, trustworthy and affordable evidence.

AIOps for Security

AIOps for Security is the use of statistics, machine learning and language models inside the detect-triage-respond loop of a security operation, evaluated and governed against an adversary: base rates, missed detections, prompt injection and limits on autonomy.

IdentityOps

IdentityOps is the day-to-day operation of workforce and machine identities: HR-driven joiner–mover–leaver, directories and identity providers, SSO, SCIM provisioning, phishing-resistant MFA and recovery, and the lifecycle of non-human identities.

Practise and get certified

From xOps School

Practise ThreatOps and get certified

The free ThreatOps track on xOps School has study notes, a 25-question practice quiz with explanations, and a verifiable certificate when you score 70% or more. Sign in with Google to start.

For teams

Instructor-led training

Live batches for your team, with completion certificates and reports for L&D/HR.

Source: master.md (the editorial source of this page) · built 2026-10-17 · diagrams rendered with @mermaid-js/mermaid-cli 11.17.0 (mermaid 11.17.2)