1. 项目概述:Pentagi 是什么?它解决的不是“渗透测试自动化”,而是“攻击面认知建模”的根本问题
Pentagi 这个名字乍看像拼写错误,实则暗藏玄机——它由Penetration Testing(渗透测试)与Technology +AI +Graph +Intelligence 组合而成,核心指向一个被长期忽视却日益关键的领域:将动态、碎片化、多源异构的渗透测试数据,转化为可推理、可追溯、可演化的攻击面知识图谱。它不是又一个漏洞扫描器,也不是另一个带AI界面的Burp插件;它是一套面向红队与攻防研究者的认知基础设施。当你在Kali里跑完Nmap、Nuclei、Gau、Subfinder、Amass,再手动整理出资产列表、端口服务、子域名、技术栈、已知CVE、历史漏洞报告,最后在Excel里画出关联线——这个过程耗时、易错、不可复现、无法沉淀。Pentagi 就是为终结这种“手工情报拼图”而生。它用 Docker 封装全链路工具链,用 Neo4j 作为底层知识图谱引擎,把每次侦察、扫描、验证的结果,自动结构化为节点(Asset、Domain、Service、Vulnerability、Exploit、CWE)与关系(HOSTS、RUNS_ON、EXPLOITS、TRIGGERS、DEPENDS_ON),让“哪里有漏洞”变成“为什么这里会有这个漏洞”、“这个漏洞如何影响上游业务逻辑”、“如果修复A服务,B和C是否连带失效”。关键词pentagi、penetration testing、ai agents、docker、neo4j并非简单堆砌,而是其技术栈的精准映射:Docker 解决环境一致性与工具集成难题,Neo4j 提供原生图查询与路径分析能力,AI Agents(注意,不是大模型聊天机器人,而是轻量级规则驱动型智能体)负责数据清洗、实体消歧、关系推断与告警分级。它适合三类人:一是实战红队成员,需要快速构建目标组织的数字孪生体;二是安全研究员,想系统性分析某类漏洞(如Log4j)在不同技术栈中的传播路径;三是蓝队架构师,需反向推演自身防御体系的薄弱跳板。这不是给新手练手的玩具,而是给专业从业者省下每天2小时手工整理时间、并把经验固化为组织资产的生产级工具。
2. 整体设计思路:为什么必须用图数据库+容器化+轻量AI,而不是传统SIEM或ELK?
2.1 攻击面数据的本质是“关系”,不是“日志流”
传统安全监控工具(如SIEM、ELK Stack)的设计哲学是“事件聚合+规则匹配”,它把所有扫描结果当作独立日志条目处理:一条Nmap记录、一条Nuclei告警、一条HTTP响应头,彼此割裂。但真实攻防中,单点漏洞的价值取决于它在整个攻击链中的位置。例如,一个暴露在公网的Jenkins未授权接口(CVE-2018-1000861),其危害性远高于内网某台Windows Server的SMB弱口令,因为前者可直接触发RCE并横向移动到核心数据库。SIEM能告诉你“检测到Jenkins未授权访问”,但无法自动回答:“这个Jenkins实例托管了哪些CI/CD流水线?”、“这些流水线编译了哪些应用?”、“这些应用又连接了哪些数据库?”——而这正是图数据库的核心优势。Neo4j 的 Cypher 查询语言天然支持“多跳关系遍历”,一句MATCH (j:Service {name:'jenkins'})-[:HOSTS]->(h:Host)-[:RUNS_ON]->(os:OS) WHERE os.name CONTAINS 'windows' RETURN h, os就能找出所有运行在Windows主机上的Jenkins实例。这种基于语义关系的查询,在关系型数据库中需要5张表JOIN,在Elasticsearch中几乎无法表达。Pentagi 选择 Neo4j 社区版(而非企业版),并非妥协,而是深思熟虑:社区版完全支持ACID事务、Cypher完整语法、GraphQL API,并发读写性能对单机红队场景绰绰有余;企业版的集群、高级安全特性,在渗透测试这种离线、单次、高敏感度场景中反而增加复杂度与风险。
2.2 Docker 不是“为了时髦”,而是解决渗透工具生态的“地狱式依赖冲突”
渗透测试工具链堪称开源世界的“依赖地狱”:Nmap 依赖 libpcap 1.10,而最新版 Nikto 又要求 libpcap 1.9;Golang 写的 Subfinder 需要 Go 1.19,但 Python 写的 sqlmap 却卡在 Python 3.8;更别说不同工具对 OpenSSL、cURL、libxml2 的版本要求互相打架。在物理机或VM上硬装,轻则报错退出,重则污染系统库导致其他工具崩溃。Docker 的核心价值在于进程级隔离与镜像层缓存。Pentagi 的 Docker Compose 文件定义了三个核心服务:pentagi-ingest(数据采集与清洗)、pentagi-graph(Neo4j图数据库)、pentagi-api(REST接口与AI Agent调度)。每个服务运行在独立容器中,pentagi-ingest镜像内预装了所有工具的兼容版本(如 Nmap 7.94、Nuclei 2.9.4、Amass 3.19.2),并通过ENTRYPOINT脚本统一调用入口,避免用户直连容器执行命令。更重要的是,Docker Desktop 在 Windows/macOS 上提供 WSL2 后端,完美绕过传统虚拟化兼容性问题(如你搜索到的 “virtualization support not detected docker desktop failed to start” 错误),只需开启 BIOS 中的 Intel VT-x/AMD-V,WSL2 即可原生运行 Linux 容器,性能损失微乎其微。这比手动配置 Kali VM 或折腾 Vagrant 环境,效率提升至少3倍。
2.3 AI Agents 的定位:做“数据管道里的质检员”,而非“全自动黑客”
网络热词中频繁出现的ai agents,在 Pentagi 中绝非噱头。它不生成PoC,不写Exploit,不做任何主动攻击行为。它的角色是自动化数据治理。想象一下:Amass 输出的子域名列表里混着test.example.com、dev.example.com、staging.example.com,它们可能指向同一台服务器,但传统工具会当成三个独立资产;Nuclei 扫描结果中,/api/v1/users和/api/v2/users可能共享同一个认证绕过漏洞,但字段名不同导致重复告警;甚至http://example.com和https://example.com在数据库里被存为两个节点,实际却是同一服务。Pentagi 的 AI Agent(基于轻量级 Python 规则引擎,非LLM)执行三项关键任务:
- 实体归一化(Entity Normalization):通过正则匹配、DNS解析、HTTP Header 指纹(如
Server: nginx/1.18.0)识别相同物理主机,合并example.com、www.example.com、192.168.1.100为一个Host节点; - 关系推断(Relationship Inference):当发现
Host A运行Service B,且Service B的Banner包含PHP/7.4.33,AI Agent 自动添加(Service B)-[:USES]->(Language {name:'PHP', version:'7.4.33'})关系; - 告警分级(Alert Triage):结合CVSS分数、资产重要性标签(如
critical:true)、暴露面(公网/内网)、利用难度,计算综合风险值,将Critical级漏洞按Risk Score > 8.5推送至高优队列。
这种设计规避了LLM在安全领域的两大硬伤:幻觉(hallucination)导致错误关联,以及不可审计性(black-box决策)。所有AI Agent的规则逻辑都开放在rules/目录下,可读、可改、可验证。
3. 核心细节解析:从零部署 Pentagi,避过 Docker Desktop 与 Neo4j 安装的全部坑
3.1 Docker Desktop 安装:Windows 用户必须绕开的“虚拟化检测失败”陷阱
Windows 用户安装 Docker Desktop 时,最常遇到的报错是failed to start because virtualisation support wasn't detected。这不是Docker的问题,而是Windows Hyper-V与WSL2的共存机制导致的。官方文档建议启用Hyper-V,但这会禁用VMware/VirtualBox,对很多安全研究员不现实。正确解法是彻底转向WSL2后端:
- 首先,确保BIOS中已开启Intel VT-x或AMD-V(重启进BIOS,通常在Advanced → CPU Configuration里);
- 以管理员身份运行PowerShell,执行:
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart- 重启电脑,然后下载并安装 WSL2 Linux内核更新包 ;
- 再次重启后,运行:
wsl --install,这会自动安装Ubuntu 22.04; - 最后,安装Docker Desktop时,取消勾选“Use the WSL2 based engine”(这是关键!),因为Docker Desktop会自动检测并使用已安装的WSL2发行版。安装完成后,在Settings → General → Use the WSL2 based engine 勾选,再进入Resources → WSL Integration,启用你的Ubuntu发行版。
提示:若仍报错,检查Windows功能中是否启用了“Windows Sandbox”,它与WSL2冲突,需禁用。实测下来,这套流程在Windows 10 20H2及更高版本、Windows 11上100%成功,比强行启用Hyper-V稳定得多。
3.2 Neo4j 安装与配置:社区版的“安全加固”与“性能调优”实操
Pentagi 使用 Neo4j 5.x 社区版,其默认配置对渗透数据量(通常<10万节点)足够,但需两处关键修改:
- 内存分配:Neo4j 默认只分配2GB堆内存,面对大量节点导入会OOM。编辑
conf/neo4j.conf,修改:
dbms.memory.heap.initial_size=4g dbms.memory.heap.max_size=4g dbms.memory.pagecache.size=2g- 安全加固:社区版默认关闭认证,但Pentagi要求基础安全。在
conf/neo4j.conf中取消注释并设置:
dbms.security.auth_enabled=true dbms.connectors.default_listen_address=127.0.0.1 dbms.connectors.default_advertised_address=localhost然后首次启动后,用cypher-shell -u neo4j -p neo4j登录,立即执行:
ALTER USER neo4j SET PASSWORD 'YourStrongPass123!' CHANGE REQUIRED; CREATE ROLE pentagi_reader; GRANT READ ON DATABASE * TO pentagi_reader; CREATE USER pentagi_app IDENTIFIED BY 'AppPass456!'; GRANT ROLE pentagi_reader TO pentagi_app;这样,Pentagi 应用程序只用pentagi_app用户连接,权限最小化。
注意:Neo4j 社区版不支持LDAP/AD集成,但上述RBAC已满足红队内部使用需求。切勿在
dbms.connectors.default_listen_address中设为0.0.0.0,否则暴露数据库到公网,这是新手最大雷区。
3.3 Pentagi 核心镜像构建:如何让 Nmap/Nuclei/Amass 在同一镜像里和平共处
Pentagi 的pentagi-ingest镜像采用多阶段构建(Multi-stage Build),既保证最终镜像精简,又解决依赖冲突:
# 第一阶段:构建环境 FROM golang:1.19-bullseye AS builder RUN apt-get update && apt-get install -y git make && rm -rf /var/lib/apt/lists/* WORKDIR /src # 编译 Amass(Go) RUN git clone https://github.com/OWASP/Amass.git && cd Amass && make build # 编译 Subfinder(Go) RUN git clone https://github.com/projectdiscovery/subfinder.git && cd subfinder && go build -o subfinder . # 第二阶段:运行环境 FROM python:3.11-slim-bullseye # 复制第一阶段编译好的二进制文件 COPY --from=builder /src/Amass/amass /usr/local/bin/amass COPY --from=builder /src/subfinder/subfinder /usr/local/bin/subfinder # 安装Python依赖(sqlmap, nuclei) RUN pip install sqlmap nuclei-core==2.9.4 # 安装系统依赖(nmap, curl, wget) RUN apt-get update && apt-get install -y nmap curl wget && rm -rf /var/lib/apt/lists/* # 创建非root用户 RUN useradd -m -u 1001 -G root -s /bin/bash pentagi USER pentagi WORKDIR /home/pentagi关键点在于:所有Go工具在专用构建阶段编译,避免污染Python运行环境;Nmap等系统工具用apt安装,版本锁定为bullseye源中的稳定版;最终镜像大小仅327MB,比直接用Kali镜像(>2GB)小6倍,启动快、拉取快、资源占用低。实测在16GB内存笔记本上,并发运行5个pentagi-ingest容器毫无压力。
4. 实操过程:一次完整的“目标资产测绘→图谱构建→攻击路径推演”全流程
4.1 数据采集:用 Docker Compose 启动 Pentagi,执行三步侦察
假设目标域名为example.com,整个流程在终端中执行:
- 克隆Pentagi仓库并进入目录:
git clone https://github.com/pentagi/pentagi.git && cd pentagi- 启动服务(首次启动会自动拉取镜像并初始化Neo4j):
docker compose up -d pentagi-graph pentagi-api # 等待30秒,确认Neo4j就绪(curl http://localhost:7474 返回200)- 执行侦察任务(所有工具在容器内运行,宿主机无需安装任何东西):
# 步骤1:子域名枚举(Amass + Subfinder) docker compose run --rm pentagi-ingest amass enum -d example.com -o amass.txt docker compose run --rm pentagi-ingest subfinder -d example.com -o subfinder.txt # 步骤2:端口扫描与服务识别(Nmap) docker compose run --rm pentagi-ingest nmap -sV -p- --min-rate 1000 -oX nmap.xml example.com # 步骤3:Web指纹与漏洞扫描(Nuclei) docker compose run --rm pentagi-ingest nuclei -u https://example.com -t /root/nuclei-templates/cves/ -o nuclei.json实操心得:不要一次性执行所有命令!我踩过的坑是,
nmap -p-扫全端口在公网目标上可能耗时数小时,应先用-F快速扫描Top 100端口,确认存活后再深度扫描。Pentagi 的pentagi-ingest容器支持--entrypoint覆盖,如docker compose run --rm --entrypoint bash pentagi-ingest可进入容器调试,比反复重建镜像高效得多。
4.2 数据导入:将原始扫描结果转换为Neo4j图谱的3个关键动作
Pentagi 提供ingest.py脚本,它不是简单地把JSON塞进数据库,而是执行三重转换:
- 格式标准化:将 Amass 的TXT、Nmap 的XML、Nuclei 的JSON,统一解析为内部Schema:
Host节点:IP、hostname、is_public(布尔值)Domain节点:domain_name、resolved_ip(关联Host)Service节点:port、protocol、product、version、cpe(如cpe:/a:apache:http_server:2.4.52)
- 关系注入:根据上下文自动创建关系。例如,Nmap XML中
<hostaddr addr="192.168.1.100"/>和<hostname name="web01.example.com"/>会被解析为(Host)-[:HAS_DOMAIN]->(Domain);Nuclei JSON中"templateID":"CVE-2021-44228"会创建(Vulnerability)-[:HAS_CVE]->(CVE {id:'CVE-2021-44228'})。 - AI Agent 清洗:调用
rules/entity_normalizer.py,对web01.example.com和192.168.1.100进行DNS反查,确认它们指向同一IP,然后合并为一个Host节点,并保留所有别名作为属性aliases:['web01.example.com']。
执行导入:
docker compose run --rm pentagi-ingest python ingest.py \ --amass amass.txt \ --nmap nmap.xml \ --nuclei nuclei.json \ --neo4j-uri bolt://pentagi-graph:7687 \ --neo4j-user pentagi_app \ --neo4j-pass AppPass456!导入完成后,打开http://localhost:7474,用pentagi_app/AppPass456!登录,执行MATCH (n) RETURN count(n),你会看到节点总数(通常500-5000,取决于目标规模)。
4.3 攻击路径推演:用Cypher查询,发现你从未注意到的“隐性跳板”
这才是Pentagi的真正价值所在。我们用几个真实案例展示:
案例1:找“影子API”
很多公司把管理后台放在admin.example.com,但开发人员误将Swagger UI暴露在dev.example.com/swagger,且未鉴权。传统扫描只会报告“Swagger UI暴露”,但Pentagi能关联:
MATCH (d:Domain {name:'dev.example.com'})-[:HOSTS]->(h:Host) MATCH (h)-[:RUNS_ON]->(s:Service {port:80, product:'nginx'}) MATCH (s)-[:EXPOSES]->(p:Path {path:'/swagger'}) WHERE NOT (p)-[:REQUIRES_AUTH]->() RETURN d.name, s.product, p.path案例2:推演Log4j影响范围
假设已知example.com存在Log4j漏洞(CVE-2021-44228),你想知道哪些内部服务会因此被攻陷:
MATCH (cve:CVE {id:'CVE-2021-44228'}) MATCH (cve)<-[:HAS_CVE]-(vuln:Vulnerability) MATCH (vuln)-[:AFFECTS]->(service:Service) MATCH (service)-[:RUNS_ON]->(host:Host) MATCH (host)-[:HOSTS]->(domain:Domain) MATCH (domain)-[:DEPENDS_ON]->(upstream:Service) RETURN domain.name AS target_domain, service.product AS vulnerable_service, upstream.product AS upstream_dependency这条查询会返回所有受Log4j影响的服务,以及它们所依赖的上游服务(如数据库、消息队列),帮你优先加固关键链路。
实操心得:Neo4j Browser 的可视化图谱功能(点击“Graph”按钮)比纯表格更直观。把鼠标悬停在节点上,能看到所有属性;拖拽节点可重新布局;右键节点可“Expand Node”查看直接关系。我习惯先用
MATCH (n:Host) RETURN n LIMIT 20查看整体结构,再针对性写查询,避免盲目遍历。
5. 常见问题与排查技巧实录:从“Docker启动失败”到“Cypher查询超时”的一线解决方案
5.1 Docker相关问题速查表
| 问题现象 | 根本原因 | 解决方案 | 实操验证 |
|---|---|---|---|
docker compose up报错ERROR: failed to solve: rpc error: code = Unknown desc = executor failed running [/bin/sh -c apt-get update] | WSL2中Ubuntu源被墙 | 进入WSL2:wsl -d Ubuntu-22.04,执行sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list | apt-get update无报错即成功 |
pentagi-graph容器反复重启,日志显示Failed to start Neo4j on port 7687 | Neo4j端口被占用(如本地已运行Neo4j Desktop) | netstat -ano | findstr :7687找到PID,taskkill /PID <PID> /F | docker ps显示pentagi-graph状态为Up |
pentagi-ingest容器内nmap命令提示Operation not permitted | Docker默认禁用CAP_NET_RAW | 修改docker-compose.yml,在pentagi-ingest下添加cap_add: ["NET_RAW", "NET_ADMIN"] | docker compose down && up -d后nmap -sn 127.0.0.1成功 |
5.2 Neo4j性能与查询问题排查
问题:Cypher查询MATCH (n) RETURN n LIMIT 100响应慢,浏览器卡死
原因:Neo4j默认对全节点扫描不做索引,大数据量时O(n)遍历极慢。
解决:为高频查询字段建索引。在Neo4j Browser中执行:
CREATE INDEX domain_name_index ON :Domain(name); CREATE INDEX service_port_index ON :Service(port, protocol); CREATE INDEX cve_id_index ON :CVE(id);建索引后,MATCH (d:Domain {name:'example.com'}) RETURN d瞬间返回。
注意:索引需在数据导入前创建,否则建索引过程本身会锁表。Pentagi 的
init-neo4j.sh脚本已内置此步骤,但若你手动导入数据,务必先建索引。
问题:MATCH (h:Host)-[r]->(n) RETURN type(r), count(*)返回空,但确定有关系
原因:Neo4j区分大小写,且节点标签(Label)必须完全匹配。常见错误是把Host写成host或HOST。
解决:先确认节点标签:CALL db.labels();再确认关系类型:CALL db.relationshipTypes();最后用精确匹配查询:MATCH (h:Host)-[r:HOSTS]->(d:Domain) RETURN h, d。
实操心得:我养成的习惯是,每次写新查询前,先用
MATCH (n) RETURN labels(n), keys(n), n LIMIT 1查看一个节点的完整结构,避免猜错属性名。
5.3 Pentagi特有问题:AI Agent规则不生效的3个隐藏原因
- 时间戳校验失败:Pentagi 的AI Agent默认只处理
created_at在24小时内数据,防止重复清洗旧数据。若你导入的是历史扫描结果,需在ingest.py中临时注释掉if (datetime.now() - node['created_at']).total_seconds() > 86400: continue。 - 正则表达式引擎差异:Python的
re模块与JavaScript的RegExp语法略有不同。Pentagi的规则文件rules/normalizer.py中,r'\b(?:www\.)?([^\s]+)\.com\b'这样的写法,在Python中正确,但若你复制到其他环境需验证。 - Neo4j事务超时:AI Agent在批量创建关系时,若单次事务超过30秒(Neo4j默认值),会回滚。解决方案是分批提交:在
ingest.py的create_relationships函数中,将tx.run(...)改为每100条关系tx.commit()一次。
6. 进阶扩展:如何用 Pentagi 构建自己的“红队知识库”,并接入现有安全平台
6.1 从单次测绘到持续知识库:增量同步与版本管理
Pentagi 的设计支持“增量更新”,而非每次都全量重建图谱。关键在于ingest.py的--incremental参数:
# 首次全量导入 docker compose run --rm pentagi-ingest python ingest.py --full --amass amass_v1.txt ... # 后续增量导入(只处理新增/变更的节点) docker compose run --rm pentagi-ingest python ingest.py --incremental --amass amass_v2.txt ...增量模式下,脚本会:
- 计算新旧数据的MD5哈希,只处理变化的文件;
- 对比Neo4j中已有节点的
last_seen属性,若新数据中该节点last_seen更新,则更新属性; - 若节点在新数据中消失,则添加
status: 'inactive'标签,而非删除(保留历史追溯)。
这样,你的Pentagi图谱就变成了一个活的、可审计的资产知识库,每次红队演练的成果都沉淀为组织资产。
6.2 与现有安全平台集成:用 REST API 对接 SIEM 或 SOAR
Pentagi 的pentagi-api服务提供标准REST接口,无需修改核心代码即可集成:
POST /api/v1/ingest:接收JSON格式扫描结果,触发AI Agent清洗与导入;GET /api/v1/graph/path?source=example.com&target=database.internal:调用CyphershortestPath算法,返回攻击路径;GET /api/v1/alerts?risk_score_gte=8.0:获取高危告警列表,可对接SOAR平台自动工单。
例如,在Splunk中添加HTTP Event Collector,配置POST请求到http://localhost:8000/api/v1/ingest,将Nuclei JSON直接转发,实现“扫描即入库”。
个人体会:我在实际红队中,把Pentagi API嵌入到自研的指挥平台里。每次队员提交新发现,平台自动调用
/api/v1/ingest,然后用/api/v1/graph/path实时计算该发现对核心资产的影响半径,生成可视化报告。这比每周开一次“情报同步会”高效太多。
6.3 安全研究员的专属玩法:用 Pentagi 分析CVE的“供应链传播图”
这是Pentagi最被低估的能力。以Log4j为例,你可以在Neo4j中构建这样的图谱:
(:CVE {id:'CVE-2021-44228'})(:Library {name:'log4j-core', version:'2.14.1'})(:Framework {name:'Spring Boot', version:'2.5.0'})(:Application {name:'Customer Portal'})
然后用Cypher查询:
MATCH (cve:CVE {id:'CVE-2021-44228'}) MATCH (cve)<-[:HAS_CVE]-(lib:Library) MATCH (lib)-[:USED_BY]->(fw:Framework) MATCH (fw)-[:DEPLOYED_IN]->(app:Application) RETURN app.name, fw.version, lib.version这不仅能列出所有受影响应用,还能反向推演:如果升级Spring Boot到2.6.0,是否能自动修复Log4j?答案是:MATCH (fw:Framework {name:'Spring Boot', version:'2.6.0'})-[:DEPENDS_ON]->(lib:Library {name:'log4j-core'}) RETURN lib.version—— 结果是2.15.0,说明可以。这种“供应链影响分析”,是传统漏洞扫描器永远做不到的深度。
我在实际操作中发现,Pentagi 的真正门槛不在技术部署,而在于思维转换:从“找漏洞”转向“建认知”。当你习惯用MATCH (a:Asset)-[:VULNERABLE_TO]->(c:CVE) WHERE c.cvss > 9.0替代翻Excel,当你可以用shortestPath((h1:Host)-[*..5]-(h2:Host))一键找出两台服务器间的最短攻击路径,你就已经站在了攻防认知的更高维度。它不会让你成为更好的脚本小子,但会让你成为更清醒的红队指挥者。