PentestGPT V2源码研究之EGATS规划器

文章目录

  • [EGATS 规划器架构详解](#EGATS 规划器架构详解)
    • [一、EGATS 算法概述](#一、EGATS 算法概述)
      • [1.1 什么是 EGATS?](#1.1 什么是 EGATS?)
      • [1.2 核心组件关系图](#1.2 核心组件关系图)
    • 二、攻击树数据结构
      • [2.1 AttackNode(攻击节点)](#2.1 AttackNode(攻击节点))
      • [2.2 AttackTree(攻击树)](#2.2 AttackTree(攻击树))
      • [2.3 节点类型详解](#2.3 节点类型详解)
    • 三、TDI(任务难度指数)计算
      • [3.1 TDIScore 结构](#3.1 TDIScore 结构)
      • [3.2 TDI 计算流程](#3.2 TDI 计算流程)
      • [3.3 TDI 可视化](#3.3 TDI 可视化)
    • [四、UCB (上置信界) 节点选择策略](#四、UCB (上置信界) 节点选择策略)
      • [4.1 UCB (上置信界) 公式详解](#4.1 UCB (上置信界) 公式详解)
      • [4.2 UCB (上置信界) 实现代码](#4.2 UCB (上置信界) 实现代码)
      • [4.3 UCB (上置信界) 决策过程示例](#4.3 UCB (上置信界) 决策过程示例)
    • [五、EGATS 主循环流程](#五、EGATS 主循环流程)
      • [5.1 完整流程图](#5.1 完整流程图)
      • [5.2 主循环代码实现](#5.2 主循环代码实现)
    • 六、反向传播机制
      • [6.1 反向传播原理](#6.1 反向传播原理)
      • [6.2 反向传播示例](#6.2 反向传播示例)
    • 七、剪枝机制
      • [7.1 剪枝条件](#7.1 剪枝条件)
      • [7.2 剪枝可视化](#7.2 剪枝可视化)
    • 八、模式选择(BFS/DFS/Hybrid)
      • [8.1 模式选择器](#8.1 模式选择器)
      • [8.2 模式对比](#8.2 模式对比)
    • 九、横向移动(Pivot)机制
      • [9.1 Pivot 子树创建](#9.1 Pivot 子树创建)
      • [9.2 凭证传播](#9.2 凭证传播)
    • 十、研究源码的方法论总结
      • [10.1 阅读顺序建议](#10.1 阅读顺序建议)
      • [10.2 理解复杂代码的技巧](#10.2 理解复杂代码的技巧)
        • [技巧 1:从调用链入手](#技巧 1:从调用链入手)
        • [技巧 2:关注数据流](#技巧 2:关注数据流)
        • [技巧 3:理解设计模式](#技巧 3:理解设计模式)
        • [技巧 4:结合测试用例](#技巧 4:结合测试用例)
      • [10.3 调试技巧](#10.3 调试技巧)
    • 十一、完整公式详解
      • 概述
      • [11.1 TDI(任务难度指数)详细计算](#11.1 TDI(任务难度指数)详细计算)
        • [11.1.1 四个维度的计算公式](#11.1.1 四个维度的计算公式)
        • [11.1.2 TDI 综合计算公式](#11.1.2 TDI 综合计算公式)
        • [11.1.3 TDI 计算示例](#11.1.3 TDI 计算示例)
        • [11.1.4 TDI 权重配置](#11.1.4 TDI 权重配置)
      • [11.2 UCB(上置信界)详细计算](#11.2 UCB(上置信界)详细计算)
        • [11.2.1 UCB 公式详解](#11.2.1 UCB 公式详解)
        • [11.2.2 UCB 三项分解](#11.2.2 UCB 三项分解)
        • [11.2.3 UCB 计算示例](#11.2.3 UCB 计算示例)
      • [11.3 反向传播详细计算](#11.3 反向传播详细计算)
        • [11.3.1 指数平滑公式](#11.3.1 指数平滑公式)
        • [11.3.2 反向传播完整流程](#11.3.2 反向传播完整流程)
        • [11.3.3 反向传播示例](#11.3.3 反向传播示例)
      • [11.4 剪枝机制完整公式](#11.4 剪枝机制完整公式)
        • [11.4.1 剪枝条件](#11.4.1 剪枝条件)
        • [11.4.2 剪枝阈值配置](#11.4.2 剪枝阈值配置)
        • [11.4.3 剪枝决策表](#11.4.3 剪枝决策表)
      • [11.5 模式选择完整公式](#11.5 模式选择完整公式)
        • [11.5.1 模式选择逻辑](#11.5.1 模式选择逻辑)
        • [11.5.2 模式选择决策表](#11.5.2 模式选择决策表)
      • [11.6 凭证传播机制](#11.6 凭证传播机制)
        • [11.6.1 凭证相关性判断](#11.6.1 凭证相关性判断)
        • [11.6.2 凭证重新评估流程](#11.6.2 凭证重新评估流程)
      • [11.7 完整公式速查表](#11.7 完整公式速查表)
    • 附录:相关文件索引

EGATS 规划器架构详解

一、EGATS 算法概述

1.1 什么是 EGATS?

EGATS (Evidence-Guided Attack Tree Search) - 证据引导的攻击树搜索,是一种结合了蒙特卡洛树搜索 (MCTS) 和启发式评估的规划算法。

python 复制代码
# 核心组件概览
┌─────────────────────────────────────────────────────────────┐
│                      EGATSPlanner                           │
│  ┌──────────────┬──────────────┬──────────────┬────────────┐│
│  │   TDA        │    UCB       │ Backprop     │  Pruning   ││
│  │ (任务难度评估) │(节点选择策略)  │(反向传播)      │  (剪枝)    ││
│  └──────────────┴──────────────┴──────────────┴────────────┘│
│         ↓                   ↓                ↓              │
│  ┌─────────────────────────────────────────────────────┐    │
│  │              Attack Tree (攻击树)                    │    │
│  │    Root → Children → Leaves                         │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

1.2 核心组件关系图

EGATSPlanner
TDAComputer
UCB Selector
Backpropagation
Pruning
Pivot Manager
Mode Selector
TDIScore 计算
节点选择 UCB 公式
奖励反向传播
剪枝决策
横向移动子树
BFS/DFS/Hybrid 模式


二、攻击树数据结构

2.1 AttackNode(攻击节点)

位于 excalibur/planner/models.py

python 复制代码
class AttackNode(BaseModel):
    """
    攻击树中的单个节点,代表渗透测试中的一个观察、假设或动作。
    
    核心属性:
    - id: 节点唯一标识符 (8 字符短 ID)
    - node_type: 节点类型 (OBSERVATION/HYPOTHESIS/ACTION)
    - status: 生命周期状态 (PENDING/ACTIVE/COMPLETED/PRUNED/FAILED)
    - promise_score: UCB 承诺分数 φ(n),基于历史奖励
    - tdi: 任务难度指数,包含 4 个加权维度
    - visit_count: 节点被访问的次数(用于 UCB)
    - success_count/failure_count: 成功/失败计数
    """

2.2 AttackTree(攻击树)

python 复制代码
class AttackTree(BaseModel):
    """
    完整的攻击树,包含所有节点和根节点引用。
    
    核心属性:
    - root_id: 根节点的 ID
    - nodes: {node_id: AttackNode} 映射表
    - total_actions: 已执行的总动作数(用于 UCB)
    - budget_remaining: 剩余预算次数
    """

2.3 节点类型详解

类型 说明 使用场景
OBSERVATION 观察节点 信息收集、端口扫描结果
HYPOTHESIS 假设节点 基于证据的推测(如"可能存在 SQL 注入")
ACTION 动作节点 要执行的操作(如"运行 sqlmap")

三、TDI(任务难度指数)计算

3.1 TDIScore 结构

位于 excalibur/planner/models.py:87

python 复制代码
class TDIScore(BaseModel):
    """
    四个加权维度:
    - horizon: 视野深度(从根节点到该节点的深度)权重 0.3
    - success_rate: 成功率(拉普拉斯平滑后)权重 0.2
    - context_load: 上下文负载(token 预算利用率)权重 0.2
    - evidence_confidence: 证据置信度权重 0.3
    
    计算公式:
        TDI = w_h*H + w_e*(1-E) + w_c*C + w_s*(1-S)
    """

3.2 TDI 计算流程

python 复制代码
# excalibur/planner/tda.py:46
def compute_tdi(self, node, tree, context_load=0.0) -> TDIScore:
    """
    1. 计算 horizon:depth / max_depth(归一化深度)
    2. 计算 success_rate:(success + 1) / (total_visits + 2)
    3. 获取 context_load:当前 token 预算利用率
    4. 计算 evidence_confidence:沿路径的平均证据级别
    5. 组合成 TDIScore
    """

3.3 TDI 可视化

python 复制代码
# 示例:TDI 值分解
TDIScore(
    horizon=0.6,           # 深度适中
    success_rate=0.75,     # 成功率较高
    context_load=0.4,      # 上下文负载中等
    evidence_confidence=0.8, # 证据较可靠
    value=0.43             # 综合难度指数(越低越好)
)

四、UCB (上置信界) 节点选择策略

4.1 UCB (上置信界) 公式详解

位于 excalibur/planner/ucb.py

python 复制代码
# UCB(n) = φ(n) + c * √(ln(N) / N_n) - dp * δ(n)
#
# 其中:
#   φ(n)    = promise_score (承诺分数,基于历史奖励)
#   c       = exploration_constant (探索常数,默认 1.414 = √2)
#   N       = 树中已执行的总动作数
#   N_n     = 节点 n 被访问的次数
#   dp      = difficulty_penalty (难度惩罚权重,默认 0.5)
#   δ(n)    = TDI 值(难度指数)

4.2 UCB (上置信界) 实现代码

python 复制代码
# excalibur/planner/ucb.py:30-67
def select_node(
    tree: AttackTree,
    exploration_constant: float = 1.414,
    difficulty_penalty: float = 0.5,
) -> AttackNode | None:
    """
    选择具有最高 UCB 分数的活动叶子节点。
    
    平衡三个因素:
    1. Exploitation (利用): 高承诺分数的节点
    2. Exploration (探索): 访问次数少的节点获得奖励
    3. Difficulty Penalty (难度惩罚): 避免选择过于困难的节点
    """

4.3 UCB (上置信界) 决策过程示例

python 复制代码
# 假设当前状态:
total_actions = 100  # N

# 候选节点 A(已访问多次,承诺分数高)
node_A = AttackNode(
    promise_score=0.8,      # φ(n) 较高
    visit_count=50,         # N_n 较大
    tdi=TDIScore(value=0.3) # δ(n) 较低(难度小)
)
# UCB(A) = 0.8 + 1.414 * √(ln(100)/50) - 0.5 * 0.3
#        = 0.8 + 1.414 * 0.26 - 0.15
#        = 0.8 + 0.37 - 0.15 = 1.02

# 候选节点 B(访问较少,承诺分数中等)
node_B = AttackNode(
    promise_score=0.6,
    visit_count=10,
    tdi=TDIScore(value=0.4)
)
# UCB(B) = 0.6 + 1.414 * √(ln(100)/10) - 0.5 * 0.4
#        = 0.6 + 1.414 * 0.58 - 0.2
#        = 0.6 + 0.82 - 0.2 = 1.22

# 结果:选择节点 B(探索奖励更高)

五、EGATS 主循环流程

5.1 完整流程图

攻击路径
状态事实
模式指导
兄弟摘要
添加发现
扩展树
剪枝
上下文压缩
Pivot 生成
是
否
开始
选择节点

Select Node
计算 TDI

Compute TDI
选择模式

Select Mode
组装上下文提示

Assemble Context Prompt
攻击路径
主机/服务/凭证
模式指导
兄弟摘要
查询 LLM

Query LLM
处理响应

Process Response
更新树与状态存储

Update Tree & State Store
添加到节点
扩展新节点
反向传播

Backpropagate

更新 n 值
检查条件

Check Conditions
Pruning
Context Comp
Pivot spawn
预算 > 0?
结束

5.2 主循环代码实现

位于 excalibur/core/controller.py:411-603

python 复制代码
async def _egats_loop(self, initial_task: str) -> dict[str, Any]:
    """
    EGATS 规划循环,共 12 个步骤:
    
    1. UCB 选择节点 (select_next_node)
    2. 计算 TDI (compute_tdi)
    3. 选择模式 (select_mode) - BFS/DFS/LLM 决策
    4. 组装上下文提示词 (assemble context)
    5. 查询后端 LLM (backend.query)
    6. 处理响应并收集发现 (process message)
    7. 反向传播结果评估 (backpropagate)
    8. 用新发现扩展树的子节点 (expand_tree)
    9. 检查剪枝条件 (check_pruning)
    10. 检查上下文压缩条件 (compress if needed)
    11. 标记当前节点为已完成
    12. 循环直到预算耗尽或停止请求
    """

六、反向传播机制

6.1 反向传播原理

python 复制代码
# excalibur/planner/backpropagation.py:13
def backpropagate(tree, node, outcome, alpha=0.7):
    """
    将节点的操作结果沿路径反向传播到根节点。
    
    更新承诺分数 φ(n):
        φ(parent) = α * reward + (1-α) * φ(parent)
    
    其中:
    - α: 平滑因子(默认 0.7),控制新旧奖励的权重
    - reward: 当前结果对应的奖励值
        SUCCESS → 1.0
        PARTIAL → 0.5
        FAILURE → 0.1
    """

6.2 反向传播示例

python 复制代码
# 初始状态
node_A.promise_score = 0.5  # 中等承诺分数

# 执行后获得 SUCCESS 结果
backpropagate(tree, node_A, outcome=ActionOutcome.SUCCESS, alpha=0.7)

# 更新计算
new_promise = 0.7 * 1.0 + (1-0.7) * 0.5
           = 0.7 + 0.15
           = 0.85

# node_A.promise_score 从 0.5 提升到 0.85
# 下次 UCB 选择时,该节点会被优先考虑(利用)

七、剪枝机制

7.1 剪枝条件

位于 excalibur/planner/pruning.py

python 复制代码
# 剪枝决策逻辑
def should_prune(node, prune_threshold=0.8, min_attempts=3):
    """
    判断节点是否应该被剪枝:
    
    条件 1: TDI > prune_threshold (难度过高)
    条件 2: visit_count >= min_attempts (已充分尝试)
    
    只有同时满足两个条件时才剪枝
    """

7.2 剪枝可视化

python 复制代码
# 示例:剪枝决策过程
node = AttackNode(
    tdi=TDIScore(value=0.85),  # TDI > 0.8 (难度高)
    visit_count=5,              # >= 3 (已充分尝试)
    status=NodeStatus.ACTIVE
)

# should_prune(node) → True
# prune_branch(tree, node) → 将该节点及其子树标记为 PRUNED

八、模式选择(BFS/DFS/Hybrid)

8.1 模式选择器

位于 excalibur/planner/mode_selector.py

python 复制代码
def select_mode(tdi_value, bfs_threshold=0.6, dfs_threshold=0.3):
    """
    根据 TDI 值选择探索模式:
    
    - TDI > 0.6:   BFS (广度优先) - 快速扫描多个分支
    - TDI < 0.3:   DFS (深度优先) - 深入挖掘当前路径
    - 否则:        Hybrid (混合) - 平衡探索和利用
    """

8.2 模式对比

模式 适用场景 特点
BFS TDI 高,需要广泛扫描 快速发现新机会,但可能错过深度利用
DFS TDI 低,路径可靠 深入挖掘当前路径,充分利用已知信息
Hybrid TDI 中等 平衡策略,灵活调整

九、横向移动(Pivot)机制

9.1 Pivot 子树创建

python 复制代码
# excalibur/planner/pivot.py:23
def spawn_pivot(tree, host, parent):
    """
    当攻陷一个新主机时,创建横向移动子树。
    
    新节点描述:
    - type: ACTION (pivot action)
    - description: "Pivot to <host> from <parent.description>"
    - host: 新攻陷的主机地址
    """

9.2 凭证传播

python 复制代码
# excalibur/planner/pivot.py:56
def propagate_credentials(tree, credentials):
    """
    根据新发现的凭据重新评估被剪枝的节点。
    
    如果新凭据可能使之前困难的节点变得可行,则重新激活它们。
    """

十、研究源码的方法论总结

10.1 阅读顺序建议

bash 复制代码
# 推荐的文件阅读顺序:

# 第 1 层:入口点和核心架构
1. README.md                    # 整体概览
2. excalibur/core/controller.py  # 中央协调器(主循环)
3. excalibur/planner/egats.py    # EGATS 编排器

# 第 2 层:数据模型和核心算法
4. excalibur/planner/models.py   # 攻击树数据结构
5. excalibur/planner/ucb.py      # UCB 节点选择
6. excalibur/planner/tda.py      # TDI 计算
7. excalibur/planner/backpropagation.py  # 反向传播
8. excalibur/planner/pruning.py  # 剪枝算法

# 第 3 层:辅助组件
9. excalibur/memory/context_assembler.py   # 上下文组装
10. excalibur/memory/state_store.py         # 状态存储
11. excalibur/planner/mode_selector.py      # 模式选择
12. excalibur/planner/pivot.py              # 横向移动

10.2 理解复杂代码的技巧

技巧 1:从调用链入手
python 复制代码
# 找到入口点,追踪执行路径
excalibur/interface/main.py (CLI entry)
    ↓
excalibur/core/controller.run()
    ↓
excalibur/core/controller._egats_loop()
    ↓
excalibur/planner/egats.select_next_node()
技巧 2:关注数据流
python 复制代码
# 追踪关键数据结构的变化
AttackTree → AttackNode → TDIScore → ActionOutcome
     ↓            ↓           ↓              ↓
  创建树       选择节点    计算难度      评估结果
技巧 3:理解设计模式
  • 单例模式 : EventBus.get()
  • 观察者模式: 事件总线与 TUI 的解耦通信
  • 策略模式: UCB、剪枝、模式选择的可配置算法
  • 工厂模式 : ContextAssembler 组装上下文
技巧 4:结合测试用例
bash 复制代码
# 运行相关测试理解功能
cd tests/unit
python -m pytest test_egats_loop.py -v    # EGATS 循环测试
cat test_ucb.py                            # UCB 算法测试

10.3 调试技巧

python 复制代码
# 在代码中添加调试输出
import logging
logging.basicConfig(level=logging.DEBUG)

# 或在关键位置添加断点
async def _egats_loop(self, initial_task: str):
    # ... 
    current_node = self._planner.select_next_node(tree)
    print(f"Selected node: {current_node.id}, UCB score: {current_node.promise_score}")
    # ...

十一、完整公式详解

概述

本节将第十一章的快速参考卡片内容扩展为完整的公式详解,涵盖 EGATS 规划器的所有核心计算公式。

核心组件与公式概览
复制代码
┌─────────────────────────────────────────────────────────────┐
│                      EGATSPlanner                           │
│  ┌──────────────┬──────────────┬──────────────┬────────────┐│
│  │   TDA        │    UCB       │ Backprop     │  Pruning   ││
│  │ (任务难度评估) │(节点选择策略)  │(反向传播)      │  (剪枝)    ││
│  └──────────────┴──────────────┴──────────────┴────────────┘│
│         ↓                   ↓                ↓              │
│  ┌─────────────────────────────────────────────────────┐    │
│  │              Attack Tree (攻击树)                    │    │
│  │    Root → Children → Leaves                         │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘
核心公式速览
类别 名称 完整公式 默认参数
TDI 综合难度指数 w_h·H + w_e·(1-E) + w_c·C + w_s·(1-S) weights: {h:0.3, e:0.3, c:0.2, s:0.2}
TDI Horizon (视野深度) depth / max_depth -
TDI Success Rate (成功率) (success + 1) / (visits + 2) (拉普拉斯平滑) -
TDI Evidence Confidence Σ(evidence_level) / path_length -
UCB 节点选择评分 φ(n) + c·√(ln(N)/Nₙ) - dp·δ(n) c=1.414, dp=0.5
Backprop 承诺分数更新 φ = α·R + (1-α)·φ_old α=0.7
Pruning 剪枝条件 TDI > threshold AND visits >= min_attempts threshold=0.8, min_attempts=3
Mode BFS 模式阈值 TDI > 0.6 -
Mode DFS 模式阈值 TDI < 0.3 -
配置参数速查
python 复制代码
# excalibur/planner/egats.py:39
_DEFAULT_CONFIG = {
    "exploration_constant": 1.414,   # UCB 探索常数 √2
    "difficulty_penalty": 0.5,       # TDI 难度惩罚权重
    "backprop_alpha": 0.7,           # 反向传播平滑因子
    "prune_threshold": 0.8,          # 剪枝阈值
    "min_prune_attempts": 3,         # 最小尝试次数
    "bfs_threshold": 0.6,            # BFS 模式切换阈值
    "dfs_threshold": 0.3,            # DFS 模式切换阈值
}

11.1 TDI(任务难度指数)详细计算

11.1.1 四个维度的计算公式
维度 符号 计算公式 取值范围 说明
Horizon (视野深度) H depth / max_depth 0, 1 归一化深度,越深难度越大
Success Rate (成功率) S (success_count + 1) / (visit_count + 2) 0, 1 拉普拉斯平滑避免除零
Context Load (上下文负载) C token_used / token_budget 0, 1 Token 预算利用率
Evidence Confidence (证据置信度) E Σ(evidence_level) / path_length 0, 1 路径上所有节点证据级别的平均值
11.1.2 TDI 综合计算公式
python 复制代码
# excalibur/planner/models.py:137-142
def compute_tdi_value(self) -> float:
    """
    TDI = w_h·H + w_e·(1-E) + w_c·C + w_s·(1-S)
    
    各项含义:
    - w_h·H: 深度带来的难度(越深越难)
    - w_e·(1-E): 证据不足带来的难度(证据越少越难)
    - w_c·C: 上下文负载带来的难度(token 占用越多越难)
    - w_s·(1-S): 成功率低带来的难度(失败多则难)
    """
    return (
        self.weight_horizon * self.horizon
        + self.weight_evidence * (1.0 - self.evidence_confidence)
        + self.weight_context * self.context_load
        + self.weight_success * (1.0 - self.success_rate)
    )
11.1.3 TDI 计算示例
python 复制代码
# excalibur/planner/tda.py:62-74
node = AttackNode(
    success_count=3,
    failure_count=1,
    visit_count=4,
    evidence_level=EvidenceLevel.CONFIRMED  # 0.8
)
tree = AttackTree(...)  # 包含完整路径信息

tdi = TDAComputer().compute_tdi(node, tree, context_load=0.3)

# 计算过程:
# horizon = depth / max_depth = 3/5 = 0.6
# success_rate = (3+1)/(4+2) = 4/6 = 0.67 (拉普拉斯平滑)
# context_load = 0.3 (传入参数)
# evidence_confidence = 路径上所有节点证据级别的平均值

print(f"TDI: {tdi.value:.3f}")
# 输出示例:TDI: 0.425
11.1.4 TDI 权重配置
python 复制代码
# excalibur/planner/egats.py:47-52
"tda_weights": {
    "horizon": 0.3,             # 视野深度权重 - 中等重要性
    "evidence": 0.3,            # 证据权重 - 高重要性(证据不足会显著增加难度)
    "context": 0.2,             # 上下文负载权重 - 较低
    "success": 0.2,             # 成功率权重 - 较低
}

11.2 UCB(上置信界)详细计算

11.2.1 UCB 公式详解
python 复制代码
# excalibur/planner/ucb.py:37-40
UCB(n) = φ(n) + c · √(ln(N) / Nₙ) - dp · δ(n)
符号 含义 默认值 说明
φ(n) promise_score (承诺分数) 0,1 基于历史奖励的节点价值估计
c exploration_constant 1.414 (=√2) 探索项权重,控制探索与利用的平衡
N total_actions - 树中已执行的总动作数
Nₙ visit_count - 节点 n 被访问的次数
dp difficulty_penalty 0.5 难度惩罚权重
δ(n) TDI 值 0,1 节点 n 的难度指数
11.2.2 UCB 三项分解
python 复制代码
# excalibur/planner/ucb.py:57-61
for node in candidates:
    visits = max(node.visit_count, 1)
    
    # 1. Exploitation (利用项): 基于历史表现
    exploitation = node.promise_score
    
    # 2. Exploration (探索项): 访问次数少的节点获得奖励
    exploration = c * sqrt(ln(N) / visits)
    
    # 3. Difficulty Penalty (难度惩罚): 高 TDI 的节点被 penalize
    difficulty_penalty = dp * tdi_value
    
    ucb = exploitation + exploration - difficulty_penalty
11.2.3 UCB 计算示例
python 复制代码
# excalibur/planner/ucb.py:57-64
total_actions = 100  # N

# 节点 A:已访问多次,承诺分数高
node_A = AttackNode(
    promise_score=0.8,      # φ(n) 较高
    visit_count=50,         # N_n 较大
    tdi=TDIScore(value=0.3) # δ(n) 较低(难度小)
)
# UCB(A) = 0.8 + 1.414 * √(ln(100)/50) - 0.5 * 0.3
#        = 0.8 + 1.414 * 0.26 - 0.15
#        = 0.8 + 0.37 - 0.15 = 1.02

# 节点 B:访问较少,承诺分数中等
node_B = AttackNode(
    promise_score=0.6,
    visit_count=10,
    tdi=TDIScore(value=0.4)
)
# UCB(B) = 0.6 + 1.414 * √(ln(100)/10) - 0.5 * 0.4
#        = 0.6 + 1.414 * 0.58 - 0.2
#        = 0.6 + 0.82 - 0.2 = 1.22

# 结果:选择节点 B(探索奖励更高)

11.3 反向传播详细计算

11.3.1 指数平滑公式
python 复制代码
# excalibur/planner/backpropagation.py:31
φ(parent) = α · R + (1-α) · φ_old(parent)
符号 含义 默认值
φ(parent) 更新后的承诺分数 -
α 平滑因子 0.7
R 当前结果奖励值 SUCCESS=1.0, PARTIAL=0.5, FAILURE=0.1
φ_old(parent) 之前的承诺分数 0,1
11.3.2 反向传播完整流程
python 复制代码
# excalibur/planner/backpropagation.py:42-51
def backpropagate(tree, node, outcome, alpha=0.7):
    path = tree.get_path_to_root(node.id)
    reward = outcome.value  # 根据结果获取奖励值
    
    for path_node in path:
        # 指数平滑更新承诺分数
        path_node.promise_score = (
            alpha * path_node.promise_score +
            (1 - alpha) * reward
        )
        
        # 更新访问统计
        path_node.visit_count += 1
        if outcome == ActionOutcome.SUCCESS:
            path_node.success_count += 1
        elif outcome == ActionOutcome.FAILURE:
            path_node.failure_count += 1
11.3.3 反向传播示例
python 复制代码
# excalibur/planner/backpropagation.py:46
node_A.promise_score = 0.5  # 初始承诺分数

# 执行后获得 SUCCESS 结果 (reward=1.0)
backpropagate(tree, node_A, outcome=ActionOutcome.SUCCESS, alpha=0.7)

# 更新计算
new_promise = 0.7 * 1.0 + (1-0.7) * 0.5
           = 0.7 + 0.15
           = 0.85

# node_A.promise_score 从 0.5 提升到 0.85

11.4 剪枝机制完整公式

11.4.1 剪枝条件
python 复制代码
# excalibur/planner/pruning.py:44-46
def should_prune(node, threshold=0.8, min_attempts=3):
    """
    剪枝决策逻辑:
    
    条件 1: TDI > threshold (难度过高)
    条件 2: visit_count >= min_attempts (已充分尝试)
    
    只有同时满足两个条件时才剪枝
    """
    if node.tdi is None:
        return False
    return node.tdi.value > threshold and node.visit_count >= min_attempts
11.4.2 剪枝阈值配置
python 复制代码
# excalibur/planner/egats.py:43-44
"prune_threshold": 0.8,         # TDI > 此值考虑剪枝
"min_prune_attempts": 3,        # 最小尝试次数后才允许剪枝
11.4.3 剪枝决策表
TDI 值 visit_count should_prune
> 0.8 >= 3 ✅ True (高难度且已充分尝试)
> 0.8 < 3 ❌ False (虽然难但还需更多尝试)
<= 0.8 >= 3 ❌ False (难度可接受,保留探索)
<= 0.8 < 3 ❌ False (难度低且未充分尝试)

11.5 模式选择完整公式

11.5.1 模式选择逻辑
python 复制代码
# excalibur/planner/mode_selector.py:42-46
def select_mode(tdi_value, bfs_threshold=0.6, dfs_threshold=0.3):
    """
    根据 TDI 值选择探索模式:
    
    - TDI > 0.6:   BFS (广度优先) - 快速扫描多个分支
    - TDI < 0.3:   DFS (深度优先) - 深入挖掘当前路径
    - 否则:        Hybrid (混合) - 平衡探索和利用
    """
    if tdi_value > bfs_threshold:
        return "reconnaissance"     # BFS 模式
    if tdi_value < dfs_threshold:
        return "exploitation"       # DFS 模式
    return "llm_decide"           # Hybrid 模式
11.5.2 模式选择决策表
TDI 值范围 返回模式 策略说明
> 0.6 reconnaissance (BFS) 高难度,需要广泛扫描发现更多机会
< 0.3 exploitation (DFS) 低难度,专注于已知可行路径的深度利用
0.3, 0.6 llm_decide (Hybrid) 中等难度,让 LLM 根据具体情况决定

11.6 凭证传播机制

11.6.1 凭证相关性判断
python 复制代码
# excalibur/planner/pruning.py:102-117
def _cred_relevant(node, credential):
    """
    检查凭据是否可能与被剪枝的节点相关。
    
    使用关键词启发式方法:如果节点的描述提到了
    与认证相关的服务,则认为凭据可能相关。
    """
    auth_keywords = [
        "login", "auth", "ssh", "rdp", "smb",
        "ftp", "password", "credential", "winrm"
    ]
    desc_lower = node.description.lower()
    return any(kw in desc_lower for kw in auth_keywords)
11.6.2 凭证重新评估流程
python 复制代码
# excalibur/planner/pruning.py:71-98
def reevaluate_pruned(tree, new_credentials):
    """
    重新打开可能受益于新凭据的被剪枝分支。
    
    当发现新凭据时,之前被剪枝的与认证相关的分支
    可能变得可行。此函数会重置其状态和统计信息。
    """
    reopened = []
    if not new_credentials:
        return reopened
    
    for node in tree.nodes.values():
        # 检查节点是否被剪枝且凭据相关
        if (node.status == NodeStatus.PRUNED and
            any(_cred_relevant(node, cred) for cred in new_credentials)):
            # 重置状态和统计信息
            node.status = NodeStatus.PENDING
            node.visit_count = 0
            node.success_count = 0
            node.failure_count = 0
            reopened.append(node.id)
    
    return reopened

11.7 完整公式速查表

类别 名称 完整公式 默认参数
TDI 综合难度指数 w_h·H + w_e·(1-E) + w_c·C + w_s·(1-S) weights: {h:0.3, e:0.3, c:0.2, s:0.2}
TDI Horizon (视野深度) depth / max_depth -
TDI Success Rate (成功率) (success + 1) / (visits + 2) (拉普拉斯平滑) -
TDI Evidence Confidence Σ(evidence_level) / path_length -
UCB 节点选择评分 φ(n) + c·√(ln(N)/Nₙ) - dp·δ(n) c=1.414, dp=0.5
Backprop 承诺分数更新 φ = α·R + (1-α)·φ_old α=0.7
Pruning 剪枝条件 TDI > threshold AND visits >= min_attempts threshold=0.8, min_attempts=3
Mode BFS 模式阈值 TDI > 0.6 -
Mode DFS 模式阈值 TDI < 0.3 -

附录:相关文件索引

文件 路径 功能
EGATSPlanner excalibur/planner/egats.py:56 主编排器
AttackNode excalibur/planner/models.py:153:153 节点数据模型
AttackTree excalibur/planner/models.py:199:199 树数据模型
UCB Selector excalibur/planner/ucb.py:30 节点选择算法
TDA Computer excalibur/planner/tda.py:46 TDI 计算
Backpropagation excalibur/planner/backpropagation.py:13 反向传播
Pruning excalibur/planner/pruning.py 剪枝算法
Mode Selector excalibur/planner/mode_selector.py 模式选择
Pivot Manager excalibur/planner/pivot.py:23 横向移动
Controller excalibur/core/controller.py:59 主控制器
相关推荐
黄金龙PLUS12 小时前
如何基于置换算法来设计对称加密算法
算法·网络安全·密码学·哈希算法·同态加密
王大傻092814 小时前
堆叠注入(Stacked Queries Injection)详解:原理、利用与防御
服务器·网络·数据库·web安全·网络安全
芯盾时代20 小时前
从《人工智能安全治理框架3.0》看智能体安全治理
人工智能·安全·网络安全·智能体
ggb喔1 天前
52pojie 的桌面工具:为什么它们总在高分屏上模糊、资源管理器重启后失效
windows·python·网络安全·软件工程·个人开发·用户界面·用户体验
小杉泽1 天前
【长三角WP】长三角网络安全攻防大赛初赛WP(Misc&Crypto&数据安全)
安全·网络安全
学逆向的2 天前
win32远程线程
网络安全·api·win32
pencek2 天前
MazeSec-113
网络安全
白猫不黑2 天前
网络安全专业:从入门到进阶的完整学习路线
学习·安全·web安全·计算机·网络安全·信息安全·编程
菩提小狗2 天前
每日安全情报报告 · 2026-10-07
网络安全·漏洞·cve·安全情报·每日安全
白猫不黑2 天前
AI自动化漏洞挖掘从入门到进阶超详细学习路线
人工智能·学习·web安全·网络安全·信息安全·渗透测试·自动化