容器逃逸常用方法
容器逃逸常发生在后渗透阶段中,攻击者通过应用层面漏洞进入容器内,由于容器本身生命周期并不稳定,逃逸到宿主机是必要操作。 本文将从实战角度记录容器逃逸各类操作,
逃逸思路
1. 首先看下容器的攻击面,一共有7个: Docker engine User Code Language VM Libs Seccomp-bpf Namespace Linux Kernel
2. docker架构图如下,其中对普通用户来说,最为熟悉的就是最外层的docker client和docker daemon,一个是docker命令行工具,另一个是dockerd后台进程。containerd则为docker和run的一个沟通
容器逃逸主要有以下方法:
* 配置不当
特权模式运行容器
* 漏洞
操作系统内核漏洞 应用程序漏洞
逃逸方法
特权模式运行容器
特权模式逃逸是一种最简单有效的逃逸方法,攻击者可以通过挂载宿主机目录到容器某个目录下,直接通过命令、写ssh公钥和crontab等getshell。
1.创建容器时通过添加–privileged=true参数,将容器以特权模式起
2.特权模式起的容器,实战可通过cat /proc/self/status |grep Cap命令判断当前容器是否通过特权模式起(000000xfffffffff代表为特权模式起)
3.fdisk -l命令查看宿主机设备为/dev/vda1,通过mount命令将宿主机根目录挂载进容器
4.使用chroot改变根目录,接下来可以直接执行命令或写crontab
容器挂载不当
容器挂载不当导致的逃逸根本原因在于业务需求或使用者图方便把危险目录直接挂载到容器中。 当然,根据使用者挂的目录不同,利用方式肯定也都不同。举一个比较常见的例子:使用者将宿主机/var/run/docker.sock文件挂载到容器中,目的是能在容器中也能操作docker。
1. docker run -itd --name mongo_sock -v /var/run/docker.sock:/var/run/docker.sock mongo:3.6-stretch创建容器并进行挂载
2. 实战中通过find命令,可查找类似docker.sock等高危目录和文件
3. cat /etc/os-release查看当前linux发型版本,准备安装docker客户端,方便操作docker
4. 访问https://download.docker.com/linux/debian/dists/,根据选择具体分支,如stretch就去https://download.docker.com/linux/debian/dists/stretch/pool/stable/amd64/下载.deb结尾的安装文件 使用这种方式安装的好处是容器内一般都缺少很多基础组件,如果通过apt-get安装实测20分钟也装不完
5. docker run -it -v /:/host rabbitmq:3-management-alpine bash命令,随便找个镜像挂载宿主机根目录到容器的/host目录下,之后就可以进行任意操作了
6. 另外看到网上还有人利用procfs通过写/proc/sys/kernel/core_pattern来进行逃逸,但触发条件比较苛刻,需要有进程奔溃才能触发,故实战中不推荐
操作系统内核漏洞
操作系统内核漏洞主要就是利用大脏牛(CVE-2016-5195),依赖于内存页的写时复制机制来逃逸到宿主机,exp链接:https://github.com/scumjr/dirtycow-vdso,不过不是每个linux发行版都通用
应用程序漏洞
目前通过应用程序漏洞逃逸的漏洞主要有两个:
-
CVE-2019-5736(runc)
-
CVE-2020-15257(containerd)
CVE-2019-5736
CVE-2019-5736是runc相关漏洞,该漏洞允许攻击者重写宿主机上的runc 二进制文件,攻击者可以在宿主机上以root身份执行命令。 该漏洞有利用条件,即容器exp执行后,需要受害者在宿主机上通过docker exec命令进入该容器。 影响版本如下:
1. docker version <=18.09.2 runc version <=1.0-rc6 \1. exp链接:https://github.com/Frichetten/CVE-2019-5736-PoC,编译go的main.go文件
2. 实战中可以curl下载,这边直接使用docker cp放入容器,执行./main,受害者执行docker exec -it ubuntu /bin/bash进入容器即触发exp
CVE-2020-15257
containerd 是一个控制 runC 的守护进程,提供命令行客户端和API。当在docker使用–net=host参数启动且与宿主机共享net namespace时,docker容器会暴露containerd-shim 监听的 Unix 域套接字,攻击者可以绕过访问权限访问 containerd 的控制API 直接操作containerd-shim ,来控制容器,从而实现Docker容器逃逸。
1. docker run -itd --net=host ubuntu:16.04以共享主机网络的方式启动容器
2. 从https://github.com/cdk-team/CDK/releases下载最新的exp压缩包到本地,解压后,上传cdk_linux_amd64可执行文件到容器,也可以模拟真实情况,从服务器上下
3. 我这边用的是0.1.8版本,每个版本命令格式有点不一样,./cdk_linux_amd64 run shim-pwn touch testtest在宿主机创建文件,可看到文件成功创建,当然也可以通过wget请求来拿回显,确认是宿主机还是容器发的请求。另外这个工具还支持其他容器相关漏洞,可自行研究。
4. 另外在执行exp时候还遇到了"runc": executable file not found的问题,宿主机上通过安装runc解决:yum -y install buildah
容器渗透常用命令
-
查看当前环境是否为容器 cat /proc/1/cgroup看回显结果中是否有docker(这个方法一般要比ls /.dockerenv要准确,实测有些容器根目录下确实没有.dockerenv)
-
查看容器操作系统详细信息 cat /etc/os-release
-
查看宿主机内核信息 uname -a
-
查看容器内进程的capability grep CapEff /proc/self/status 在其他机器上执行capsh --decode=value查看具体权限,value为前一个命令输出结果
-
查看环境变量 env(环境变量中可能存在敏感信息,如password)
-
危险挂载文件查找,如docker.sock find / -name docker.sock
————————————————
版权声明:本文为CSDN博主「ATpiu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:
- 点赞
- 收藏
- 关注作者
评论(0)