Elle constitue sans doute une des attaques les plus sophistiquées et gravissimes et ces dernières années.
Ses conséquences auraient pu être désastreuses pour le monde Linux tout entier, en particulier pour Debian et sa descendance (à cause de systemd).
La chaîne de dépendances plus large dans laquelle liblzma (fournie par le projet xz) se retrouve est chargée par sshd (lié à libsystemd).
Toute faille dans liblzma pouvait donc rapidement se traduire par un vecteur d'attaque massif sur sshd.
Voici le résumé de l'attaque, traduit directement du site https://research.swtch.com/xz-timeline
Publié le lundi 1er avril 2024.
Mise à jour le mercredi 3 avril 2024.
Sur une période de plus de deux ans, un attaquant se faisant appeler « Jia Tan » a travaillé comme un contributeur assidu et efficace à la bibliothèque de compression xz, obtenant finalement un accès en écriture (commit) ainsi qu'un rôle de mainteneur. Grâce à cet accès, il a installé une porte dérobée très subtile et soigneusement dissimulée dans liblzma, une partie de xz qui est aussi une dépendance d'OpenSSH sshd sur Debian, Ubuntu et Fedora, ainsi que sur d'autres systèmes Linux basés sur systemd qui ont patché sshd pour lier libsystemd. (Notez que cela n'inclut pas des systèmes comme Arch Linux, Gentoo ou NixOS, qui ne patchent pas sshd.) Cette porte dérobée guette l'envoi, par l'attaquant, de commandes cachées au début d'une session SSH, conférant ainsi à l'attaquant la capacité d'exécuter arbitrairement des commandes sur la machine cible sans s'authentifier ni ouvrir de session : il s'agit donc d'une exécution de code à distance ciblée et non authentifiée.
L'attaque a été rendue publique le 29 mars 2024 et semble être la première attaque sérieuse connue sur la chaîne d'approvisionnement de logiciels open source largement utilisés. Elle marque un tournant dans la sécurité de la chaîne d'approvisionnement open source, en bien ou en mal.
Cet article propose une chronologie détaillée que j'ai reconstituée sur l'aspect d'ingénierie sociale de l'attaque, qui remonte apparemment à fin 2021.
(Voir aussi mon analyse du script d'attaque.)
Pour toute correction ou ajout, n'hésitez pas à me contacter sur Bluesky, Mastodon ou par e-mail.
2005--2008 : Lasse Collin, avec l'aide d'autres personnes, conçoit le format de fichier .xz en s'appuyant sur l'algorithme de compression LZMA, lequel compresse les fichiers à environ 70 % de la taille obtenue par gzip [1]. Au fil du temps, ce format devient largement utilisé pour la compression d'archives tar, d'images du noyau Linux et de bien d'autres usages.
2021-10-29 : Jia Tan envoie son premier patch, anodin, sur la liste de diffusion xz-devel, ajoutant un fichier « .editorconfig ».
2021-11-29 : Jia Tan envoie son deuxième patch anodin sur xz-devel, corrigeant un problème apparent de reproductibilité de compilation. D'autres patchs apparemment tout à fait inoffensifs (même rétrospectivement) suivront.
2022-02-07 : Lasse Collin intègre le premier commit dont l'auteur, dans les métadonnées git, est « <jiat0218@gmail.com> » (« liblzma: Add NULL checks to LZMA and LZMA2 properties encoders »).
2022-04-19 : Jia Tan envoie encore un patch anodin sur la liste de diffusion xz-devel.
2022-04-22 : « Jigar Kumar » envoie le premier d'une série d'e-mails se plaignant que le patch de Jia Tan n'est pas encore intégré. (« Les patchs restent des années sur cette liste. Il n'y a aucune raison de penser que ça arrivera bientôt. ») À ce stade, Lasse Collin a déjà intégré quatre patchs de Jia Tan, dont les messages de commit mentionnent « Thanks to Jia Tan ».
2022-05-19 : « Dennis Ens » envoie un message sur xz-devel pour savoir si XZ for Java est maintenu.
2022-05-19 : Lasse Collin répond en s'excusant du retard et ajoute : « Jia Tan m'a aidé hors liste pour XZ Utils et il pourrait avoir un rôle plus important à l'avenir, au moins pour XZ Utils. Il est clair que mes ressources sont trop limitées (d'où les nombreux e-mails sans réponse), donc quelque chose doit changer sur le long terme. »
2022-05-27 : Jigar Kumar envoie un e-mail de relance dans le fil de discussion du patch. « Plus d'un mois et toujours aucun progrès pour la fusion. Rien de surprenant. »
2022-06-07 : Jigar Kumar envoie un e-mail de relance au sujet de Java. « Aucun progrès tant qu'il n'y aura pas un nouveau mainteneur. Le journal des commits pour XZ en C est également clairsemé. Dennis, vous feriez mieux d'attendre qu'un nouveau mainteneur soit nommé ou de faire un fork vous-même. Soumettre des patchs ici est inutile en ce moment. L'actuel mainteneur n'est plus motivé ou ne veut plus s'en occuper. C'est triste à voir pour un projet comme celui-ci. »
2022-06-08 : Lasse Collin réagit. « Je n'ai pas perdu tout intérêt, mais ma capacité à me consacrer au projet est assez limitée, principalement pour des raisons de santé mentale à long terme, mais aussi à cause d'autres éléments. Récemment, j'ai un peu travaillé hors liste avec Jia Tan sur XZ Utils, et peut-être qu'il jouera un rôle plus grand à l'avenir. C'est aussi important de rappeler qu'il s'agit d'un projet hobby, non rémunéré. »
2022-06-10 : Lasse Collin intègre le premier commit dont l'auteur est « Jia Tan » dans les métadonnées git (« Tests: Created tests for hardware functions »). À noter aussi qu'il existait un commit antérieur (07/02/2022) où le nom complet était simplement « jiat75 ».
2022-06-14 : Lasse Collin intègre le seul commit dont l'auteur est « <jiat75@gmail.com> ». Il se peut qu'il s'agisse d'une configuration git temporaire oubliée côté Jia Tan.
2022-06-14 : Jigar Kumar envoie un message de relance. « Avec votre rythme actuel, je doute fort que la version 5.4.0 sorte cette année. Le seul progrès depuis avril consiste en quelques petits changements de code de test. Vous ignorez les nombreux patchs qui prennent la poussière sur cette liste de diffusion. À l'heure actuelle, vous bloquez votre dépôt. Pourquoi attendre la 5.4.0 pour changer de mainteneur ? Pourquoi reporter ce dont votre dépôt a besoin ? »
2022-06-21 : Dennis Ens envoie un message de relance. « Je suis désolé pour vos problèmes de santé mentale, mais il est important de connaître ses propres limites. Je comprends que c'est un projet hobby pour tous les contributeurs, mais la communauté en demande plus. Pourquoi ne pas confier le maintien de XZ en C à quelqu'un d'autre pour vous concentrer sur XZ for Java ? Ou confier XZ for Java à une autre personne pour vous concentrer sur XZ en C ? Essayer de maintenir les deux se traduit par deux projets mal entretenus. »
2022-06-22 : Jigar Kumar envoie un message de relance sur le fil du patch en C. « Y a-t-il du nouveau ? Jia, je vois que tu as des commits récents. Pourquoi ne pas fusionner toi-même ce patch ? »
2022-06-29 : Lasse Collin répond : « Comme je l'ai déjà sous-entendu dans des e-mails précédents, Jia Tan pourrait avoir un rôle plus important dans le projet à l'avenir. Il m'a beaucoup aidé hors liste et il est pratiquement déjà co-mainteneur. :-) Je sais que peu de choses ont bougé dans le dépôt git, mais tout se fait par étapes. Quoi qu'il en soit, un changement de maintenance est déjà en cours au moins pour XZ Utils. »
À ce stade, Lasse semble avoir commencé à collaborer encore plus étroitement avec Jia Tan. Brian Krebs note que beaucoup de ces adresses e-mail n'apparaissent nulle part ailleurs sur Internet, même dans des bases de données de fuites (ni non plus sur xz-devel par la suite). Il est probable qu'il s'agisse de faux comptes créés pour faire pression sur Lasse afin qu'il donne plus de contrôle à Jia. La stratégie a fonctionné. Au cours des mois suivants, Jia a commencé à répondre de manière autoritaire à des fils de discussion sur xz-devel au sujet de la future version 5.4.0.
2022-09-27 : Jia Tan donne un résumé concernant la version 5.4.0. (« La version 5.4.0, qui inclura le décompresseur multithread, est prévue pour décembre. La liste des problèmes en cours concernant la 5..4.0 [sic] que je suis est... »)
2022-10-28 : Jia Tan est ajouté à l'organisation Tukaani sur GitHub. Être membre de l'organisation ne donne pas automatiquement un accès particulier, mais c'est une étape nécessaire avant qu'on lui attribue les droits de mainteneur.
2022-11-30 : Lasse Collin remplace son adresse personnelle pour les rapports de bogues par un alias qui redirige vers lui et Jia Tan, et précise dans le fichier README que « les mainteneurs du projet, Lasse Collin et Jia Tan, peuvent être contactés via <xz@tukaani.org> ».
2022-12-30 : Jia Tan fusionne directement un lot de commits dans le dépôt xz (« CMake: Update .gitignore for CMake artifacts from in source build »). À ce moment-là, nous savons qu'il dispose d'un accès en écriture. Fait intéressant, un peu plus loin dans le même lot, on trouve le seul commit dont le nom complet est « Jia Cheong Tan ».
2023-01-11 : Lasse Collin publie et crée son dernier tag de version, v5.4.1.
2023-03-18 : Jia Tan publie et crée pour la première fois une version (tag) sous sa responsabilité, v5.4.2.
2023-03-20 : Jia Tan met à jour la configuration de Google oss-fuzz pour que les rapports de bugs lui soient envoyés.
2023-06-22 : Hans Jansen envoie deux patchs, intégrés par Lasse Collin, qui utilisent la fonctionnalité « GNU indirect function » pour sélectionner à l'exécution une fonction CRC plus rapide. Le commit final est retravaillé par Lasse Collin et fusionné par Jia Tan. Ce changement est important, car il fournit un point d'ancrage permettant au code de la porte dérobée de modifier les tables de fonctions globales avant qu'elles ne soient remappées en lecture seule. Bien que ce changement puisse être un simple ajout d'optimisation des performances, Hans Jansen réapparaîtra en 2024 pour promouvoir la version xz compromise et n'existe pas ailleurs sur Internet.
2023-07-07 : Jia Tan désactive le support ifunc pendant les builds oss-fuzz, affirmant que ifunc est incompatible avec AddressSanitizer. Cela pourrait être anodin en soi, bien que cela prépare aussi la voie à l'utilisation ultérieure d'ifunc.
2024-01-19 : Jia Tan déplace le site web vers GitHub Pages, ce qui lui donne le contrôle de la page web de XZ Utils. Lasse Collin a sans doute créé l'enregistrement DNS pour le sous-domaine xz.tukaani.org pointant vers GitHub Pages. Après la découverte de l'attaque, Lasse Collin a supprimé cet enregistrement DNS pour ramener le site sous tukaani.org, qu'il contrôle.
2024-02-23 : Jia Tan fusionne un code binaire de porte dérobée dissimulé dans quelques fichiers binaires de test. Le fichier README indiquait déjà (bien avant l'arrivée de Jia Tan) : « Ce répertoire contient un tas de fichiers pour tester la gestion des fichiers .xz, .lzma (LZMA_Alone) et .lz (lzip) dans les implémentations de décompresseur. Beaucoup de ces fichiers ont été créés à la main à l'éditeur hexadécimal, il n'y a donc pas de "code source" plus détaillé que ces fichiers eux-mêmes. » Il est très courant pour ce type de bibliothèque de conserver de tels fichiers de test. Jia Tan en a profité pour y insérer quelques fichiers que personne n'examinerait en détail.
2024-02-24 : Jia Tan crée le tag de la version v5.6.0, publie et diffuse un paquet xz-5.6.0.tar.gz qui contient un script build-to-host.m4 malveillant pour ajouter la porte dérobée lors de la construction de paquet deb/rpm. Ce fichier m4 n'est pas présent dans le dépôt source, mais de nombreux autres fichiers légitimes y sont ajoutés au moment de la génération du paquet, donc cela ne suscite pas de soupçon à première vue. Toutefois, le script a été modifié par rapport à la copie habituelle pour inclure la porte dérobée. (Voir mon analyse pas à pas du script d'attaque xz.)
2024-02-24 : Gentoo commence à constater des plantages avec la version 5.6.0. Cela semble être un véritable bug lié à ifunc plutôt qu'un bogue de la porte dérobée cachée, puisque c'est la première version de xz avec les modifications ifunc de Hans Jansen, et Gentoo ne patchant pas sshd pour utiliser libsystemd, la porte dérobée n'a aucun effet là-bas.
2024-02-26 : Debian ajoute xz-utils 5.6.0-0.1 dans la branche unstable.
2024-02-27 : Jia Tan commence à contacter Richard W.M. Jones pour mettre à jour Fedora 40 (confirmé en privé par Rich Jones).
2024-02-28 : Debian ajoute xz-utils 5.6.0-0.2 dans unstable.
2024-02-28 : Jia Tan casse la détection de Landlock dans le script configure en introduisant une faute de frappe subtile dans le programme C utilisé pour vérifier la prise en charge de Landlock. Le script configure essaie de compiler et exécuter ce petit programme C pour tester la présence de Landlock, mais comme le programme a une erreur de syntaxe, il ne peut jamais être compilé ni exécuté, et le script conclut systématiquement que Landlock n'est pas disponible. Lasse Collin est indiqué comme « committer » ; il a peut-être manqué la faute de frappe, ou bien l'auteur est usurpé. Il est probable qu'il ait tout simplement raté l'erreur, étant donné que Jia Tan n'a pas cherché à usurper la paternité de ses nombreux autres commits. Ce patch semble préparer autre chose que la modification de sshd, puisque Landlock concerne l'outil xz et non liblzma. On ne sait pas exactement quoi, pour l'instant.
2024-02-29 : Sur GitHub, @teknoraver ouvre une pull request pour arrêter de lier liblzma dans libsystemd. Cela aurait vraisemblablement empêché l'attaque de fonctionner. Kevin Beaumont suppose que, sachant cette modification imminente, l'attaquant a accéléré son plan. @teknoraver a expliqué sur HN qu'il s'agissait d'une PR faisant partie d'une série de changements destinés à alléger les dépendances de libsystemd ; on en avait déjà parlé deux fois fin janvier.
2024-03-04 : Les distributions RedHat commencent à observer des erreurs Valgrind dans la fonction _get_cpuid de liblzma (le point d'entrée de la porte dérobée). La course est lancée pour corriger cela avant que les distributions Linux n'examinent le problème de trop près.
2024-03-05 : La pull request supprimant la dépendance à liblzma est fusionnée dans libsystemd. Une autre course contre la montre s'engage, pour que la porte dérobée soit efficace avant que les distributions ne suppriment complètement cette dépendance.
2024-03-05 : Debian ajoute xz-utils 5.6.0-0.2 dans la branche testing.
2024-03-05 : Jia Tan intègre deux correctifs de bogues ifunc. Ils semblent être de véritables correctifs pour un réel bogue d'ifunc. Un des commits fait référence au bug Gentoo et fait aussi une faute de frappe dans le numéro de bug GCC.
2024-03-08 : Jia Tan intègre un soi-disant correctif pour Valgrind. C'est une diversion, mais elle fonctionne.
2024-03-09 : Jia Tan met à jour les fichiers de porte dérobée. C'est le vrai correctif pour Valgrind, modifiant les deux fichiers de test contenant le code d'attaque. « Les fichiers originaux ont été générés aléatoirement en local sur ma machine. Pour mieux reproduire ces fichiers à l'avenir, j'ai utilisé une graine constante pour les recréer. »
2024-03-09 : Jia Tan publie la version 5.6.1 (tag) et distribue xz 5.6.1, qui contient une nouvelle variante de la porte dérobée. À ce jour, je n'ai pas vu d'analyse détaillant les différences entre l'ancienne et la nouvelle.
2024-03-20 : Lasse Collin envoie à la LKML (Linux Kernel Mailing List) une série de patches remplaçant son e-mail personnel par un contact mainteneur mentionnant à la fois lui et Jia Tan pour le code de compression xz dans le noyau. Rien n'indique que Lasse Collin ait ici une intention malveillante ; il s'agit probablement de mettre à jour les références à l'entretien du code. Bien sûr, Jia Tan l'a peut-être encouragé à le faire, et pouvoir envoyer des patchs xz au noyau Linux aurait pu constituer un levier intéressant pour l'attaquant. On n'est pas encore au niveau d'une attaque « Reflections on Trusting Trust », mais on s'en rapproche.
2024-03-25 : Hans Jansen réapparaît (!), en ouvrant un rapport de bogue Debian pour mettre à jour xz-utils vers 5.6.1. Comme durant la campagne de pression de 2022, on voit d'autres adresses mail du style nom###@fournisseur qui n'existent pas ailleurs sur Internet et qui militent pour cette mise à jour.
2024-03-27 : Debian passe à la version 5.6.1.
2024-03-28 : Jia Tan dépose un rapport de bug Ubuntu pour obtenir la mise à jour de xz-utils 5.6.1 (depuis Debian).
2024-03-28 : Andres Freund découvre la faille et en informe en privé Debian et distros@openwall. RedHat attribue l'identifiant CVE-2024-3094.
2024-03-28 : Debian revient en arrière depuis la 5.6.1 à la version 5.6.1+really5.4.5-1.
2024-03-28 : Arch Linux modifie le paquet 5.6.1 pour le construire depuis Git (plutôt que depuis l'archive tar).
2024-03-29 : Andres Freund publie un avertissement relatif à la porte dérobée sur la liste publique oss-security@openwall, indiquant qu'il l'a découverte « au cours des dernières semaines ».
2024-03-29 : RedHat annonce que la version xz compromise a été livrée dans Fedora Rawhide et Fedora Linux 40 Beta.
2024-03-30 : Debian arrête momentanément les builds pour reconstruire ses machines de build avec Debian stable (au cas où le xz malveillant aurait échappé à leur bac à sable ?).
2024-03-30 : Haiku OS bascule vers des instantanés du dépôt GitHub comme source de xz.