1. 论文信息与核心问题
论文:What Makes a Good LLM Agent for Real-world Penetration Testing?
链接:arXiv:2602.17622
PDF:https://arxiv.org/pdf/2602.17622
这篇论文问的是:什么样的 LLM Agent 才能做真实世界的自动化渗透测试?
它的核心观点可以概括成一句话:
自动化渗透 Agent 的难点,不只是把工具调对,而是把渗透过程建模成一个带证据、状态和回溯的搜索问题。
普通 ReAct Agent 更像一条线:
1 | Think -> Act -> Observe -> Think -> Act -> ... |
PentestGPT v2 则更接近攻击树搜索:
1 | 收集证据 -> 生成假设 -> 执行动作 -> 更新状态 -> 评估路径 -> 深入 / 回溯 / 剪枝 |
2. 两类失败:执行失败和路径失败
论文把现有 Pentest Agent 的失败分成两类。
第一类是 Type A:工具、知识、执行能力不足。比如工具参数写错、输出解析失败、不知道某个 CVE 的利用方式,或者没有正确调用 Metasploit、Impacket、sqlmap、ffuf 这类工具。
这类问题偏工程,可以通过 typed tool、RAG、parser、precondition / postcondition 缓解。它关心的是:Agent 能不能把动作执行对?
第二类是 Type B:复杂任务中的路径选择失败。比如侦察不足就开始利用、exploit 失败后反复重试、不会回到其他端口、拿到新凭证后不会重新访问旧资源,或者长上下文里忘掉关键状态。
这类问题更接近真实渗透的核心难点。它关心的是:Agent 知不知道当前路线是否还值得继续?
论文真正想解决的是 Type B。因为真实渗透不是单步命令生成,而是多阶段、不确定、需要回溯的搜索过程。
3. PentestGPT v2 的三个核心模块
PentestGPT v2 的设计可以压缩成三块:
| 模块 | 解决的问题 |
|---|---|
| Tool and Skill Layer | 动作能不能稳定执行 |
| TDA + EGATS Planner | 当前攻击路径是否值得继续 |
| Memory Subsystem | 长链任务中的状态如何保留 |

左边输入攻击目标,中间用 TDA-EGATS 做路径规划,再通过 Tool Layer 执行动作,Memory 负责保存状态。
需要注意的是,PentestGPT v2 是 Python 实现的 单 Agent、多模块架构。Tool Layer、TDA-EGATS Planner 和 Memory Subsystem 是同一个 Agent 内部的功能模块,而不是多个相互协作的独立 Agent。
3.1 Tool Layer:让 LLM 选择动作,而不是手写命令
普通 Agent 经常让 LLM 直接拼 shell:
1 | nmap -sV -p- 10.10.10.5 |
PentestGPT v2 的做法是把工具封装成 typed interface:
1 | scan_ports(target, ports, mode) |
每个接口都可以带输入 schema、输出 schema、precondition、postcondition、parser 和 error handler。这样 LLM 只负责选择高层动作,参数校验、命令执行和输出解析交给工具层。
1 | LLM 负责决定做什么 |
这一步主要解决 Type A:把动作执行对。
3.2 TDA-EGATS:给路径打分,再更新攻击树
TDA 是 Task Difficulty Assessment,EGATS 是 Evidence-Guided Attack Tree Search。这两个机制可以放在一起看:TDA 负责评估当前路径,EGATS 负责根据评估结果更新攻击树。
攻击树不是一串线性的命令历史,而是一组候选攻击分支。每条分支上会混合出现三类信息:
1 | Observation: 已确认的事实,例如端口、服务、用户名、凭证 |
TDA 主要看四个信号:
1 | Horizon Estimation: 当前路径离目标还有多远 |
这些信号会汇总成 TDI, Task Difficulty Index。TDI 越低,说明这条路径越值得继续深入;TDI 越高,说明继续投入的收益越低,应该考虑补侦察、回溯或剪枝。
最后服务于一个问题:
当前这条攻击路径,现在还值不值得继续投入?
TDI 作为路径难度和优先级信号反馈给 EGATS。EGATS 再用这个信号调整搜索策略:难度低、证据强的分支会被优先深入;难度高、证据弱的分支会转回侦察;连续失败且 TDI 持续升高的分支会被降权或剪枝。
例如,只发现端口开放时,证据很弱,更适合继续侦察;PoC 能触发或者拿到凭证时,证据变强,可以继续利用;如果某个分支连续失败,EGATS 就会降低它的优先级或者直接剪枝。拿到新凭证后,之前因为缺少身份而走不通的旧分支也可以被重新激活。
这里的核心流程是:
1 | 维护多条候选路径 |
和普通 ReAct loop 最大的区别在于:ReAct 通常只根据当前 observation 生成下一步动作,而 PentestGPT v2 会维护多条候选路径,并持续比较这些路径的证据强度、剩余难度和历史失败情况。
3.3 Memory:把关键事实从 prompt 里拿出来
Memory Subsystem 保存的不是普通聊天记录,而是结构化渗透状态:
1 | hosts |
例如:
1 | host: 10.10.10.5 |
这些状态会被攻击树节点引用,并在需要时重新注入上下文。它的作用是:
1 | 关键事实持久化 |
这对 AD、多主机、多凭证场景尤其重要。因为域内渗透高度依赖凭证复用、session 管理和横向移动,如果 Agent 忘掉前面拿到的身份,后续路径就会断掉。
4. Falafel 案例:从爆破切到 type juggling
论文里比较直观的案例是 HTB Falafel。

旧版 PentestGPT 在拿到 hash 后,持续沿着爆破方向尝试。这个方向看起来合理,但投入很多次仍然没有结果。
PentestGPT v2 的行为不同:
1 | 当前路径多次失败 |
于是它没有一直卡在 hash cracking 上,而是转向另一个攻击假设:PHP type juggling。
这个例子可以很好地说明 PentestGPT v2 的技术重点:它不是单纯让 LLM 更会写命令,而是让 Agent 根据证据和历史结果调整搜索方向。
真实渗透里的很多进展都来自 pivot。比如从 Web 转到 SMB,从弱口令转到配置泄露,从单机提权转到域内横向。Agent 如果不会评估路线价值,就很容易在一个看似合理但实际无效的方向上耗尽预算。
5. 技术启发
这篇论文比较有价值的地方,是把 Pentest Agent 的问题拆成了三个层次:
1 | 执行可靠性:动作能不能做对 |
普通 Agent 把渗透测试看成一串工具调用:
1 | 看到服务 -> 调工具 -> 看输出 -> 再调工具 |
PentestGPT v2 把它看成搜索问题:
1 | 维护攻击树 |
这篇论文给自动化渗透 Agent 提供了一个更合理的抽象:
在可复用攻击模式空间里,Agent 的关键能力是证据驱动的搜索、回溯和状态管理。