Skip to content
academia.sh

Lesson 04 / 15

Exploit and Payload

Breaking the chain from vulnerability to impact into steps: 5 exploits and 4 payloads produce 12 valid chains; chain length ranges from 2 to 7 and totals 53 steps; breaking a single step cuts at most 8 chains; blocking a payload cuts at most 5 chains and blocking an exploit at most 4; the same break leaves 0 completed steps at access and 41 at impact; even when all six middle steps are broken, 1 of 12 chains still stands; and that single chain carries 25.7% of the total probability mass.

Published Updated

In this lesson

  • Separates exploit from payload and models the chain from vulnerability to impact as a step sequence
  • Computes how many chains breaking each step cuts, and how many steps had already completed when it is cut
  • Compares three levers: breaking a step, blocking an exploit, blocking a payload
Contents

The previous lesson counted every item as a single event: probability given, impact given, multiplied. But a 600-fictional-unit impact is not born in a single moment. First something is reached, then a weakness is triggered, then something is executed, privilege expands, and impact is only written once all of these have completed. The number we call probability is actually the probability of this chain completing from start to end.

Exploit is the step sequence that actually uses a vulnerability. Payload is the effect written after the exploit completes. The two are separate things, and that separation sets what this lesson measures: the same exploit can carry more than one payload, and the same payload can arrive with more than one exploit. This lesson builds the chain as a model and ties it to a single question — which step to break cuts how many chains.

A Chain Is a Sequence of Steps

The structure below is a model: there is no working exploit, no tool, no payload here — only a data structure made of step names. The vulnerability names come from the previous two lessons’ list. Trying these steps on a real system without written authorization and a defined scope is both illegal and unprofessional.

SC16: a chain follows the eight-step canonical order, and every chain is a subsequence of that order. SC17: an exploit is the step sequence that uses a vulnerability; a payload is the effect written after the exploit completes, and it brings its own extra steps. SC18: a payload matches an exploit only if the step it requires is present in that exploit. SC19: if a step is broken, every chain that includes it is cut; at the moment it is cut, the chain’s steps before it have already completed.

// security/chain.mjs — the step model of the chain from vulnerability to impact (model): there
// is no working exploit here, only a data structure made of step names. No randomness.

// SC16: a chain follows the eight-step canonical order; every chain is a subsequence of that order.
export const STEP = ["access", "discovery", "triggering", "execution",
  "privilege-escalation", "lateral-movement", "persistence", "impact"];
export const LETTER = { access: "A", discovery: "D", triggering: "T", execution: "E",
  "privilege-escalation": "P", "lateral-movement": "M", persistence: "S", impact: "I" };

// SC17: an exploit is the step sequence that uses a vulnerability; a payload is the effect
// written after the exploit completes, and it brings its own extra steps.
export const EXPLOIT = [
  { name: "credential-reuse", vuln: "default-password", step: ["access", "discovery"] },
  { name: "input-triggering", vuln: "unvalidated-input",
    step: ["access", "triggering", "execution"] },
  { name: "unsigned-package", vuln: "unsigned-update",
    step: ["access", "discovery", "triggering", "execution"] },
  { name: "account-sharing", vuln: "shared-account", step: ["access", "discovery"] },
  { name: "transfer-interception", vuln: "unencrypted-transfer", step: ["access"] },
];

// SC18: a payload matches an exploit only if the step it requires is present in that exploit.
export const PAYLOAD = [
  { name: "data-exfiltration", need: [], extra: ["impact"] },
  { name: "record-tampering", need: ["discovery"], extra: ["privilege-escalation", "impact"] },
  { name: "service-disruption", need: ["execution"], extra: ["impact"] },
  { name: "persistent-access", need: ["execution"], extra: ["lateral-movement", "persistence", "impact"] },
];

export const CHAIN = EXPLOIT.flatMap((e) => PAYLOAD
  .filter((p) => p.need.every((n) => e.step.includes(n)))
  .map((p) => ({ exploit: e.name, vuln: e.vuln, payload: p.name,
    step: STEP.filter((s) => e.step.includes(s) || p.extra.includes(s)) })));

export const mask = (c) => STEP.map((s) => (c.step.includes(s) ? LETTER[s] : ".")).join("");
export const passing = (s) => CHAIN.filter((c) => c.step.includes(s));
// SC19: if a step is broken, every chain that includes it is cut; at the moment it is cut,
// that chain's steps before it have already completed.
export const priorTotal = (s) => passing(s).reduce((n, c) => n + c.step.indexOf(s), 0);
export const closed = (set) =>
  CHAIN.filter((c) => c.step.some((s) => set.includes(s))).length;

// SC20: every step has a completion probability and steps are treated as independent (model);
// a chain's completion probability is the product of its step probabilities.
export const STEP_P = { access: 0.5, discovery: 0.7, triggering: 0.4, execution: 0.6,
  "privilege-escalation": 0.35, "lateral-movement": 0.5, persistence: 0.6, impact: 0.9 };
export const probability = (c) => c.step.reduce((p, s) => p * STEP_P[s], 1);
export const MASS = CHAIN.reduce((s, c) => s + probability(c), 0);
export const closedMass = (set) => CHAIN
  .filter((c) => c.step.some((s) => set.includes(s)))
  .reduce((s, c) => s + probability(c), 0);
// security/break.mjs — which step to break closes how many chains, how much had already happened.
import { STEP, LETTER, EXPLOIT, PAYLOAD, CHAIN, MASS, mask, passing, priorTotal, closed,
  probability, closedMass }
  from "./chain.mjs";

const write = (g, ...s) => console.log(s.map((v, i) =>
  (g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i]))).join(""));
const length = CHAIN.map((c) => c.step.length);

console.log(`${EXPLOIT.length} exploits x ${PAYLOAD.length} payloads -> ${CHAIN.length} valid chains; ` +
  `step order ${STEP.map((s) => LETTER[s]).join("")} = ${STEP.join(", ")}; ` +
  `chain length ${Math.min(...length)}..${Math.max(...length)}, ` +
  `total steps ${length.reduce((a, x) => a + x, 0)}`);

const A = [-26, 20, 10, 7];
console.log("\n1. valid chains");
write(A, "exploit", "payload", "mask", "steps");
for (const c of CHAIN) write(A, c.exploit, c.payload, mask(c), c.step.length);

const B = [-24, 11, 10, 8, 12];
console.log("\n2. if a step is broken");
write(B, "step", "in chains", "closed", "left", "steps done");
for (const s of STEP)
  write(B, s, passing(s).length, closed([s]), CHAIN.length - closed([s]), priorTotal(s));

const C = [-26, 11, 10, 8];
console.log("\n3. if a payload is blocked (exploit stays in place)");
write(C, "payload", "in chains", "closed", "left");
for (const p of PAYLOAD) {
  const n = CHAIN.filter((c) => c.payload === p.name).length;
  write(C, p.name, n, n, CHAIN.length - n);
}
for (const e of EXPLOIT) {
  const n = CHAIN.filter((c) => c.exploit === e.name).length;
  write(C, "exploit " + e.name.slice(0, 15), n, n, CHAIN.length - n);
}

const MID = STEP.slice(1, -1); // access and impact are the legitimate ends, cannot be removed outright
const D = [-30, 10, 8];
console.log("\n4. best single and pair of middle steps (access and impact excluded)");
write(D, "broken step set", "closed", "left");
const single = MID.map((s) => [s]).sort((x, y) => closed(y) - closed(x))[0];
const pair = MID.flatMap((s, i) => MID.slice(i + 1).map((t) => [s, t]))
  .sort((x, y) => closed(y) - closed(x))[0];
for (const set of [single, pair, MID])
  write(D, set.map((s) => LETTER[s]).join("+"), closed(set), CHAIN.length - closed(set));
const open = CHAIN.filter((c) => !c.step.some((s) => MID.includes(s)));
console.log(`chains still standing once every middle step is broken: ` +
  open.map((c) => `${c.exploit} + ${c.payload} (${mask(c)})`).join(", "));

const E = [-24, 11, 11, 12, 15];
console.log("\n5. chains closed vs probability mass closed");
write(E, "step", "closed", "chains %", "mass %", "mass/chain");
for (const s of STEP) {
  const c = (closed([s]) / CHAIN.length) * 100, m = (closedMass([s]) / MASS) * 100;
  write(E, s, closed([s]), c.toFixed(1), m.toFixed(1), (m / c).toFixed(2));
}
const mostLikely = [...CHAIN].sort((x, y) => probability(y) - probability(x));
console.log(`total mass ${MASS.toFixed(4)}; most likely chain ${mostLikely[0].exploit} + ` +
  `${mostLikely[0].payload} (${probability(mostLikely[0]).toFixed(4)}, ` +
  `${((probability(mostLikely[0]) / MASS) * 100).toFixed(1)}% of mass), least likely ` +
  `${mostLikely.at(-1).exploit} + ${mostLikely.at(-1).payload} (${probability(mostLikely.at(-1)).toFixed(4)})`);
5 exploits x 4 payloads -> 12 valid chains; step order ADTEPMSI = access, discovery, triggering, execution, privilege-escalation, lateral-movement, persistence, impact; chain length 2..7, total steps 53

1. valid chains
exploit                                payload      mask  steps
credential-reuse             data-exfiltration  AD.....I      3
credential-reuse              record-tampering  AD..P..I      4
input-triggering             data-exfiltration  A.TE...I      4
input-triggering            service-disruption  A.TE...I      4
input-triggering             persistent-access  A.TE.MSI      6
unsigned-package             data-exfiltration  ADTE...I      5
unsigned-package              record-tampering  ADTEP..I      6
unsigned-package            service-disruption  ADTE...I      5
unsigned-package             persistent-access  ADTE.MSI      7
account-sharing              data-exfiltration  AD.....I      3
account-sharing               record-tampering  AD..P..I      4
transfer-interception        data-exfiltration  A......I      2

2. if a step is broken
step                      in chains    closed    left  steps done
access                           12        12       0           0
discovery                         8         8       4           8
triggering                        7         7       5          11
execution                         7         7       5          18
privilege-escalation              3         3       9           8
lateral-movement                  2         2      10           7
persistence                       2         2      10           9
impact                           12        12       0          41

3. if a payload is blocked (exploit stays in place)
payload                     in chains    closed    left
data-exfiltration                   5         5       7
record-tampering                    3         3       9
service-disruption                  2         2      10
persistent-access                   2         2      10
exploit credential-reus             2         2      10
exploit input-triggerin             3         3       9
exploit unsigned-packag             4         4       8
exploit account-sharing             2         2      10
exploit transfer-interc             1         1      11

4. best single and pair of middle steps (access and impact excluded)
broken step set                   closed    left
D                                      8       4
D+T                                   11       1
D+T+E+P+M+S                           11       1
chains still standing once every middle step is broken: transfer-interception + data-exfiltration (A......I)

5. chains closed vs probability mass closed
step                         closed   chains %      mass %     mass/chain
access                           12      100.0       100.0           1.00
discovery                         8       66.7        60.1           0.90
triggering                        7       58.3        25.7           0.44
execution                         7       58.3        25.7           0.44
privilege-escalation              3       25.0        14.1           0.56
lateral-movement                  2       16.7         3.1           0.19
persistence                       2       16.7         3.1           0.19
impact                           12      100.0       100.0           1.00
total mass 1.7492; most likely chain transfer-interception + data-exfiltration (0.4500, 25.7% of mass), least likely unsigned-package + persistent-access (0.0227)

Numbers belong to the measurement class; their inputs are SC16–SC19.

Five Exploits, Twelve Chains

The first table shows once more how a product narrows. Five exploits and four payloads make twenty combinations; the valid ones are twelve, because not every payload matches every exploit. service-disruption and persistent-access require the execution step; transfer-interception consists only of the access step, so it carries a single payload and produces the shortest chain, at two steps.

Chain lengths range from 2 to 7 and total 53 steps. Length comes from the payload: the unsigned-package exploit is four steps, the persistent-access payload adds three more on top, and the chain climbs to seven. The same exploit ends at five steps with the data-exfiltration payload. The exploit is fixed; the payload sets the chain’s length.

This is why the separation matters. The input-triggering mask appears in three chains as A.TE...I, A.TE...I, and A.TE.MSI — the first two are exactly the same step sequence and differ only in the payload’s name. Looked at from the defense side, these two chains pass through the same places, produce the same records, and get cut by the same control; the only difference is the effect written once they occur.

Which Step to Break Cuts How Many Chains

The second table is this lesson’s central measurement. For each of the eight steps there are two numbers: how many chains it cuts, and how many steps have already completed when it is cut.

The order of cutting power is access and impact (12), discovery (8), triggering and execution (7), privilege-escalation (3), lateral-movement and persistence (2). The order decreases from the front of the chain to the back, because chains are shared early on and branch later. An earlier step closes more paths.

The last column reverses the same ranking. When access is broken, no step has completed; when impact is broken, 41 steps have already completed across the twelve chains. execution cuts 7 chains and leaves 18 completed steps behind it; discovery cuts 8 chains and leaves only 8. Two steps with close to the same cutting power leave behind very different amounts of work already done.

The 12 that appears in the table for both end steps is misleading. access is in every chain, but breaking it outright means shutting down the service itself — legitimate requests pass through the same step. impact is also in every chain, but breaking it there means limiting the damage after the event, not closing a path. The usable lever sits in the six middle steps.

Blocking a Payload Does Not Cut the Chain

The third table sets three levers side by side. Blocking a payload closes at most 5 chains (data-exfiltration); blocking an exploit closes at most 4 (unsigned-package); breaking a step closes 8. All three columns run over the same twelve chains, and the difference comes purely from where the lever is placed.

The payload is the weakest lever, and the reason is visible in the table: the payload sits at the end of the chain and is interchangeable. The unsigned-package exploit carries four payloads; blocking one of them leaves the remaining three chains in place. Cutting the same exploit closes all four at once. Breaking a step is wider still, because a single step is shared across multiple exploits: the discovery step appears in three separate exploits and cuts eight chains at once.

The practical payoff of this ordering is where defense gets written. A control that recognizes and stops a specific effect closes a single column; putting the same effort into a step the chain shares closes four times as much. A defense placed at the end of the chain has to be repeated once for every branch the chain has.

The Chain the Middle Steps Cannot Reach

The fourth table shows the lever’s limit. The best single middle step is discovery, closing 8 chains and leaving 4. The best pair is discovery and triggering: 11 chains close, 1 remains. When all six middle steps are broken, the result does not change — still 11 close, 1 remains.

The chain still standing is the transfer-interception exploit with the data-exfiltration payload, and its mask is A......I. This chain has no step in its middle: it goes straight from access to impact. Every defense written into the six middle steps never touches it at all, because it does not pass through any of them.

This row records a limit of the chain model itself. Breaking the chain into steps makes it possible to choose where a defense goes; but a chain whose middle-step set is empty falls outside that choice. The only way to close it is to touch the first step — access — and access is exactly the step the table sets aside as “cannot be removed outright.” The next question is unavoidable because of this: access was written as a single step, yet how many separate forms does reaching an asset actually take.

Chain Count and Probability Mass Are Not the Same Thing

The fifth table gives every chain a completion probability — the product of its step probabilities — and counts not how many chains a broken step closes, but how much probability mass it closes. The total mass of the twelve chains is 1.7492.

The two columns do not move together. discovery closes 66.7% of the chains and 60.1% of the mass; the ratio, 0.90, is balanced. triggering and execution close 58.3% of the chains but only 25.7% of the mass — a ratio of 0.44. Two controls that do almost the same job by count differ by two and a half times in terms of realized probability. The reason is length: chains that pass through execution are longer, and every additional step multiplies the probability down once more. lateral-movement and persistence are the extreme case — they close 16.7% of the chains and 3.1% of the mass.

The last line ties back to the previous lesson’s number. The most likely chain is the transfer-interception and data-exfiltration pair: two steps, a probability of 0.4500, and on its own it carries 25.7% of the total mass. The least likely is the seven-step unsigned-package with persistent-access: 0.0227. The third lesson wrote a probability of 0.03 for the unsigned-update item and 0.25 for unencrypted-transfer; this is where those two numbers come from — as the chain lengthens, probability falls and impact grows.

This sharpens the fourth table’s finding even further. The single chain still standing once every middle step is broken is also the chain carrying a quarter of the mass. Counted by number, it is a remainder of 1 in 12; weighed by probability, it is the single largest share the defense leaves outside.

Summary

  • Exploit is the step sequence that uses a vulnerability, and payload is the effect written after the exploit completes; five exploits with four payloads produce 12 valid chains, lengths 2 to 7, totaling 53 steps.
  • Breaking a step closes more paths the closer it sits to the start of the chain: 12, 8, 7, 7, 3, 2, 2. Two chains of the same exploit can follow the identical step sequence and differ only in the payload’s name.
  • The same break leaves a different amount of completed work depending on where it sits in the chain: 0 steps at access, 8 at discovery, 18 at execution, 41 at impact.
  • The three levers are not equal: blocking a payload closes at most 5, blocking an exploit at most 4, and breaking a step 8 chains; the payload is the weakest lever because it sits at the end of the chain.
  • When all six middle steps are broken, 1 of 12 chains still stands — the one with no step in its middle, going straight from access to impact.
  • Chain count and probability mass are separate measures: triggering closes 58.3% of the chains but 25.7% of the mass; the one chain still standing carries 25.7% of the mass.

Next Step

Every measurement in this lesson stood on a single assumption: that access is one step. All twelve of the twelve chains started from that step, and that step was never opened up. But reaching an asset is not passing through a single door — there are separate paths starting from a branch endpoint, a field app, a shared interface, or a management endpoint, and each passes through a different number of stops. The topic’s last lesson models these paths on a graph, actually runs the path count, and counts how many paths reducing the attack surface closes and how many legitimate work items it stops.

To keep your progress and take notes, Log in

My notes

Log in to take notes.

Start typing to search.

↑↓ ↵ Esc navigate · open · close