Bonjour,
Intro
une faille dans la bibliothèque log4j (un composant java libre utilisé pour les logs) a été découverte la semaine dernière suite à un souci dans minecraft. La faille est assez sévère en partie parce que c’est assez trivial a exploiter, mais surtout de part les pratiques du monde java, à savoir de coller les libs avec le binaire, et d’oublier. La version impacté est la 2, la version 1 n’etant pas impacté à priori, ou pas de façon aussi importante.
Le compte rendu initial explique un peu le souci, et une analyse plus poussée a été aussi écrite dans la journée. En gros, c’est la combinaison de plusieurs comportements innocents en apparence quand ils sont pris séparément.
D’une part le fait de pouvoir rajouter des variables dans des chaines de format (avec %{xxx}), chose qui est utilisé via la configuration de log4j (donc sous le contrôle de l’admin et/ou du dev). Log4j a une configuration en XML, ou on peut vraiment aller finement dans les détails de ce qu’on loggue ou et comment.
Une autre fonction qui est importante pour la faille a été de rajouter le support de JNDI (une API java qui permet d’abstraire les requetes pour aller sur LDAP, DNS, NIS, ou un bus RMI/CORBA). Ça permet d’utiliser LDAP de manière transparente dans la chaine de format, pour par exemple configurer ça en partie via un serveur distant. Je ne pense pas que j’aurais lusage de ce genre de fonction, mais j’imagine dans un truc avec des milliers de programmes, ça peut avoir un usage, surtout si on part du principe que c’est via la config sous le contrôle de l’admin.
J’aimerais pointer que Java visait à une forme de transparence réseau au début (on peut critiquer Sun, mais je pense qu’ils ont eu la bonne idée trop tôt). RMI, c’est remote method invocation, c’est l’ancêtre d’un appel HTTP REST, ou le successeur des bons vieux RPC du monde Unix. Il y a eu des failles sur ça, et donc le fait de charger des classes via LDAP ou RMI est désactiver par défaut depuis 2/3 ans dans java.
Et enfin, la dernier fonction, le fait que log4j supporte les chaines de format comme printf le fait.
Avec du coup un remake des failles dans printf avec les chaines de format fournis par l’utilisateur.
Je détaille, parce qu’en cherchant sur le sujet, j’ai vu pas mal de gens critiquer les volontaires de log4j et c’est important de comprendre que le souci n’est pas d’avoir mis du code bugué, mais d’avoir mis des fonctions toutes raisonnables, sauf combinés.
Mais même si c’était un bug, les bugs, ça arrive. Un article récent sur la toxicité dans le libre montre que c’est une cause de burnout chez les devs, donc je pense que c’est important de ne pas oublier qu’il y a des humains qui tentent de faire de leur mieux derrière le libre.
Impact
J’en parle ici, parce que de ce que je voit, il y a potentiellement beaucoup de monde touché.
Comme j’ai dit, le monde java a tendance à embarquer les libs (vu que ça tourne partout), et mes collègues sont assez occupés sur ça depuis hier (entre les demandes en interne et les demandes clients). Je vais me concentrer sur les logiciels que des CHATONS pourraient avoir dans leur infras, vu que c’est grosso modo ce que j’ai regardé pour mon boulot.
Jenkins
Jenkins, logiciel bien connu de CI/CD, n’est pas impacté. Il y a un article de blog qui dit qu’une autre lib est utilisé. Mais il y a un certain nombre de plugin touchés, la plupart semblent obscurs, à part audit-log
. Une fonction groovy est dispo pour tester ça, et la liste est sur le bugtracker de Jenkins.
Gerrit
Gerrit utilise log4j version 1. C’est normalement suffisant pour ne pas avoir de souci. La faille existe via un autre vecteur, mais ça requiert l’usage d’une configuration extrêmement spécifique, et ça ne permet pas d’exécuter de code. De ce que je vois, la communauté gerrit n’a d’article ni rien pour le moment. Et log4j 1 n’est plus maintenu depuis 6 ans, donc c’est pas terrible à un autre niveau.
Jitsi
Jitsi est plus ou moins impacté. Plus ou moins car il semble que 2 composants sont touchés, mais je n’ai pas déployé Jitsi, donc je ne sais pas si c’est des composants importants ou pas.
Elasticsearch (et forks), logstash
Visiblement, Elasticsearch en lui même n’est pas vulnérable (pour la partie execution de code, on peut toujours exfiltrer des variables d’environnement via le DNS). Certains autres produits de la boite qui peuvent ou pas être libres et qui peuvent ou pas venir avec le composant principal peuvent l’être. Je ne sais pas pour les forks, mais je suppose que c’est pareil.
Logstash est pleinement affecté, et doit être mis à jour.
Big blue button
BBB est en partie écrit en java (si j’en crois les stats github). Quel partie, je ne sais pas. Mais il semble que la bibliothèque sous jacente ne soit pas log4j, mais slf4j, la même que Jenkins, donc j’aurais tendance à dire « non vulnérable ». Pareil, si quelqu’un avec un BBB peut regarder, ça serait sympa.
Protections génériques contre la faille
En dehors de mettre à jour (ce qui implique des mises à jours), il y a des choses qui font que la faille ne va pas forcément toucher des CHATONS, ou qui vont limiter les exploitations les plus rapides
Avoir une JVM à jour
L’exploit public le plus utilisé se sert de JNDI et LDAP. C’est quelque chose qui est par défaut à « off » dans les JVM depuis 2017. Donc une JVM à jour suffit. Il faut comparer java -version
avec les versions sur l’annonce. Attention, ça ne bloque que la partie facile. Il reste d’autres manières bien plus complexes d’exploiter la faille (et surtout qui dépendent des versions et des libs chargés, donc plus fragile et moins automatisable).
Bloquer le réseau
Je pense que si c’est possible, bloquer le réseau (soit via systemd, soit via iptables, ou via apparmor/selinux) permet de compliquer suffisamment la via d’un attaquant pour gagner du temps. Le risque n’est pas que quelqu’un passe 1 mois à attaquer un service mais plus qu’une vague d’attaque automatique soit mise en place pour miner du bitcoin (vu que c’est ce qui arrive sur les failles wordpress, jenkins, etc). Donc bloquer le réseau en sortie a tendance à suffire pour ce genre d’attaque.
J’ai fait ça pour les 2 services (zanata et gerrit) potentiellement vulnérables avant d’aller chercher les détails. Iptables a un module owner
qui permet de filtrer en sortie de la machine par uid, ce qui permet d’éviter de tout casser. Mais les 2 utilisent log4j 1, donc ça devrait aller.
Retirer la classe vulnérable dans l’archive java
Je n’ai pas testé, mais visiblement, des gens proposent de retirer directement le bout de code qui pose souci via zip et rm. C’est à essayer en cas de dernier recours.Je n’ai pas de lien à donner, mais dans tout les cas, faire une copie avant de magouiller le soft me parait important.
Conclusion
Je pense qu’au moins pour les chatons, il n’y a pas de raison de trop s’affoler au contraire d’une entreprise moyenne avec une tonne de code java en interne (ou des logiciels proprio à mettre à jour), mais qu’on dort mieux après une vérif rapide de sa version de la JVM et des softs utilisés.