CVE-2023-37582 漏洞分析
调试端口
10011 broker
10012 namsrv
漏洞描述
RocketMQ 是一个开源的分布式消息中间件,NameServer 为 Producer 和 Consumer 节点提供路由信息的组件。
由于 CVE-2023-33246 的补丁中并未对 DefaultRequestProcessor#updateConfig 方法中的 configStorePath 属性值进行过滤,当 NameServer 地址暴露在公网并且缺乏权限校验,未经授权的攻击者可 payload 注入到 configStorePath 中,调用 NameServer 的更新配置函数将恶意文件上传到 RocketMQ 服务器中实现远程代码执行。
漏洞影响版本
Apache RocketMQ <= 5.1.1
Apache RocketMQ <= 4.9.6
环境搭建
先 wget 需要的东西
1 | wget https://archive.apache.org/dist/rocketmq/5.1.1/rocketmq-all-5.1.1-bin-release.zip |
然后 Dockerfile
1 | FROM openjdk:8u342-jdk |
docker-compose.yml
1 | version: '2' |
其实这里用之前 CVE-2023-33246 的环境也可以,但是最好是用 4.x 的,下载环境需要一段时间
漏洞复现与分析
这个漏洞本质上是 CVE-2023-33246 的补丁绕过,或者也可以说根本没有做什么防护,先来看 diff
https://github.com/apache/rocketmq/commit/fb1c67d536c95ec7bd5904e61b9d97c4c2ee5a3d
很简单的 diff,只是把 configStorePathName
改成了 configStorePath
上一次在分析 CVE-2023-33246 的时候,我抓过一个流量包,其中的内容就是在 CVE-2023-33246 中的 rocketmq 协议。
拿其中的一段 TCP 流量出来说
1 | {"code":25,"flag":0,"language":"JAVA","opaque":0,"serializeTypeCurrentRPC":"JSON","version":401}filterServerNums=1 |
很显然,目前提取出来的部分应该是 TCP 请求中的一段参数,下个断点分析一下这一段通信过程
通信过程分析
1 | ...c..._{"code":0,"flag":1,"language":"JAVA","opaque":0,"serializeTypeCurrentRPC":"JSON","version":435}...d... |
协议主要包含四部分 协议总长度+ json 长度+ json + body,前后两段的 c、d 对应的是 ascii 码
在这一段 json 数据包当中,比较引人注目的是 "code":25
,不同的 code 代表了不同的业务,根据数据包当中的 code 字段,程序会进行不同的业务处理,处理业务在 org.apache.rocketmq.broker.processor.AdminBrokerProcessor#processRequest
方法中
其中代码块 case RequestCode.UPDATEE_BROKER_CONFIG
提到一个类 RequestCode
,后续会用到
跟进 this.updateBrokerConfig()
方法,方法中先将 body 字段的值提取出来,封装进 Properties
类当中,封装完的结果如图
往下,跟进 this.brokerController.getConfiguration().update()
方法,到第 187 行,循环遍历所有的配置,并根据对应类,更新配置
可以看到,经过这一步之后,里面的值已经是被更新了
程序接着调用 persist()
方法, persist()
方法做的业务其实是将 configObjectList
写入进对应的配置文件当中。
很清晰的是,程序会将配置写入到两个文件中,分别是 filename
和 filename.bak
,其中 filename
的值对应的是 configStorePath
,也是 CVE-2023-33246 的黑名单字段
在整段程序执行结束后可以发现 ../conf/broker.conf
的内容改变了,且 rocketHome 已经被修改为了我们的输入
构造 EXP
既然可以对文件进行修改与写入,根据漏洞描述,修改存储路径为计划任务路径写入 crontab 造成 RCE 即可,因为要写入 crontab,所以涉及到权限问题,其中初始化的 kvConfigPath、configStorePath 带有当前用户,而 kvConfigPath 处于黑名单中,configStorePath 还未被过滤
且攻击目标为 namesrv,brokerConfigPath
是用于存储 broker 组件对应的配置文件的,在 V 5.1.1 当中,brokerConfigPath
是 broker 组件的黑名单
至此就可以构造出 EXP 来写入定时任务 RCE
EXP
1 | import socket |
- 本文标题:CVE-2023-37582 Apache RocketMQ RCE 漏洞分析
- 创建时间:2023-11-21 11:42:50
- 本文链接:2023/11/21/CVE-2023-37582-Apache-RocketMQ-RCE-漏洞分析/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!