From 90e696a465dc845b3e2c4893b6161329b1749d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Ruiz=20Garc=C3=ADa?= Date: Wed, 10 Jun 2026 18:54:33 +0200 Subject: [PATCH] feat: wire threat-model.md into Phase 5 exploitation planning Closes #36. - prompts/phase-5-exploit.md: add threat-model.md to required reading (conditional), expand threat-model selection section with project threat model consumption instructions, add threat-model sub-bullet to workflow step 3, add 2 self-validation checklist items (both with conditional qualifiers), add final-response summary bullet. - .opencode/agents/exploiter.md: add conditional threat-model.md to required reading. - .opencode/skills/exploit-development/SKILL.md: add conditional threat-model.md to inputs, add step 0 to exploit design methodology for consulting threat-model capabilities and non-capabilities. - templates/exploit-readme.md: add Threat Model Assumptions section documenting attacker capabilities assumed, non-capabilities respected, trust boundaries crossed, existing controls navigated, and open assumptions. - tests/test_prompts_threat_model.py: add 15 tests covering Phase 5 prompt, exploiter agent, exploit-development skill, and exploit README template integration. All references are conditional (if present / when present) so projects without threat-model.md continue to work unchanged. --- .opencode/agents/exploiter.md | 1 + .opencode/skills/exploit-development/SKILL.md | 5 + prompts/phase-5-exploit.md | 33 ++++++ templates/exploit-readme.md | 19 +++ tests/test_prompts_threat_model.py | 108 ++++++++++++++++++ 5 files changed, 166 insertions(+) diff --git a/.opencode/agents/exploiter.md b/.opencode/agents/exploiter.md index bfb242a8..74e38d3e 100644 --- a/.opencode/agents/exploiter.md +++ b/.opencode/agents/exploiter.md @@ -29,6 +29,7 @@ Before developing an exploit, read: - existing validation evidence under `itemdb/evidence//` - relevant source files under `src/` - sandbox documentation under `sandbox/` +- If present, `itemdb/notes/threat-model.md` — use to scope attacker capabilities, respect documented non-capabilities, identify trust boundaries crossed, and note existing controls and open assumptions that affect exploit feasibility. Use target-specific skills when they apply, for example: diff --git a/.opencode/skills/exploit-development/SKILL.md b/.opencode/skills/exploit-development/SKILL.md index 58db4623..4aa811ee 100644 --- a/.opencode/skills/exploit-development/SKILL.md +++ b/.opencode/skills/exploit-development/SKILL.md @@ -19,6 +19,7 @@ Before developing an exploit, read: - the assigned CONFIRMED finding - existing validation evidence under `itemdb/evidence//` - relevant source files under `src/` +- If present, `itemdb/notes/threat-model.md` — operational threat model with attacker capabilities, non-capabilities, trust boundaries, existing controls, and open assumptions that scope exploitation realistically. ## Outputs @@ -72,6 +73,10 @@ Given the vulnerability type and sandbox environment, what is the maximum achiev Build the minimum viable exploit that reaches the escalation ceiling: +0. When `itemdb/notes/threat-model.md` is available, review how the finding's + attacker profile, trust boundary, and impact align with the documented + capabilities, non-capabilities, and existing controls. Do not design an + exploit that assumes capabilities explicitly excluded as non-capabilities. 1. Identify the exact entry point (URL, function, command, input). 2. Craft the payload that triggers the vulnerability. 3. Add the escalation payload (shellcode, exfiltration query, traversal path). diff --git a/prompts/phase-5-exploit.md b/prompts/phase-5-exploit.md index fddf0b03..276102d3 100644 --- a/prompts/phase-5-exploit.md +++ b/prompts/phase-5-exploit.md @@ -36,6 +36,7 @@ Read the following files (all paths are relative to the project/workspace root): - existing validation evidence under `itemdb/evidence//` - relevant source files under `src/` - sandbox documentation under `sandbox/` +- If present, `itemdb/notes/threat-model.md` — operational threat model from Phase 1b: assets, attacker capabilities and non-capabilities, trust-boundary summary, existing controls, abuse-path themes, risk calibration, and open assumptions. Use it to scope exploitation realistically. Use additional target-specific skills when they apply: @@ -74,6 +75,27 @@ Before building the PoC, explicitly state the threat model and write it into or message consumed by the target. - **Physical / peripheral** — attacker controls USB, Bluetooth, NFC, etc. +When `itemdb/notes/threat-model.md` is present, consult it before selecting the +attacker posture above. The project threat model provides: + +- **Attacker capabilities** that scope what the PoC may assume (network + position, credentials, local access, prior knowledge). +- **Explicit non-capabilities** that the PoC must not assume. If the threat + model states the attacker does not hold admin credentials, the PoC must not + rely on admin access. +- **Trust boundaries** that identify the correct interaction surface for the + chosen posture. +- **Existing controls** (WAF, rate limiting, sandboxing, ASLR, etc.) that the + PoC must defeat or work around — do not silently bypass controls the threat + model documents as present. +- **Open assumptions** that may change exploit feasibility — record any + assumption you rely on in `exploits/README.md`. + +If the threat model contradicts a chosen posture (e.g., the finding crosses a +boundary not reachable by the documented attacker), document the discrepancy +and either adjust the posture or explain why the finding remains exploitable +under a realistic attacker profile. + The PoC must operate at the boundary defined by the chosen threat model and not cross it inward. @@ -150,6 +172,11 @@ realistic surface would be and why it is not reachable. 2. Review relevant source code **only to understand the bug and locate sinks/sources**, not to call the vulnerable code directly from the PoC. 3. Pick the threat model and map the attack surface: + - When `itemdb/notes/threat-model.md` is available, use it to identify + the correct attacker posture, validate that chosen capabilities are + not contradicted by documented non-capabilities, identify trust + boundaries the finding crosses, and note existing controls and open + assumptions that affect feasibility. - For network bugs: which endpoint/port/protocol reaches the sink? What auth, CSRF, rate limiting, or WAF sits in front? - For memory-corruption bugs: which binary/service/driver, invoked how, @@ -420,6 +447,11 @@ Before declaring exploitation successful, confirm every item: `Not applicable.`), `# Inputs and preconditions`, `# Recording`, and `# Remediation idea` (with corrected-code excerpt or unified diff) are filled. +- [ ] The PoC does not assume attacker capabilities explicitly listed as + non-capabilities in `itemdb/notes/threat-model.md` (when present). +- [ ] Material threat-model assumptions affecting exploit feasibility are + documented in `exploits/README.md` (when `itemdb/notes/threat-model.md` + is present; otherwise note its absence). If any item fails, the exploit is not valid black-box and must be reworked. @@ -430,6 +462,7 @@ At the end, summarize: - finding exploited, - run summary written, - threat model assumed, +- threat-model assumptions from `itemdb/notes/threat-model.md` that materially affected exploitation feasibility or scope (when present), - exploit type developed, - primitives built and mitigations defeated (when applicable), - impact demonstrated, diff --git a/templates/exploit-readme.md b/templates/exploit-readme.md index 977c2d7a..bfefbad3 100644 --- a/templates/exploit-readme.md +++ b/templates/exploit-readme.md @@ -32,6 +32,25 @@ Examples: - XSS to session hijacking, - crypto weakness to key recovery. +# Threat Model Assumptions + +Document material assumptions from the project threat model +(`itemdb/notes/threat-model.md`) that affected exploitation planning. If no +threat model exists, write "No project threat model available" and skip the +sub-items. + +- **Attacker capabilities assumed**: which capabilities from the threat model + the PoC relies on (e.g., network reachability, low-privilege shell, valid + credentials). +- **Non-capabilities respected**: which explicit non-capabilities the PoC does + not assume (e.g., no admin access, no physical access). +- **Trust boundaries crossed**: which documented trust boundary the exploit + traverses. +- **Existing controls navigated**: which controls documented in the threat + model the exploit defeats, bypasses, or works around (and how). +- **Open assumptions**: any threat-model assumptions that, if wrong, would + change exploit feasibility or impact. + # Exploitation Method Describe the exploitation approach step by step. diff --git a/tests/test_prompts_threat_model.py b/tests/test_prompts_threat_model.py index eb341b07..333d7b25 100644 --- a/tests/test_prompts_threat_model.py +++ b/tests/test_prompts_threat_model.py @@ -174,3 +174,111 @@ def test_phase_4_mentions_trust_boundaries_in_validation_context() -> None: def test_phase_4_mentions_existing_controls() -> None: content = _read_prompt("phase-4-validate.md") assert "existing controls" in content.lower() + + +# --------------------------------------------------------------------------- +# Phase 5 exploiter agent — threat-model.md integration +# --------------------------------------------------------------------------- + +def test_exploiter_agent_references_threat_model() -> None: + content = _read_opencode(".opencode/agents/exploiter.md") + assert "itemdb/notes/threat-model.md" in content + + +def test_exploiter_agent_uses_conditional_language() -> None: + content = _read_opencode(".opencode/agents/exploiter.md") + content_lower = content.lower() + assert ( + "when available" in content_lower + or "when present" in content_lower + or "if present" in content_lower + ) + + +def test_exploiter_agent_mentions_non_capabilities() -> None: + content = _read_opencode(".opencode/agents/exploiter.md") + assert "non-capabilities" in content + + +# --------------------------------------------------------------------------- +# Phase 5 exploit-development skill — threat-model.md integration +# --------------------------------------------------------------------------- + +def test_exploit_development_skill_references_threat_model() -> None: + content = _read_opencode(".opencode/skills/exploit-development/SKILL.md") + assert "itemdb/notes/threat-model.md" in content + + +def test_exploit_development_skill_mentions_non_capabilities() -> None: + content = _read_opencode(".opencode/skills/exploit-development/SKILL.md") + assert "non-capabilities" in content + + +# --------------------------------------------------------------------------- +# Phase 5 prompt — threat-model.md integration +# --------------------------------------------------------------------------- + +def test_phase_5_explicitly_references_threat_model_when_present() -> None: + content = _read_prompt("phase-5-exploit.md") + assert "itemdb/notes/threat-model.md" in content + + +def test_phase_5_uses_conditional_when_present_language() -> None: + content = _read_prompt("phase-5-exploit.md") + content_lower = content.lower() + assert ( + "when available" in content_lower + or "when present" in content_lower + or "if present" in content_lower + ) + + +def test_phase_5_mentions_attacker_capabilities_and_non_capabilities() -> None: + content = _read_prompt("phase-5-exploit.md") + assert "attacker capabilit" in content.lower() + assert "non-capabilities" in content + + +def test_phase_5_mentions_trust_boundaries() -> None: + content = _read_prompt("phase-5-exploit.md") + assert "trust boundar" in content.lower() + + +def test_phase_5_mentions_existing_controls() -> None: + content = _read_prompt("phase-5-exploit.md") + assert "existing controls" in content.lower() + + +def test_phase_5_mentions_open_assumptions() -> None: + content = _read_prompt("phase-5-exploit.md") + assert "open assumptions" in content.lower() + + +def test_phase_5_checklist_references_non_capabilities() -> None: + content = _read_prompt("phase-5-exploit.md") + assert "non-capabilities" in content + assert "threat-model.md" in content + + +def test_phase_5_final_response_mentions_threat_model_assumptions() -> None: + content = _read_prompt("phase-5-exploit.md") + assert "threat-model assumptions" in content.lower() + + +# --------------------------------------------------------------------------- +# Exploit README template — threat-model assumptions section +# --------------------------------------------------------------------------- + +def test_exploit_readme_template_has_threat_model_assumptions_section() -> None: + content = _read_opencode("templates/exploit-readme.md") + assert "# Threat Model Assumptions" in content + + +def test_exploit_readme_template_mentions_non_capabilities() -> None: + content = _read_opencode("templates/exploit-readme.md") + assert "non-capabilities" in content.lower() + + +def test_exploit_readme_template_mentions_open_assumptions() -> None: + content = _read_opencode("templates/exploit-readme.md") + assert "open assumptions" in content.lower()