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
CVE-2022-22965 — Análise técnica aprofundada de CVE-2022-22965 (Spring4Shell) com configuração de ambiente, walkthrough de depuração e detalhamento da cadeia de exploit para prática educacional em laboratório. | Kitploit
Ferramentas/GitHubGitHub/khidottrivi/cve-2022-22965
Análise de VulnerabilidadesAnálise de CódigoExploraçãoExploração de Aplicações WebAprendizado e EducaçãoLabs e Prática
GitHubkhidottrivi/cve-2022-22965

CVE-2022-22965

Análise técnica aprofundada de CVE-2022-22965 (Spring4Shell) com configuração de ambiente, walkthrough de depuração e detalhamento da cadeia de exploit para prática educacional em laboratório.

Ver Repositório
42há 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

Análise CVE 2022-22965_Spring4Shell

Descrição da vulnerabilidade

Spring4Shell é o nome de um CVE que existe no Spring Core do Spring Framework.

Com pontuação CVSS 3.x de 9.8, a vulnerabilidade é classificada como de risco máximo (crítica). Esta vulnerabilidade permite que um invasor execute código de exploração remotamente e controle o servidor que contém a vulnerabilidade.

Junto com a popularidade do Spring Core na internet e a gravidade do impacto do Spring4Shell, esta vulnerabilidade é avaliada por especialistas como tendo um impacto não inferior ao Log4shell.

Escopo de impacto

O Spring4Shell não afeta todas as aplicações web que usam o Spring Framework na internet, mas requer que a aplicação web atenda aos seguintes critérios:

  • Aplicação usando Spring Framework versão < 5.2, 5.2.0 – 5.2.19 ou 5.3.0 - 5.3.17
  • Aplicação que usa uma das dependências Spring-webmvc ou Spring-webflux
  • Aplicação usando Java com JDK versão >= 9
  • Aplicação empacotada como um arquivo Java web tradicional (arquivo .war) e implantada no Tomcat (a vulnerabilidade não foi detectada em aplicações executadas com Springboot)

Configuração do ambiente

Meu ambiente de configuração terá os seguintes parâmetros:

  • Spring Framework 5.1.0
  • Spring-webmvc dependency 5.1.0
  • JDK 11.0.13 (estou usando uma máquina virtual Kali 2021.4a e esta versão do Java é a instalada por padrão)
  • Apache Tomcat 9.0.45

Criar ambiente, projeto com a vulnerabilidade e configurar debug com Intellij

  1. Instalação do Apache Tomcat

    Como mencionado acima, estou usando Kali 2021.4a e Apache Tomcat 9.0.45. Se você não sabe como instalar o Apache Tomcat e deseja instalá-lo no Kali Linux, pode consultar este link.

    Nota: Substitua o link https://mirror.kiu.ac.ug/apache/tomcat/tomcat-9/v9.0.45/bin/apache-tomcat-9.0.45.tar.gz por https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.45/bin/apache-tomcat-9.0.45.tar.gz

  2. Escolha da IDE

    Precisamos de uma IDE para codificar o projeto, empacotá-lo como um arquivo .war e, muito importante, depurar. Eu uso Intellij, você pode usar Eclipse ou Netbeans, etc., desde que a IDE suporte Java.

  3. Criar um projeto simples com a vulnerabilidade

    Meu projeto é muito simples, composto por:

    • um modelo HelloWorld.java

      Untitled

    • um controller HelloWorldController.java

      Untitled

    • uma view hello.jsp

      Untitled

  4. Construir o arquivo .war

    Para empacotar o projeto, faça: Build -> Build Artifacts -> helloworld:war -> Build.

    Aguarde a conclusão bem-sucedida da construção. Neste momento, o projeto terá uma pasta out adicional. Vá para ./out/artifacts/your_war_name/ e verá um arquivo your_war_name.war. Este arquivo .war é o projeto web após compilação e empacotamento, e pode ser usado para implantação em servlets Java como Apache Tomcat.

    Se a opção Build Artifacts estiver desabilitada (não é possível construir artefatos), é porque o Build Artifacts não foi configurado para este projeto. Vá em: File -> Project Structure -> Artifacts -> Delete todos os artefatos existentes -> Add (sinal de +) -> Web Application: Exploded -> From Modules... -> OK (finalizar criação do Exploded) -> Add (sinal de +) -> Web Application: Archive -> For 'helloworld:war exploded' -> OK. Depois execute Build Artifacts novamente.

  5. Implantação e configuração de debug

    • Implantação

      Para implantar um arquivo .war no Apache Tomcat, basta copiar o arquivo .war para a pasta /webapps dentro do diretório do Apache Tomcat (exemplo: para mim, copio o arquivo helloworld.war (renomeei para facilitar) para /opt/tomcat/apache-tomcat-9.0.45/webapps/). Depois, inicie o servidor Tomcat de duas maneiras (para Linux):

      • /opt/tomcat/apache-tomcat-9.0.45/bin/catalina.sh start (a aplicação será executada com os direitos do usuário que executou o comando; no meu caso, root@@)
      • sudo service tomcat start (a aplicação geralmente será executada com os direitos do usuário tomcat, dependendo de como você configurou o serviço ao instalar o Apache Tomcat)

      Após a implantação, acesse http://localhost:8080/helloworld

    • Configuração de debug

      Para configurar o debug (remoto) do Tomcat, siga os passos abaixo:

      1. Lado do servidor:

        • abra o arquivo catalina.sh e substitua o valor localhost pelo ip_da_maquina_virtual do parâmetro JPDA_ADDRESS

          Untitled

        • inicie o servidor Tomcat novamente com: /opt/tomcat/apache-tomcat-9.0.45/bin/catalina.sh jpda start. Neste momento, além de abrir a porta 8080 para o servidor HTTP, o Tomcat abrirá a porta 8000 para podermos conectar e depurar

        Nota: Nesta parte de debug, estou executando o Intellij no Windows 10 e o Tomcat em uma máquina virtual Kali, por isso precisei alterar o JDPA_ADDRESS. Se você configurar tanto o Intellij quanto o Windows 10 na mesma máquina, não precisa alterar.

      2. Lado do Intellij:

        • vá em Run -> Edit Configurations... -> Add (sinal de +) -> Remote JVM Debug

        • Defina um nome, ajuste Host e Port para o IP e porta que você alterou no arquivo catalina.sh -> OK -> Shift + F9 (iniciar debug)

          Untitled

Análise detalhada

Primeiramente, vou analisar o projeto que estou usando para depuração. Como mencionado acima, este projeto é simples, consistindo em:

  • Um modelo HelloWorld.java, onde o objeto HelloWorld tem dois atributos: message (string), person (string) e métodos setter/getter (por ter estrutura simples, esse objeto é chamado de Plain Old Java Object - POJO). O projeto deve ter uma classe POJO - Esta é uma condição necessária para explorar a vulnerabilidade Spring4Shell.
  • Um controller HelloWorldController.java, onde há um método helloPost que recebe como parâmetros um objeto helloWorld (HelloWorld) e um model (Model). No método helloPost, é feito addAttribute ao model a partir dos valores dos atributos de helloWorld (person e message) - A segunda condição para explorar o Spring4Shell é ter um controller que receba um objeto POJO como entrada.
  • Uma view hello.jsp, que chama os atributos do model (enviados do controller HelloWorldController.java) e os exibe para o usuário.

Aqui está um exemplo:

Untitled

A aplicação capturou as informações dos parâmetros da requisição POST e criou um objeto helloWorld{“person”:”Leo”, “message”:”Hi there”}. Este objeto helloWorld é a entrada para o método helloPost. A aplicação realiza as etapas mencionadas para retornar a resposta ao usuário.

O processo de conversão dos parâmetros no corpo da requisição POST para o objeto helloWorld é totalmente automático pelo Spring. Como ele faz isso e será que ele valida os parâmetros inseridos?

Fonte (Source) class CachedIntrospectionResults

Esta imagem foi capturada durante a depuração, com uma requisição cujo corpo é “class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT” (chamo o lado esquerdo (stack trace) de (1) e o lado direito de (2)):

Untitled

Em (1) destaquei os pontos importantes (olhando de baixo para cima). O Spring aplica applyPropertyValue ao objeto helloWorld a partir dos parâmetros da requisição POST. E se os parâmetros forem simples como person=Leo&message=Hi%20there, o Spring consegue encontrar que a chave 'person' corresponde a helloWorld.person e 'message' a helloWorld.message.

Mas o Spring também permite enviar objetos via requisição HTTP (falar em enviar objetos via HTTP é exagerado, mas é uma forma simplificada de entender). Suponha que o atributo person não seja mais uma string, mas um objeto Person que contém dois subatributos: name (string) e age (int). E para enviar informações sobre este objeto Person ao servidor, seria assim: “person.name=Leo&person.age=23”.

Portanto, o formato dos parâmetros será A.B.C.D… = X, não mais A=X. E para processar o formato A.B.C.D… = X, suponha um parâmetro como A.B.C = X; simplesmente, o Spring fará algo como converter isso em getA.getB.setC(X).

Não vou explicar o que é getA, mas vou dar um exemplo: com o corpo da requisição “person.name=Leo&person.age=23”, o Spring procura no objeto helloWorld o atributo person e o método getPerson; se existir, Spring chama helloWorld.getPerson(), obtendo um objeto do tipo Person, que chamarei de person1. Então, Spring procura em person1 o atributo 'name' e o método setName (já que após 'name' vem '='); se existir, Spring chama setName(Leo) para person1.

Para person.age, o Spring não vai recomeçar do início para encontrar person e depois age, mas usará os objetos anteriores já obtidos, neste caso helloWorld e person1.

Após essas etapas, no servidor teremos um objeto helloWorld{person:{name:”Leo”, age:23}} (ignore o atributo message por enquanto).

Então, como o Spring consegue encontrar os atributos de cada objeto, por exemplo, o atributo ‘person’ do objeto helloWorld?

Observe no início de (1) a função CachedIntrospectionResults(beanClass), que lista os atributos de beanClass. Em (2), quando beanClass é model.HelloWorld, vemos 3 atributos. No entanto, o modelo HelloWorld que criei tem apenas 2 atributos: ‘person’ e ‘message’. Portanto, a função retornou um atributo adicional ‘class’. Se expandir a linha ‘class’, verá que propertytype é ‘java.lang.class’.

Portanto, podemos afetar um objeto class do tipo java.lang.class -> Esta é a origem (source) deste Spring4Shell.

CVE-2010-1622

Relacionado à fonte acima, houve um CVE-2010-1622 que envolve esta fonte. O autor do CVE-2010-1622 explorou esta fonte com o payload class.classLoader.URLs[0] = X.

Porque na classe java.lang.class há o método getClassLoader() que retorna um objeto ClassLoader, e este ClassLoader pode afetar o array de URLs do Tomcat (usado para carregar recursos). E ao poder afetar as URLs, um atacante pode alterar o valor de URLs[0] para um endereço URL e realizar um acesso remoto a um arquivo Jar malicioso (controlado pelo atacante).

Para corrigir isso, o Spring implementou um filtro (blacklist) na função CachedIntrospectionResults(beanClass):

Untitled

Se ‘beanClass’ == Class.class (java.lang.class), então pd deve ser diferente de ‘classLoader’ e ‘protectionDomain’, e a evidência é que após CachedIntrospectionResults carregar todos os atributos de java.lang.class, os dois atributos ‘classLoader’ e ‘protectionDomain’ não aparecem:

Untitled

Mas, em vez disso, a partir do JDK 9, Class.class ganhou um atributo ‘module’ e dentro de Class.module há um atributo classLoader:

Untitled

→ Portanto, usando JDK 9 em diante, é possível contornar a blacklist do Spring!!!

Destino (Sink) class AccessLogValue

Com base no PoC público do Spring4Shell, podemos ver que o payload usado tem o formato:

class.module.classloader.resources.context.parent.pipeline.first ⇔ Class.getModule().getClassLoader().getResources().getContext().getParent().getPipeline().getFirst()

Com base na depuração, podemos ver a seguinte cadeia de gadgets:

java.lang.class.getModule() -> java.lang.module.getClassLoader() -> org.apache.catalia.loader.ParallelWebappClassLoader.getResources() -> org.apache.catalia.webresources.StandardRoot.getContext() -> org.apache.catalia.core.StandardContext.getParent() -> org.apache.catalia.core.StandardHost.getPipeline() -> org.apache.catalia.core.StandardPipeline.getFirst() -> org.apache.catalia.valves.AccessLogValue.

E a classe AccessLogValue possui os seguintes atributos:

Untitled

Podemos obter um objeto AccessLogValue, e este AccessLogValue afeta a gravação de logs do Tomcat.

→ Podemos criar arquivos no servidor configurando os atributos do objeto AccessLogValue no servidor Tomcat. Para fazer isso, no PoC eles configuraram os atributos Prefix, Suffix, Pattern, Directory e fileDateFormat. E o payload da requisição será:

“class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bprefix%7Di%20java.io.InputStream%20in%20%3D%20%25%7Bc%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=shell&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=”

  • Lista de Breakpoints

    Para facilitar o processo de depuração, você pode definir breakpoints nos seguintes pontos:

    Untitled

Conclusão

Esta análise na verdade não tem parte de conclusão; este trecho foi adicionado apenas por formalidade!!!

Se você está procurando uma correção, está aqui.

Baixar ferramenta