FlawOpen

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

● Apache Software Foundation · CVE-2021-44228 · December 2021 · CVSS 10.0 · Critique
Recherche · FlawOpen

Log4Shell (CVE-2021-44228) : cause et correctif

CVE-2021-44228 permettait aux logs de déclencher lookups Log4j 2 et charger des classes via JNDI. Mettez Log4j à jour et inventoriez ses copies.[1], [2], [4]

💡 Explication en Langage Simple (ELI5)

Un bureau emploie un commis dont le seul travail est de noter ce que disent les visiteurs. Quelqu'un découvre que si un visiteur prononce une certaine formule, le commis arrête d'écrire, se rend à une adresse citée dans la formule, récupère une enveloppe scellée auprès d'un inconnu et suit les instructions qu'elle contient. Le commis n'était censé que prendre des notes.[1]

Concepts Clés et Termes

Lookups dans les messages
Une fonction de Log4j 2 qui remplaçait les expressions ${...} des messages de journal par des valeurs au moment de l'écriture. Avant la 2.15.0, cela s'appliquait aussi aux données du message, pas seulement au motif configuré.[1]
JNDI
Java Naming and Directory Interface, une API de recherche d'objets dans des annuaires comme LDAP. Un lookup JNDI vers un serveur distant pouvait renvoyer une classe que la JVM chargeait.[1]
Injection d'expression (CWE-917)
Des données non fiables atteignent un évaluateur d'expressions : un texte fourni comme donnée est exécuté comme instruction.[1]
Dépendance transitive
Une bibliothèque incluse dans l'application uniquement parce qu'une autre en dépend. Beaucoup d'expositions à Log4Shell venaient de copies de Log4j que personne n'avait recensées.[4]
Nomenclature logicielle (SBOM)
Une liste lisible par machine de chaque composant et version d'une build, qui permet de répondre vite à « où tourne Log4j 2.14 chez nous ? ».[4], [3]

Correspondances de référentiels

Chronologie de l'Incident

2021-11-24

Chen Zhaojun, d'Alibaba Cloud Security, signale la faille à Apache en privé.[1]

2021-12-09

La faille devient publique ; Log4j 2.15.0 sort et des balayages massifs commencent en quelques heures.[1], [4]

2021-12-17

La CISA publie l'Emergency Directive 22-02, qui impose aux agences fédérales américaines de repérer et d'atténuer Log4j.[3]

2021-12-28

Log4j 2.17.1 corrige CVE-2021-44832, la dernière des trois CVE apparues après la 2.15.0 (avec CVE-2021-45046 et CVE-2021-45105).[1]

Déroulement de l'Attaque Étape par Étape

Étape 1

Du texte d'attaquant atteint un appel de journalisation

Toute valeur journalisée par l'application, comme un nom d'utilisateur, un en-tête ou un terme de recherche, peut porter une expression de lookup choisie par l'attaquant.[1]

Étape 2

Log4j évalue l'expression

Les versions vulnérables traitent les lookups dans les données journalisées : l'expression est résolue au lieu d'être écrite comme du texte.[1], [2]

Étape 3

JNDI sort sur le réseau

Un lookup JNDI fait se connecter le serveur à un annuaire désigné dans l'expression, souvent sur l'infrastructure de l'attaquant.[1], [4]

Étape 4

Du code distant s'exécute

L'annuaire distant peut désigner à la JVM une classe à charger, qui s'exécute alors avec les privilèges de l'application. Là où les connexions sortantes étaient bloquées, cette étape échouait.[1], [2]

Code Source : Vulnérable vs Sécurisé

Configuration Maven illustrative. Importer log4j-bom fait résoudre tous les modules Log4j, y compris les copies amenées par d'autres bibliothèques, vers une seule version récente. La règle enforcer fait ensuite échouer la build si un log4j-core antérieur à 2.17.1 reste accessible, y compris de façon transitive, afin qu'une nouvelle dépendance ne réintroduise pas discrètement le code vulnérable. La mise à jour est le vrai correctif ; bloquer LDAP et RMI sortants depuis les serveurs d'application est la défense en profondeur qui a cassé l'exploitation même là où le correctif tardait.

IMPLÉMENTATION VULNÉRABLE
<!-- 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 SÉCURISÉ ET ROBUSTE
<!-- 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>

Liste de Contrôle de Sécurité pour l'Ingénierie

Sources