mcpField
R
review-attack-path

review-attack-path

github.com/subimagesec安全052 次安装2 天前更新
代码仓库

关于 review-attack-path

review-attack-path 是用于 SubImage 攻击路径分析的技能,供安全分析人员检查已知路径、从资产追踪相关路径或寻找尚未建模的后续跳转。它要求以图数据证据区分已确认、推断与假设,并可按需叠加未持久化的情景模拟。

主要功能

  1. 01逐步解读已知攻击路径
  2. 02从资产查找相关路径
  3. 03探测未建模的后续跳转
  4. 04运行预览模式情景模拟
  5. 05按证据等级标示结论
  6. 06创建工单或发送通知

适用场景

  1. 01评估攻击路径终端资产的影响
  2. 02检查某资产参与的攻击路径
  3. 03从路径终点寻找横向移动可能
  4. 04模拟资产失陷后的潜在路径

MCP 相关

通过 subimageRunCypher 等 SubImage 工具读取图数据与模式,并调用情景模拟、工单和通知工具。技能面向 SubImage 的 MCP 工具工作流。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/subimagesec/skills --skill review-attack-path

安装后在 Claude Code 中输入/review-attack-path确认已加载。

详细介绍

审查攻击路径

功能说明

针对 SubImage 攻击路径引擎和底层 Neo4j 图的三种模式:

  1. 遍历已知路径,用通俗语言说明路径,指出最敏感的终端资产,并提出最快的修复方案。
  2. 从资产切入,查找该资产所在的路径,并审查其中风险最高的路径。
  3. 搜寻 n+1 扩展:探查路径终端节点之后的图,找出引擎尚未建模的可信后续步骤,并以内联候选转换的形式呈现。

可选的假设情景模拟可叠加到上述任一模式中。

适用场景

✅ 用户有来自 SubImage UI 或列表响应的攻击路径 ID。 ✅ 用户有一个资产,想知道它是否位于任何路径上。 ✅ 用户想扩展现有路径:“从这里查找横向移动”“评估 的爆炸半径”“接下来可能发生什么”。 ✅ 用户想进行假设分析:“如果攻击者攻陷 X,会发生什么?”。 ✅ 用户刚完成 subimage-mcp:investigate-cve 并确认了切入点。

❌ 用户想查看完整路径目录:只需列出 (:AttackPath:Signal) 并概述,不必逐步分析。 ❌ 用户想了解引擎背后的静态规则集:发现项请使用 subimage-mcp:triage-new-findings,或查阅文档。

前提条件

路径、路径步骤以及 n+1 探测都会通过 subimageRunCypher 读取图;架构探索则由 subimageListModuleSchemaNodes 和 subimageGetNodesSchema 提供支持。假设情景模拟会先使用 subimageGetScenarioCapabilities,再使用 subimageCreateAttackPathScenario;这两个工具运行引擎,而不是读取图。工单和通知后续操作使用 subimageListLinearTeams、subimageCreateTicket、subimageSendNotification。

必需输入

选择一种入口模式,并收集对应的值。如有任何信息缺失,请明确询问用户。

入口模式必需值缺失时询问
遍历已知路径<ATTACK_PATH_ID>“攻击路径 ID 是什么?查看 SubImage 中某条路径时,可在 URL 中找到;也可以用 Cypher 列出活动路径并选择一条(参见模式 A)。”
从资产切入<ASSET_ID>(资源 ARN 或完全限定 ID)“资产 ID 是什么?AWS 资产请提供资源 ARN,GCP/Azure 资产请提供完全限定 ID,也可以提供 SubImage 详情页 URL。”
搜寻 n+1 扩展一个起始 <ATTACK_PATH_ID> 或 一个已知为目标终端节点的 <ASSET_ID>“n+1 搜寻应从哪里开始:从特定路径的终端节点开始,还是从一个应视为已被攻陷的资产开始?”

对于假设情景,还需收集:

值缺失时询问
<NODE_LABEL>“起始节点标签是什么?(例如 AWSEC2Instance、AWSS3Bucket、User。)”
要授予的能力“要模拟攻击者具备哪些能力?先运行 subimageGetScenarioCapabilities,查看此节点标签支持哪些有效能力。”

判断准则(调用任何工具前请阅读)

图是事实依据。请保持审慎。

  1. 每项输出都要区分三个置信度层级。通过内容所在的章节隐式标记每项陈述:
    • 已确认:由攻击路径引擎直接返回,或由命中具体带标签行的 Cypher 查询直接返回。
    • 推断:通过有文档记录的架构关系组合两项已确认事实,并由支持该关联的 Cypher 探测提供依据。
    • 假设:假设情景的结果,或没有具体行作为依据的图结构观察。务必明确说明。
  2. 不得臆造标签、关系、转换或安全语义。如果架构中未显示某种关系,则该路径不存在。
  3. 图中的相邻关系不代表可利用性。两个节点之间存在关系是必要条件,但并非充分条件。
  4. 宁可漏掉薄弱的想法,也不要报告错误的信息。错误的转换报告比不报告更糟。
  5. 如果证据薄弱或含糊,请明确说明。不要掩盖不确定性。

工作流程

模式 A:遍历已知攻击路径
  1. 阅读路径中按顺序排列的步骤。攻击路径是一个 :AttackPath:Signal,其步骤按位置关联到该路径:

    MATCH (a:AttackPath:Signal {id: '<ATTACK_PATH_ID>'})-[h:HAS_STEP]->(s:AttackPathStep)
    OPTIONAL MATCH (s)-[:FROM]->(src)
    OPTIONAL MATCH (s)-[:TO]->(dst)
    RETURN a.title AS title, a.criticality_score AS criticality,
           h.position AS position, s.transition_id AS transition,
           s.capability AS capability, s.description AS description,
           collect(DISTINCT src.id) AS from_ids, collect(DISTINCT dst.id) AS to_ids
    ORDER BY position
    

    使用 s.description,它是渲染后的步骤文本。s.templated_description 仍包含未渲染的占位符,不适合用于展示。该查询按构造限定为单条路径的步骤,因此无需使用 LIMIT。

    此处使用 FROM|TO 是正确的连接方式,因为这些是步骤展示的端点,而且路径 ID 已知。若要查找哪些路径涉及某个资产,则不应使用这种连接方式;请参见模式 B。

  2. 将路径拆分为四个部分:

    • 初始入侵:入口节点,以及攻击者借此入侵的方式。
    • 关键跳转:1 到 3 个会实质改变攻击者处境的转换(权限提升、网络可达范围扩大、数据访问)。
    • 终端节点:链条中的最后一个节点。
    • 最终影响:攻击者此时掌控的对象或能够执行的操作。
  3. 将每次转换改写为通俗易懂的句子(“攻击者从 X 转到 Y,原因是 <转换中的原因>”)。不要重新罗列 JSON。

  4. 按影响排序:生产环境 / 客户数据 / 特权身份 > 内部环境 / 开发环境 > 沙盒。

模式 B:从资产切入
  1. 查找涉及该资产的路径。资产通过 AttackerCapacity 参与其中,因此连接方式是先通过 REASON|ON 连接到该 capacity,再通过 GRANTS 连接回步骤:

    MATCH (n {id: '<ASSET_ID>'})-[:REASON|ON]-(c:AttackerCapacity)
          <-[:GRANTS]-(:AttackPathStep)<-[:HAS_STEP]-(a:AttackPath:Signal)
    WHERE coalesce(a.status, 'active') IN ['active', 'accepted']
    RETURN DISTINCT a.id AS id, a.title AS title, a.criticality_score AS criticality,
           a.context_type AS context, coalesce(a.status, 'active') AS status
    ORDER BY criticality DESC, id
    LIMIT 20
    

    不要将其改写为 (:AttackPathStep)-[:FROM|TO]->(n)。 FROM 和 TO 是派生边,用于保存步骤展示的端点:TO 来自步骤自身的 capacity,FROM 来自上一步的 capacity。资产可以是某个 capacity 持有它的REASON,却从未成为端点;按端点匹配时,这类资产恰好会返回“无路径”。对于渲染已知路径,端点连接方式是正确的,这正是模式 A 的做法;但它不适用于发现路径。

    对状态使用 coalesce 并非防御性填充:路径 Signal 可能没有 status 属性,而这种情况仍视为活跃。

    返回 context_type,而不是按其筛选,这与产品自身的查找行为一致。若用户要求查看整个环境的情况,或者同一路径按每个 context 重复返回,则将范围缩小到 'default'。

  2. 如果结果为空:“目前没有已知攻击路径涉及 <ASSET_ID>。该资产仍可能受到引擎尚未建模的路径威胁。要我从此资产开始运行 n+1 扩展搜索(模式 C)吗?”只有使用上述 capacity 连接方式,这种说明才可靠。

  3. 如果结果非空:选取排名最高的 1 到 3 条路径,并对每条路径运行模式 A。

模式 C:寻找 n+1 扩展

这是分析员模式新增的功能:检查路径的终端节点,并探查图,以确定是否存在引擎尚未建模的可信后续步骤。

  1. 选择要扩展路径的终端节点(或者,如果用户指定了 <ASSET_ID>,则直接使用它)。
  2. 检查架构中该节点旁边有哪些内容:
    subimageListModuleSchemaNodes(module="<module-of-the-node>")
    subimageGetNodesSchema(node_names=["<TerminalLabel>"])
    
    注意关系类型和目标标签。
  3. 对每种合理的关系,运行一个小型 Cypher 探查,以确认确实存在实际行(见下文 Cypher 规则)。可信 n+1 类别示例:
    • 横向移动:从已攻陷的计算实例出发,通过安全组/VPC 对等连接/共享服务账户访问可达的对等节点。
    • 权限提升:从非管理员身份出发,查找可有效授予管理员权限的角色或策略边(iam:PassRole、AssumeRole、组成员关系、具有星号权限的自定义角色)。
    • 数据窃取:从任何已攻陷的计算实例出发,查找具有敏感数据标签或允许公开读取的可达存储。
    • 跨账户/跨租户:信任关系、跨账户角色代入、联合身份桥接。
  4. 在报告任何内容前,应用下方的 5 项检查清单。
  5. 在输出中列出每个可信扩展(格式见下文)。递增计数器,并在最终输出中提及计数。
模式 D:假设场景(叠加)

仅当用户提出请求时(“如果 X 被攻陷会怎样”“模拟授予 Y”)。

  1. 使用 subimageGetScenarioCapabilities(node_label="<NODE_LABEL>") 发现有效能力。
  2. 告诉用户有哪些可用能力,并询问要授予哪些能力。
  3. 使用 subimageCreateAttackPathScenario(..., preview_only=true)。始终传入 preview_only=true:用户可以检查结果,而不会将其持久化为真实路径。
  4. 使用模式 A 遍历生成的路径。

图探查的 Cypher 规则

以下规则同样适用于上述模式 A 和模式 B 查询,以及模式 C 探查:

  • subimageRunCypher 不接受查询参数,因此 <ATTACK_PATH_ID> 和 <ASSET_ID> 必须以内联字面量的形式传入。替换前转义反斜杠和单引号;ARN 和完全限定的 GCP/Azure ID 可能包含这些字符,未转义的撇号会导致语句出错。
  • 无论写入什么 LIMIT,工具最多返回 100 行,并同时报告真实的 total_count。这远高于此处所需的数量,但如果探查触及该上限,请引用 total_count,而不是当前页的行数。
  • 攻击路径的关系清单是封闭的。步骤的关系为 <-[:HAS_STEP]-、-[:GRANTS]->、-[:FROM]->、-[:TO]->;能力的关系为 <-[:GRANTS]-、-[:ON]->、-[:REASON]->,以及指向其他能力的 REQUIRED。不存在 (:AttackPathStep)-[:ON]-> 或 (:AttackPathStep)-[:REASON]->;这两种关系都从能力节点引出。
  • 始终为探索性查询设置上限:LIMIT 5。范围更大的扫描会消耗令牌,却不会增加有效信息。
  • 先从宽泛查询开始,再逐步细化。第一个查询确认结构存在;第二个查询获取具体行。
  • 对于文本匹配,优先使用 toLower(prop) CONTAINS "term",而不是正则表达式。
  • 切勿使用无界可变长度路径(-[*]->)。请限制范围:最多使用 -[*1..3]->。
  • 在据此推理前,先确认标签和关系确实存在于实际行中。如果 MATCH (a:Foo)-[:BAR]->(b) 返回 0 行,则该关系仅为概念关系;不要将其描述为可利用的关系。
  • 如果 subimageRunCypher 返回 0 行,这本身就是已确认的事实:该租户中不存在此关系。

何时呈现候选扩展

仅当以下五项全部成立时,才在输出中包含候选项:

  1. 此租户图中的真实行支持源标签和目标标签(而不只是架构)。
  2. 图中存在它们之间的关系(Cypher 探测至少找到一行)。
  3. 攻击者当前所处的位置在合理情况下允许执行此步骤(能力、网络可达性、身份)。
  4. 此步骤能带来有意义的新影响、新权限或新可达范围(而不只是“另一个相同类型的节点”)。
  5. 现有转换中显然尚未对该步骤建模(检查相似节点类型之间的几条现有路径)。

任意一项不成立,就不要呈现该项。请在内部说明原因,然后继续。

候选扩展格式

将每个候选项呈现为一个子块,并准确包含以下字段:

  • context:Attack path analysis: <用户请求,用一句话概述>
  • problem:Potential missing transition: <SourceLabel> can reach <TargetLabel> via <relationship>, enabling <impact>. Transition type: <lateral-movement | privilege-escalation | data-exfiltration | cross-account>. Evidence: <N> matches. Cypher pattern: <one-line MATCH>.
  • workaround:partial
  • workaround_detail:The current path stops at <terminal node>, but graph evidence suggests the attacker may continue to <target> via <mechanism>.
  • suggested_improvement:Add a transition from <SourceLabel> to <TargetLabel> under conditions: <list of validated conditions>.

输出

针对每条已检查的路径(模式 A 和 B):

# Attack path: <short title>

**Criticality**: <score / category>  ;  **Steps**: <N>

## In plain English
The attacker starts at [[entity:<Label>:<id>|<short>]] (<one-line context>).
1. <transition 1 in plain language>
2. <transition 2 in plain language>
3. ...
N. The chain ends at [[entity:<Label>:<id>|<short>]] which gives them <impact>.

## What this means
- **Initial compromise**: <one line>
- **Key pivot(s)**: <one line, naming the transitions that mattered>
- **Terminal impact**: <one line, naming what the attacker now controls>
- **Most sensitive impacted asset**: [[entity:<Label>:<id>|<short>]] (<why it matters>)
- **Why this path is exploitable today**: <rooted in the actual transitions, no speculation>

## Fastest remediation
<one or two concrete actions in priority order. Name the policy, the SG rule, the secret, the role.>

## What to do next
- Mitigate: <action>; owner: <team or `unknown`>
- Re-run after the change: SubImage refreshes paths on the next sync.

模式 C 之后,追加:

## n+1 extension hunt
- probes run: <count>
- credible extensions found: <count>
- candidate extensions surfaced: <count>

<for each surfaced candidate, render the five-field sub-block from "Candidate extension format" above>

如果模式 C 未发现可信内容,请明确说明:“没有可信的 n+1 扩展得到图证据支持。终端节点 <id> 当前并未与任何通过五项检查的对象相邻。”

始终使用 [[entity:<Label>:<node.id>|<display>]] 标记实体,以便聊天界面链接到实体。

可选后续操作

如果用户希望创建工单:

  1. 使用 subimageListLinearTeams() 获取团队 ID。
  2. 使用 subimageCreateTicket(team_id=..., title="Mitigate: <path title>", description="<the narrative + remediation>")。

创建前确认团队。subimageSendNotification 也遵循相同规则:先确认频道。

反模式

  • 将原始转换列表作为 Markdown 表格返回。聊天系统提示禁止将工具数据如此呈现,而且这也无助于让路径易于理解。
  • 对修复方案含糊其辞(如“检查 IAM 策略”)。请指出具体的策略、规则和资源。
  • 猜测引擎未生成的转换(“攻击者也可以……”)。如果用户提出要求,请使用 Cypher 探测运行模式 C;没有证据时,绝不要声称存在扩展。
  • 只进行一次薄弱探测就报告转换设想。请执行五项检查;任意一项不成立,都不要报告。
  • 一次响应中检查 5 条以上路径。用户只会处理排名最高的 1 或 2 条;更多内容只会沦为背景噪声。
  • 在假设场景中忘记设置 preview_only=true。不带此标记的形式会保存场景,而用户初次查看时通常并不希望如此。
  • 将架构中的关系视为已确认可利用性。先探测,再报告。

参考资料

  • 工具指南(由 subimageReadMe 始终加载):第 4 领域“攻击路径分析”,第 1 领域“知识图谱探索”(Cypher)。
  • 常用于跳转至此处的漏洞分诊配套技能:subimage-mcp:investigate-cve。
  • 架构:https://app.subimage.io/docs/architecture/attack_path

评论

支持 Markdown