
Spring Framework CVE-2022-22965 — проверка условий локального воздействия, исправление обновлением версии и повторное тестирование
Данный проект предназначен для изучения и проверки условий влияния, рисков, методов устранения и процесса повторного тестирования после устранения уязвимости CVE-2022-22965 в Spring Framework, также известной как Spring4Shell.
Проект выполнен в локальной авторизованной среде, развёрнутой лично. Основное внимание уделяется не атаке на реальные цели, а поэтапному подтверждению условий, связанных с уязвимостью, путём развёртывания тестовой среды Spring MVC до и после устранения уязвимости, а также безопасному и контролируемому наблюдению в режиме только для чтения за различиями во внутренних путях свойств механизма привязки данных Spring до и после обновления версии.
В рамках проекта выполнены следующие этапы:
Данный проект предназначен исключительно для личной локальной среды или явно авторизованной среды тестирования безопасности.
Проект не направлен на сканирование, разведку и эксплуатацию уязвимостей каких-либо публичных веб-сайтов, серверов или сторонних бизнес-систем и не содержит реальных пользовательских или бизнес-данных.
В ходе тестирования не выполнялись следующие действия:
Запрещается использовать методы тестирования из данного проекта против любых неавторизованных целей.
CVE-2022-22965, обычно называемая Spring4Shell, — это уязвимость удалённого выполнения кода в Spring Framework, связанная с механизмом привязки данных параметров запроса.
Spring MVC поддерживает автоматическую привязку параметров HTTP-запроса к свойствам Java-объектов. Например, в данном проекте параметры имени и электронной почты принимаются следующим образом:
@ModelAttribute("profile") UserProfile profile
В обычных условиях параметры запроса name и email привязываются к объекту UserProfile в соответствии с именами свойств.
В затронутых версиях ограничения доступа к некоторым внутренним путям свойств недостаточно строгие. При использовании JDK 9 или более поздней версии, а также при выполнении определённых условий, связанных с Servlet-контейнером, способом развёртывания и привязкой данных, внешние параметры запроса могут продолжить доступ от обычного бизнес-объекта к внутренним объектам, связанным с Java Class, модулями, загрузчиками классов или контейнером.
В определённых эксплуатируемых средах злоумышленник может дополнительно изменить конфигурацию сервера или записать файлы на сервер, что создаёт риск удалённого выполнения кода.
Данный проект не выполняет полную эксплуатацию удалённого кода, а использует следующий путь свойства для безопасной диагностики различий в режиме только для чтения:
class.module.name
Проект выполнен в личной изолированной экспериментальной среде VMware.
127.0.0.1Тестовые данные штатной функциональности:
Alice[email protected]Путь свойства для диагностики безопасности:
class.module.name
spring4shell-local-verification-lab/
README.md: описание проекта, методика тестирования, результаты проверки и пояснения по устранениюdocs/: отчёт о локальной проверке условий влияния, устранении и повторном тестировании Spring4Shellimages/: скриншоты среды проекта, процесса тестирования и повторного тестированияvulnerable-demo/: проект до устранения на Spring Framework 5.3.17fixed-demo/: проект после устранения на Spring Framework 5.3.18notes/: учебные заметки и записи процессаОсновная структура исходного кода:
config/: классы конфигурации Spring MVC и классы инициализации приложенияcontroller/: контроллер обработки форм и диагностики путей свойствmodel/: класс UserProfile для приёма параметров имени и электронной почтыWEB-INF/views/: JSP-страницы главной страницы, результата отправки и результата диагностикиВ рамках проекта созданы два приложения Spring MVC — до и после устранения уязвимости.
Каталог проекта:
vulnerable-demo
Используемая версия:
Spring Framework 5.3.17
Создаваемый WAR-файл:
spring4shell-vulnerable-demo.war
Адрес доступа:
http://127.0.0.1:8080/spring4shell-vulnerable-demo/
Диагностическая страница:
http://127.0.0.1:8080/spring4shell-vulnerable-demo/binding-probe
Каталог проекта:
fixed-demo
Используемая версия:
Spring Framework 5.3.18
Создаваемый WAR-файл:
spring4shell-fixed-demo.war
Адрес доступа:
http://127.0.0.1:8080/spring4shell-fixed-demo/
Диагностическая страница:
http://127.0.0.1:8080/spring4shell-fixed-demo/binding-probe
Тестовый проект предоставляет простую форму профиля пользователя, содержащую:
Контроллер принимает параметры запроса следующим образом:
@ModelAttribute("profile") UserProfile profile
Когда пользователь отправляет имя и электронную почту, Spring MVC автоматически привязывает параметры name и email к объекту UserProfile.
Страница результата считывает связанный объект и отображает отправленные пользователем имя и адрес электронной почты.
Эта функция используется для подтверждения нормальной работы проекта, а также для доказательства наличия действующей точки входа привязки данных параметров запроса Spring MVC в приложении.
Проект построен по принципу «сначала подтвердить штатную функциональность, затем подтвердить условия влияния, после чего провести диагностику рисков в режиме только для чтения, и наконец устранить уязвимость и провести повторное тестирование».
@ModelAttribute для привязки параметров запроса к объекту UserProfile.class.module.name в режиме только для чтения с помощью Spring BeanWrapper.В рамках проекта были поэтапно подтверждены следующие условия влияния:
spring-webmvc@ModelAttributeФактически развёрнутые зависимости Spring в проекте до устранения включают:
spring-beans-5.3.17.jarspring-core-5.3.17.jarspring-web-5.3.17.jarspring-webmvc-5.3.17.jarДанный проект не судит о наличии уязвимости только по версии Spring Framework, а проводит комплексный анализ с учётом JDK, Spring MVC, Tomcat, развёртывания WAR и точки входа привязки данных.
Чтобы избежать выполнения разрушительной эксплуатации уязвимости, данный проект использует предоставляемый Spring Framework BeanWrapper для проверки следующего пути свойства в режиме только для чтения:
class.module.name
Данный путь означает:
class: доступ к объекту Java Class, соответствующему текущему бизнес-объектуmodule: доступ к Java-модулю, к которому относится данный классname: чтение имени модуляВ процессе диагностики вызываются только методы проверки читаемости свойства и чтения значения свойства:
Таким образом, данная диагностика может использоваться только для наблюдения за различиями в доступе к внутренним путям свойств до и после устранения и сама по себе не может доказать факт удалённого выполнения кода.
Среда до устранения использует:
Spring Framework 5.3.17
Проверяемый путь свойства:
class.module.name
Результаты диагностики:
truenullЗначение true означает, что текущая среда может продолжать разрешение module.name через свойство class обычного бизнес-объекта.
Результат чтения равен null, потому что текущее WAR-приложение работает в безымянном (unnamed) модуле Java, имя модуля пусто, что не означает сбой чтения пути свойства.
Среда после устранения использует:
Spring Framework 5.3.18
Повторная диагностика с тем же путём свойства:
class.module.name
Результаты диагностики:
falseNot readableРезультаты до и после устранения образуют чёткое сравнение:
Данный результат показывает, что после обновления версии доступ к исходному диагностическому пути свойства был ограничен, и наблюдаемое до устранения проявление риска больше не возникает.
В данном проекте устранение выполнено путём обновления версии Spring Framework.
Конфигурация до устранения:
<spring.version>5.3.17</spring.version>
Конфигурация после устранения:
<spring.version>5.3.18</spring.version>
В процессе устранения были выполнены следующие операции:
fixed-demo.Фактически развёрнутые зависимости Spring в проекте после устранения включают:
spring-beans-5.3.18.jarspring-core-5.3.18.jarspring-web-5.3.18.jarspring-webmvc-5.3.18.jarДанный результат доказывает, что исправленная версия была пересобрана и фактически развёрнута, а не просто изменён номер версии в pom.xml.
После обновления до Spring Framework 5.3.18 повторно откройте главную страницу исправленного проекта и отправьте следующие тестовые данные:
Alice[email protected]После отправки страница по-прежнему корректно отображает:
Alice[email protected]Данный результат показывает, что обновление версии не повлияло на исходную функцию привязки параметров запроса и отображения страниц проекта.
Механизм автоматической привязки данных Spring MVC может обращаться к свойствам Java-объектов по именам параметров HTTP-запроса.
Обычным бизнес-параметрам name и email требуется доступ только к соответствующим обычным свойствам объекта UserProfile.
Однако механизм доступа к свойствам Spring также поддерживает вложенные пути свойств с точками. В затронутых версиях ограничения на некоторые внутренние пути свойств недостаточно строгие, что позволяет внешним параметрам в определённых средах переходить от обычного бизнес-объекта к объектам, связанным с Java Class, модулями, загрузчиками классов или Servlet-контейнером.
Когда во внутренних объектах существуют записываемые свойства, способные повлиять на конфигурацию сервера или файловую систему, и приложение одновременно удовлетворяет условиям JDK, Tomcat, развёртывания WAR и привязки данных, может дополнительно возникнуть риск удалённого выполнения кода.
Данная уязвимость вызвана не наличием проблем в самих свойствах name или email, и не все проекты, использующие Spring MVC, обязательно могут быть эксплуатированы. Для реализации уязвимости обычно требуется одновременное наличие нескольких условий.
В реальных бизнес-системах рекомендуется принять следующие меры:













В рамках проекта в локальной изолированной среде были выполнены подтверждение условий влияния CVE-2022-22965 в Spring Framework, диагностика проявления рисков, устранение путём обновления версии и повторное тестирование после устранения.
Проект до устранения использовал Spring Framework 5.3.17. В среде JDK 11, Spring MVC, Apache Tomcat 9.0.60 и классического развёртывания WAR путь свойства class.module.name был определён как доступный для чтения.
Проект после устранения обновил Spring Framework до 5.3.18. Тот же путь свойства стал недоступен для чтения, при этом штатная функция привязки данных имени и электронной почты продолжает работать.
В проекте не выполнялась полная эксплуатация удалённого кода — вместо этого с помощью безопасного и контролируемого метода только для чтения была подтверждена разница до и после устранения.
Проект демонстрирует следующие ключевые компетенции: