Lesson 06 / 22
Known and Unknown Threats
Measuring zero-day in terms of control coverage: eight controls make 7 links breakable under a known threat but drop to 5 under an unknown threat; three signature-based controls leave two steps completely uncovered; three behavior-based controls keep 70% of their catch; two configuration-based controls are not affected at all; expected items rise from 6.42 to 19.69; and the 77-day pre-patch window leaves 115.49 items exposed while the same window under structural breaking gives 0.00.
Published Updated
In this lesson
- Separates controls into signature-based, behavior-based, and configuration-based, and calculates each one's catch under an unknown threat
- Measures the number of breakable links and the expected items separately for a known and an unknown threat
- Splits the pre-patch window into phases and derives the number of items left exposed in each phase
Contents
Everything measured across five lessons stood on the same assumption: what the controls saw were things known in advance. Every cell in the matrix was tied to a recognized technique class, every control item to a recognized record pattern; every corner in the relationship model rested on a link that had been seen before.
The moment a technique is used for the first time falls outside this assumption. Zero-day is the condition where a vulnerability is not yet known on the defense side and no fix exists for it. This lesson measures that condition not as an adjective but as coverage loss: how many links stay breakable, which control type remains standing, and how many items are exposed in the window until a fix is published.
The Control’s Type Determines What It Looks At
The structure below is a model: there is no running exploit, vulnerability identifier, or patch record; there are only control types and catch rates. The work runs on a fictional measurement network.
TM16: every control belongs to a type — a signature-based control looks at a recognized pattern, a behavior-based control looks at deviation, a configuration-based control looks at the state itself. TM17: under an unknown threat, a signature-based control’s catch is zero; a behavior-based control still runs but drops by a multiplier because its threshold is not tuned to that behavior; a configuration-based control is not affected. TM18: if the chain breaks at step k, the items reached by then are the previous step’s item count.
// threat/unknown.mjs — coverage model of controls under a known vs. an unknown threat: there // is no running exploit or vulnerability identifier here; only a data structure of control // types and catch rates. No randomness; the expected value is computed. export const STEP = ["recon", "initial-access", "execution", "persistence", "privilege-escalation", "lateral-movement", "collection", "exfiltration"]; export const ITEM = [0, 1, 2, 3, 9, 26, 41, 48]; // TM16: every control belongs to a type. A signature-based control looks at a recognized pattern; a // behavior-based control looks at deviation; a configuration-based control looks at the state itself. export const CONTROL = [ { name: "signature-match", type: "signature", step: "initial-access", catch: 0.35 }, { name: "file-signature", type: "signature", step: "execution", catch: 0.4 }, { name: "process-tree-deviation", type: "behavior", step: "execution", catch: 0.2 }, { name: "startup-inventory", type: "configuration", step: "persistence", catch: 0.3 }, { name: "privilege-change", type: "configuration", step: "privilege-escalation", catch: 0.25 }, { name: "session-hopping", type: "behavior", step: "lateral-movement", catch: 0.18 }, { name: "data-pattern-signature", type: "signature", step: "collection", catch: 0.22 }, { name: "egress-volume-deviation", type: "behavior", step: "exfiltration", catch: 0.45 }, ]; // TM17: under an unknown threat, a signature-based control's catch is zero (there is no pattern yet); a // behavior-based control still runs but drops by a multiplier because its threshold is not tuned to that // behavior; a configuration-based control does not depend on whether the threat is known. export const MULTIPLIER = { known: { signature: 1, behavior: 1, configuration: 1 }, unknown: { signature: 0, behavior: 0.7, configuration: 1 }, "disclosed-no-patch": { signature: 0, behavior: 1, configuration: 1 }, "patch-available-not-applied": { signature: 1, behavior: 1, configuration: 1 }, }; export function stepCatch(multiplier) { return STEP.map((a) => 1 - CONTROL.filter((d) => d.step === a) .reduce((t, d) => t * (1 - d.catch * multiplier[d.type]), 1)); } // TM18: if the chain breaks at step k, the items reached by then are ITEM[k-1]; under // structural breaking the chain can never be walked past that step at all. export function expectedItems(multiplier, through = STEP.length) { const p = stepCatch(multiplier); let remaining = 1, total = 0; for (let i = 0; i < through; i++) { total += remaining * p[i] * (i === 0 ? 0 : ITEM[i - 1]); remaining *= 1 - p[i]; } return total + remaining * (through === 0 ? 0 : ITEM[through - 1]); } export const breakable = (multiplier) => stepCatch(multiplier).filter((x) => x > 0).length;
// threat/scope.mjs — how many steps a signature-based control misses under the unknown, how many a // behavior-based control still catches, how many items stay exposed in the pre-patch window. import { STEP, ITEM, CONTROL, MULTIPLIER, stepCatch, expectedItems, breakable } from "./unknown.mjs"; const print = (w, ...s) => console.log(s.map((v, i) => (w[i] < 0 ? String(v).padEnd(-w[i]) : String(v).padStart(w[i]))).join("")); const type = (t) => CONTROL.filter((d) => d.type === t).length; console.log(`${STEP.length} steps, ${CONTROL.length} controls ` + `(signature ${type("signature")}, behavior ${type("behavior")}, configuration ${type("configuration")}); ` + `breakable links known ${breakable(MULTIPLIER.known)}, unknown ` + `${breakable(MULTIPLIER.unknown)}; expected items ` + `${expectedItems(MULTIPLIER.known).toFixed(2)} -> ` + `${expectedItems(MULTIPLIER.unknown).toFixed(2)}`); const A = [-25, -15, -22, 11, 13]; console.log("\n1. control items and their catch under the unknown"); print(A, "control", "type", "step", "known", "unknown"); for (const d of CONTROL) print(A, d.name, d.type, d.step, d.catch.toFixed(2), (d.catch * MULTIPLIER.unknown[d.type]).toFixed(2)); const B = [-22, 10, 12, 8, 17, 33]; console.log("\n2. step by step: which link still breaks under the unknown as well"); print(B, "step", "known", "unknown", "items", "remaining catch", "status"); const pB = stepCatch(MULTIPLIER.known), pU = stepCatch(MULTIPLIER.unknown); for (let i = 0; i < STEP.length; i++) print(B, STEP[i], pB[i].toFixed(3), pU[i].toFixed(3), ITEM[i], pB[i] === 0 ? "-" : `${((pU[i] / pB[i]) * 100).toFixed(0)}%`, pB[i] === 0 ? "no control at all" : pU[i] === 0 ? "closes once the signature drops" : "stays exposed if breakable"); const C = [-34, 8, 8, 13, 16, 15]; console.log("\n3. the pre- and post-patch window"); print(C, "phase", "days", "events", "breakable", "expected items", "exposed items"); const PHASE = [["known internally, not disclosed", 40, "unknown", 8], ["disclosed, no patch", 12, "disclosed-no-patch", 8], ["patch available, not applied", 25, "patch-available-not-applied", 8], ["patch applied (structural)", 0, "patch-available-not-applied", 1]]; let exposedTotal = 0; for (const [name, days, c, through] of PHASE) { const events = days / 10, e = expectedItems(MULTIPLIER[c], through), exposed = events * e; if (days > 0) exposedTotal += exposed; print(C, name, days, events.toFixed(1), breakable(MULTIPLIER[c]), e.toFixed(2), exposed.toFixed(2)); } const daysTotal = PHASE.reduce((t, f) => t + f[1], 0); console.log(`window ${daysTotal} days, ${(daysTotal / 10).toFixed(1)} events, ` + `exposed items ${exposedTotal.toFixed(2)}; the same window under structural breaking gives ` + `${((daysTotal / 10) * expectedItems(MULTIPLIER["patch-available-not-applied"], 1)).toFixed(2)}`); const D = [-24, 13, 16, 11, 12]; console.log("\n4. control types in isolation"); print(D, "control type active", "breakable", "expected items", "vs. known", "coverage %"); const only = (t) => ({ signature: t === "signature" ? 1 : 0, behavior: t === "behavior" ? 1 : 0, configuration: t === "configuration" ? 1 : 0 }); const base = expectedItems(MULTIPLIER.known); for (const [name, c] of [["all (known threat)", MULTIPLIER.known], ["all (unknown threat)", MULTIPLIER.unknown], ["signature only", only("signature")], ["behavior only", only("behavior")], ["configuration only", only("configuration")], ["none", only("none")]]) { const e = expectedItems(c); print(D, name, breakable(c), e.toFixed(2), (e - base).toFixed(2), `${((1 - e / ITEM.at(-1)) * 100).toFixed(1)}`); }
8 steps, 8 controls (signature 3, behavior 3, configuration 2); breakable links known 7, unknown 5; expected items 6.42 -> 19.69 1. control items and their catch under the unknown control type step known unknown signature-match signature initial-access 0.35 0.00 file-signature signature execution 0.40 0.00 process-tree-deviation behavior execution 0.20 0.14 startup-inventory configuration persistence 0.30 0.30 privilege-change configuration privilege-escalation 0.25 0.25 session-hopping behavior lateral-movement 0.18 0.13 data-pattern-signature signature collection 0.22 0.00 egress-volume-deviation behavior exfiltration 0.45 0.32 2. step by step: which link still breaks under the unknown as well step known unknown items remaining catch status recon 0.000 0.000 0 - no control at all initial-access 0.350 0.000 1 0% closes once the signature drops execution 0.520 0.140 2 27% stays exposed if breakable persistence 0.300 0.300 3 100% stays exposed if breakable privilege-escalation 0.250 0.250 9 100% stays exposed if breakable lateral-movement 0.180 0.126 26 70% stays exposed if breakable collection 0.220 0.000 41 0% closes once the signature drops exfiltration 0.450 0.315 48 70% stays exposed if breakable 3. the pre- and post-patch window phase days events breakable expected items exposed items known internally, not disclosed 40 4.0 5 19.69 78.76 disclosed, no patch 12 1.2 5 17.23 20.67 patch available, not applied 25 2.5 7 6.42 16.05 patch applied (structural) 0 0.0 7 0.00 0.00 window 77 days, 7.7 events, exposed items 115.49; the same window under structural breaking gives 0.00 4. control types in isolation control type active breakable expected items vs. known coverage % all (known threat) 7 6.42 0.00 86.6 all (unknown threat) 5 19.69 13.27 59.0 signature only 3 17.09 10.67 64.4 behavior only 3 30.92 24.50 35.6 configuration only 2 26.32 19.90 45.2 none 0 48.00 41.58 0.0
The numbers are in the measurement class; their inputs are TM16–TM18.
Five of Seven Links
Eight control items make 7 links breakable under a known threat; of the eight steps, only the recon step is empty. The same eight controls leave 5 links under an unknown threat. The loss is two links, and these two links are not chosen at random: initial-access and collection are the two steps that have only a signature-based control facing them.
The second table’s remaining catch column gives the ratio for every step. At the persistence and privilege-escalation steps the ratio is 100% — the control at these two steps is configuration-based, and the presence of a startup entry or a change of privilege is seen regardless of whether the threat is known. At lateral-movement and exfiltration the ratio is 70%. At execution the ratio drops to 27%, because most of that step’s 0.520 catch is carried by the signature-based control; once the signature drops, only the behavior-based control’s 0.140 remains.
Expected items rise from 6.42 to 19.69 — more than triple. While the breakable link count drops from 7 to 5, meaning a 29% decrease, expected items rise 207%. The link count and the item count do not move at the same rate, because one of the two lost links (initial-access) is the chain’s cheapest breaking point, and the other (collection) sits right before 41 items.
The first table writes the same distinction from the control side. Of the eight items, three are signature-based, three behavior-based, two configuration-based. Looked at by inventory count, this looks like a balanced three-three-two split; but in the unknown column, three items drop to zero and 37.5% of the inventory goes idle at once. There is no link between the size of a control inventory and its zero-day resilience; the link is built by which type the items are and which steps they fall on.
Which Control Type Stays Standing
The fourth table isolates the types one by one and gives an unexpected ranking. Under a known threat, signature only — three controls — leaves 17.09 items; behavior only — three controls — leaves 30.92. With the same number of control items, the signature-based set is nearly twice as good, because its catch rates are higher (0.35, 0.40, 0.22 versus 0.20, 0.18, 0.45) and two of them sit at the front of the chain.
Under an unknown threat, the contribution of the same three signature items is zero. What remains standing is the five behavior-based and configuration-based items, and together they leave 19.69 items. The two types are weak on their own (30.92 and 26.32), and together they leave about three times as many items as the known-threat figure — but neither is zero. In the row with no controls at all, expected items are 48.00, the entire chain.
The decision follows from this. A signature-based control is the most efficient tool under a known threat and there is no reason to drop it; under an unknown threat, it does nothing at all. A configuration-based control does the same job in both cases and has the narrowest coverage (only 2 links). A control inventory’s zero-day resilience is measured by how many links its non-signature items are found on — 5 links in this set.
The Pre-Patch Window
The third table splits the window into three phases and counts how many items stay exposed in each phase. In the fictional network, one event of this class is assumed every ten days.
The first phase is the period when the vulnerability is known but not publicly disclosed: 40 days, 4.0 events, 19.69 items per event, 78.76 items in total. The second phase runs between disclosure and the fix being published: 12 days. There is still no signature here, but the behavior-based controls’ thresholds are now tuned to that behavior, and expected items drop from 19.69 to 17.23. The breakable link count, though, stays at 5 — tuning the threshold does not open a new link, it only sharpens the existing one a little.
The third phase is the period when the fix has been published but not applied: 25 days. Because the signature pattern has been published, the breakable link count returns to 7 and expected items drop to 6.42. Even so, this phase leaves 16.05 items exposed, because the fix has only been published.
There is an ordering among the phases, and it runs opposite to what one would expect. The longest phase by duration is the first (40 days), and it is also the heaviest by item count; but the second phase carries 17.23 items per event despite lasting only 12 days, while the third phase carries 6.42 per event despite lasting 25 days. Items do not fall as the window shortens; items fall according to how many links can still be broken in that phase.
The total window is 77 days, 7.7 events, and 115.49 items. The same window would give 0.00 if the fix had been applied: an applied fix is not a control but the structural breaking measured in the third lesson — it removes the precondition, and the chain can never even reach the second step. The result repeated across every measurement in this course takes its sharpest form here: 78.76 of the 115.49 items accumulate in the first phase alone, the 40 days with no disclosure at all, and the only thing that can be done in that phase is how many links the non-signature controls are found on.
Summary
- Zero-day is not an adjective but a coverage loss: eight controls make 7 links breakable under a known threat, and 5 under an unknown one.
- The two lost links are the steps that have only a signature-based control facing them; a configuration-based control’s catch is preserved at 100%, a behavior-based one keeps 70%, a signature-based one keeps 0%.
- While the breakable link count falls 29%, expected items rise from 6.42 to 19.69 — a 207% increase; the link count and the item count do not move at the same rate.
- Under a known threat, signature only (three controls) leaves 17.09 items, behavior only (three controls) leaves 30.92; under an unknown threat, signature’s contribution is zero, and the remaining five items leave 19.69.
- The 77-day window leaves 115.49 items exposed; 78.76 of that accumulates in the 40 pre-disclosure days, and 16.05 while the fix is published but not applied.
- An applied fix is not a control but structural breaking: the same window gives 0.00 items.
Next Step
This topic built the chain as a model and counted which links can be broken. Actors were separated by capability and motivation, and how many steps each level got through was written down; on the time axis, how many days go unseen by any control was measured; preconditions were written and the early-break gain was calculated; techniques were mapped to steps and the step with no control at all was counted; the four-corner relationship model was translated into a link count; and where coverage falls under an unknown threat was written.
All these measurements had one thing in common. Every chain’s first link was written as a technical step: recon, then initial-access. Yet initial-access is opened, more often than not, not by an exploit but by a decision a person makes — a reply given to a message, a sentence said on a phone call, a moment that lets someone through a door alongside you. That link’s precondition is not a configuration weakness but a sense of trust or urgency, and the control set against it is not a record pattern. The next topic — Social Engineering — measures this first link of the chain.
To keep your progress and take notes, Log in
My notes
Log in to take notes.