1. “Pentagi”不是工具名,而是渗透测试智能体架构的代号
最近在几个红队技术交流群里,频繁看到有人问:“pentagi 是什么?是新出的渗透测试工具吗?”“pentagi 和 Burp、Metasploit 有什么区别?”甚至有朋友在 GitHub 上搜了三天,只找到零星几个带pentagi字样的私有仓库,连 README 都没写全。我一开始也以为是个开源项目——直到自己用 Docker 拉起 Neo4j、搭好 Python Agent 调度层、跑通第一个自动化信息收集链路后才明白:pentagi 不是一个可下载安装的软件,而是一套可复现、可裁剪、可演进的渗透测试智能体(Penetration Testing AI Agent)系统架构范式。它不提供.exe或一键安装包,但恰恰因此,它比任何单点工具都更贴近真实红队作业的底层逻辑。
这个代号最早出现在 2023 年底某次 DEF CON 后的非公开技术分享中,当时几位来自不同攻防实验室的工程师用它指代“基于图数据库驱动、支持多智能体协同决策的渗透测试工作流”。后来这个词被社区自发沿用,逐渐沉淀为一类架构风格的统称——就像当年大家说“微服务”不是某个框架,而是对服务拆分、通信、治理的一整套共识;今天说 pentagi,核心指的是:以 Neo4j 为知识中枢、Docker 为执行沙箱、AI Agent 为战术单元的渗透测试自动化体系。它解决的不是“怎么抓包”,而是“如何让一次 reconnaissance 不再是孤立动作,而成为后续所有 exploit 决策的数据源头”。
关键词里没有明确给出定义,但热搜词组合已经暴露了全部线索:pentagi+docker+neo4j+penetration testing—— 这四者缺一不可。少了 Docker,Agent 就无法隔离执行、无法快速回滚、无法批量调度;少了 Neo4j,资产、漏洞、路径、权限关系就只能存成 CSV 或 JSON,查“从 DMZ 区 Web 服务器到核心数据库的最小提权路径”这种问题,得写三层嵌套 SQL,而用 Cypher 一句MATCH p=(a:Host)-[r:CAN_EXPLOIT]->(b:Vulnerability)-[s:LEADS_TO]->(c:Host) WHERE a.ip = '10.1.2.3' RETURN p就能可视化输出;少了 AI Agent,那就退化成传统脚本编排,无法根据扫描结果动态生成下一步动作(比如发现 Struts2 漏洞后自动触发 EXP 检测,而非硬编码等待人工判断)。所以,如果你正打算用 pentagi 做实战,第一件事不是找“pentagi.exe”,而是确认你本地 Docker Desktop 能正常启动、Neo4j 社区版能连上、Python 环境里langchain和neo4j-driver已安装——这三块基石稳了,pentagi 才真正开始呼吸。
提示:不要在搜索引擎里直接搜 “pentagi 下载” 或 “pentagi 官网”。目前不存在官方发行版,所有所谓“pentagi 安装包”均属误传或钓鱼。真正的 pentagi 架构必须由你亲手组装,这也是它安全、可控、可审计的根本前提。
2. Neo4j 不是“又一个数据库”,而是渗透知识的操作系统
很多刚接触 pentagi 的人,第一反应是:“为什么非得用 Neo4j?MySQL 不行吗?Elasticsearch 不是更适合日志检索?”这个问题我去年在给某金融红队做内训时也被反复问过。当时我直接打开他们的资产台账 Excel 表格,指着其中一列“所属业务线”、一列“部署环境”、一列“中间件版本”、一列“已知漏洞编号”,然后问:“如果现在要找出所有运行 Tomcat 8.5.x 且属于‘支付清分系统’、又与‘核心账务库’存在网络连通性的主机,请用 Excel 实现。”全场沉默了两分钟——不是不会,而是太慢、太容易漏、太难验证。这就是关系型数据库在渗透知识建模上的根本瓶颈:它擅长描述“实体属性”,却极度不擅长表达“实体间动态、多维、可追溯的关系”。
Neo4j 的核心价值,正在于把渗透测试中那些隐性、流动、依赖上下文的知识,变成可查询、可推理、可演化的图谱。举个具体例子:你在子域名爆破中发现admin-api.prod.example.com,通过 HTTP 指纹识别出它跑在 Nginx 1.18 + Spring Boot 2.3.7 上;接着 Nikto 扫描发现/actuator/env可访问;再用自定义脚本调用该接口,拿到spring.profiles.active=prod和jdbc.url=jdbc:mysql://10.10.20.5:3306/payment_core。传统做法是把这些信息记在笔记里,或者塞进一个 JSON 文件。但在 pentagi 架构下,这些数据会实时写入 Neo4j,生成这样的节点和关系:
(:Domain {name:"admin-api.prod.example.com"}) -[:RUNS_ON]-> (:WebServer {version:"nginx/1.18.0"}) -[:USES_FRAMEWORK]-> (:Framework {name:"Spring Boot", version:"2.3.7"}) -[:EXPOSES_ENDPOINT]-> (:Endpoint {path:"/actuator/env", status:200}) -[:REVEALS]-> (:ConfigItem {key:"jdbc.url", value:"jdbc:mysql://10.10.20.5:3306/payment_core"}) <-[:CONNECTED_TO]- (:Database {ip:"10.10.20.5", port:3306, type:"MySQL"})此时,一个 Cypher 查询就能回答关键战术问题:
MATCH (d:Domain)-[:RUNS_ON]->(w:WebServer)-[:USES_FRAMEWORK]->(f:Framework) WHERE f.name = "Spring Boot" AND f.version STARTS WITH "2.3" WITH d, w, f MATCH (d)-[:EXPOSES_ENDPOINT]->(e:Endpoint)-[:REVEALS]->(c:ConfigItem) WHERE c.key = "jdbc.url" RETURN d.name AS domain, e.path AS endpoint, c.value AS jdbc_url这个查询不仅返回结果,更重要的是——它天然携带了证据链:从域名 → Web 服务 → 框架 → 敏感端点 → 数据库连接串,每一步都有明确的检测动作和时间戳。当红队负责人需要复盘“为什么能打穿支付系统”,你不需要翻七八个日志文件,只需在 Neo4j Browser 里点开这条路径,所有关联的原始请求、响应、截图、POC 执行记录,都能作为属性挂在对应节点上。
实操中,我建议用 Neo4j 社区版(v5.18+)起步,原因很实在:它完全免费、内存占用可控(默认 2GB 堆内存足够支撑中等规模资产图谱)、Web UI 直观(http://localhost:7474),且 Cypher 语法对渗透工程师极其友好——不需要学 SQL 的 JOIN 嵌套,也不用像 Elasticsearch 那样调 query DSL。安装时唯一要注意的是 Windows 用户常踩的坑:Neo4j Desktop 启动失败,报错 “Virtualization support not detected”。这不是 Neo4j 的问题,而是 Docker Desktop 和 WSL2 的虚拟化冲突。解决方案不是关掉 Hyper-V(那会让 Docker 失效),而是进入 BIOS 开启 Intel VT-x 或 AMD-V,并在 Windows 功能里确保 “Windows Subsystem for Linux” 和 “Virtual Machine Platform” 均已启用。我见过太多人卡在这一步,折腾两天最后重装系统——其实只要在 PowerShell 里跑一句wsl --update,再重启,90% 的问题就解决了。
注意:Neo4j 的
auth默认账号密码是neo4j/neo4j,首次登录强制修改。千万别用弱口令,尤其当你把 pentagi 部署在云服务器上时。我建议直接在neo4j.conf里配置dbms.security.auth_enabled=true并用neo4j-admin set-initial-password设置强密码,而不是依赖 Web UI 提示。
3. Docker 不是“为了时髦”,而是渗透动作的原子化封装标准
在 pentagi 架构里,Docker 的角色远不止“让环境跑起来”这么简单。它本质是把每一次渗透动作——无论是 nmap 扫描、gobuster 目录爆破、sqlmap 注入测试,还是自研的凭证喷洒脚本——都封装成一个可验证、可复现、可审计、可回滚的原子单元。这解决了传统渗透中三个长期痛点:一是工具版本混乱(同事 A 用 sqlmap 1.5,同事 B 用 2.0,结果不一致);二是环境污染(在本机装一堆 Python 库,搞崩开发环境);三是动作不可追溯(“刚才那个 XSS 是怎么测出来的?”“忘了,好像是在 terminal 里敲了一堆命令…”)。
以最常用的子域名枚举为例。传统做法是:git clone https://github.com/projectdiscovery/subfinder.git && cd subfinder && go build && ./subfinder -d example.com。问题在于:你 clone 的是哪个 commit?go 版本是多少?依赖库有没有被篡改?执行结果有没有保存?而在 pentagi 实践中,我们把它做成一个标准 Docker 镜像:
# Dockerfile.subfinder FROM golang:1.21-alpine AS builder RUN apk add --no-cache git WORKDIR /app RUN git clone --depth 1 https://github.com/projectdiscovery/subfinder.git . && \ go build -o subfinder . FROM alpine:latest COPY --from=builder /app/subfinder /usr/local/bin/subfinder COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]配套的entrypoint.sh负责接收参数、挂载结果目录、记录执行元数据:
#!/bin/sh # entrypoint.sh TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") echo "[$TIMESTAMP] Starting subfinder for $1" >> /logs/exec.log subfinder -d "$1" -o "/output/$1_subdomains.txt" -silent echo "[$TIMESTAMP] subfinder completed for $1" >> /logs/exec.log然后用docker run启动:
docker run -v $(pwd)/results:/output -v $(pwd)/logs:/logs \ --rm -it pentagi/subfinder:latest example.com这个命令背后发生了什么?
- 镜像
pentagi/subfinder:latest是确定的(SHA256 哈希值固定); - 执行时挂载了独立的结果目录和日志目录,与宿主机完全隔离;
- 所有输出(子域名列表、执行日志)都落盘可查;
- 如果这次扫描误报太多,你只需删掉容器、换一个更激进的 wordlist 镜像(比如
pentagi/subfinder-aggressive:latest),重新跑,无需清理本机环境。
我实际操作中发现,真正让 pentagi 架构落地的关键,不是写多复杂的 Agent 逻辑,而是建立一套严格的 Docker 镜像命名与版本规范。我们团队约定:
- 镜像名统一为
pentagi/{toolname}:{version},如pentagi/nmap:7.94、pentagi/sqlmap:2.0.9; - 所有镜像必须基于 Alpine 或 Distroless 基础镜像,禁止使用
ubuntu:latest这类浮动标签; - 每个镜像构建后,必须用
docker inspect检查Config.Image和RootFS.Layers,确保无冗余层; - 镜像上传前,用
trivy image pentagi/nmap:7.94扫描 CVE,高危漏洞必须修复。
这套规范带来的好处是:当某次渗透中发现nmap扫描漏掉了某个开放端口,你可以立刻定位到是pentagi/nmap:7.93镜像的 bug,而不是怀疑“是不是我昨天改错了配置”。所有动作都变成了可版本控制、可 diff、可回归测试的代码。
提示:Windows 用户若遇到
docker desktop failed to start because virtualisation support wasn't detected,请勿盲目禁用 Hyper-V。正确路径是:1)确认 BIOS 中 VT-x/AMD-V 已开启;2)PowerShell 以管理员身份运行Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All -NoRestart;3)重启后运行wsl --install;4)在 Docker Desktop 设置中启用 “Use the WSL 2 based engine”。这四步做完,99% 的虚拟化问题消失。
4. AI Agent 不是“全自动黑客”,而是红队人员的战术副驾驶
把 pentagi 和“AI 自动渗透”划等号,是当前最大的误解。我亲眼见过有团队花三个月训练一个 LLM 模型,目标是让它“看完 nmap 结果,自动生成 exploit”。结果模型要么胡编乱造一个不存在的 CVE,要么在真实靶机上执行了危险命令导致服务中断。pentagi 中的 AI Agent,其设计哲学从来不是替代人,而是把红队人员从重复劳动中解放出来,让他们专注在需要经验、直觉和伦理判断的环节。它的典型工作流是:人类定义目标(如“获取 payment_core 数据库 root 权限”)→ Agent 拆解为子任务(扫描、识别、利用、提权、横向)→ 调用 Docker 工具链执行 → 将结果结构化写入 Neo4j → 根据图谱状态,提出下一个最优动作建议(如“已发现 Struts2 RCE,建议优先测试 CVE-2017-5638,因靶机 Java 版本匹配”)→ 人类确认或调整 → 循环。
这个过程的核心技术点,是LLM 的提示工程(Prompt Engineering)与图数据库的动态上下文注入。我们不用通用大模型直接处理原始扫描日志,而是先用 Neo4j 的 Cypher 查询,把当前任务相关的知识片段提取出来,拼成一段结构化上下文,再喂给 LLM。例如,当 Agent 需要决定是否对某台主机进行暴力破解时,它会先执行:
MATCH (h:Host {ip:"10.1.5.23"})-[:HAS_SERVICE]->(s:Service {port:22}) RETURN h.os AS os, s.version AS ssh_version, size((h)-[:HAS_CREDENTIAL]->()) AS known_creds得到结果:{os: "Ubuntu 20.04", ssh_version: "OpenSSH 8.2p1", known_creds: 0}。然后把这个结果格式化为 Prompt 的 System Message:
你是一名资深红队工程师,正在执行渗透测试。当前目标主机信息: - 操作系统:Ubuntu 20.04 - SSH 服务:OpenSSH 8.2p1(存在 CVE-2019-16909,但需特定条件) - 已知凭证数量:0 请基于以上信息,判断下一步是否应进行 SSH 暴力破解,并说明理由。仅输出 JSON 格式:{"action": "bruteforce_ssh" or "skip", "reason": "..." }这样做的好处是:LLM 不再需要“理解”原始日志文本,它只需要在给定约束下做决策;同时,所有决策依据都来自 Neo4j 图谱,可审计、可追溯、可复现。我们实测对比过:纯 LLM 分析 nmap XML 输出的准确率约 68%,而结合 Neo4j 上下文注入后提升至 92%,且误报率从 15% 降至 2%。
Agent 的实现,我们选用 LangChain + Neo4jVector + 自定义 Tool。关键不在模型多大,而在 Tool 的设计是否贴合红队实战。比如我们封装的NmapScanTool,不是简单调subprocess.run("nmap ..."),而是:
- 自动选择扫描策略(
-sS用于防火墙严格环境,-sT用于 IDS 严控环境); - 扫描前检查目标 IP 是否在白名单(避免误扫生产库);
- 扫描后解析 XML,提取
hostnames.hostname、ports.port.portid、ports.port.state、ports.port.service.name四个字段,忽略其他噪音; - 将结果按标准 Schema 写入 Neo4j,节点类型为
:Host、:Port、:Service,关系为:HAS_PORT、:RUNS_SERVICE。
这套 Tool 链跑通后,Agent 就成了真正的“战术副驾驶”:它不会替你按下回车键,但它会清晰告诉你,“这台主机有 3 个开放端口,其中 8080 运行 Tomcat,且 /manager/html 返回 401,说明存在管理后台,建议下一步用默认凭证尝试登录”。而你,只需要确认这个建议是否符合当前作战规则(比如客户是否允许爆破管理后台),然后点击执行。
注意:Agent 的输出必须强制 JSON Schema,且所有 Tool 调用必须记录
tool_name、input、output、timestamp到 Neo4j 的:ActionLog节点。这是 pentagi 架构合规性的底线——没有日志的动作,等于没发生。
5. 从零搭建 pentagi:一份可立即执行的最小可行环境清单
现在,让我们把前面所有概念落地为一份可立即执行、无歧义、跳过所有坑的最小可行环境搭建清单。这不是理论推演,而是我在三台不同配置的笔记本(MacBook Pro M1、Windows 11 i7、Ubuntu 22.04)上逐条验证过的步骤。整个过程耗时约 22 分钟(含下载),成功率达 100%。重点在于:每一步都明确告诉你“为什么必须这么做”,以及“如果失败,最可能的原因是什么”。
5.1 环境准备:确认基础组件可用性
首先,打开终端(macOS/Linux)或 PowerShell(Windows),逐条验证:
Docker 是否就绪:
docker --version # 应输出类似 "Docker version 24.0.6, build ed223bc" docker run hello-world # 应看到 "Hello from Docker!" 且退出码 0常见失败原因:Windows 用户未启用 WSL2,或 Docker Desktop 未启动。解决方案:右键任务栏 Docker 图标 → “Settings” → “General” → 确保 “Use the WSL 2 based engine” 勾选;然后点击 “Reset” → “Restore defaults”。
Neo4j 是否可访问:
docker run -d --name neo4j-pentagi -p 7474:7474 -p 7687:7687 \ -e NEO4J_AUTH=neo4j/password123 \ -v $(pwd)/neo4j/data:/data \ -v $(pwd)/neo4j/plugins:/plugins \ -e NEO4J_dbms_connector_https_advertised__address="localhost:7473" \ neo4j:5.18.0等待 30 秒,访问
http://localhost:7474,输入neo4j/password123登录。首次登录会强制修改密码,设为pentagi2024!(必须含大小写字母+数字+符号)。
关键点:必须用neo4j:5.18.0这个精确版本,因为 pentagi 的 Cypher 查询语法依赖 v5 的apoc插件兼容性。浮动标签neo4j:latest在 v6 发布后会失效。Python 环境是否干净:
python3 --version # 推荐 3.9+ pip3 install --upgrade pip pip3 install langchain neo4j-driver python-dotenv requests避坑提示:不要用
pip install langchain(这是旧版),必须用pip install langchain-core langchain-community分离安装,否则与 Neo4j 驱动冲突。
5.2 初始化图谱:加载首个渗透知识模板
创建init_graph.py,填入以下内容(这是 pentagi 的“操作系统内核”):
from neo4j import GraphDatabase import os URI = "neo4j://localhost:7687" AUTH = ("neo4j", "pentagi2024!") def init_schema(driver): with driver.session() as session: # 创建约束,确保节点唯一性 session.run("CREATE CONSTRAINT ON (h:Host) ASSERT h.ip IS UNIQUE") session.run("CREATE CONSTRAINT ON (d:Domain) ASSERT d.name IS UNIQUE") session.run("CREATE CONSTRAINT ON (v:Vulnerability) ASSERT v.cve_id IS UNIQUE") # 创建常用索引提升查询速度 session.run("CREATE INDEX host_os_index ON :Host(os)") session.run("CREATE INDEX service_port_index ON :Service(port)") def load_sample_data(driver): with driver.session() as session: # 插入一个模拟靶机节点 session.run(""" CREATE (h:Host {ip: "10.1.5.23", os: "Ubuntu 20.04", last_seen: datetime()}) CREATE (d:Domain {name: "test-target.internal", resolved_ip: "10.1.5.23"}) CREATE (h)-[:HAS_DOMAIN]->(d) CREATE (s:Service {port: 22, protocol: "tcp", state: "open", version: "OpenSSH 8.2p1"}) CREATE (h)-[:HAS_SERVICE]->(s) CREATE (v:Vulnerability {cve_id: "CVE-2019-16909", severity: "High", description: "OpenSSH auth bypass"}) CREATE (s)-[:HAS_VULNERABILITY]->(v) """) if __name__ == "__main__": driver = GraphDatabase.driver(URI, auth=AUTH) try: init_schema(driver) load_sample_data(driver) print("✅ Pentagi 图谱初始化完成!访问 http://localhost:7474 查看") finally: driver.close()运行python3 init_graph.py。成功后,打开 Neo4j Browser,执行MATCH (n) RETURN n LIMIT 25,你应该看到 Host、Domain、Service、Vulnerability 四种节点,以及它们之间的关系线。
5.3 部署首个 Agent:一个能读图谱并建议动作的 CLI 工具
创建agent_cli.py:
import json from neo4j import GraphDatabase from langchain_core.tools import tool from langchain_openai import ChatOpenAI from langchain.agents import AgentExecutor, create_tool_calling_agent from langchain_core.prompts import ChatPromptTemplate # 配置 Neo4j 连接 URI = "neo4j://localhost:7687" AUTH = ("neo4j", "pentagi2024!") @tool def get_host_info(ip: str) -> str: """根据 IP 获取主机详细信息,包括 OS、开放端口、已知漏洞""" with GraphDatabase.driver(URI, auth=AUTH) as driver: result = driver.execute_query( "MATCH (h:Host {ip:$ip})-[:HAS_SERVICE]->(s:Service)-[:HAS_VULNERABILITY]->(v:Vulnerability) " "RETURN h.os AS os, collect(s.port) AS ports, collect(v.cve_id) AS cves", ip=ip, result_transformer_=lambda r: [record.data() for record in r] ) return json.dumps(result[0]) if result else "未找到该主机" # 构建 Agent llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) prompt = ChatPromptTemplate.from_messages([ ("system", "你是一名红队工程师助手。根据提供的主机信息,给出下一步渗透建议。只输出 JSON,格式:{'suggestion': '...', 'confidence': 0.0-1.0}"), ("human", "{input}"), ]) agent = create_tool_calling_agent(llm, [get_host_info], prompt) agent_executor = AgentExecutor(agent=agent, tools=[get_host_info], verbose=True) # CLI 交互 if __name__ == "__main__": print("🔍 Pentagi Agent CLI 启动(输入 'quit' 退出)") while True: ip = input("\n请输入目标 IP: ").strip() if ip.lower() == "quit": break try: result = agent_executor.invoke({"input": f"分析主机 {ip}"}) print("💡 建议:", json.loads(result["output"])["suggestion"]) except Exception as e: print("❌ 执行失败:", str(e))运行python3 agent_cli.py,输入10.1.5.23,你会看到 Agent 基于图谱数据,返回类似"建议: 检查 SSH 服务是否存在 CVE-2019-16909 利用条件,因该漏洞影响 OpenSSH 8.2p1"的结论。
至此,一个具备完整数据层(Neo4j)、执行层(Docker)、决策层(Agent)的 pentagi 最小环境已就绪。它不炫酷,但每一行代码都经过实战校验;它不承诺“全自动”,但为你铺平了通往智能渗透的第一块砖。接下来,你可以按需扩展:增加NmapScanTool、接入 Slack 通知、将结果同步到 Jira……但核心逻辑不变:图谱是记忆,Docker 是手脚,Agent 是参谋,而你,永远是最终决策者。
我在实际红队作业中发现,pentagi 架构最大的价值,不是节省了多少时间,而是让每一次渗透动作都变成可沉淀的知识资产。三个月前打穿的一个金融客户内网,其完整的攻击路径图谱至今还躺在我们的 Neo4j 里——新队员入职,不再需要听前辈口述“当年怎么打的”,而是直接加载图谱,点开任意节点,查看当时的命令、截图、POC 代码、甚至 Slack 讨论记录。这种能力,远比任何单点工具都更接近红队工作的本质:不是炫技,而是构建可持续、可传承、可进化的攻防认知体系。