让 AI 接管 Kali:在 macOS 上构建 OpenClaw 渗透测试沙盒全记录
当大模型不再只是聊天机器人,而是能亲手操控 Nmap、Metasploit 这些黑客工具时,会发生什么?
这篇文章记录了我在 macOS(Apple Silicon)上从零搭建一个 OpenClaw + Kali Linux 沙盒的完整过程——包括每一个踩过的坑和最终的解决方案。最终目标是让 AI 代理通过结构化的工具链,自主完成网络侦察、漏洞分析甚至深度渗透任务,同时保持零幻觉的数据精度。
整体架构
核心逻辑很简单:用 kali-rolling 作为基础镜像打底,注入 Node.js 22 运行环境,并通过 AgentSkills 规范的 Markdown 文件将 Kali 的二进制工具直接暴露给 AI 代理。
整个系统分为三层:
- 底层:Docker 容器中的 Kali Linux + 安全工具链
- 中间层:Python 解析器(手写的数据清洗中间件)
- 上层:OpenClaw 代理通过 Skill 文件调度工具、做出决策
┌─────────────────────────────────────────────────────────────────────┐
│ macOS (Host) │
│ │
│ ┌───────────┐ ┌──────────────────────────────────────────┐ │
│ │ Browser │ :18789 │ Docker Container (kali-rolling) │ │
│ │ ─┼────────►│ │ │
│ │ localhost │ │ ┌────────┐ ┌─────────────────┐ │ │
│ └───────────┘ │ │ socat │ :18790 │ OpenClaw Gateway│ │ │
│ │ │0.0.0.0 ┼───────►│ 127.0.0.1:18789│ │ │
│ │ └────────┘ └────────┬────────┘ │ │
│ │ │ │ │
│ │ ┌──────────────▼──────────┐ │ │
│ │ │ AgentSkills Engine │ │ │
│ │ │ ┌─────────────────┐ │ │ │
│ │ │ │ SKILL.md Files │ │ │ │
│ │ │ │ (nmap_pro ...) │ │ │ │
│ │ │ └────────┬────────┘ │ │ │
│ │ └───────────┼────────────┘ │ │
│ │ │ │ │
│ │ ┌──────────────▼────────────┐ │ │
│ │ │ Python Parsers (中间件) │ │ │
│ │ │ nmap_parser.py │ │ │
│ │ │ sqlmap_parser.py │ │ │
│ │ │ XML/stdout → JSON │ │ │
│ │ └──────────────┬────────────┘ │ │
│ │ │ │ │
│ │ ┌──────────────▼────────────┐ │ │
│ │ │ Kali Toolchain (武器库) │ │ │
│ │ │ nmap searchsploit msf │ │ │
│ │ │ gobuster hydra sqlmap │ │ │
│ │ └───────────────────────────┘ │ │
│ │ │ │
│ ┌───────────┐ │ [cpus: 2.0 | memory: 4G | bridge net] │ │
│ │ workspace/ │◄────────┤ Volume Mounts │ │
│ │ (reports) │ │ │ │
│ └───────────┘ └──────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
第一步:构建底层环境
我们需要一个干净且包含渗透工具的自定义镜像。OpenClaw 依赖 Node.js 22+ 运行。
# 使用 Kali 官方滚动更新镜像(原生支持 ARM64/Apple Silicon)
FROM kalilinux/kali-rolling
# 安装核心安全工具包与依赖
RUN apt-get update && apt-get install -y --no-install-recommends \
nmap \
metasploit-framework \
exploitdb \
python3 \
python3-pip \
curl \
git \
ca-certificates \
socat \
&& rm -rf /var/lib/apt/lists/*
# 安装 Node.js 22.x(OpenClaw 运行刚需)
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y nodejs
# 全局安装 OpenClaw
RUN npm install -g openclaw@latest
# 初始化工作目录与技能存放目录
WORKDIR /workspace
RUN mkdir -p /root/.openclaw/skills
# 启动 OpenClaw Gateway 服务
CMD ["openclaw", "gateway", "--port", "18789"]
注意这里我直接把 socat 也装进去了——后面你会知道为什么。
第二步:Docker Compose 编排与资源熔断
为了防止 OpenClaw 陷入逻辑死循环耗尽 Mac 资源(Token 燃烧和内存溢出),必须在编排文件里加上严格的 Cgroups 限制。
services:
openclaw-pentest:
build: .
container_name: openclaw-kali-sandbox
command: >
sh -c "openclaw gateway --port 18789 --allow-unconfigured &
socat TCP-LISTEN:18790,fork,bind=0.0.0.0 TCP:127.0.0.1:18789"
ports:
- "18789:18790"
volumes:
- ./workspace:/workspace
- ./custom_skills:/root/.openclaw/skills
- ~/.config/openclaw_kali:/root/.openclaw/config
deploy:
resources:
limits:
cpus: '2.0'
memory: 4G
networks:
- pentest-net
restart: unless-stopped
networks:
pentest-net:
driver: bridge
这里有个关键的设计:command 里同时启动了 OpenClaw 和 socat。为什么?
第三步:用 socat 暴力打通网络
拉起容器后,浏览器访问 http://localhost:18789 却是白屏。排查发现,OpenClaw 的 Gateway 服务把监听地址硬编码绑死在了 127.0.0.1——这意味着它只接受容器内部的请求,Docker 的端口映射根本穿不透。
翻了配置文件也找不到修改 host 的选项后,我选择了最稳妥的方案:用 socat 在网络层做桥接。
原理很简单:让 socat 监听容器的 0.0.0.0:18790(对外开放),把所有流量原封不动地转发给 127.0.0.1:18789(OpenClaw 绑死的地址)。Mac 的 Docker 端口映射则把宿主机的 18789 映射到容器的 18790。
Mac 浏览器 :18789 → Docker → 容器 :18790 (socat) → 127.0.0.1:18789 (OpenClaw)
重新构建并拉起:
docker compose up -d --build --force-recreate

页面终于弹出来了!但迎面就是一条红色报错:unauthorized: gateway token missing。
第四步:找到网关令牌
红条报错是标准的安全机制——前端需要一个 Token 才能合法地给后台下指令。
查看容器启动日志:
docker logs openclaw-kali-sandbox
日志里有一句 Generated a new token and saved it to config。顺着线索找到了配置文件的真正位置:
cat /root/.openclaw/openclaw.json
里面躺着那串随机生成的 Token。复制它,在 OpenClaw 网页端的 Settings → Config 中填入 Gateway Token 并保存。
刷新页面,右上角从红色的 Health Offline 变成了绿色的 Health OK。
第五步:拆掉一个隐藏的"定时炸弹"
拿到控制权后,我迫不及待地在 Chat 界面发出第一条指令:whoami。结果后台疯狂报错,提示找不到 Anthropic API Key——但我明明配置的是 OpenAI 的 GPT-4o。
经过排查,真凶是一个叫 session-memory 的内置钩子。它的作用是给聊天会话自动起名字,但硬编码调用了 Anthropic 模型。即便主模型是 GPT-4o,这个后台小动作也会因为缺少 Anthropic 的 Key 而把整个进程卡死。
解决方案:直接禁用它。
openclaw hooks disable session-memory
重启容器后,再用官方向导重新配置认证:
openclaw onboard --auth-choice openai-api-key
如果不确定当前的密钥状态,可以用"体检"命令一键诊断:
openclaw status --all
第六步:Hello World —— 首次接管成功
一切就绪后,回到 Chat 界面:
"帮我执行
whoami和ip a,看看你现在的系统权限和网络 IP。"
Agent 返回:root。
ip a 报错了,原因很简单——Kali 的精简 Docker 镜像没装 iproute2。让 Agent 自己修复:
执行 apt-get update && apt-get install -y iproute2 net-tools
装完后再跑 ip a,顺利拿到了 172.x.x.x 的容器内网 IP。底层通信与身份鉴权的闭环彻底打通了。
第七步:防幻觉工程 —— Nmap 结构化解析器
AI 能执行命令了,但直接让大模型读 Nmap 那上百行的原生输出,不仅容易产生幻觉,还会疯狂烧 Token。
解决方案:禁止 Agent 直接读取原生输出,强制通过 Python 解析器获取结构化数据。
编写解析器 /workspace/nmap_parser.py
import xml.etree.ElementTree as ET
import sys
import json
def parse_nmap_xml(xml_file):
try:
tree = ET.parse(xml_file)
root = tree.getroot()
results = []
for host in root.findall('host'):
ip = host.find('address').get('addr')
status = host.find('status').get('state')
ports = []
for port in host.findall('.//port'):
p_id = port.get('portid')
state = port.find('state').get('state')
service = port.find('service')
svc_name = service.get('name') if service is not None else "unknown"
ports.append({"port": p_id, "state": state, "service": svc_name})
results.append({"ip": ip, "status": status, "ports": ports})
return json.dumps(results, indent=2)
except Exception as e:
return json.dumps({"error": str(e)})
if __name__ == "__main__":
if len(sys.argv) > 1:
print(parse_nmap_xml(sys.argv[1]))
它做的事情很简单:把 Nmap 输出的 XML 压缩成只包含 IP、端口、状态和服务名称的干净 JSON。几千行的扫描结果变成几十个字符,信噪比直接拉满。
第八步:注入自定义 Skill —— 踩坑与通关
OpenClaw 采用 Anthropic 主导的 AgentSkills 规范。通过带 Frontmatter 的 Markdown 文件,告诉 Agent 有哪些工具可用以及调用规则。
第一次尝试(失败)
我按照直觉创建了 custom_skills/nmap_pro.md,但 openclaw skills check 显示 Total: 51——全是内置技能,自定义文件完全没被识别。
三个隐形坑
排查后发现 2026.2.22 版本有几个严格限制:
- 文件命名:每个技能必须是独立文件夹,主控文件必须全大写命名为
SKILL.md - 目录层级:全局技能路径是
~/.openclaw/skills/,不是随便放 - YAML 引号:
description字段如果不加双引号且包含特殊字符,解析引擎会静默跳过
正确的姿势
# 创建符合规范的目录结构
mkdir -p /root/.openclaw/skills/nmap_pro/
然后写入 SKILL.md:
---
name: nmap_pro
description: "Professional Nmap scanning skill with structured output for AI parsing."
metadata:
openclaw:
requires:
bins: ["nmap", "python3"]
---
# Nmap Pro Skill
You are a reconnaissance specialist. Use Nmap to audit the target network.
## Protocol:
1. **Scan**: Run `nmap -sV -T4 -oX /workspace/scan_temp.xml <TARGET>`.
2. **Parse**: Run `python3 /workspace/nmap_parser.py /workspace/scan_temp.xml`.
3. **Output**: Return ONLY the JSON output. Any verbal summary is strictly forbidden.
## Security Rule:
- Only scan IP addresses or domains explicitly provided by the user.
修复权限后再次检查:
chmod -R 755 /root/.openclaw/skills/
openclaw skills check
Total: 52,nmap_pro 稳稳出现在 Ready to use 列表里。
第九步:首次结构化扫描 —— 数据闭环验证
回到 Chat 界面,发出指令:
"使用 nmap_pro 技能扫描本地网关 172.17.0.1,禁止任何文字解释,直接输出 Python 解析器生成的原始 JSON 代码块。"
Agent 先执行了 nmap -sV -T4 -oX /workspace/scan_temp.xml 172.17.0.1,紧接着调用 python3 /workspace/nmap_parser.py /workspace/scan_temp.xml,最后返回了一段干净整齐的 JSON:
[
{
"ip": "172.17.0.1",
"status": "up",
"ports": [
{"port": "111", "state": "open", "service": "rpcbind"}
]
}
]
三个闭环全部验证通过:
- 二进制工具执行:Agent 能正确驱动 Kali 内的
nmap - 中间件解析:Python 脚本成功介入,把 XML 压缩为高价值 JSON
- 零幻觉反馈:强制 JSON 输出彻底杜绝了模型对复杂网络报告的胡言乱语
进阶:可以接管的完整武器库
Nmap 只是 Hello World。沿着攻击链(Kill Chain),Kali 的工具库可以封装成多个维度的 Skill:
Web 漏洞挖掘(Gobuster + SQLmap)
让 Agent 先用 gobuster 做目录爆破,发现带参数的敏感路径后,联动 sqlmap 进行注入测试。
关键工程细节:sqlmap 的控制台输出是海量的字符雨,直接扔给大模型会引发严重幻觉并瞬间烧干 Token。正确做法是写 Python 包装器解析 SQLmap 的 JSON 报告,只提取存在漏洞的参数和 Payload,然后限制 Agent 只能调用包装器,不能直接调用原生工具。
---
name: advanced_web_exploitation
description: "Skill for web directory discovery and SQL injection testing."
metadata:
openclaw:
requires:
bins: ["gobuster", "python3"]
files: ["/workspace/tools/sqlmap_parser.py"]
---
# Web Exploitation Skill
## Tools Available:
1. **Gobuster**: `gobuster dir -u <TARGET> -w /usr/share/wordlists/dirb/common.txt -q`
2. **SQLmap (Via Python Wrapper)**: You CANNOT run sqlmap directly.
- Command: `python3 /workspace/tools/sqlmap_parser.py --target <URL>`
- Returns a clean JSON summary of vulnerable parameters.
密码爆破(Hydra + Hashcat)
AI 在字典生成上有得天独厚的优势——可以根据目标企业的域名、员工姓名缩写、成立年份等信息,实时生成高针对性的专属字典,再联动 Hydra 进行精准爆破。
终极杀器:Metasploit RPC 接管
接管 Metasploit 有两种方案:
- 资源脚本驱动:让 Agent 根据扫描结果自动编写
.rc脚本,然后执行msfconsole -r exploit.rc - RPC 接口直连:通过
pymetasploit3与 MSF 的msgrpc服务建立 API 通信,Agent 甚至可以在拿到 Meterpreter Shell 后继续执行后渗透命令
全托管接管工程路线图
整个工程分为五期:
| 阶段 | 核心目标 | 关键交付 |
|---|---|---|
| 第一期 | 基础设施与信息收集 | Docker 沙盒、Nmap/Gobuster 解析器、资产状态机 |
| 第二期 | 漏洞研判与 RAG 增强 | 本地向量数据库、CVE 语义检索、动态 Payload 验证 |
| 第三期 | Metasploit RPC 接管 | MSF 桥接器、JSON 指令映射、会话管理 |
| 第四期 | 后渗透与横向移动 | Meterpreter 封装、自动提权、敏感数据隔离 |
| 第五期 | 全自动对抗 | 本地模型部署、指令校验审查、多智能体协同 |
从第一期的工具调用,到第五期的多智能体协同攻防,这条路线将传统安全工具链与现代 AI 系统架构深度结合。
踩坑总结
回顾整个搭建过程,几个最关键的经验教训:
- 网络绑死问题:容器内服务绑定
127.0.0.1是常见坑,socat是最通用的桥接方案 - 硬编码钩子:OpenClaw 的
session-memory钩子会绕过主模型配置偷偷调用 Anthropic,必须手动禁用 - Skill 文件规范:2026 版要求
SKILL.md全大写命名 + 独立文件夹 + YAML 双引号,三者缺一不可 - 防幻觉架构:永远不要让大模型直接读取工具的原生输出——用 Python 解析器做中间件,只喂结构化 JSON
这种"AI 负责高层逻辑决策 + 自定义代码负责底层数据解析"的架构,才是在安全领域落地 AI Agent 的正确姿势。Agent 不需要理解 XML 的每一行,它只需要看到干净的 JSON,然后做出下一步决策。
openclaw-kali-sandbox/
├── Dockerfile # Kali + Node.js + socat 基础镜像
├── docker-compose.yml # 资源限制 + socat 端口桥接 + Volume 挂载
│
├── custom_skills/ # 自定义 Skill 目录 (挂载到容器内)
│ ├── nmap_pro/
│ │ └── SKILL.md # Nmap 结构化扫描技能
│ ├── kali_recon/
│ │ └── SKILL.md # 综合侦察技能 (Nmap + SearchSploit)
│ └── web_exploit/
│ └── SKILL.md # Web 渗透技能 (Gobuster + SQLmap Wrapper)
│
├── workspace/ # 共享工作区 (扫描报告 + 解析脚本)
│ ├── nmap_parser.py # Nmap XML → JSON 解析器
│ ├── tools/
│ │ └── sqlmap_parser.py # SQLmap 输出清洗包装器
│ ├── scan_temp.xml # Nmap 原始扫描输出 (临时)
│ └── recon_report.md # Agent 生成的结构化报告
│
└── ~/.config/openclaw_kali/ # 持久化配置 (API Key + Token)
└── openclaw.json
