Содержание статьи
Общая информация
Наряду с Apache Struts 2, уязвимость в котором мы разбирали в прошлой статье, под раздачу багов попал и веб-сервер Tomcat. За последнее время было найдено сразу несколько уязвимостей.
19 сентября команда разработчиков в очередной рассылке официально подтвердила наличие и успешный фикс двух уязвимостей, которые получили статус критических. Первая значится под номером CVE-2017-12615. После того как ее запатчили, сразу же нашелся способ обойти заплатку (CVE-2017-12616), и последовал новый фикс. Не поверишь, но вскоре обошли и его — уязвимость носит номер CVE-2017-12617, и ее общий смысл сводится к тому, что неавторизированный пользователь, манипулируя именем файла в PUT-запросе, может создать JSP-файл с произвольным содержимым. Уязвимости подвержены все ветки, начиная с 5.x и заканчивая 9.x.
WARNING
Статья адресована специалистам по безопасности и тем, кто собирается ими стать. Вся информация предоставлена исключительно в ознакомительных целях. Ни редакция, ни автор не несут ответственности за любой возможный вред, причиненный материалами данной статьи.
Стенд
Сначала, как водится, поднимаем тестовый стенд. Я буду использовать версии Tomcat для Windows, так как CVE-2017-12615 и CVE-2017-12616 касаются только их.
Для проверки уязвимостей можно использовать любую из версий — 7.0.81, 8.5.20 или 9.0.0.M26. Все они уязвимы.
Также ты всегда можешь использовать Docker, благо у Apache есть официальный репозиторий, из которого можно поднять любую версию Tomcat одной командой.
docker run -it --rm -p 8888:8080 tomcat:7.0.81
Теперь на порте 8888 у тебя обитает выбранная версия веб-сервера.
После успешного запуска нужно отредактировать конфигурационный файл web.xml и добавить в него вот такие строки.
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
Они идут в этот раздел:
<servlet>
<servlet-name>default</servlet-name>
Таким образом мы выключаем параметр readonly
, что позволяет использовать запросы PUT
и DELETE
. Но простое включение этой опции, конечно же, не открывает нам возможность записывать и удалять JSP-файлы.
Базовые детали уязвимостей
Для обработки запросов к JSP и JSPX скрипты используют класс org.apache.jasper.servlet.JspServlet
.
/conf/web.xml
246: <servlet>
247: <servlet-name>jsp</servlet-name>
248: <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
А за обработку остальных файлов отвечает org.apache.catalina.servlets.DefaultServlet
. Именно в нем и реализован метод PUT.
/java/org/apache/catalina/servlets/DefaultServlet.java
539: /**
540: * Process a PUT request for the specified resource.
...
548: @Override
549: protected void doPut(HttpServletRequest req, HttpServletResponse resp)
550: throws ServletException, IOException {
551:
552: if (readOnly) {
553: resp.sendError(HttpServletResponse.SC_FORBIDDEN);
554: return;
555: }
Как видишь, работа этого метода зависит от опции readOnly
, которую мы и выключили, так как по умолчанию она установлена в true.
/java/org/apache/catalina/servlets/DefaultServlet.java
162: protected boolean readOnly = true;
Идея эксплоита заключается в том, чтобы заставить PUT-запрос к файлу JSP обрабатываться с помощью DefaultServlet
. Это можно провернуть несколькими способами. Чтобы лучше вникнуть в детали, сначала мы поговорим о методах, которые можно использовать только в версиях для Windows.
Давай запустим Tomcat версии 7.0.79 и выполним такой запрос:
PUT /read.txt%20 HTTP/1.1
Host: tomcat.visualhack:8080
Connection: close
Content-Length: 3
any
Если ты знаешь про особенности и ограничения в названиях файлов системы Windows, то, увидев пробел в конце пути, сразу же все поймешь. Дело в том, что файлы, создаваемые штатными методами ОС, не могут содержать пробелы в начале или в конце имени — те просто отбрасываются. Но ведь Tomcat написан на Java, скажешь ты. Чтобы все прояснить, посмотрим на ключевые шаги обработки нашего запроса.
Ты уже знаешь, что за его обработку отвечает DefaultServlet
. Если файл еще не существует, то выполнение передается методу bind
.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»