Удаленное выполнение кода при десериализации в Java
От: maxkar  
Дата: 14.12.15 19:46
Оценка: 11 (2)
Всем доброго времени суток.

Сегодня наткнулся на интересную тему. Если Java-приложение использует определенные библиотеки и десериализует объекты из сети, оно подвержено удаленному выполнению кода. При этом уязвимость не имеет никакого отношения к buffer overflow и прочим проблемам в реализации десериализатора.

Подробности: здесь, здесь и здесь.

Для ленивых, тезисно:
1. В Java есть сериализация и десериализация объектов в бинарной форме.
2. Она восстанавливает объекты с правильным (исходным) типом.
3. Этот механизм настраиваем и позволяет типам задавать свои сериализаторы/десериализаторы.
4. В apache-common-collections и некоторых других библиотеках это настройка (кастомизация) выполняет код, пришедший в данных (там не машинный код, а некий аналог байт-кода java, но не принципиально). Да, так было задумано разработчиками.
5. Можно сделать запрос, который выполняет непотребные вещи вроде Runtime.exec("calc.exe") и т.п. Причем запрос можно делать к любому сервису, использующему десериализацию.

Что необычно. Для использования уязвимости не обязательно вызывать "уязвимую библиотеку" в коде. Достаточно наличия ее в classpath (в пути загрузки библиотек). Т.е. был у нас какой-то банальный RPC-сервис, и все было хорошо. Добавили apache-common-collections (даже не используя ее) — уязвимость появилась.

Сопутствующие факторы для уязвимости (полезно при дизайне/использовании своего API):
1. API десериализации. Это ObjectInputStream.readObject(). Нельзя указать целевой класс (т.е. любой сервис с десериализацией уязвим, даже если он ожидает простые и безопасные объекты).
2. Широкий полиморфизм. Т.е. наличие в структуре данных Object[] тоже позволит десериализовывать произвольные объекты (в том числе — и в "уязвимых" классах). Этим часто RPC-подобные сервисы грешат, восстанавливая параметры.
3. Запуск кода из десериализатора (да и вообще чего-то, полученного из сети). Это основная проблема. Другими мерами не лечится.

Ну и немного не по теме. Хочется высказать свое "фи" сборкам библиотек вроде dropwizard, spring boot и подобным "средам быстрого старта". Оно, конечно, позволяет что-то сделать на коленке и запустить. Но вот потом становится сложно. Ни отдельную библиотеку не обновить (не поймешь, используется ли она и что отвалится). Ни аудит нормальный не провести при необходимости. Где там у них список сервисов доступных по-умолчанию? И что вообще сконфигурировано а что — нет. Как вот я должен узнавать, включен у них JMX (одна из уязвимых штук) для удобства разработчиков, или все же нет?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.