Содержание статьи
warning
Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, проводящих тестирование в рамках контракта. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и нарушение тайны переписки преследуются по закону.
CVE-2026-34486 — это критическая уязвимость удаленного выполнения кода (RCE) через десериализацию в модуле Apache Tomcat Tribes. Она позволяет неавторизованному злоумышленнику захватить сервер одним запросом. На деле это регрессия CVE-2026-29146: исправляли одну уязвимость, но создали новую. При этом новую уязвимость легче эксплуатировать. Если в CVE-2026-29146 надо было перехватывать зашифрованные пакеты и методично зондировать сервер, чтобы по его реакции на ошибки паддинга восстановить открытый текст, то в CVE-2026-34486 достаточно отправить один сырой запрос.
Apache Tomcat Tribes — модуль Apache Tomcat для обмена сообщениями между серверами Tomcat, если их несколько. Несколько серверов нужны для балансировки нагрузки в высоконагруженных проектах, когда один сервер не справляется с трафиком. Например, распределенные проекты стараются размещать серверы ближе к пользователям, чтобы сократить время отклика, но есть и другие варианты применения.
В любом случае, если серверов несколько, возникают проблемы с обеспечением целостности данных и бесшовной работы приложения. Если пользователь авторизовался, о сессии должны узнать все серверы. Иначе при переключении пользователю придется авторизовываться снова и снова. Чтобы решить эти проблемы, и нужен Apache Tribes.
Tribes управляет внутренней кухней кластера серверов; его порты недоступны снаружи. Есть три основных сценария атаки:
- Доступ к корпоративной сети. Злоумышленник, например, может взломать компьютер сотрудника или проникнуть в незащищенный Wi-Fi.
- Атака на соседний сервер. Кластер серверов не всегда находится внутри корпоративной среды. В этом случае у хакера есть шанс найти наименее защищенный сервер и использовать его как точку опоры.
- Классическая SSRF (server-side request forgery). Если веб‑приложение уязвимо, хакер может заставить сервер сделать запрос к Tribes и отправить вредоносный пейлоад.
Анатомия уязвимости
При исправлении CVE-2026-29146 разработчики допустили ошибку в классе EncryptInterceptor, который должен был обеспечивать защиту:
@Override public void messageReceived(ChannelMessage msg) { try { byte[] data = msg.getMessage().getBytes(); data = encryptionManager.decrypt(data); XByteBuffer xbb = msg.getMessage(); // Заменяем сообщение на расшифрованное xbb.clear(); xbb.append(data, 0, data.length); } catch (GeneralSecurityException gse) { log.error(sm.getString("encryptInterceptor.decrypt.failed"), gse); } // Десериализация выполнится в любом случае super.messageReceived(msg); }В безопасном коде каждый пакет данных расшифровывает функция encryptionManager. с помощью ключа. Если хакер пришлет сырые данные или данные, зашифрованные неправильным ключом, код упадет с ошибкой BadPaddingException или IllegalBlockSizeException. Выполнение кода прекратится.
Пример безопасного метода messageReceived можно посмотреть в исходниках Tribes версии 9.0.115 — в файле EncryptInterceptor., на строке 142.

В коммите 0112ed22 разработчики вынесли вызов super. за пределы try/. Это логическая ошибка. Хакеру не нужно подбирать ключ шифрования — наоборот, нужно вызвать ошибку расшифровки. Если хакер отправит открытые данные, сервер не упадет, а запишет ошибку в лог и продолжит работу.

Вредоносные байты идут прямиком в компонент GroupChannel, который использует класс XByteBuffer для обработки сообщения. Первый этап обработки — десериализация с помощью XByteBuffer.. Метод запускает стандартный механизм чтения объектов через поток ObjectInputStream.

При десериализации объекта Java автоматически выполняет служебные методы вроде readObject( или hashCode(, которые описаны в классе. Важно понимать, что атакующий не добавляет ничего нового, он только отправляет объект со знакомой серверу структурой. Сервер знает каждый вложенный объект и может сопоставить его с конкретным классом. Классы прописаны в его classpath админами или разработчиками. Часто это классы из Apache Commons Collections или встроенных библиотек JDK. Это общеизвестные наборы классов с хорошо исследованными особенностями и слабыми сторонами.
info
Commons Collections (часть проекта Apache Commons) — библиотека для Java, которая дополняет стандартный Java Collections Framework (JCF). В ней есть новые структуры данных и инструменты для работы с объектами. Например, Trie — древовидная структура данных для быстрого поиска строк по префиксу.
Пейлоад — это цепочка связанных классов (гаджетов), конечная цель которой — вызов опасной функции, например java.. Если описать цепочку гаджетов в виде объекта, такой объект выглядел бы так:
{
"HashSet": {
"HashMap": {
"TiedMapEntry": {
"LazyMap": {
"ChainedTransformer": [
{ "ConstantTransformer": "java.lang.Runtime.class" },
{ "InvokerTransformer": { "method": "getMethod", "args": ["getRuntime"] } },
{ "InvokerTransformer": { "method": "invoke", "args": [] } },
{ "InvokerTransformer": { "method": "exec", "args": ["whoami"] } }
]
}
}
}
}
}
Полная цепочка вызовов на примере Apache Commons Collections:
HashSet.readObject()
HashMap.put(key, ...)
TiedMapEntry.hashCode()
LazyMap.get("poc")
ChainedTransformer.transform()
ConstantTransformer -> Runtime.class
InvokerTransformer -> Runtime.getMethod("getRuntime")
InvokerTransformer -> Runtime.getRuntime()
InvokerTransformer -> runtime.exec(cmd)
Разработчики не всегда используют Commons Collections, это просто популярный набор. Есть и альтернативы: Spring, Groovy, Commons BeanUtils, JDK. Кроме того, версия Commons Collections бывает разной, и для каждой выстраивается своя цепочка. Например, в ysoserial вшито восемь вариаций для этой библиотеки. Задача хакера — подобрать подходящую цепочку гаджетов.
Сборка тестового окружения
Создаем Dockerfile, который установит и настроит уязвимую версию Apache Tomcat 9.0.116:
# Уязвимая версия Apache TomcatFROM tomcat:9.0.116-jdk8RUN mv /usr/local/tomcat/webapps.dist/* /usr/local/tomcat/webapps/
RUN set -ex \ && curl -fSL https://repo1.maven.org/maven2/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar \ -o /usr/local/tomcat/lib/commons-collections-3.2.1.jar
COPY server.xml /usr/local/tomcat/conf/server.xmlОбрати внимание: для теста используем commons-collections-3..
Продолжение доступно только участникам
Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».
Присоединяйся к сообществу «Xakep.ru»!
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
