FlawOpen

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

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

Log4Shell (CVE-2021-44228): causa y solución

CVE-2021-44228 permitía que datos registrados activaran lookups de Log4j 2 y carga de clases vía JNDI. Actualice Log4j y localice copias incluidas.[1], [2], [4]

💡 Explicación en Lenguaje Sencillo (ELI5)

Una oficina tiene un empleado cuya única tarea es anotar lo que dicen los visitantes. Alguien descubre que, si un visitante pronuncia cierta frase, el empleado deja de escribir, va a una dirección mencionada en la frase, recoge un sobre cerrado de manos de un desconocido y sigue las instrucciones que contiene. El empleado solo debía tomar nota.[1]

Conceptos Clave y Términos

Lookups en mensajes
Una función de Log4j 2 que sustituía expresiones ${...} dentro de los mensajes de registro por valores al registrar. Antes de la 2.15.0 se aplicaba también a los datos del mensaje, no solo al patrón configurado.[1]
JNDI
Java Naming and Directory Interface, una API para buscar objetos en servicios de directorio como LDAP. Un lookup JNDI a un servidor remoto podía devolver una clase para que la JVM la cargara.[1]
Inyección de expresiones (CWE-917)
Datos no confiables llegan a un evaluador de expresiones, de modo que un texto aportado como dato se ejecuta como instrucción.[1]
Dependencia transitiva
Una biblioteca que tu aplicación incluye solo porque otra depende de ella. Muchas exposiciones a Log4Shell venían de copias de Log4j que nadie tenía inventariadas.[4]
Lista de materiales de software (SBOM)
Una lista legible por máquina de cada componente y versión de una compilación, que permite responder rápido «¿dónde ejecutamos Log4j 2.14?».[4], [3]

Mapeos de marcos

Cronología del Incidente

2021-11-24

Chen Zhaojun, de Alibaba Cloud Security, notifica el fallo en privado a Apache.[1]

2021-12-09

El fallo se hace público; se publica Log4j 2.15.0 y en pocas horas empiezan los escaneos masivos.[1], [4]

2021-12-17

CISA emite la Emergency Directive 22-02, que obliga a las agencias federales de EE. UU. a localizar y mitigar Log4j.[3]

2021-12-28

Log4j 2.17.1 corrige CVE-2021-44832, la última de tres CVE posteriores a la 2.15.0 (CVE-2021-45046 y CVE-2021-45105).[1]

Flujo de Ataque Paso a Paso

Paso 1

El texto del atacante llega a una llamada de registro

Cualquier valor que la aplicación registre, como un nombre de usuario, una cabecera o un término de búsqueda, puede llevar una expresión de lookup elegida por el atacante.[1]

Paso 2

Log4j evalúa la expresión

Las versiones vulnerables procesan lookups dentro de los datos registrados, así que la expresión se resuelve en lugar de escribirse como texto.[1], [2]

Paso 3

JNDI sale a la red

Un lookup JNDI hace que el servidor se conecte a un servicio de directorio indicado en la expresión, a menudo en la infraestructura del atacante.[1], [4]

Paso 4

Se ejecuta código remoto

El directorio remoto puede indicar a la JVM una clase que cargar, que después se ejecuta con los privilegios de la aplicación. Donde las conexiones salientes estaban bloqueadas, este paso fallaba.[1], [2]

Código Fuente: Vulnerable vs. Seguro

Configuración de Maven ilustrativa. Importar log4j-bom hace que todos los módulos de Log4j, incluidas las copias que traen otras bibliotecas, se resuelvan a una única versión actual. La regla de enforcer hace fallar la compilación si aún se alcanza algún log4j-core anterior a la 2.17.1, también de forma transitiva, para que una dependencia nueva no reintroduzca en silencio el código vulnerable. Actualizar es la corrección real; bloquear LDAP y RMI salientes en los servidores de aplicaciones es la defensa en profundidad que cortó la explotación incluso donde el parche se retrasó.

IMPLEMENTACIÓN VULNERABLE
<!-- 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. -->
PARCHE SEGURO Y 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 Verificación de Seguridad para Ingeniería

Fuentes