
Тестовая программа CVE-2014-0094 для struts1
Здесь обобщается влияние уязвимости CVE-2014-0094 на Struts1. Если не указано иное, все проверки выполнялись на java 1.7.0_02, struts 1.3.10, apache-tomcat-6.0.39, FreeBSD 8.2.
Обратите внимание: содержимое исходных кодов и текстов не гарантируется ни при каких условиях. Кроме того, я не причастен ни к каким событиям, которые могут произойти. И уж тем более я не имею никакого отношения к злоупотреблению этим материалом. (Хотя, как ни говори, ничего нового в этом нет.)
В этот раз я привёл конкретные примеры решений, опираясь на различные веб-сайты. За исключением общеизвестных фактов, в исходных кодах указаны URL, которые я использовал в качестве источников. Я благодарен тем, кто опубликовал эту информацию.
Я постарался по возможности не использовать специальные термины и описал всё простыми словами, хотя, возможно, такое описание не совсем точно.
У этой уязвимости в Struts1 есть разные названия — CVE-2014-0094, S2-020 и т.д., — и не совсем понятно, существуют ли они официально; но для простоты будем называть её CVE-2014-0094.
Не нужно лишний раз объяснять: CVE-2014-0094 — это очень серьёзная проблема.
http://www.nta.go.jp/sonota/sonota/osirase/service.htm
Согласно «Уведомлению о приостановке сервиса (важно)» от 25 апреля 2014 года, касающемуся «программы e-Tax (WEB-версия)», «раздела подготовки налоговых деклараций и т.п.» и «раздела NISA (японская ISA)», веб-служба Национального налогового агентства использует Struts1, и сервис был остановлен в тот же день, когда была обнаружена уязвимость.
По-видимому, остановка была выполнена незамедлительно, чтобы ограничить ущерб.
Когда мы провели здесь экспериментальную проверку, мы подтвердили, что одного лишь перехода по URL достаточно, чтобы остановить сервис и вызвать утечку произвольных файлов.
Поскольку достаточно лишь перейти по URL, злоумышленник может просто отправить в список рассылки (ML) письмо с URL с анонимного адреса электронной почты, — установить виновного будет трудно, а остановить сервис можно легко.
Вот насколько просто можно атаковать эту проблему.
Это самое главное. Если сторонняя организация объявила, что воздействие, по крайней мере, вероятно, правильный подход — сначала остановить систему и предотвратить расширение ущерба. Даже если последующее расследование покажет, что воздействия не было, утёкшая информация не вернётся. Разумеется, здесь необходимо политическое решение. В случае компании под вопросом оказываются этические принципы, повседневная осведомлённость о проблемах, реагирование на риски и т.п.
Эта проблема вызвана тем, что часть значений настроек, хранящихся в системе, может быть перезаписана. Необходимо выяснить, какие значения настроек можно перезаписать. В зависимости от этих значений определяется, какие атаки возможны.
Эти значения настроек различаются в зависимости от контейнера сервлетов. В tomcat6 выполнение произвольного кода, по-видимому, невозможно, но в tomcat8 возможно выполнение произвольного кода. Кроме того, в зависимости от используемого окружения — jetty, WebSphere Application Server и т.д. — необходимо проверить, какие значения настроек доступны.
В случае tomcat6 считается, что можно изменить 23 таких параметра. class.classLoader.resources.dirContext.docBase Если изменить этот параметр, нормальная работа системы становится невозможной; кроме того, если вместо отображения JSP указать файл на сервере, становится возможным получение (утечка) произвольных файлов.
В случае tomcat8 возможно выполнение произвольного кода, но это объясняется тем, что значений, которые можно задать, больше, чем в tomcat6. Если такого значения настроек нет в используемом контейнере сервлетов, считается, что на данный момент проблема незначительна.
Изменение значений настроек, о котором идёт речь, возможно не только путём включения этой строки в URL, но и через скрытое поле обычного запроса; кроме того, как сообщается, это значение можно включить в cookie.
Если значение задано в скрытом поле, по журналу доступа (access log) этого не видно.
Нередко перезапуск выполняется глубокой ночью в воскресенье; если незадолго до этого выполнить перезапись docBase и получение файлов, а затем систему перезапустят, системному администратору будет трудно заметить аномалию. Если именно в этот промежуток времени часто появляются статусы 404, 500 и т.п., весьма вероятно, что произошла утечка каких-то файлов.
Поддержка Struts1 прекращена (оставим в стороне вопрос «что такое поддержка open source?»), и патчи безопасности не выпускаются. Решать проблему необходимо самостоятельно.
Всё началось с проблемы в BeanUtil; необходимо реализовать игнорирование некорректных строк, поступающих в него. BeanUtil — это инструмент для изменения значений настроек объектов (это довольно неточное описание).
Примеры реализации:
com.haselab.struts.filter
web.xml
Если кратко: в web.xml при запуске системы вызывается программа, изменяющая поведение BeanUtil. Вызывается SafeResolverListener.java, и в дальнейшем BeanUtil будет использовать SafeResolver.java. В SafeResolver.java, если анализируемая строка (без учёта регистра) равна 'classLoader', возвращается "". То есть становится невозможно задать произвольное значение для classLoader. В качестве примера такого поведения я использовал https://gist.github.com/nakamura-to/11347570 (программа короткая, поэтому она приведена как есть).
Если на стороне приложения необходимо изменить параметр classLoader, этот способ сделать это не позволит, поэтому в таком случае он не подходит. Однако, как правило, имя classLoader вряд ли где-то используется, так что пока проблем нет. Если есть сомнения, можно выполнить по всем исходным кодам приложения, например: grep -r -i classLoader * и убедиться, что такого имени не существует.
Я проверил перезапись docBase. После развёртывания через mvn откройте в браузере каталог приложения struts. При каждом нажатии кнопки выполняется перезапись docBase и отображение содержимого файла /etc/passwd.