Во фреймворке 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 комментарий

  1. avator888

    25.09.2018 at 22:58

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

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

Check Also

Целенаправленная социальная инженерия. Нестандартные техники введения в заблуждение

В предыдущей статье мы разобрали массовые атаки. Но их применимость ограничена: пентестер …