runc 容器逃逸原理

1. 竞争条件

这是 runc 容器逃逸中一种经典的利用方式。以 CVE-2019-5736 为例,其核心原理是:

  • 进程切换和文件句柄劫持:当我们在宿主机上执行 docker exec 等命令时,实际上 runc 会在容器内启动一个新的进程。在 runc 启动这个新进程到真正执行用户指定命令的这段极短的时间内,存在一个“窗口期”
  • 恶意代码的快速覆盖:攻击者可以在容器内通过一个精心设计的恶意程序,持续地监控并尝试以写权限打开 runc 进程的文件句柄(/proc/self/exe)。一旦 runc 进程完成了权限降级,文件句柄被释放但尚未关闭,攻击者的恶意程序就会立即抢占这个句柄,并向宿主机上的 runc 二进制文件写入恶意 payload
  • 获得宿主机 root 权限:当 runc 尝试执行后续命令时,它执行的不再是正常的二进制文件,而是已经被篡改的恶意代码。因为 runc 本身是以 root 权限在宿主机上运行的,所以攻击者就成功地以 root 权限执行了任意命令,实现了容器逃逸

2. 特权模式与危险配置

虽然这不是 runc 自身的漏洞,但它是最常见的容器逃逸方式之一,常常与 runc 的使用有关

  • 特权容器(Privileged Container):如果一个容器被以特权模式启动(docker run --privileged),它将获得几乎所有宿主机的 root 能力。这种模式下,容器内的进程可以访问宿主机上的所有设备、挂载宿主机的文件系统,甚至可以操纵内核模块。攻击者可以轻易地通过挂载宿主机根目录并使用 chroot 命令切换根目录,从而完全控制宿主机
  • Docker Socket 挂载:另一种常见配置错误是直接将 /var/run/docker.sock(Docker 守护进程的 Unix Socket)挂载到容器内部。这样做的后果是,容器内的进程可以直接与 Docker 守护进程通信,相当于拥有了在宿主机上创建、运行、停止任何容器的权限。攻击者可以利用这个权限创建另一个特权容器,将宿主机根目录挂载进去,然后轻松实现逃逸

3. 文件描述符泄漏与符号链接

最近的漏洞,如 CVE-2024-21626,则利用了另一种机制:

  • 工作目录和文件描述符:这个漏洞是由于 runc 在处理容器进程的启动和工作目录时存在缺陷。攻击者可以利用 /proc/self/fd/ 这个特殊目录,通过设置容器的工作目录或创建符号链接,来访问本不应该被容器访问到的宿主机文件描述符
  • 突破命名空间隔离:容器通过命名空间(Namespaces)机制来隔离文件系统、进程、网络等资源。但是,如果攻击者可以找到一种方式,让容器内的进程能够操作宿主机上的文件句柄,那么就可以绕过这些命名空间的隔离,从而读写宿主机上的任意文件,最终实现逃逸
Copyright © 版权信息 all right reserved,powered by Gitbook该文件修订时间: 2025-09-25 03:13:19

results matching ""

    No results matching ""