Во фреймворке Apache Struts 2, виновном в утечке данных у Equifax, нашли очередную дыру. Она позволяет злоумышленнику, не имея никаких прав в системе, выполнить произвольный код от имени того пользователя, от которого запущен веб-сервер. Давай посмотрим, как эксплуатируется эта уязвимость.

INFO

В 2017 году мы рассмотрели две уязвимости в Struts 2, обе из которых приводили к выполнению произвольного кода в системе. Одна была связана с реализацией REST API, а другая как раз с парсингом языка OGNL (кстати, именно она и подвела Equifax).

Баг обнаружил исследователь Мань Юэ Мо (Man Yue Mo) из Semmle Security Research team 10 апреля 2018 года. Под угрозой оказались все версии фреймворка до 2.3.34 и 2.5.16 включительно. Атакующий может внедрить собственный namespace в приложение с помощью параметра в HTTP-запросе. При этом он никак не фильтруется приложением Struts и может быть произвольной строкой, которая затем попадает в парсер языковых конструкций OGNL (Object-Graph Navigation Language). А это прямая дорога к RCE.

Уязвимость получила внутренний идентификатор S2-057 (CVE-2018-11776) и статус критической. Давай разбираться, какие промахи допустили разработчики на этот раз.

 

Стенд

Один из немногих случаев, когда поднятие стенда на Java не представляет никаких проблем. В качестве веб-сервера я буду использовать Apache Tomcat версии 8.5.20 для Windows. Фреймворк возьму последней уязвимой версии ветки 2.3 — 2.3.34. Скачать ее можно с официального сервера архивных версий.

В архиве нас будет интересовать только файл struts2-showcase.war из папки apps. По сути, это тот же архив в формате ZIP. Просто распакуй его в директорию webapps/struts2-showcase.

Это почти все приготовления. Осталось только создать комфортные условия для тестирования уязвимости. Для этого отредактируем содержимое файла struts-actionchaining.xml из директории struts2-showcase/WEB-INF/classes.

/webapps/struts2-showcase/WEB-INF/classes/struts-actionchaining.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
  "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
  "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
  <package name="actionchaining" extends="struts-default">
    <action name="actionChain1" class="org.apache.struts2.showcase.actionchaining.ActionChain1">
      <result type="redirectAction">
        <param name = "actionName">comehere</param>
      </result>
    </action>
  </package>
</struts>

После этого запускаем сервер, переходим по адресу http://127.0.0.1:8080/struts2-showcase/index.action и наблюдаем приветственную страницу с примерами использования Struts 2.

Готовый к экспериментам стенд с Apache Struts 2.3.34
Готовый к экспериментам стенд с Apache Struts 2.3.34

Если у тебя Linux, то рекомендую взять Docker и поднять стенд одной командой:

$ docker run -d -p 8080:8080 vulhub/struts2:2.3.34-showcase

После этого не забудь отредактировать файл /usr/local/tomcat/webapps/ROOT/WEB-INF/classes/struts-actionchaining.xml и перезапустить Tomcat.

Возникло желание немного подебажить? Тогда твой выбор — IntelliJ IDEA. Просто открой папку с исходниками (/struts-2.3.34/src), в ней и настрой запуск сервера с приложением Showcase через Maven.

Конфигурация запуска приложения Struts 2 Showcase в IntelliJ IDEA
Конфигурация запуска приложения Struts 2 Showcase в IntelliJ IDEA

Дальше можешь выбирать пункт Debug из меню Run, ставить брейки и дебажить как тебе вздумается.

 

Детали уязвимости

Существует несколько кейсов, при которых возможна эксплуатация уязвимости. Первый из них — когда опция alwaysSelectFullNamespace установлена в true. Такую настройку, например, использует очень популярный плагин для Struts под названием Convention.

/plugins/convention/src/main/resources/struts-plugin.xml
...
<struts order="20">
  ...
  <constant name="struts.mapper.alwaysSelectFullNamespace" value="true"/>
  ...

Если твое приложение использует этот плагин, значит, оно уязвимо. Struts Showcase его использует.

/struts2-showcase/META-INF/maven/org.apache.struts/struts2-showcase/pom.xml
...
<dependency>
  <groupId>org.apache.struts</groupId>
  <artifactId>struts2-convention-plugin</artifactId>
</dependency>
...

Второй вариант — если приложение использует действия (actions), которые сконфигурированы без указания конкретного пространства имен (namespace), или использует в качестве него символы подстановки (/*). Это относится не только к действиям, определенным внутри конфигурационных файлов Struts, но и к пространству имен, используемых непосредственно в исходном коде. Помнишь, во время поднятия стенда мы изменяли файл struts-actionchaining.xml? Тем самым мы создали условия для возможной атаки.

Продолжение доступно только подписчикам

Вариант 1. Оформи подписку на «Хакер», чтобы читать все материалы на сайте

Подписка позволит тебе в течение указанного срока читать ВСЕ платные материалы сайта. Мы принимаем оплату банковскими картами, электронными деньгами и переводами со счетов мобильных операторов. Подробнее о подписке

Вариант 2. Купи один материал

Заинтересовала информация, но нет возможности оплатить подписку? Тогда этот вариант для тебя! Обрати внимание: этот способ покупки доступен только для материалов, опубликованных более двух месяцев назад.


2 комментария

  1. avator888

    25.09.2018 at 22:58

    +1 автору в карму

  2. r0uly

    18.10.2018 at 05:34

    Великолепная статья!

Оставить мнение

Check Also

Устранены семь уязвимостей в новой версии WordPress

Вышло первое обновление безопасности для свежей ветки WordPress 5.0. Были исправлены семь …