Apache Tomcat RCE (CVE-2020-9484) - Райтап и Эксплойт

Apache Tomcat RCE (CVE-2020-9484) - Райтап и Эксплойт

Moody

Пару дней назад была обнаружена новая уязвимость удаленного выполнения кода для Apache Tomcat. Уязвимые версии:

  • Apache Tomcat 10.x <10.0.0-M5
  • Apache Tomcat 9.x <9.0.35
  • Apache Tomcat 8.x <8.5.55
  • Apache Tomcat 7.x <7.0.104

Иными словами, все версии tomcat 7, 8, 9 и 10, выпущенные до апреля 2020 года.

Обновитесь как можно быстрее, чтобы избежать плохих последствий.

Предпосылки

Существует ряд предпосылок для использования этой уязвимости.

  1. PersistentManager включен и использует FileStore
  2. Злоумышленник может загрузить файл с произвольным содержимым, контролировать его имя и знать, куда он был загружен.
  3. В пути к classpath есть библиотеки, которые можно использовать для атак, связанных с десериализацией Java-объектов

Tomcat PersistentManager

Сначала несколько слов о PersistentManager. Tomcat использует слово «Manager» для описания компонента, который выполняет управление сеансом. Сеансы используются для сохранения состояния между клиентскими запросами. На то, как они будут храниться, влияют несколько факторов:

  • Где хранится информация о сеансе? В памяти или на диске?
  • В каком виде она хранится? JSON, сериализованный объект и т. д.
  • Как генерируются идентификаторы сессий?
  • Какие атрибуты сеансов мы хотим сохранить?

Tomcat предоставляет две реализации, которые можно использовать:

  • org.apache.catalina.session.StandardManager (по умолчанию)
  • org.apache.catalina.session.PersistentManager

StandardManager будет хранить сессии в памяти. Если tomcat правильно настроен, он будет хранить сеансы в сериализованном объекте на диске (по умолчанию «SESSIONS.ser»).

PersistentManager делает то же самое, но с небольшим дополнением: замена пустых сессий. Если сеанс простаивал в течение x секунд, он будет выгружен на диск. Такой способ используется, чтобы уменьшить потребление оперативной памяти.

Вы можете указать, где и как будут сохраняться сеансы обмена. Tomcat предлагает два варианта:

  • FileStore: укажите каталог на диске, где каждый сеанс будет храниться в виде файла с именем на основе идентификатора сеанса.
  • JDBCStore: укажите таблицу в базе данных, где каждый сеанс будет храниться как отдельная строка

Конфигурация

По умолчанию tomcat работает с включенным StandardManager. Администратор может настроить использование PersistentManager вместо StandardManager, изменив conf/context.xml:

<Manager className="org.apache.catalina.session.PersistentManager"
         maxIdleSwap="15">  
  <Store className="org.apache.catalina.session.FileStore"
         directory="./session/" />
</Manager>  

Пока в context.xml не записан тег Manager, будет использоваться StandardManager.

Эксплойт

Когда Tomcat получает HTTP-запрос с cookie-файлом JSESSIONID, он обращается к Manager, чтобы узнать, существует ли данный сеанс. Так как злоумышленник может контролировать значение, отправленное в запросе, что произойдет, если он введет что-нибудь, вроде «../../../../../../tmp/12345»?

  1. Tomcat попросит Manager проверить, существует ли сеанс с идентификатором «../../../../../../tmp/12345»
  2. Тот, в свою очередь, сначала проверит, находится ли этот сеанс в памяти.
  3. Если он не находит сеанс в памяти, но при этом работает как PersistentManager, то после поиска в оперативной памяти, Manager проверит наличие сеанса на диске.
  4. Он проверит следующую директорию directory + sessionid + ".session", которая при ранее отправленных параметрах, будет иметь значение «./session/../../../../../../tmp/12345.session«
  5. Если файл существует, он будет десериализован и из него будет получена информация о сеансе.
Веб-приложение возвращает ошибку HTTP 500 при эксплуатации, поскольку обнаруживает вредоносный сериализованный объект вместо того объекта, который содержит ожидаемую информацию о сеансе.

Из строки в трассировке стека, отмеченной красным, мы видим, что PersistentManager пытается загрузить сеанс из FileStore. Синяя линия показывает, что он пытается десериализовать объект. Ошибка появляется после успешной десериализации, но при попытке интерпретировать объект как сеанс (который им не является). На этом этапе вредоносный код уже был выполнен.

Все, что остается для использования этой уязвимости, - это то, чтобы злоумышленник поместил вредоносный сериализованный объект (т. е. сгенерированный ysoserial) в папку /tmp/12345.session.

Создавать эксплойт не имеет особого смысла, так как это всего лишь один HTTP-запрос. Однако на Github есть краткий PoC, опубликованный masahiro311.

Вывод

Эта атака несет за собой большую угрозу (RCE), но условия, которые должны быть выполнены, делают вероятность эксплуатации низкой.

  • PersistentManager должен быть включен вручную администратором tomcat. Это может произойти только на веб-сайтах с высокой нагрузкой (но не слишком высокой, поскольку более вероятно, что вместо File Store будет использоваться JDBC Store).
  • Злоумышленник должен найти отдельную уязвимость загрузки небезопасных файлов, чтобы разместить вредоносный сериализованный файл на сервере.
  • На пути к classpath должны быть библиотеки, уязвимые для атак, связанных с десериализацией Java-объектов.

Тем не менее, был затронут большой диапазон версий Tomcat.


Прочитать оригинал этого материала на английском можно здесь.

Cybred - канал об информационной безопасности и конкурентной разведке, вдохновленный идеями олдскульных андеграундных интернет-сообществ о свободе распространения информации в сети и всеобщей взаимопомощи.

Report Page