“事先声明:本次测试过程完全处于本地或授权环境,仅供学习与参考,不存在未授权测试过程。本文提到的漏洞《MinIO未授权SSRF漏洞(CVE-2021-21287)》已经修复,也请读者勿使用该漏洞进行未授权测试,否则作者不承担任何责任
”
随着工作和生活中的一些环境逐渐往云端迁移,对象存储的需求也逐渐多了起来,MinIO就是一款支持部署在私有云的开源对象存储系统。MinIO完全兼容AWS S3的协议,也支持作为S3的网关,所以在全球被广泛使用,在Github上已有25k星星。
我平时会将一些数据部署在MinIO中,在CI、Dockerfile等地方进行使用。本周就遇到了一个环境,其中发现一个MinIO,其大概情况如下:
MinIO运行在一个小型Docker集群(swarm)中
MinIO开放默认的9000端口,外部可以访问,地址为
http://192.168.227.131:9000
,但是不知道账号密码192.168.227.131
这台主机是CentOS系统,默认防火墙开启,外部只能访问9000端口,dockerd监听在内网的2375端口(其实这也是一个swarm管理节点,swarm监听在2377端口)
本次测试目标就是窃取MinIO中的数据,或者直接拿下。
0x01 MinIO代码审计
既然我们选择了从MinIO入手,那么先了解一下MinIO。其实我前面也说了,因为平时用到MinIO的时候很多,所以这一步可以省略了。其使用Go开发,提供HTTP接口,而且还提供了一个前端页面,名为“MinIO Browser”。当然,前端页面就是一个登陆接口,不知道口令无法登录。
那么从入口点(前端接口)开始对其进行代码审计吧。
在User-Agent满足正则.*Mozilla.*
的情况下,我们即可访问MinIO的前端接口,前端接口是一个自己实现的JsonRPC:
![](https://i-blog.csdnimg.cn/blog_migrate/da1c657cf4e2b68b3815c2ee98444863.png)
我们感兴趣的就是其鉴权的方法,随便找到一个RPC方法,可见其开头调用了webRequestAuthenticate
,跟进看一下,发现这里用的是jwt鉴权:
![](https://i-blog.csdnimg.cn/blog_migrate/08742d12dcab0901e548d1e616356cbe.png)
jwt常见的攻击方法主要有下面这几种:
将alg设置为None,告诉服务器不进行签名校验
如果alg为RSA,可以尝试修改为HS256,即告诉服务器使用公钥进行签名的校验
爆破签名密钥
查看MinIO的JWT模块,发现其中对alg进行了校验,只允许以下三种签名方法:
![](https://i-blog.csdnimg.cn/blog_migrate/fca72755895dfc2743874680d65097f2.png)
这就堵死了前两种绕过方法,爆破当然就更别说了,通常仅作为没办法的情况下的手段。当然,MinIO中使用用户的密码作为签名的密钥,这个其实会让爆破变的简单一些。
鉴权这块没啥突破,我们就可以看看,有哪些RPC接口没有进行权限验证。
很快找到了一个接口,