FlawOpen

flawopen.com/Incidents/log4shell-jndi-injection-december-2021

● Apache Software Foundation · CVE-2021-44228 · December 2021 · CVSS 10.0 · Crítica
Pesquisa · FlawOpen

Log4Shell (CVE-2021-44228): causa e correção

O CVE-2021-44228 permitia que dados registrados acionassem lookups do Log4j 2 e carregamento via JNDI. Atualize o Log4j e inventarie cópias embutidas.[1], [2], [4]

💡 Explicação em Linguagem Simples (ELI5)

Um escritório tem um funcionário cuja única tarefa é anotar o que os visitantes dizem. Alguém descobre que, se um visitante disser certa frase, o funcionário para de anotar, vai até um endereço citado na frase, pega um envelope lacrado de um desconhecido e segue as instruções que estão dentro. O funcionário só deveria anotar.[1]

Conceitos Centrais e Termos

Lookups de mensagem
Um recurso do Log4j 2 que substituía expressões ${...} dentro das mensagens de log por valores na hora do registro. Antes da 2.15.0, isso valia também para os dados dentro da mensagem, não só para o padrão configurado.[1]
JNDI
Java Naming and Directory Interface, uma API para buscar objetos em serviços de diretório como o LDAP. Um lookup JNDI num servidor remoto podia devolver uma classe para a JVM carregar.[1]
Injeção de expressão (CWE-917)
Dados não confiáveis chegam a um avaliador de expressões, e um texto fornecido como dado é executado como instrução.[1]
Dependência transitiva
Uma biblioteca que a aplicação inclui só porque outra biblioteca depende dela. Muitas exposições ao Log4Shell vieram de cópias do Log4j que ninguém havia listado.[4]
Lista de materiais de software (SBOM)
Uma lista legível por máquina de cada componente e versão dentro de um build, que permite responder rapidamente "onde rodamos o Log4j 2.14?".[4], [3]

Mapeamentos de frameworks

Linha do Tempo do Incidente

2021-11-24

Chen Zhaojun, da Alibaba Cloud Security, relata a falha de forma privada à Apache.[1]

2021-12-09

A falha se torna pública; o Log4j 2.15.0 é lançado e varreduras em massa começam em poucas horas.[1], [4]

2021-12-17

A CISA emite a Emergency Directive 22-02, exigindo que os órgãos federais dos EUA localizem e mitiguem o Log4j.[3]

2021-12-28

O Log4j 2.17.1 corrige a CVE-2021-44832, a última de três CVEs posteriores à 2.15.0 (CVE-2021-45046 e CVE-2021-45105).[1]

Fluxo de Ataque Passo a Paso

Passo 1

Um texto do atacante chega a uma chamada de log

Qualquer valor que a aplicação registre, como nome de usuário, cabeçalho ou termo de busca, pode trazer uma expressão de lookup escolhida pelo atacante.[1]

Passo 2

O Log4j avalia a expressão

As versões vulneráveis processam lookups dentro dos dados registrados, então a expressão é resolvida em vez de ser gravada como texto.[1], [2]

Passo 3

O JNDI sai para a rede

Um lookup JNDI faz o servidor se conectar a um serviço de diretório citado na expressão, muitas vezes na infraestrutura do atacante.[1], [4]

Passo 4

Código remoto é executado

O diretório remoto pode indicar à JVM uma classe para carregar, que então roda com os privilégios da aplicação. Onde as conexões de saída estavam bloqueadas, essa etapa falhava.[1], [2]

Código-Fonte: Vulnerável vs. Seguro

Configuração Maven ilustrativa. Importar o log4j-bom faz todos os módulos do Log4j, inclusive cópias trazidas por outras bibliotecas, se resolverem numa única versão atual. A regra do enforcer então reprova o build se algum log4j-core anterior à 2.17.1 ainda estiver acessível, inclusive de forma transitiva, para que uma nova dependência não reintroduza em silêncio o código vulnerável. Atualizar é a correção de fato; bloquear LDAP e RMI de saída nos servidores de aplicação é a defesa em profundidade que interrompeu a exploração mesmo onde o patch atrasou.

IMPLEMENTAÇÃO VULNERÁVEL
<!-- pom.xml: a direct dependency pinned to a vulnerable release -->
<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.14.1</version>
  </dependency>
</dependencies>
<!-- Nothing stops another library from pulling in an older log4j-core transitively. -->
PATCH SEGURO E ROBUSTO
<!-- pom.xml: one version for every Log4j module, and a build that fails on old ones -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-bom</artifactId>
      <version>2.24.3</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-enforcer-plugin</artifactId>
      <version>3.5.0</version>
      <executions>
        <execution>
          <id>ban-vulnerable-log4j</id>
          <goals><goal>enforce</goal></goals>
          <configuration>
            <rules>
              <bannedDependencies>
                <searchTransitive>true</searchTransitive>
                <excludes>
                  <exclude>org.apache.logging.log4j:log4j-core:[2.0-beta9,2.17.1)</exclude>
                </excludes>
              </bannedDependencies>
            </rules>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Lista de Verificação de Segurança para Engenharia

Fontes