Docker安全

img

Docker攻击面

容器一共有7个攻击面:Linux Kernel、Namespace/Cgroups/Aufs、Seccomp-bpf、Libs、Language VM、User Code、Container(Docker) engine

以容器逃逸为风险模型,提炼出3个攻击面:

1. Linux内核漏洞

2. 容器自身

3. 不安全部署(配置)

1. Linux内核漏洞

容器的内核与宿主内核共享,使用Namespace与Cgroups这两项技术使容器内的资源与宿主机隔离,所以Linux内核产生的漏洞能导致容器逃逸

攻击样例说明:

vDSO(Virtual Dynamic Shared Object)是内核为了减少内核与用户空间频繁切换,提高系统调用效率而设计的机制。它同时映射在内核空间以及每一个进程的虚拟内存中,包括那些以root权限运行的进程。通过调用那些不需要上下文切换(context switching)的系统调用可以加快这一步骤(定位vDSO)。vDSO在用户空间(userspace)映射为R/X,而在内核空间(kernelspace)则为R/W。这允许我们在内核空间修改它,接着在用户空间执行。又因为容器与宿主机内核共享,所以可以直接使用这项技术逃逸容器。

利用步骤如下:

1.获取vDSO地址,在新版的glibc中可以直接调用getauxval()函数获取。

2.通过vDSO地址找到clock_gettime()函数地址,检查是否可以hijack。

3.创建监听socket。

4.触发漏洞,Dirty CoW是由于内核内存管理系统实现CoW时产生的漏洞。通过条件竞争,把握好在恰当的时机,利用CoW的特性可以将文件的read-only映射为write。子进程不停的检查是否成功写入。父进程创建二个线程,ptrace_thread线程向vDSO写入shellcode。

madvise_thread线程释放vDSO映射空间,影响ptrace_thread线程CoW的过程,产生条件竞争,当条件触发就能写入成功。

5.执行shellcode,等待从宿主机返回root shell,成功后恢复vDSO原始数据。

2. 容器自身

docker架构图:

img

Docker本身由docker(docker client)dockerd(docker daemon)组成。但从Docker 1.11开始,Docker不再是简单的通过docker dameon来启动,而是集成许多组件,包括containerdrunc等等。

Docker client是docker的客户端程序,用于将用户请求发送给dockerd。dockerd实际调用的是containerdapi接口,containerd是dockerdrunc之间的一个中间交流组件,主要负责容器运行、镜像管理等。containerd向上为dockerd提供了gRPC接口,使得dockerd屏蔽下面的结构变化,确保原有接口向下兼容;向下,通过containerd-shimrunc结合创建及运行容器。

CVE-2019-5736

runc – container breakout vulnerability:runc在使用文件系统描述符时存在漏洞,该漏洞可导致特权容器被利用,造成容器逃逸以及访问宿主机文件系统;攻击者也可以使用恶意镜像,或修改运行中的容器内的配置来利用此漏洞。

漏洞简介

runc是一个根据OCI(Open Container Initiative)标准创建并运行容器的CLI tool,目前Docker、Containerd和CRI-O等容器都运行在runc之上。

该漏洞允许恶意容器(以最少的用户交互)覆盖主机上的runc二进制文件,从而获得root权限在主机上执行代码。
漏洞可能影响通过受影响版本Docker部署的应用、虚拟主机、云服务器。K8s集群,含有受影响runc版本的Linux发行版等。

该漏洞允许恶意容器(以最少的用户交互)覆盖主机runc二进制文件,从而在主机上以root级别执行代码。

CVE-2019-14271

漏洞简介

docker cp命令使用了docker-tar辅助程序,该程序会以宿主机的root权限加载容器的libnss库,只要攻击者可以攻破容器,构造恶意的libnss库,就能逃逸容器获取宿主机root权限。

3. 不安全部署(配置)

在实际中,经常会遇到这种状况:不同的业务会根据自身业务需求有自己的一套配置,而这套配置并未得到有效的管控审计,使得内部环境变的复杂多样,无形之中又增加了许多风险点。譬如,最常见的:

  • 特权容器或者以root权限运行容器。

  • 不合理的Capability配置(权限过大的Capability)

特权模式

特权模式于版本0.6时被引入Docker,允许容器内的root拥有外部物理机root权限,而此前容器内root用户仅拥有外部物理机普通用户权限。

使用特权模式启动容器,可以获取大量设备文件访问权限。因为当管理员执行docker run --privileged时,Docker容器将被允许访问主机上的所有设备,并可以执行mount命令进行挂载。

这种容器适于运行系统管理类的任务,它除了维护自己的文件系统和网络的隔离性外,*能全权访问主机的共享内存、设备、所有的 capability *等。

img

查找特权容器命令:

1
docker ps --quiet -a | xargs docker inspect --format='{{.Id}} {{.Name}} {{.HostConfig.Privileged}}'

Docker安全加固

对于安全实施准则,我们将其分为三个阶段:

1.攻击前:裁剪攻击面,减少对外暴露的攻击面(本文涉及的场景关键词:隔离)。

2.攻击时:降低攻击成功率(本文涉及的场景关键词:加固)。

3.攻击后:减少攻击成功后攻击者所能获取的有价值的信息、数据以及增加留后门难度等。

参考:

https://www.atjiang.com/limiting-risk-with-isolation-in-docker/

https://zhuanlan.zhihu.com/p/43586159