v3.5.0: attack graph + kill chain (OWASP/CWE/MITRE) + GPT 5.5/5.4/5.3-codex/5.2 + report graph

- Finding enriched with owasp / mitre / kill-chain stage / exploitability /
  business_impact / chains_from (attack-path edges).
- attack_graph module: derive OWASP Top 10 + MITRE ATT&CK technique + kill-chain
  stage from CWE (heuristic, no extra model call); render a Mermaid attack-path
  flowchart (findings grouped by stage, explicit + implicit edges) and an ASCII
  kill chain for the REPL.
- enrich() runs in finish() for every engagement.
- HTML report gains an "Attack Path & Kill Chain" section (Mermaid via CDN, dark)
  plus a stage/sev/OWASP/MITRE/exploitability table.
- REPL print_findings shows the ASCII kill-chain + severity summary after a run.
- models: add GPT-5.5, GPT-5.4, GPT-5.4-mini, GPT-5.3-codex, GPT-5.2.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
CyberSecurityUP
2026-06-24 21:14:06 -03:00
parent d864ea8b8a
commit 1be053c4a2
7 changed files with 199 additions and 6 deletions
+10 -2
View File
@@ -345,9 +345,17 @@ async fn run_mode(base: &Path, mut cfg: RunConfig, mcp: bool, mode: Mode) -> any
pub(crate) fn print_findings(out: &RunOutput) {
println!("\n=== {} validated finding(s) ===", out.findings.len());
println!("{}", serde_json::to_string_pretty(&out.findings).unwrap_or_default());
if !out.findings.is_empty() {
let mut by = std::collections::BTreeMap::new();
for f in &out.findings { *by.entry(f.severity.as_str()).or_insert(0) += 1; }
let chips: Vec<String> = by.iter().map(|(k, v)| format!("{k}:{v}")).collect();
println!(" severity: {}", chips.join(" "));
println!("\n \x1b[1mAttack path / kill chain\x1b[0m");
print!("{}", harness::attack_graph::ascii_killchain(&out.findings));
}
if !out.artifacts.is_empty() {
println!("artifacts: {}", out.artifacts.join(", "));
println!("\n artifacts: {}", out.artifacts.join(", "));
println!(" (full attack graph rendered in report.html)");
}
}