Teaching Script — Module S03: Pentest and Red Team Harnesses

Module: S03 — Pentest and Red Team Harnesses · Duration: ~90 minutes Format: Verbatim transcript. Cues [SLIDE N] map to 03-slide-deck.html.


[SLIDE 1 — Title]

This is Module S Zero Three: Pentest and Red Team Harnesses. Ninety minutes. The third module of Pillar One, and where the bug bounty harness from S Zero Two becomes a full-engagement operational harness. Four sub-sections: kill chain state management, plan correction under adversarial conditions, the sandbox inversion problem, and report generation as a harness output. By the end you can build a harness that conducts a multi-stage red team engagement — initial access through exfiltration — with persistent kill chain state, automatic re-planning when exploits fail, containment that protects the host even when the agent is compromised, and a client-ready report at the end.

This module assumes S Zero Two. The engagement memory, the wrapped tool suite, the evidence chain, the triage pipeline — all of that is the foundation we extend. If any of those terms are unfamiliar, go back to S Zero Two first.

[SLIDE 2 — S03.1: Kill Chain State Management]

Sub-section one. Kill chain state management. The S Zero Two engagement memory was a flat surface — domains, ports, services, findings. That representation works when each finding is independent. An XSS on slash-search has no structural dependency on an open port finding.

A red team engagement is different. A red team kill chain is a sequence with dependencies. Foothold requires initial access. Lateral movement requires foothold. Privilege escalation requires a session on the target. Exfiltration requires privilege. The state is not a set of independent findings. It is a graph of dependent objectives. That is the core shift from S Zero Two to S Zero Three.

[SLIDE 3 — MITRE ATT&CK as the state machine]

MITRE ATT and CK is the canonical taxonomy of adversary tactics and techniques. When used correctly, it is also a state machine for the harness loop. Each ATT and CK technique is a node. The kill chain is a path through nodes. The engagement state is the set of nodes reached so far.

Each node has a tactic and a technique — for example, T1190, Exploit Public-Facing Application, under the Initial Access tactic. Each node has a state: unexplored, attempted, succeeded, failed, or out of scope. Critically, each node has explicit prerequisites — the node IDs that must be in succeeded state before this node can be attempted — and evidence references linking back to the evidence chain from S Zero Two point three.

The prerequisites are load-bearing. A harness that cannot answer "why am I allowed to attempt lateral movement now" will attempt it too early — before foothold — and waste cycles, or too late — after detection — and get caught. Explicit prerequisites make the dependency structure machine-checkable.

The node states are not arbitrary labels. Each represents a distinct operational condition, and the transitions are the harness's control flow. A node moves from unexplored to attempted only when the harness has verified prerequisites are met and the agent has selected the technique. It moves from attempted to succeeded only when the objective is confirmed — not when the exploit returns output, but when the output is verified to have achieved the objective. A shell that returns a prompt is a succeeded shell; a shell that returns an error is not. It moves from attempted to failed on a hard failure, which triggers plan correction. It moves to out of scope when the scope check rejects the target or action, and that transition is terminal — re-checking an out-of-scope node every cycle wastes computation.

The transition that teams get wrong is attempted to attempted — the soft-failure retry. A soft failure, a timeout or rate limit, should retry the same node, but only with backoff and only up to a configurable limit. Without the limit, a flapping target can loop the harness indefinitely. Without distinguishing soft from hard failure, a patched exploit loops just the same.

[SLIDE 4 — Attack graph vs. linear plan]

A linear plan is a checklist. Step one, step two, step N. It works when every step succeeds. In an adversarial environment, steps fail, and a linear plan has no native notion of "what else could I try." The S Zero Two triage pipeline handles independent findings. It cannot represent "I tried T1190, it failed, so now I want to try T1078 Valid Accounts via credential reuse instead, because both satisfy the Initial Access prerequisite."

The rule: linear plan when you have a single objective, a single technique, and high confidence in success — a one-shot CVE validation. Attack graph when you have multi-objective, multiple techniques per objective, and dependencies — anything the client is paying more than a day for.

You can switch mid-engagement. Start linear, promote to a graph the moment a step fails or a second objective appears. The promotion is cheap — a linear plan is a degenerate graph, a single chain.

The anti-pattern is the reverse: starting with a graph, then collapsing it back into a linear plan "for simplicity" when the graph gets dense. That collapse throws away the alternative paths the agent will need when its primary technique fails. Don't do it.

[SLIDE 5 — Why general harnesses lose the chain]

A general agent harness from Course One calls a tool, gets a result, reasons about the next step. Between tool calls, the only state is the context window. Across sessions, there is no state. For a kill chain requiring ten sequential objectives, this fails in two specific ways.

First, intermediate state loss between tool calls. The model attempts initial access, succeeds, the result goes into the context window as a tool result. Three tool calls later, the context compacts, and the fact that initial access succeeded is gone. The agent attempts lateral movement, which requires a session from initial access, and the prerequisite check fails — not because the prerequisite wasn't met, but because the harness forgot it was met.

Second, cross-session state loss. The engagement pauses on day one with foothold achieved. On day two, a fresh session has no memory of the foothold. The agent either re-attempts initial access — wasting time, generating noise, risking detection — or proceeds as if no foothold exists and misses the dependency.

The cure is the same for both: the attack graph is persisted outside the context window and queried before every step. The context window carries reasoning for the current step. The graph carries structural truth across the whole engagement. Pause and resume is clean because the graph is serialized to disk at every state transition, and on resume the harness rebuilds reasoning from the graph via an orientation prompt — it does not trust yesterday's reasoning, which may be based on stale target state.

[SLIDE 6 — S03.2: Plan Correction Under Adversarial Conditions]

Sub-section two. Plan correction under adversarial conditions. In Course One, an error is a tool that returned a traceback. The fix is retry, or report the error. In an offensive engagement, an error is an exploit that didn't land, a credential that didn't work, a path that turned out to be patched.

The correct response is not retry-the-same-thing. It is re-plan. This is the attacker's equivalent of error handling, and it is the single biggest differentiator between a script that runs exploits and a harness that conducts an engagement.

The formalization comes from the RedTeamLLM paper, Brown et al, twenty twenty-four. The four-step plan correction loop.

[SLIDE 7 — The four-step loop]

Step one, detect. Distinguish a hard failure from a soft failure. Hard failure: the exploit returned no result, the target is patched, authentication was rejected. Soft failure: timeout, rate limit, transient network error. Hard failures trigger plan correction. Soft failures trigger retry-with-backoff. Conflating the two is the most common harness bug in this category — retrying a patched exploit three times before realizing it's a hard failure wastes engagement time and generates detectable noise.

The reliable signal for the distinction is whether the failure is reproducible. A single timeout is soft. Three consecutive timeouts against a target that responds to other requests is hard — the service is down or blocking you. A single authentication rejection is hard — credentials are wrong, and retrying does not make them right. The harness implements a small classifier, a handful of rules mapping response patterns to hard or soft, and logs the classification with the attempt so the operator can audit the decisions later.

Step two, re-hypothesize. The original hypothesis was "technique T1190 will give me initial access via this CVE." The failure invalidates that hypothesis. The re-hypothesis step asks: what else could satisfy the Initial Access tactic? The harness consults its knowledge base for alternative techniques that satisfy the same tactic and whose prerequisites are met.

Step three, re-plan. Select the next-best alternative and update the attack graph. Mark the failed node as failed. Add the new candidate node as unexplored. Update current position if the failure means the agent is no longer positioned where it thought it was.

Step four, retry. Execute the new technique. This is a new attempt on a new node — not a retry of the old one.

The key invariant: failed techniques are removed from the candidate set. The knowledge base query uses exclude-failed equals true. This forces genuine substitution, not variation on a failed technique. This is the cure for exploit lock-in — the harness that has a favorite exploit, it fails, and the harness retries with minor variations instead of trying something genuinely different.

[SLIDE 8 — Generalize vs. specialize]

When selecting an alternative, the harness faces a choice. Generalize: use a broad attack pattern that works across many targets. Higher reliability, lower stealth, often noisier. Specialize: use a target-specific payload, a CVE for the exact software version identified during recon. Higher impact if it works, but fails immediately if the version is wrong or patched.

The heuristic: specialize first when you have high-confidence target intelligence — exact version, confirmed configuration. Generalize when intelligence is low, or when the specialized technique has already failed and you need a fallback.

The RedTeamLLM paper's ablation is worth citing here: harnesses with a generalize-on-failure fallback complete forty percent more objectives than harnesses that only specialize. The reason is that in an adversarial environment, the specialized intelligence is frequently wrong. The target version differs from what recon reported. The patch was applied. The config was changed. A generalized fallback gives you a second path when specialization fails.

[SLIDE 9 — S03.3: The Sandbox Inversion Problem]

Sub-section three. The sandbox inversion problem. This is the load-bearing sub-section of this module. Pay attention here.

In Course One, you learned that the sandbox contains the agent to protect the host. The agent runs inside a container, its filesystem access is limited, its network is restricted. That model is correct for a coding agent. It is inverted for an offensive agent.

An offensive agent must reach out to attack the target. If you contain it the way Course One contains a coding agent, it cannot do its job. But if you remove containment entirely, a compromised agent — compromised via prompt injection from target output, the S Zero One point three threat model — can attack you. Lateral movement into your host. Exfiltration of your engagement credentials. Pivot into your internal network.

This is the sandbox inversion. The offensive sandbox must let the agent reach out to declared targets while preventing the agent, if compromised, from reaching anywhere else, and preventing any inbound foothold from propagating back to the host.

[SLIDE 10 — Dual containment]

The resolution is dual containment — two independent containment boundaries, each enforcing a different property.

Boundary one, outbound scope enforcement. The agent may initiate connections only to declared in-scope targets. This is S Zero One point two's scope enforcement, but applied at the network layer — firewall rules, an egress proxy — not just the middleware. The middleware checks intent: the model wants to call nmap on X. The network layer enforces outcome: even if the middleware is bypassed, the packet cannot leave for X. Both are required.

Boundary two, inbound isolation. Nothing the agent does on the target can establish a foothold back into the host. The agent's container has no inbound routes from the target network. Reverse shells, callbacks, command-and-control channels that the agent sets up as part of the engagement must terminate inside the container's isolated segment, not on the host.

The two boundaries are independent by design. If the agent is compromised via prompt injection and attempts to scan the developer's internal network — one ninety two dot one sixty-eight dot x dot x — the outbound boundary blocks it. The internal network is not in scope. If the agent sets up a reverse shell as part of a legitimate engagement technique, the inbound boundary ensures that shell terminates in the container, not on the host.

And to be concrete about what "compromised agent" means: the agent's behavior has been altered by content it ingested from the target. A target web application serves a page containing instructions that cause the agent to write a backdoor to the host filesystem. A database record contains text that causes the agent to exfiltrate the host's SSH keys. A response header that causes the agent to scan the host's internal network. None of these require the model to be malicious. They require only that the model follows instructions, and the instructions came from the target rather than the operator. Dual containment assumes this will happen and bounds the blast radius structurally, not behaviorally.

[SLIDE 11 — Credential quarantine and the metadata trap]

A specific sub-problem. During an engagement, the agent discovers credentials. Target database passwords, API keys, harvested hashes. These are engagement artifacts. They must not touch the host's credential stores — the browser password manager, the SSH agent, the keychain, the dot-AWS-credentials file. If they do, a compromised agent can use them to escalate beyond the engagement, or they leak into the host environment and violate the data isolation the client expects.

The rule: all engagement credentials live in a quarantine store inside the container — a separate encrypted vault with its own key, accessible only to the agent process, destroyed when the container is destroyed. The host's credential stores are not mounted into the container at all. This is enforced by container configuration, not by agent cooperation.

And the metadata trap. Cloud instance metadata endpoints are a common SSRF target and a common accidental-exfiltration path. If the host is a cloud instance and the agent can reach one six nine dot two five four dot one six nine dot two five four, a compromised agent can steal the host's cloud credentials. Deny it at the proxy, always, every engagement, no exceptions.

[SLIDE 12 — Verify both directions independently]

The dual containment model is only trustworthy if you can verify each direction independently. Verification is not "we configured it correctly." Verification is "we attempted the forbidden thing and observed the block."

Outbound verification: from inside the container, attempt a connection to an out-of-scope target — a canary host you control. Confirm the connection is refused. Attempt an in-scope target. Confirm it succeeds.

Inbound verification: from the target network segment, attempt to establish a connection back to the host, or to the agent container's management interface. Confirm it is refused. The only thing that should traverse the host-container boundary is the control plane — the harness's own instructions to the agent — over a separate channel.

A harness that has not verified both directions is making an untested safety claim. Lab three makes this concrete — you will configure dual containment in Docker and then actively attempt to break out of it both ways.

[SLIDE 13 — S03.4: Report Generation as a Harness Output]

Sub-section four. Report generation as a harness output. The deliverable is not the attack. The client cannot use a foothold. They cannot invoice a reverse shell. The deliverable is the report.

A red team engagement that ends with "we got Domain Admin, here are the screenshots" is an incomplete engagement. The same engagement that ends with a structured report — findings, evidence, CVSS scores, remediation mapped to controls — is complete. Report generation is therefore a first-class harness output, designed from the start, not an afterthought. The report is generated from structured data accumulated through the engagement.

[SLIDE 14 — CVSS is always a draft]

This is the most important caveat in this sub-section. CVSS scoring is a known weakness of large language models. The model will produce a vector string that looks plausible — attack vector, complexity, privileges required, user interaction, all filled in. The problem is that the model frequently gets these wrong in ways that matter. It overstates exploitability when the description contains scary words. It understates when the exploit path is subtle. It produces scores that disagree with human analysts by two or more points on the ten-point scale with regularity.

The harness policy: CVSS scores are always generated as drafts, clearly labeled as auto-scored, and routed to human review before they reach the client. The report renders them with a visible "draft — pending analyst review" marker. The model is not the final authority on severity. The human analyst is.

And the corollary: do not train the model's confidence on its own CVSS output. If the harness lets the model see its previous CVSS scores as ground truth, the errors compound. The CVSS draft is a single-shot suggestion from structured data, reviewed by a human, and the human's adjusted score is what goes in the final report.

[SLIDE 15 — Report pipeline]

The report pipeline. Inputs are the three structured stores — the attack graph, which tells you which objectives succeeded; the evidence chain, which provides the proof for each; and the engagement memory from S Zero Two point one, which provides target context.

Each succeeded node becomes a finding. CVSS is drafted automatically but always flagged as pending human review — it is the known-weak output. CWE mapping is a deterministic lookup — it cannot hallucinate. Remediation splits: the OWASP control mapping is a lookup; the target-specific detail, like "patch nginx to version X dot Y," is model-generated. The executive summary is written last, after all findings are triaged and scored, because it summarizes the finding set as a whole — overall posture, top three findings in business language, aggregate metrics, strategic priorities.

The anti-pattern is the generic executive summary — a paragraph of security boilerplate that could describe any engagement. The cure is to ground the summary in the specific finding set: name the actual top finding, cite the actual attack path, quote the actual metric. If the summary could be swapped with another engagement's summary without detection, it failed.

One source of truth, three renderings: HTML for the interactive primary deliverable with clickable evidence references; PDF for clients who need a static, signable artifact; JSON as the machine-readable export for ticketing systems. All three are generated from the same finding records. A harness that maintains separate report data from engagement data has two sources of truth, and they will drift.

One more point on what gets reported. Not every succeeded node becomes a finding. A discovery technique that succeeds is operational progress, not a client-facing vulnerability. The report distinguishes vulnerability findings — nodes where the technique exploited a remediable weakness, which get CWE mappings and remediation — from operational achievements — successful recon, successful lateral movement using valid credentials the client issued — which appear in the narrative as attack-path demonstration but do not get individual remediation entries. And failed attempts stay in the evidence chain and internal record; a failed attempt that triggered detection may appear as an operational note confirming the client's detection coverage. The harness tags each succeeded node during the pipeline.

And the evidence linkage is not decorative. A finding without evidence is an assertion. A finding that links to evidence record ev-zero-four-seven — the exact request, the exact response, the timestamp, the scope authorization — is a demonstrated fact the client cannot dispute. The report's credibility is a function of its evidence density, and the harness accumulates that density automatically through the S Zero Two point three evidence chain.

[SLIDE 16 — What you take into S04]

S Zero Four takes this foundation and applies it to CTF harness engineering. Shorter engagements, known-flag objectives, the specific harness tweaks that win competitions. The red team harness becomes a CTF harness.

The four pillars from this module — attack graph state, plan correction, dual containment, client-ready reporting — are the load-bearing structures. Everything in S Zero Four is a specialization of these for the CTF context.

[End of script]

# Teaching Script — Module S03: Pentest and Red Team Harnesses

**Module**: S03 — Pentest and Red Team Harnesses · **Duration**: ~90 minutes
**Format**: Verbatim transcript. Cues `[SLIDE N]` map to `03-slide-deck.html`.

---

[SLIDE 1 — Title]

This is Module S Zero Three: Pentest and Red Team Harnesses. Ninety minutes. The third module of Pillar One, and where the bug bounty harness from S Zero Two becomes a full-engagement operational harness. Four sub-sections: kill chain state management, plan correction under adversarial conditions, the sandbox inversion problem, and report generation as a harness output. By the end you can build a harness that conducts a multi-stage red team engagement — initial access through exfiltration — with persistent kill chain state, automatic re-planning when exploits fail, containment that protects the host even when the agent is compromised, and a client-ready report at the end.

This module assumes S Zero Two. The engagement memory, the wrapped tool suite, the evidence chain, the triage pipeline — all of that is the foundation we extend. If any of those terms are unfamiliar, go back to S Zero Two first.

[SLIDE 2 — S03.1: Kill Chain State Management]

Sub-section one. Kill chain state management. The S Zero Two engagement memory was a flat surface — domains, ports, services, findings. That representation works when each finding is independent. An XSS on slash-search has no structural dependency on an open port finding.

A red team engagement is different. A red team kill chain is a sequence with dependencies. Foothold requires initial access. Lateral movement requires foothold. Privilege escalation requires a session on the target. Exfiltration requires privilege. The state is not a set of independent findings. It is a graph of dependent objectives. That is the core shift from S Zero Two to S Zero Three.

[SLIDE 3 — MITRE ATT&CK as the state machine]

MITRE ATT and CK is the canonical taxonomy of adversary tactics and techniques. When used correctly, it is also a state machine for the harness loop. Each ATT and CK technique is a node. The kill chain is a path through nodes. The engagement state is the set of nodes reached so far.

Each node has a tactic and a technique — for example, T1190, Exploit Public-Facing Application, under the Initial Access tactic. Each node has a state: unexplored, attempted, succeeded, failed, or out of scope. Critically, each node has explicit prerequisites — the node IDs that must be in succeeded state before this node can be attempted — and evidence references linking back to the evidence chain from S Zero Two point three.

The prerequisites are load-bearing. A harness that cannot answer "why am I allowed to attempt lateral movement now" will attempt it too early — before foothold — and waste cycles, or too late — after detection — and get caught. Explicit prerequisites make the dependency structure machine-checkable.

The node states are not arbitrary labels. Each represents a distinct operational condition, and the transitions are the harness's control flow. A node moves from unexplored to attempted only when the harness has verified prerequisites are met and the agent has selected the technique. It moves from attempted to succeeded only when the objective is confirmed — not when the exploit returns output, but when the output is verified to have achieved the objective. A shell that returns a prompt is a succeeded shell; a shell that returns an error is not. It moves from attempted to failed on a hard failure, which triggers plan correction. It moves to out of scope when the scope check rejects the target or action, and that transition is terminal — re-checking an out-of-scope node every cycle wastes computation.

The transition that teams get wrong is attempted to attempted — the soft-failure retry. A soft failure, a timeout or rate limit, should retry the same node, but only with backoff and only up to a configurable limit. Without the limit, a flapping target can loop the harness indefinitely. Without distinguishing soft from hard failure, a patched exploit loops just the same.

[SLIDE 4 — Attack graph vs. linear plan]

A linear plan is a checklist. Step one, step two, step N. It works when every step succeeds. In an adversarial environment, steps fail, and a linear plan has no native notion of "what else could I try." The S Zero Two triage pipeline handles independent findings. It cannot represent "I tried T1190, it failed, so now I want to try T1078 Valid Accounts via credential reuse instead, because both satisfy the Initial Access prerequisite."

The rule: linear plan when you have a single objective, a single technique, and high confidence in success — a one-shot CVE validation. Attack graph when you have multi-objective, multiple techniques per objective, and dependencies — anything the client is paying more than a day for.

You can switch mid-engagement. Start linear, promote to a graph the moment a step fails or a second objective appears. The promotion is cheap — a linear plan is a degenerate graph, a single chain.

The anti-pattern is the reverse: starting with a graph, then collapsing it back into a linear plan "for simplicity" when the graph gets dense. That collapse throws away the alternative paths the agent will need when its primary technique fails. Don't do it.

[SLIDE 5 — Why general harnesses lose the chain]

A general agent harness from Course One calls a tool, gets a result, reasons about the next step. Between tool calls, the only state is the context window. Across sessions, there is no state. For a kill chain requiring ten sequential objectives, this fails in two specific ways.

First, intermediate state loss between tool calls. The model attempts initial access, succeeds, the result goes into the context window as a tool result. Three tool calls later, the context compacts, and the fact that initial access succeeded is gone. The agent attempts lateral movement, which requires a session from initial access, and the prerequisite check fails — not because the prerequisite wasn't met, but because the harness forgot it was met.

Second, cross-session state loss. The engagement pauses on day one with foothold achieved. On day two, a fresh session has no memory of the foothold. The agent either re-attempts initial access — wasting time, generating noise, risking detection — or proceeds as if no foothold exists and misses the dependency.

The cure is the same for both: the attack graph is persisted outside the context window and queried before every step. The context window carries reasoning for the current step. The graph carries structural truth across the whole engagement. Pause and resume is clean because the graph is serialized to disk at every state transition, and on resume the harness rebuilds reasoning from the graph via an orientation prompt — it does not trust yesterday's reasoning, which may be based on stale target state.

[SLIDE 6 — S03.2: Plan Correction Under Adversarial Conditions]

Sub-section two. Plan correction under adversarial conditions. In Course One, an error is a tool that returned a traceback. The fix is retry, or report the error. In an offensive engagement, an error is an exploit that didn't land, a credential that didn't work, a path that turned out to be patched.

The correct response is not retry-the-same-thing. It is re-plan. This is the attacker's equivalent of error handling, and it is the single biggest differentiator between a script that runs exploits and a harness that conducts an engagement.

The formalization comes from the RedTeamLLM paper, Brown et al, twenty twenty-four. The four-step plan correction loop.

[SLIDE 7 — The four-step loop]

Step one, detect. Distinguish a hard failure from a soft failure. Hard failure: the exploit returned no result, the target is patched, authentication was rejected. Soft failure: timeout, rate limit, transient network error. Hard failures trigger plan correction. Soft failures trigger retry-with-backoff. Conflating the two is the most common harness bug in this category — retrying a patched exploit three times before realizing it's a hard failure wastes engagement time and generates detectable noise.

The reliable signal for the distinction is whether the failure is reproducible. A single timeout is soft. Three consecutive timeouts against a target that responds to other requests is hard — the service is down or blocking you. A single authentication rejection is hard — credentials are wrong, and retrying does not make them right. The harness implements a small classifier, a handful of rules mapping response patterns to hard or soft, and logs the classification with the attempt so the operator can audit the decisions later.

Step two, re-hypothesize. The original hypothesis was "technique T1190 will give me initial access via this CVE." The failure invalidates that hypothesis. The re-hypothesis step asks: what else could satisfy the Initial Access tactic? The harness consults its knowledge base for alternative techniques that satisfy the same tactic and whose prerequisites are met.

Step three, re-plan. Select the next-best alternative and update the attack graph. Mark the failed node as failed. Add the new candidate node as unexplored. Update current position if the failure means the agent is no longer positioned where it thought it was.

Step four, retry. Execute the new technique. This is a new attempt on a new node — not a retry of the old one.

The key invariant: failed techniques are removed from the candidate set. The knowledge base query uses exclude-failed equals true. This forces genuine substitution, not variation on a failed technique. This is the cure for exploit lock-in — the harness that has a favorite exploit, it fails, and the harness retries with minor variations instead of trying something genuinely different.

[SLIDE 8 — Generalize vs. specialize]

When selecting an alternative, the harness faces a choice. Generalize: use a broad attack pattern that works across many targets. Higher reliability, lower stealth, often noisier. Specialize: use a target-specific payload, a CVE for the exact software version identified during recon. Higher impact if it works, but fails immediately if the version is wrong or patched.

The heuristic: specialize first when you have high-confidence target intelligence — exact version, confirmed configuration. Generalize when intelligence is low, or when the specialized technique has already failed and you need a fallback.

The RedTeamLLM paper's ablation is worth citing here: harnesses with a generalize-on-failure fallback complete forty percent more objectives than harnesses that only specialize. The reason is that in an adversarial environment, the specialized intelligence is frequently wrong. The target version differs from what recon reported. The patch was applied. The config was changed. A generalized fallback gives you a second path when specialization fails.

[SLIDE 9 — S03.3: The Sandbox Inversion Problem]

Sub-section three. The sandbox inversion problem. This is the load-bearing sub-section of this module. Pay attention here.

In Course One, you learned that the sandbox contains the agent to protect the host. The agent runs inside a container, its filesystem access is limited, its network is restricted. That model is correct for a coding agent. It is inverted for an offensive agent.

An offensive agent must reach out to attack the target. If you contain it the way Course One contains a coding agent, it cannot do its job. But if you remove containment entirely, a compromised agent — compromised via prompt injection from target output, the S Zero One point three threat model — can attack you. Lateral movement into your host. Exfiltration of your engagement credentials. Pivot into your internal network.

This is the sandbox inversion. The offensive sandbox must let the agent reach out to declared targets while preventing the agent, if compromised, from reaching anywhere else, and preventing any inbound foothold from propagating back to the host.

[SLIDE 10 — Dual containment]

The resolution is dual containment — two independent containment boundaries, each enforcing a different property.

Boundary one, outbound scope enforcement. The agent may initiate connections only to declared in-scope targets. This is S Zero One point two's scope enforcement, but applied at the network layer — firewall rules, an egress proxy — not just the middleware. The middleware checks intent: the model wants to call nmap on X. The network layer enforces outcome: even if the middleware is bypassed, the packet cannot leave for X. Both are required.

Boundary two, inbound isolation. Nothing the agent does on the target can establish a foothold back into the host. The agent's container has no inbound routes from the target network. Reverse shells, callbacks, command-and-control channels that the agent sets up as part of the engagement must terminate inside the container's isolated segment, not on the host.

The two boundaries are independent by design. If the agent is compromised via prompt injection and attempts to scan the developer's internal network — one ninety two dot one sixty-eight dot x dot x — the outbound boundary blocks it. The internal network is not in scope. If the agent sets up a reverse shell as part of a legitimate engagement technique, the inbound boundary ensures that shell terminates in the container, not on the host.

And to be concrete about what "compromised agent" means: the agent's behavior has been altered by content it ingested from the target. A target web application serves a page containing instructions that cause the agent to write a backdoor to the host filesystem. A database record contains text that causes the agent to exfiltrate the host's SSH keys. A response header that causes the agent to scan the host's internal network. None of these require the model to be malicious. They require only that the model follows instructions, and the instructions came from the target rather than the operator. Dual containment assumes this will happen and bounds the blast radius structurally, not behaviorally.

[SLIDE 11 — Credential quarantine and the metadata trap]

A specific sub-problem. During an engagement, the agent discovers credentials. Target database passwords, API keys, harvested hashes. These are engagement artifacts. They must not touch the host's credential stores — the browser password manager, the SSH agent, the keychain, the dot-AWS-credentials file. If they do, a compromised agent can use them to escalate beyond the engagement, or they leak into the host environment and violate the data isolation the client expects.

The rule: all engagement credentials live in a quarantine store inside the container — a separate encrypted vault with its own key, accessible only to the agent process, destroyed when the container is destroyed. The host's credential stores are not mounted into the container at all. This is enforced by container configuration, not by agent cooperation.

And the metadata trap. Cloud instance metadata endpoints are a common SSRF target and a common accidental-exfiltration path. If the host is a cloud instance and the agent can reach one six nine dot two five four dot one six nine dot two five four, a compromised agent can steal the host's cloud credentials. Deny it at the proxy, always, every engagement, no exceptions.

[SLIDE 12 — Verify both directions independently]

The dual containment model is only trustworthy if you can verify each direction independently. Verification is not "we configured it correctly." Verification is "we attempted the forbidden thing and observed the block."

Outbound verification: from inside the container, attempt a connection to an out-of-scope target — a canary host you control. Confirm the connection is refused. Attempt an in-scope target. Confirm it succeeds.

Inbound verification: from the target network segment, attempt to establish a connection back to the host, or to the agent container's management interface. Confirm it is refused. The only thing that should traverse the host-container boundary is the control plane — the harness's own instructions to the agent — over a separate channel.

A harness that has not verified both directions is making an untested safety claim. Lab three makes this concrete — you will configure dual containment in Docker and then actively attempt to break out of it both ways.

[SLIDE 13 — S03.4: Report Generation as a Harness Output]

Sub-section four. Report generation as a harness output. The deliverable is not the attack. The client cannot use a foothold. They cannot invoice a reverse shell. The deliverable is the report.

A red team engagement that ends with "we got Domain Admin, here are the screenshots" is an incomplete engagement. The same engagement that ends with a structured report — findings, evidence, CVSS scores, remediation mapped to controls — is complete. Report generation is therefore a first-class harness output, designed from the start, not an afterthought. The report is generated from structured data accumulated through the engagement.

[SLIDE 14 — CVSS is always a draft]

This is the most important caveat in this sub-section. CVSS scoring is a known weakness of large language models. The model will produce a vector string that looks plausible — attack vector, complexity, privileges required, user interaction, all filled in. The problem is that the model frequently gets these wrong in ways that matter. It overstates exploitability when the description contains scary words. It understates when the exploit path is subtle. It produces scores that disagree with human analysts by two or more points on the ten-point scale with regularity.

The harness policy: CVSS scores are always generated as drafts, clearly labeled as auto-scored, and routed to human review before they reach the client. The report renders them with a visible "draft — pending analyst review" marker. The model is not the final authority on severity. The human analyst is.

And the corollary: do not train the model's confidence on its own CVSS output. If the harness lets the model see its previous CVSS scores as ground truth, the errors compound. The CVSS draft is a single-shot suggestion from structured data, reviewed by a human, and the human's adjusted score is what goes in the final report.

[SLIDE 15 — Report pipeline]

The report pipeline. Inputs are the three structured stores — the attack graph, which tells you which objectives succeeded; the evidence chain, which provides the proof for each; and the engagement memory from S Zero Two point one, which provides target context.

Each succeeded node becomes a finding. CVSS is drafted automatically but always flagged as pending human review — it is the known-weak output. CWE mapping is a deterministic lookup — it cannot hallucinate. Remediation splits: the OWASP control mapping is a lookup; the target-specific detail, like "patch nginx to version X dot Y," is model-generated. The executive summary is written last, after all findings are triaged and scored, because it summarizes the finding set as a whole — overall posture, top three findings in business language, aggregate metrics, strategic priorities.

The anti-pattern is the generic executive summary — a paragraph of security boilerplate that could describe any engagement. The cure is to ground the summary in the specific finding set: name the actual top finding, cite the actual attack path, quote the actual metric. If the summary could be swapped with another engagement's summary without detection, it failed.

One source of truth, three renderings: HTML for the interactive primary deliverable with clickable evidence references; PDF for clients who need a static, signable artifact; JSON as the machine-readable export for ticketing systems. All three are generated from the same finding records. A harness that maintains separate report data from engagement data has two sources of truth, and they will drift.

One more point on what gets reported. Not every succeeded node becomes a finding. A discovery technique that succeeds is operational progress, not a client-facing vulnerability. The report distinguishes vulnerability findings — nodes where the technique exploited a remediable weakness, which get CWE mappings and remediation — from operational achievements — successful recon, successful lateral movement using valid credentials the client issued — which appear in the narrative as attack-path demonstration but do not get individual remediation entries. And failed attempts stay in the evidence chain and internal record; a failed attempt that triggered detection may appear as an operational note confirming the client's detection coverage. The harness tags each succeeded node during the pipeline.

And the evidence linkage is not decorative. A finding without evidence is an assertion. A finding that links to evidence record ev-zero-four-seven — the exact request, the exact response, the timestamp, the scope authorization — is a demonstrated fact the client cannot dispute. The report's credibility is a function of its evidence density, and the harness accumulates that density automatically through the S Zero Two point three evidence chain.

[SLIDE 16 — What you take into S04]

S Zero Four takes this foundation and applies it to CTF harness engineering. Shorter engagements, known-flag objectives, the specific harness tweaks that win competitions. The red team harness becomes a CTF harness.

The four pillars from this module — attack graph state, plan correction, dual containment, client-ready reporting — are the load-bearing structures. Everything in S Zero Four is a specialization of these for the CTF context.

[End of script]