Spring4Shell: explicação da vulnerabilidade de RCE zero-day no Spring Framework
1 de abril de 2022
0 minutos de leituraEm 30 de março de 2022, foi descoberta uma vulnerabilidade crítica de execução remota de código (RCE) no Spring Framework. Mais especificamente, ela faz parte do pacote spring-beans, uma dependência transitiva tanto de spring-webmvc quanto de spring-webflux. Essa vulnerabilidade é mais um exemplo da importância de proteger a cadeia de suprimentos de software de código aberto.
Fontes de segurança como Lunasec, Rapid7 e Praetorian confirmaram que a vulnerabilidade é real. Enquanto isso, o Spring já lançou uma nova versão que mitiga o problema, por isso recomendamos a atualização. Embora a Spring4Shell não pareça ter o mesmo impacto da recente vulnerabilidade Log4Shell, todas as organizações que usam o Spring Framework ainda devem avaliá-la e priorizá-la. Nesta publicação, vamos explorar como a RCE funciona.
Entendendo a Spring4Shell
Se tivermos um controller com um mapeamento de requisição carregado na memória, já estaremos vulneráveis a esse problema. Abaixo, você vê nosso GreetingController com um PostMapping para /greeting. Quando chamamos nossa aplicação, por exemplo, no Tomcat em http://mydomain/myapp/greeting, ela tenta transformar a entrada em um POJO (Plain Old Java Object), que, neste caso, é o objeto Greeting.
No entanto, como o Spring usa serialização internamente para mapear esses valores para o objeto Java, também é possível definir outros valores. Depois de investigar um pouco, descobrimos que é possível definir propriedades de uma classe. Isso é relevante se você executa a aplicação no Tomcat.
Para mostrar isso na prática, podemos usar o seguinte curl para criar um arquivo rce.jsp por meio de algumas propriedades de registro em log da classe.
Tudo o que for definido no padrão acabará como conteúdo do arquivo. Com alguns escapes bem pensados e o uso de cabeçalhos, nossa equipe conseguiu criar um arquivo JSP no servidor Tomcat contendo o corpo simples <% out.println(“HACKED”); %>. Esse arquivo ficou disponível em /myapp/rce.jsp.

A POC completa, criada por Kirill Efimov e Aviad Hahami, da equipe de pesquisa de segurança da Snyk, está disponível no GitHub
Se conseguimos avaliar um simples out.println, também podemos criar arquivos JSP com comandos de terminal que abrem um acesso de shell reverso usando Runtime.exec(). Outra opção é criar uma interface de web shell com os recursos do JSP.
Um exploit semelhante, mencionado em muitos outros blogs, consiste em criar um JSP capaz de executar um comando. Este script Python cria para você a requisição adequada com os cabeçalhos necessários. Depois de executar o script em nossa aplicação de demonstração, conseguimos executar o comando whoami da seguinte forma: [http://localhost:8080/tomcatwar.jsp?pwd=j&cmd=whoami](http://localhost:8080/tomcatwar.jsp?pwd=j&cmd=whoami).

Quem está vulnerável?
Como a situação está evoluindo rapidamente, só podemos dizer o que sabemos até agora.
Nas versões afetadas do spring-beans, parece que essa vulnerabilidade só funciona quando se usa o JDK 9 ou superior. A introdução do JDK 9 praticamente contornou um problema antigo, CVE-2010-1622.
Como muitos desenvolvedores Java já migraram para versões posteriores ao Java 8 e o Spring Framework é amplamente usado, acreditamos que muitas aplicações Java podem estar vulneráveis a esse problema.
Há várias maneiras de resolver esse problema. Os mantenedores do Spring lançaram uma nova versão do framework. Portanto, a melhor recomendação é atualizar o Spring Framework para a versão 5.3.18 ou 5.2.20. De acordo com nossa equipe de segurança, basta atualizar o pacote `spring-bean` para a versão mais recente, mas faz mais sentido atualizar o framework inteiro. Se você usa o Spring Boot, as versões 2.6.6 ou 2.5.12 incluem o Spring Framework atualizado.
Se não for possível atualizar para uma versão mais recente do Spring, talvez seja viável voltar a usar o Java 8.
Outra opção é criar um InitBinder no controller ou um ControllerAdvice separado, como no exemplo abaixo.
Mas lembre-se de que essa não é uma solução definitiva. Criar uma lista de bloqueio como essa não é considerada uma boa prática de segurança, mas pode ganhar algum tempo. Os mantenedores do Spring Framework sugerem criar um RequestMappingHandlerAdapter para atualizar o WebDataBinder ao final, depois de toda a inicialização, conforme explicado na publicação do blog.
Dependência de frameworks e bibliotecas
A Spring4Shell mostra mais uma vez o quanto dependemos de frameworks e bibliotecas de código aberto. No entanto, quando surge uma vulnerabilidade de segurança como essa ou a recente RCE Log4Shell, é importante ficar sabendo dela para poder mitigá-la imediatamente.
A Snyk ajuda você a acompanhar essas vulnerabilidades ao analisar suas aplicações regularmente. A Snyk alerta você e sua equipe quando novas vulnerabilidades são detectadas e recomenda as próximas etapas para manter suas aplicações seguras.
Para concluir, vulnerabilidades zero-day como essa nos lembram da importância de manter as bibliotecas atualizadas. Com tudo em dia, fica mais fácil aplicar atualizações, recompilar e lançar uma nova versão rapidamente.
Comece a resolver desafios de capture the flag
Aprenda a resolver desafios de capture the flag assistindo sob demanda ao nosso workshop virtual introdutório.
