Lesson 05 / 22
Diamond Model
Translating the four-corner relationship model into a link count: the actor, infrastructure, capability, and victim corners fill 77 of 134 possible links across 20 observations; the narrowing ratio of knowing one corner comes out exactly equal to that corner pair's link sparsity; the strongest corner (50%) becomes visible at the chain's eighth step and only after 41 items; the earliest-visible corner narrows only 30.7%; the capability corner gives 43.1% narrowing at a cost of 1 item; and adding a second corner adds only 10 to 13.1 points to the narrowing.
Published Updated
In this lesson
- Models an event with actor, infrastructure, capability, and victim corners and counts the links of the corner pairs
- Measures how many candidates knowing one corner leaves in the other corners by running the model
- Ranks narrowing power together with its visibility cost and derives the gain of adding a second corner
Contents
The matrix left one question unanswered. Cells say “this step can be carried out through this technique” and record whether a control sees that technique. But once an observation is in hand — a record, a connection, a file trace — which event that observation belongs to cannot be read from the matrix. The same technique class occurs in many independent events.
A second structure fills this gap and names an event by four corners: who (actor profile), through which infrastructure, with which capability, and against whom. Four corners produce six pairwise links, and the claim the model carries is this: when one corner is known, the others narrow. This lesson measures that narrowing as a link count.
Four Corners, Six Links
The observation set below is fictional: no real actor, infrastructure item, campaign, or organization name appears; the actor corner is written only by capability and motivation level.
TM13: an observation records four corners together, and the four corners produce six pairwise links. TM14: knowing a corner means staying confined to the observations that carry that value; the remaining candidate count is the number of distinct values of the target corner in that subset. TM15: every corner becomes visible at a particular step of the chain, and the item count reached by that step is the cost of using that corner.
// threat/corner.mjs — data structure of the four-corner relationship model: every observation ties together an // event's four corners. The observations are fictional; no real actor, infrastructure item, campaign, or // organization name appears. The actor corner is written only by capability and motivation level. // TM13: an observation records four corners together: actor profile, infrastructure item, // capability (technique class), and victim item. Four corners produce 6 pairwise links. export const CORNER = ["actor", "infrastructure", "capability", "victim"]; export const OBSERVATION = ` capability-2-revenue shared-hosting attachment-based branch-endpoint capability-2-revenue shared-hosting attachment-based subscriber-portal capability-2-revenue open-proxy valid-credential-login subscriber-portal capability-2-revenue shared-hosting valid-credential-login branch-endpoint capability-2-revenue open-proxy attachment-based field-application capability-3-revenue shared-hosting external-service-exploitation subscriber-portal capability-3-revenue rented-endpoint external-service-exploitation billing-service capability-3-revenue rented-endpoint interpreter-invocation billing-service capability-3-revenue open-proxy attachment-based field-application capability-3-revenue shared-hosting valid-credential-login subscriber-portal capability-3-insider-access own-endpoint credential-reuse field-application capability-3-insider-access own-endpoint valid-credential-login billing-service capability-3-insider-access own-endpoint credential-reuse billing-service capability-3-insider-access own-endpoint encrypted-channel branch-endpoint capability-5-targeted compromised-endpoint external-service-exploitation field-application capability-5-targeted compromised-endpoint interpreter-invocation field-application capability-5-targeted compromised-endpoint credential-reuse billing-service capability-5-targeted compromised-endpoint encrypted-channel branch-endpoint capability-5-targeted rented-endpoint encrypted-channel billing-service capability-5-targeted rented-endpoint interpreter-invocation subscriber-portal` .trim().split("\n").map((r) => { const [actor, infrastructure, capability, victim] = r.trim().split(/\s+/); return { actor, infrastructure, capability, victim }; }); export const value = (k) => [...new Set(OBSERVATION.map((g) => g[k]))]; // TM14: knowing a corner means staying confined to observations that carry that value; the remaining // candidate count is the number of distinct values of the target corner in that subset, averaged over the groups. export function narrow(known, target) { const total = value(target).length; const groups = new Map(); for (const g of OBSERVATION) { const key = known.map((k) => g[k]).join("|"); if (!groups.has(key)) groups.set(key, new Set()); groups.get(key).add(g[target]); } const avg = [...groups.values()].reduce((t, s) => t + s.size, 0) / groups.size; return { avg, total, ratio: 1 - avg / total, group: groups.size }; } // TM15: every corner becomes visible at a particular step of the chain; the item count reached by // that step is the cost of using that corner. The actor corner is never directly visible; it is inferred. export const VISIBILITY = { victim: { step: "initial-access", items: 0 }, capability: { step: "execution", items: 1 }, infrastructure: { step: "exfiltration", items: 41 }, actor: { step: "-", items: null } };
// threat/pivot.mjs — how many candidates knowing one corner eliminates from the others. import { CORNER, OBSERVATION, value, narrow, VISIBILITY } from "./corner.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 pair = CORNER.flatMap((a, i) => CORNER.slice(i + 1).map((b) => [a, b])); const possible = pair.reduce((t, [a, b]) => t + value(a).length * value(b).length, 0); const seen = pair.reduce((t, [a, b]) => t + new Set(OBSERVATION.map((g) => `${g[a]}|${g[b]}`)).size, 0); console.log(`${OBSERVATION.length} observations, ${CORNER.length} corners ` + `(${CORNER.map((k) => `${k} ${value(k).length}`).join(", ")}); ` + `${pair.length} corner pairs, ${possible} possible links, ${seen} present in the observations ` + `(${((seen / possible) * 100).toFixed(1)}%)`); const A = [-16, -16, 10, 11, 13]; console.log("\n1. corner pairs: how many links are present in the observations"); print(A, "corner", "corner", "possible", "present", "sparsity %"); for (const [a, b] of pair) { const n = new Set(OBSERVATION.map((g) => `${g[a]}|${g[b]}`)).size; const o = value(a).length * value(b).length; print(A, a, b, o, n, (100 - (n / o) * 100).toFixed(1)); } const B = [-16, -16, 8, 16, 13, 8]; console.log("\n2. how many candidates remain in the other corner once one is known"); print(B, "known", "target", "total", "avg candidates", "narrowing %", "group"); for (const b of CORNER) for (const h of CORNER) { if (b === h) continue; const d = narrow([b], h); print(B, b, h, d.total, d.avg.toFixed(2), (d.ratio * 100).toFixed(1), d.group); } const C = [-16, -16, 15, 17, 6]; console.log("\n3. which corner becomes visible when, and how much it narrows"); print(C, "corner", "visible step", "items by then", "avg narrowing %", "rank"); const strength = CORNER.map((k) => ({ k, g: CORNER.filter((h) => h !== k) .reduce((t, h) => t + narrow([k], h).ratio, 0) / (CORNER.length - 1) })) .sort((x, y) => y.g - x.g); for (const { k, g } of strength) print(C, k, VISIBILITY[k].step, VISIBILITY[k].items ?? "inferred", (g * 100).toFixed(1), strength.findIndex((x) => x.k === k) + 1); const D = [-30, -16, 16, 13, 9]; console.log("\n4. what a second corner buys"); print(D, "known corner(s)", "target", "avg candidates", "narrowing %", "added %"); for (const h of CORNER) { const single = CORNER.filter((k) => k !== h) .map((k) => ({ k, d: narrow([k], h) })).sort((x, y) => x.d.avg - y.d.avg)[0]; const other = CORNER.filter((k) => k !== h && k !== single.k); const pairD = narrow([single.k, other[0]], h); print(D, single.k, h, single.d.avg.toFixed(2), (single.d.ratio * 100).toFixed(1), "-"); print(D, `${single.k} + ${other[0]}`, h, pairD.avg.toFixed(2), (pairD.ratio * 100).toFixed(1), ((pairD.ratio - single.d.ratio) * 100).toFixed(1)); } console.log("if three corners are known, remaining average candidates: " + CORNER.map((h) => `${h} ${narrow(CORNER.filter((k) => k !== h), h).avg.toFixed(2)}`).join(", ")); const best = strength[0]; console.log(`strongest corner ${best.k} (${(best.g * 100).toFixed(1)}%), ` + `visible at the ${VISIBILITY[best.k].step} step and by then ` + `${VISIBILITY[best.k].items} items have been reached; earliest-visible corner ` + `victim (${VISIBILITY.victim.items} items) and its narrowing ` + `${(strength.find((x) => x.k === "victim").g * 100).toFixed(1)}%`);
20 observations, 4 corners (actor 4, infrastructure 5, capability 6, victim 4); 6 corner pairs, 134 possible links, 77 present in the observations (57.5%) 1. corner pairs: how many links are present in the observations corner corner possible present sparsity % actor infrastructure 20 8 60.0 actor capability 24 13 45.8 actor victim 16 13 18.8 infrastructure capability 30 15 50.0 infrastructure victim 20 12 40.0 capability victim 24 16 33.3 2. how many candidates remain in the other corner once one is known known target total avg candidates narrowing % group actor infrastructure 5 2.00 60.0 4 actor capability 6 3.25 45.8 4 actor victim 4 3.25 18.8 4 infrastructure actor 4 1.60 60.0 5 infrastructure capability 6 3.00 50.0 5 infrastructure victim 4 2.40 40.0 5 capability actor 4 2.17 45.8 6 capability infrastructure 5 2.50 50.0 6 capability victim 4 2.67 33.3 6 victim actor 4 3.25 18.8 4 victim infrastructure 5 3.00 40.0 4 victim capability 6 4.00 33.3 4 3. which corner becomes visible when, and how much it narrows corner visible step items by then avg narrowing % rank infrastructure exfiltration 41 50.0 1 capability execution 1 43.1 2 actor - inferred 41.5 3 victim initial-access 0 30.7 4 4. what a second corner buys known corner(s) target avg candidates narrowing % added % infrastructure actor 1.60 60.0 - infrastructure + capability actor 1.20 70.0 10.0 actor infrastructure 2.00 60.0 - actor + capability infrastructure 1.38 72.3 12.3 infrastructure capability 3.00 50.0 - infrastructure + actor capability 2.25 62.5 12.5 infrastructure victim 2.40 40.0 - infrastructure + actor victim 1.88 53.1 13.1 if three corners are known, remaining average candidates: actor 1.05, infrastructure 1.00, capability 1.33, victim 1.11 strongest corner infrastructure (50.0%), visible at the exfiltration step and by then 41 items have been reached; earliest-visible corner victim (0 items) and its narrowing 30.7%
The numbers are in the measurement class; their inputs are TM13–TM15.
Narrowing Is a Sparsity Measure
The four corners’ value counts are 4, 5, 6, and 4. The six corner pairs define a total of 134 possible links; 20 observations fill 77 of them. The remaining 57 links are never seen at all, and the model’s whole power comes from there.
Reading the second table alongside the first reveals an equality: every corner pair’s sparsity percentage turns out exactly equal to the narrowing percentage calculated for that pair. The actor-infrastructure pair’s sparsity is 60.0%; knowing the actor narrows infrastructure by 60.0%, and knowing infrastructure narrows the actor by 60.0% as well. The actor-victim pair’s sparsity is 18.8%, and so is its narrowing.
The equality is not a coincidence. For every value of a corner, the sum of the remaining candidate counts is exactly the number of distinct links in that pair; dividing by the group count gives the average candidate, and relating that to the target corner’s total value count yields link density. Narrowing power is how empty the link matrix is. The model is therefore not an intuition but something countable: the fewer combinations that have occurred between two corners, the more knowing one narrows the other.
The warning that follows from this is on the same scale. As the observation count grows, the link matrix fills, and narrowing power falls. A growing observation pool does not automatically strengthen inference; once the matrix starts filling, the same corner discriminates less.
The Strongest Corner Is the Most Expensive Corner
The third table is this lesson’s central comparison: every corner’s average narrowing power is written side by side with the step at which it becomes visible in the chain.
Infrastructure heads the ranking: it narrows the other three corners by an average of 50.0%. But the infrastructure corner only becomes visible at the exfiltration step — the external endpoint shows up as data leaves — and by that point 41 items have been reached. The strongest clue is born at the chain’s latest link.
This late birth comes from the model’s own structure. The infrastructure corner is strong because its link matrix with the actor is the emptiest one — every actor profile uses only a few forms of infrastructure. That same sparsity is also why this corner appears late on the defense side: a sparsely used item only falls into a record at the chain’s end, on an outward-facing step.
Victim sits at the bottom of the ranking: 30.7% narrowing. This corner is free on the defense side, because which item is targeted is already clear at the initial-access step, and at that point 0 items have been lost. The free one is the weakest; the strongest one is the most expensive.
The row in between makes the call. Capability narrows 43.1% and becomes visible at the execution step — the items reached by then are 1. Infrastructure’s 6.9-point edge costs 40 more items. Measured by the chain’s own scale, the best corner is not the one that narrows the most but the one that narrows the most per item spent; on that measure the capability corner is thirty-five times more efficient than infrastructure. The victim corner is free, so no such ratio can be formed for it; what sets it apart is not efficiency but having the lowest narrowing of all.
There is also an asymmetry inside the second table itself. Even though the narrowing percentage is equal in both directions for the same pair, the remaining candidate count is not: knowing infrastructure brings the actor down from 4 candidates to 1.60, knowing the actor brings infrastructure down from 5 to 2.00. The percentage is the same, the absolute number is different, and the decision is made with the absolute number. Targeting the corner with the smaller value set produces a more precise result at the same sparsity.
The actor corner stands apart in the table: it is never directly visible at any step; it is inferred from the other three corners. Its narrowing power is 41.5%, but this power is only meaningful as a target of inference — knowing the actor narrows the other corners, but the only way to know the actor is through the other corners.
The Return of a Second Corner
The fourth table finds the best single pivot for every target corner, then adds a second corner to it.
The best single corner for narrowing the actor is infrastructure: it drops from four candidates to 1.60 (60.0%). Adding the capability corner brings it down to 1.20 (70.0%) — the second corner’s contribution is 10 points. In the other three rows the added contribution is 12.3, 12.5, and 13.1 points. In all four cases, the second corner brings roughly one-sixth as much extra narrowing as the first.
The reason for the diminishing return is in the first table. The second corner only works within the subset the first one leaves behind, and that subset is already sparse; the number of links the second pivot can still remove is far smaller than what the first removed. The last row shows the limit: once three corners are known together, the remaining average candidate is between 1.00 and 1.33 — meaning nothing is left to add after the third corner.
This writes how the four-corner model is used in practice. The first pivot delivers nearly all of the decision; the second pivot is a verification tool. Going from 1.60 to 1.20 on the actor corner means, on average, “one candidate” instead of “two candidates,” and this difference is decisive on some observation sets — but if it is bought at the cost of waiting 40 more items, the price paid is larger than the narrowing gained.
Put on the chain’s scale: waiting for one more corner means advancing one more step in the chain. With the previous lesson’s numbers, that wait — going from execution to exfiltration — means moving from 1 item to 41 items. The relationship model delivers narrowing, but the narrowing’s cost carries no decision unless it is written on the chain’s own scale.
Summary
- Four corners (actor, infrastructure, capability, victim) produce six pairwise links; 20 observations fill 77 of 134 possible links, and the remaining 57 gaps supply the model’s entire power.
- The narrowing percentage of knowing a corner is exactly equal to that corner pair’s link sparsity; narrowing power is how empty the link matrix is.
- As the observation count grows, the matrix fills and narrowing power falls; growing the pool does not strengthen inference by itself.
- The strongest corner is infrastructure (50.0%), but it becomes visible at the exfiltration step, after 41 items; the earliest-visible corner is the victim (0 items), and it narrows only 30.7%.
- The capability corner narrows 43.1% at a cost of 1 item; infrastructure’s 6.9-point edge costs 40 more items.
- The second corner’s contribution is between 10.0 and 13.1 points — roughly one-sixth of what the first pivot provides; the first pivot makes the decision, the second verifies it.
Next Step
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 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, though, falls outside this assumption. There is not yet a pattern to recognize, that row in the link matrix is empty, and no fix has been released either. The topic’s final lesson measures this situation in terms of coverage: of the links that can be broken under a known threat, how many can still be broken under an unknown threat; how many steps a signature-based control misses; how many a behavior-based control still catches; and how many items stay exposed in the window until a fix is published.
To keep your progress and take notes, Log in
My notes
Log in to take notes.