attack-path-stitcher
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAttack Path Stitcher
Attack Path Stitcher
The Validation Run task (#3) produces confirmed findings per asset. Real attacker risk lives in chains: a finding on asset A leaks credentials that enable a finding on asset B that pivots into asset C. This skill builds that graph.
Mounted onto cloud-agent task #6.
验证运行任务(#3)会生成单资产的已确认发现。真实的攻击者风险存在于攻击链中:资产A上的发现泄露了凭据,这些凭据可被利用来触发资产B上的发现,进而渗透到资产C。本技能负责构建这种攻击图谱。
挂载于cloud-agent任务#6之上。
Trigger
触发方式
Cron daily (default 03:00 UTC). May also re-run after a Validation Run task batch completes.
每日通过Cron定时触发(默认UTC时间03:00)。也可在验证运行任务批次完成后重新运行。
Workflow
工作流程
- Load inputs.
- — every confirmed finding across all engagements.
validated/*.json - — the org-wide surface graph (assets, services, network zones, trust relationships).
artifacts/org-surface.json - — for credential / token extraction during stitching.
findings/finding-NNN/evidence/raw-source.txt
- Build asset nodes. One node per asset in , attributed with:
org-surface.json,tier,services,network_zone.trust_relationships - Build edges — one edge per detected pivot. See for the seven detectors:
reference/edge-detectors.md- Credential reuse (creds leaked on A reused as auth on B)
- Shared secret / API key (same secret appears in two assets' evidence)
- Trust-zone transitive access (A in zone X has implicit reach to B in zone X)
- AD path hops (kerberoast / DC sync / RBCD chains)
- Cloud IAM role chains (assume-role from compromised asset)
- SSRF → internal asset reach (A's SSRF reaches B's internal endpoint)
- Supply-chain (A is a dependency of B per SBOM)
source-code-scanning
- Compute reachability closure. For each tier-node, BFS backwards through edges to find every external-facing node that can reach it. Mark these as "entry points".
crown_jewel - Write graph to plus a human DOT file
artifacts/attack-paths.json(renderable with Graphviz).artifacts/attack-paths.dot
Implementation runs through which handles the graph construction. The skill provides the rules the tool consults; the tool does the iteration.
tools/chain-merger.py- 加载输入数据
- — 所有项目中的每一项已确认发现。
validated/*.json - — 全组织范围的资产面图谱(包含资产、服务、网络区域、信任关系)。
artifacts/org-surface.json - — 用于拼接过程中的凭据/令牌提取。
findings/finding-NNN/evidence/raw-source.txt
- 构建资产节点:为中的每个资产创建一个节点,并赋予以下属性:
org-surface.json(层级)、tier(服务)、services(网络区域)、network_zone(信任关系)。trust_relationships - 构建边:每检测到一次跳转就创建一条边。七个检测器的详情请参阅:
reference/edge-detectors.md- 凭据复用(资产A泄露的凭据被用于资产B的身份验证)
- 共享密钥/API密钥(同一密钥出现在两个资产的证据中)
- 信任区域传递访问(位于区域X的资产A可隐式访问同一区域X的资产B)
- AD路径跳转(Kerberoast/域控制器同步/RBCD链)
- 云IAM角色链(从已攻陷资产扮演角色)
- SSRF→内部资产访问(资产A的SSRF可访问资产B的内部端点)
- 供应链(根据生成的SBOM,资产A是资产B的依赖项)
source-code-scanning
- 计算可达闭包:针对每个(核心资产)层级的节点,通过边反向进行广度优先搜索(BFS),找到所有可到达该节点的外部节点,并将这些节点标记为“入口点”。
crown_jewel - 写入图谱:将图谱写入,同时生成人类可读的DOT文件
artifacts/attack-paths.json(可通过Graphviz渲染)。artifacts/attack-paths.dot
实现过程由执行,该工具负责图谱构建。本技能提供工具需遵循的规则,工具负责迭代执行。
tools/chain-merger.pyOutput
输出
{OUTPUT_DIR}/
artifacts/
attack-paths.json # nodes, edges, entry_points, crown_jewel_paths
attack-paths.dot # Graphviz source
attack-paths.md # ranked list of distinct paths (human read)attack-paths.jsonjson
{
"generated_at": "2026-05-13T03:00:00Z",
"nodes": [
{"id": "asset42", "tier": "revenue", "services": ["http/443"], "zone": "dmz",
"external": true, "findings": ["finding-012", "finding-018"], "max_cvss": 9.8}
],
"edges": [
{"src": "asset42", "dst": "asset77", "detector": "credential-reuse",
"via_findings": ["finding-012", "finding-019"],
"evidence": "credential (userpass) present in evidence of asset42 and asset77",
"feasibility": 1.0}
],
"entry_points": ["asset42", "asset05"],
"confirmed_paths": [
{"jewel": "asset99", "paths": [
{"hops": ["asset42", "asset77", "asset99"],
"edges": [{"src":"asset42","dst":"asset77","detector":"credential-reuse","feasibility":1.0,"via_findings":["finding-012"]},
{"src":"asset77","dst":"asset99","detector":"ssrf-reach","feasibility":1.0,"via_findings":["finding-024"]}],
"feasibility": 1.0, "max_cvss": 9.8, "path_class": "confirmed"}
]}
],
"inferred_paths": [
{"jewel": "asset99", "paths": [
{"hops": ["asset05", "asset99"], "edges": [...],
"feasibility": 0.5, "max_cvss": 7.5, "path_class": "inferred"}
]}
],
"truncation": {
"edge_cap_hit": false, "depth_truncated_count": 0,
"topn_dropped_count": 0, "max_depth": 8, "edge_cap": 50000
}
}Crucial for RFP §3.3 compliance: contains ONLY paths where every edge has feasibility 1.0 AND every edge cites at least one validated finding. These are the "confirmed attack paths" the RFP requires. carries topology / supply-chain hops with no PoC evidence — surfaced for analyst review but excluded from remediation SLA buckets by .
confirmed_pathsinferred_pathsrisk-prioritiser{OUTPUT_DIR}/
artifacts/
attack-paths.json # nodes, edges, entry_points, crown_jewel_paths
attack-paths.dot # Graphviz source
attack-paths.md # ranked list of distinct paths (human read)attack-paths.jsonjson
{
"generated_at": "2026-05-13T03:00:00Z",
"nodes": [
{"id": "asset42", "tier": "revenue", "services": ["http/443"], "zone": "dmz",
"external": true, "findings": ["finding-012", "finding-018"], "max_cvss": 9.8}
],
"edges": [
{"src": "asset42", "dst": "asset77", "detector": "credential-reuse",
"via_findings": ["finding-012", "finding-019"],
"evidence": "credential (userpass) present in evidence of asset42 and asset77",
"feasibility": 1.0}
],
"entry_points": ["asset42", "asset05"],
"confirmed_paths": [
{"jewel": "asset99", "paths": [
{"hops": ["asset42", "asset77", "asset99"],
"edges": [{"src":"asset42","dst":"asset77","detector":"credential-reuse","feasibility":1.0,"via_findings":["finding-012"]},
{"src":"asset77","dst":"asset99","detector":"ssrf-reach","feasibility":1.0,"via_findings":["finding-024"]}],
"feasibility": 1.0, "max_cvss": 9.8, "path_class": "confirmed"}
]}
],
"inferred_paths": [
{"jewel": "asset99", "paths": [
{"hops": ["asset05", "asset99"], "edges": [...],
"feasibility": 0.5, "max_cvss": 7.5, "path_class": "inferred"}
]}
],
"truncation": {
"edge_cap_hit": false, "depth_truncated_count": 0,
"topn_dropped_count": 0, "max_depth": 8, "edge_cap": 50000
}
}符合RFP §3.3要求的关键:仅包含所有边的feasibility(可行性)为1.0且每条边至少引用一项已验证发现的路径。这些是RFP要求的“已确认攻击路径”。包含无PoC(概念验证)证据的拓扑/供应链跳转——供分析师审阅,但会被排除在修复SLA(服务水平协议)范围之外。
confirmed_pathsinferred_pathsrisk-prioritiserRules
规则
- Edges require evidence. An edge is only written if at least one finding's evidence corroborates the pivot. No speculative edges.
- Bi-directional ≠ assumed. If A reaches B, do not infer B reaches A. Each direction needs its own evidence.
- Deduplicate by . Multiple findings that enable the same hop merge into one edge with
(src, dst, detector)listing all of them.via_findings - Feasibility ∈ {1.0, 0.5, 0.25}. Reliable PoC re-run = 1.0; conditional (race, timing, specific user) = 0.5; theoretical (logically follows but never demonstrated) = 0.25.
- Limit path enumeration. For each crown-jewel, return top-10 paths per class (confirmed + inferred separately) sorted by . Full graph is in
feasibility × max_cvss / hop_countfor downstream prioritisation.attack-paths.json - Read-only. Stitcher never re-fires PoCs and never touches . It only reads.
findings/ - Bound graph size. Stop edge construction at 50,000 edges; cap path-search depth at (default 8 hops). Emit
--max-depth,truncation.edge_cap_hit, andtruncation.depth_truncated_countin the JSON so downstream consumers can detect silent path loss.truncation.topn_dropped_count - Confirmed vs inferred is non-negotiable. A path appears in only if every edge has feasibility 1.0 AND every edge has a non-empty
confirmed_paths. Trust-zone-only, shared-secret-only, and supply-chain-only chains land invia_findings. This split is the contract that lets the RFP-§3.3 claim "confirmed attack paths" stand.inferred_paths - Schema enforcement on input. drops
tools/chain-merger.pyrows missingvalidated/{id}.jsonorfinding_id, or whoseasset, with stderr WARNs. Upstream validator must comply with the schema inverdict != "VALID".projects/rfp-3.2/task-03-validation-run.md
- 边需有证据支持:只有当至少一项发现的证据能佐证跳转时,才会创建边。禁止创建推测性边。
- 双向访问不可默认推断:若资产A可访问资产B,不可推断资产B也能访问资产A。每个方向的访问都需要单独的证据支持。
- 按去重:支持同一跳转的多项发现会合并为一条边,所有相关发现会列在
(src, dst, detector)中。via_findings - Feasibility(可行性)取值为{1.0, 0.5, 0.25}:可重复验证的可靠PoC=1.0;有条件的(竞争条件、时间窗口、特定用户)=0.5;理论上的(逻辑可行但从未被证明)=0.25。
- 限制路径枚举:针对每个核心资产,按(可行性×最高CVSS评分/跳数)排序,返回每个类别(已确认和推断分别统计)的前10条路径。完整图谱存储在
feasibility × max_cvss / hop_count中,供下游任务进行优先级排序。attack-paths.json - 只读模式:拼接器不会重新触发PoC,也不会修改目录,仅进行读取操作。
findings/ - 限制图谱规模:当边数达到50,000条时停止构建;路径搜索深度上限为参数指定的值(默认8跳)。在JSON中输出
--max-depth、truncation.edge_cap_hit和truncation.depth_truncated_count字段,以便下游任务检测是否存在未被记录的路径丢失情况。truncation.topn_dropped_count - 已确认与推断路径的划分不可动摇:只有当所有边的可行性为1.0且每条边的非空时,路径才会出现在
via_findings中。仅基于信任区域、共享密钥或供应链的攻击链会被归入confirmed_paths。这种划分是确保RFP-§3.3中“已确认攻击路径”声明有效的核心约定。inferred_paths - 输入Schema强制校验:会丢弃
tools/chain-merger.py中缺少validated/{id}.json或finding_id字段,或者asset的记录,并在标准错误输出中发出警告。上游验证器必须遵循verdict != "VALID"中定义的Schema。projects/rfp-3.2/task-03-validation-run.md
References
参考资料
- — the 7 detector rules with concrete signal patterns.
reference/edge-detectors.md - — cloud-agent runtime contract.
projects/rfp-3.3/task-06-attack-path-stitcher.md
- — 包含7个检测器规则及具体信号模式的文档。
reference/edge-detectors.md - — cloud-agent运行时约定文档。
projects/rfp-3.3/task-06-attack-path-stitcher.md