CVE-2023-28432 Minio信息泄露导致RCE
source link: https://y4er.com/posts/minio-cve-2023-28432/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
CVE-2023-28432 Minio信息泄露导致RCE
https://github.com/minio/minio/security/advisories/GHSA-6xvq-wj2x-3h3q
这通告把漏洞点都给出来了…
看这篇文章《Docker下MinIO的使用》
docker-compose.yml
version: '3.7'
# starts 4 docker containers running minio server instances. Each
# minio server's web interface will be accessible on the host at port
# 9001 through 9004.
services:
minio1:
image: minio/minio:RELEASE.2020-01-16T22-40-29Z
container_name: minio1
volumes:
- data1-1:/data1
- data1-2:/data2
ports:
- "9001:9000"
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
minio2:
image: minio/minio:RELEASE.2020-01-16T22-40-29Z
container_name: minio2
volumes:
- data2-1:/data1
- data2-2:/data2
ports:
- "9002:9000"
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
minio3:
image: minio/minio:RELEASE.2020-01-16T22-40-29Z
container_name: minio3
volumes:
- data3-1:/data1
- data3-2:/data2
ports:
- "9003:9000"
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
minio4:
image: minio/minio:RELEASE.2020-01-16T22-40-29Z
container_name: minio4
volumes:
- data4-1:/data1
- data4-2:/data2
ports:
- "9004:9000"
environment:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
command: server http://minio{1...4}/data{1...2}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
## By default this config uses default local driver,
## For custom volumes replace with volume driver configuration.
volumes:
data1-1:
data1-2:
data2-1:
data2-2:
data3-1:
data3-2:
data4-1:
data4-2:
docker-compose pull
docker-compose up
http://172.16.16.128:9001/ 到9004端口都是minio集群
根据官方GitHub中的通告 https://github.com/minio/minio/security/advisories/GHSA-6xvq-wj2x-3h3q 可知
在集群部署中,MinIO返回所有环境变量,包括MINIO_SECRET_KEY和MINIO_ROOT_PASSWORD,导致信息泄露。
// 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,
}
}
给出了补丁的commit https://github.com/minio/minio/commit/3b5dbf90468b874e99253d241d16d175c2454077
diff可见增加了敏感字段skip的操作
最终路由映射到 http://172.16.16.128:9001/minio/bootstrap/v1/verify
cmd/routers.go:75 判断了一下是集群才会注册上述路由
curl -XPOST http://172.16.16.128:9001/minio/bootstrap/v1/verify
minio是个go写的项目,go rce的方式不是很多,我的思路是找自更新的点。
在这个commit中 https://github.com/minio/minio/commit/05444a0f6af8389b9bb85280fc31337c556d4300
加了一个二进制文件签名校验
这个函数在cmd/admin-handlers.go ServerUpdateHandler函数中被调用,对应的路由为POST /minio/admin/v3/update?updateURL={updateURL}
有一些版本好像是v2
ServerUpdateHandler函数中经过了几个处理,代码比较长,我贴一下精简之后的。
func (a adminAPIHandlers) ServerUpdateHandler(w http.ResponseWriter, r *http.Request) {
// 验证是否是admin权限
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.ServerUpdateAdminAction)
// 从POST /minio/admin/v3/update?updateURL={updateURL}取updateURL参数
vars := mux.Vars(r)
updateURL := vars["updateURL"]
mode := getMinioMode()
// 解析url
u, err := url.Parse(updateURL)
// 下载Release信息并解析出对应的更新信息
content, err := downloadReleaseURL(u, updateTimeout, mode)
sha256Sum, lrTime, releaseInfo, err := parseReleaseData(content)
// 指定二进制文件的下载路径
u.Path = path.Dir(u.Path) + SlashSeparator + releaseInfo
// 下载二进制文件
reader, err := downloadBinary(u, mode)
// 验证签名
err = verifyBinary(u, sha256Sum, releaseInfo, mode, reader)
// 提交二进制文件
err = commitBinary()
// 发送重启信号给channel
globalServiceSignalCh <- serviceRestart
}
而在verifyBinary中envMinisignPubKey环境变量应该是默认为空,导致签名校验无效。
攻击者可以伪造updateURL来触发恶意自更新来执行任意二进制文件,不过这个动静可能有点大,而且恶意二进制文件应该是针对minio二开的,否则服务可能会挂掉。
最后一点,就是如何使用敏感信息泄露的用户来提权到admin用户。
commit应该是67f4ba154a27a1b06e48bfabda38355a010dfca5 看了下没看懂,先放一放,让子弹飞一会。
r师太吊了,打call。
文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK