- Selon une analyse préliminaire de rétro-ingénierie de la porte dérobée xz, ce comportement se rapproche d’une exécution de code à distance (RCE) plutôt que d’un simple contournement d’authentification
- Le point central est le flux dans lequel
RSA_public_decrypt, détourné par hook, vérifie la signature de la clé hôte du serveur avec une cléEd448fixe - Si la vérification de signature réussit, la charge utile peut être transmise à
system()pour être exécutée - L’analyse correspond à des résultats préliminaires partagés avec autorisation, et la publication Bluesky contient une citation ou du contenu intégré
- La porte dérobée est résumée comme ayant une porte d’entrée et étant non rejouable, et doit donc être distinguée d’une attaque reposant sur la simple réutilisation de la même entrée
Flux d’exécution de la porte dérobée xz
- L’analyse préliminaire de rétro-ingénierie, partagée avec autorisation, se concentre sur
RSA_public_decrypt, détourné par hook- vérifie la signature de la clé hôte du serveur avec une clé
Ed448fixe - après vérification, transmet la charge utile à
system()
- vérifie la signature de la clé hôte du serveur avec une clé
Classification et contraintes
- Ce comportement est classé non comme un contournement d’authentification, mais comme une exécution de code à distance (RCE)
- La porte dérobée est résumée comme possédant des caractéristiques gated/unreplayable
- La publication Bluesky d’origine contient une citation ou un autre contenu intégré
1 commentaires
Avis sur Hacker News
Il existe des résultats de reverse engineering supplémentaires sur cette affaire. Ils contiennent les informations de remapping de symboles extraites du prefix trie que la backdoor utilisait pour masquer des chaînes, et il semble qu’elle ait aussi tenté de se dissimuler au reverse engineering et à l’analyse eux-mêmes
https://gist.github.com/smx-smx/a6112d54777845d389bd7126d6e9...
La liste complète des chaînes décodées se trouve ici
https://gist.github.com/q3k/af3d93b6a1f399de28fe194add452d01
Pour quelqu’un qui connaît mal les internes d’OpenSSL, la valeur N semble venir du champ
ndersa_sthttps://github.com/openssl/openssl/blob/56e63f570bd5a479439b...
Cette valeur est un
BIGNUM, et semble être un type de longueur variablehttps://github.com/openssl/openssl/blob/56e63f570bd5a479439b...
La backdoor extrait cette valeur du certificat reçu de l’attaquant distant, tente de la déchiffrer avec ChaCha20 et, en cas de succès, la transmet à
system().system()est essentiellement un simple wrapper qui exécute une ligne de script shell avec les privilèges de l’utilisateur sous lequel tourne le processus courantSi je comprends bien, c’est pire qu’un contournement de clé publique. Avec un contournement de clé publique, en théorie, on n’obtiendrait que les droits de l’utilisateur qui tente de se connecter, et il est très probable que les configurations SSH renforcées aient désactivé la connexion root
Mais ici, il s’agit d’une exécution de code à distance dans le contexte même du processus
sshd, donc sisshdtourne en root, la charge utile peut elle aussi s’exécuter en root. Pour une exécution de code à distance largement répandue, c’est pratiquement ce qu’il y a de pireJe me demande quelle aurait été la probabilité que cette backdoor soit découverte plus tard si elle ne l’avait pas été à cause d’un problème de performance. J’avais compris que le problème de performance était une erreur dans le code / un défaut corrigeable, et il est important de savoir s’il existait des outils capables de le détecter
Ce genre de question est très lié au fait de comprendre si ce type de backdoor est une première, ou seulement la première à avoir été révélée
Une seule petite erreur peut tout faire s’effondrer, et parfois une simple phrase suffit à déclencher une réaction en chaîne qui révèle un plan minutieusement élaboré
Les enquêtes criminelles se déroulent comme ça tous les jours. Le travail de police est limité par les ressources, mais les logiciels sont examinés chaque jour par des gens qui les analysent par passion, par des spécialistes qui continuent à le faire comme un hobby, et par des professionnels dont c’est le métier
Au final, il est très probable que cela aurait été découvert un jour
L’attaque contre XZ a été très bien exécutée, presque un chef-d’œuvre. Je ne serais pas surpris qu’un organisme étatique ait été impliqué. Mais elle a aussi bénéficié d’une chance incroyable. Si l’un des éléments désormais signalés comme problématiques avait été découvert, beaucoup de collègues, pas seulement moi, se seraient lancés dans une longue traque
Une conclusion qu’on peut en tirer, c’est que si xz/liblzma n’avait pas été open source, il aurait été impossible de trouver ce problème. Bien sûr, c’est aussi parce que c’était open source que cela a été possible au départ, mais imaginez que cela ait été dans Windows ou MacOS
Mais s’il n’est pas utilisé, il n’atteint pas son objectif. Plus il est utilisé, plus la probabilité qu’il soit détecté par la suite augmente aussi. La comparaison avec SolarWinds est pertinente
Personnellement, l’appel à
system()était assez grossier, et un scanner de fonctionnalités binaires aurait peut-être pu trouver ce cheminsshdintervient à une étape acceptable, celle de l’édition de liens, et si cette analyse est correcte, ce n’est pas non plus une backdoor à clé maître, donc il n’y a pas de traces d’audit de connexion classiques. Et le fait quesshdlance d’autres processus peut évidemment être autoriséUne politique SELinux très fine pourrait peut-être détecter que
sshdexécute autre chose qu’un shell, mais un tel niveau de durcissement est probablement très rareLa question de la détection en dehors de la cible a en quelque sorte déjà été expérimentée. Plusieurs personnes ont examiné la charge utile avec
valgrindet d’autres outils, sans rien voir. Elle est aussi assez bien protégée pour ne pas être découverte dans un environnement de débogage. L’infrastructure exposée sous la charge utile n’est en effet pas compatible avec des outils comme ASanMême lorsqu’il est lié, le code s’exécute bien avant
main(), donc en fouillant autour deliblzmaavec un débogueur, on n’observe généralement pas son exécutionAvec
strace, on peut voir tous les appels système et les actions du linker après la création du processus. Mais d’après ce qu’on sait pour l’instant, la charge utile ne semble pas effectuer d’appels système à ce stade pour décider si elle doit s’activer ; elle semble plutôt examinerargv,environ, etc.[0] https://en.wikipedia.org/wiki/PWB/UNIX
[1] https://news.ycombinator.com/item?id=38020792
Il semble qu’une chaîne soit encodée dans la charge utile binaire
https://gist.github.com/q3k/af3d93b6a1f399de28fe194add452d01...
Cette chaîne agit comme un kill switch
https://piaille.fr/@zeno/112185928685603910
Si c’est vraiment le cas, une mesure d’atténuation possible serait la suivante
-a. Sinon, vous risquez de vider le fichier d’environnement. Et, en général, la bonne chose à faire est de mettre à jour vers une version sans code malveillant, puis de redémarrerQuelqu’un peut-il expliquer simplement ce que fait exactement la backdoor ? Le sait-on déjà ? La backdoor elle-même ne semble pas être la charge utile ; je me demande s’il faut une archive malveillante, ou si elle accroche le processus
sshdpour écouter les paquets malveillants d’un attaquant distantLe texte d’origine donne l’impression que l’attaquant peut envoyer une charge utile malveillante lors de la phase préalable à l’authentification d’une session SSH, mais je ne comprends pas non plus pourquoi il est dit qu’un exploit pourrait ne jamais voir le jour. Si l’on peut rétroconcevoir le code, ne peut-on pas aussi écrire une preuve de concept ?
Au final, comment l’attaquant prend-il le contrôle d’une machine qui contient cette backdoor ?
La situation est similaire ici. Avant de faire quoi que ce soit de suspect, xz tente de déchiffrer certaines données. Comme il s’agit d’un mécanisme asymétrique, il est possible de vérifier le déchiffrement sans fournir la clé de chiffrement secrète, car on dispose de la clé publique correspondante
Comme il est pratiquement impossible de trouver la clé secrète, et que l’échec du déchiffrement de la charge utile ne provoque pas de comportement visiblement différent, le code d’exploitation pourrait ne jamais être rendu public. Le seul moyen de créer un code d’exploitation serait que la clé secrète soit découverte d’une manière ou d’une autre, ce qui, en pratique, ne pourrait arriver que si le développeur de la backdoor la divulguait
sshdchargelibsystemd, qui charge à son tour la bibliothèque XZ contenant le code compromisLa bibliothèque XZ injecte ses propres versions des fonctions OpenSSL qui vérifient les signatures RSA
Lorsqu’une personne se connecte en SSH et présente un certificat SSH signé pour l’authentification, ces fonctions modifiées sont appelées
Un certificat peut contenir, dans le processus normal de connexion, des assertions comme le nom d’utilisateur ou le rôle, qui servent à déterminer si le certificat est valable pour la connexion d’un utilisateur donné. Mais si la fonction modifiée détecte un certificat signé avec une clé d’attaquant précise, elle extrait certains sous-champs du certificat et les exécute comme commande système. Le contexte d’exécution est
sshd, donc l’utilisateur rootMalheureusement, on ne connaît pas la clé de signature de l’attaquant ; on connaît seulement la clé publique utilisée par le code compromis pour la vérification. En gros, l’attaquant peut exécuter des commandes arbitraires en root sur un système infecté, et les traces se limiteraient au mieux à une tentative de connexion échouée. Sur un système exposé à Internet, ce genre de tentative est déjà très fréquent
Le point essentiel est qu’il faut une signature produite avec la clé de l’attaquant. Tant que cette clé n’est pas divulguée ou que l’algorithme RSA n’est pas cassé, il est impossible pour d’autres chercheurs ou des tiers d’exploiter cette backdoor. Si RSA était cassé, il y aurait des problèmes bien plus graves que celui-ci
Pour l’instant, seul l’attaquant peut exécuter l’exploit, donc il est également impossible de scanner. À part des effets secondaires comme une baisse de performance, il est difficile à détecter — et c’est d’ailleurs ainsi qu’il a été découvert
Il est difficile de comprendre comment un paquet aussi essentiel, utilisé chaque jour par autant de serveurs Linux, peut en arriver à ne plus être maintenu par son auteur d’origine faute de financement. Quelque chose doit changer dans l’open source
Une solution pourrait être une licence obligeant les entreprises ou organisations au-delà d’une certaine taille à payer des frais de maintenance
Les vendeurs ont donc une incitation à maintenir l’open source sûr : payer les mainteneurs, commander des audits de code, ou embaucher des salariés à temps plein pour contribuer
Si l’on va actuellement sur le dépôt xz, il est désactivé pour violation des conditions d’utilisation de GitHub. La désactivation en elle-même est compréhensible, mais j’aimerais que GitHub conserve le code et l’historique, affiche une bannière et bloque seulement les fonctionnalités exploitables
Cela permettrait aux chercheurs et à d’autres personnes d’étudier l’exploit. Dans des situations plus mineures, si une bibliothèque héberge du code malveillant et que le dépôt est supprimé, on pourrait simplement conclure que ce n’était pas grand-chose
Si le code source vous intéresse, il est facile à trouver. Ce code et le dépôt Git sont reliés à de nombreux dépôts Git dans le monde entier, et les sources ont aussi été intégrées plusieurs fois dans les releases
En tant que mainteneur de fait d’un jeu open source peu connu, j’ai vu des développeurs aller et venir. Toute contribution utile, je la fusionne simplement
Certains collaborateurs vont assez loin dans les fonctionnalités, dans un mélange de C et de C++ aux styles de code variés. Je ne saisis pas toujours tous les détails d’implémentation, mais quelque part je me dis que si quelqu’un y glissait une backdoor vraiment malveillante, le projet serait fichu
Heureusement, le jeu est très obscur et sa surface d’attaque est minuscule. Malgré tout, cela m’a coupé l’envie de signer de bonne foi des binaires Windows
Cette backdoor xz est vraiment un cauchemar gigantesque, et je plains les développeurs d’origine ainsi que toutes les personnes entraînées là-dedans
Quand on marche sur un chemin en forêt, une voiture qui passe peut tout simplement vous renverser. Le conducteur a de fortes chances de ne jamais être retrouvé, il n’y a aucun moyen de l’empêcher, et la police n’est pas à côté. Ce scénario, bien plus effrayant qu’une backdoor logicielle, est en réalité le niveau minimal de risque qu’il faut accepter pour vivre en faisant quoi que ce soit. Et cela arrive effectivement
Mais, au bout du compte, l’immense majorité des gens ne cherchent pas activement à nuire aux autres. Tout ce que font les humains a toujours reposé sur cette hypothèse, et c’est encore le cas
La véritable illusion problématique, c’est de croire qu’un peu plus de rigueur dans les revues de code, davantage de linters, de CI et de pattern matching, une adoption plus large de la signature de code et la vérification de l’identité des gens empêcheront ce genre de chose. C’est un symptôme du délire à la Silicon Valley selon lequel le monde peut et doit être géré et contrôlé à tous les niveaux de détail. De tels « remèdes » peuvent être bien pires que n’importe quel mal qu’ils prétendent prévenir
[1]: http://hintjens.com/blog:106
Je comprends l’avantage de créer une communauté où les contributeurs prennent plaisir à participer au projet. Mais j’ai eu l’impression que cela faisait grandir le projet sans vision ni direction claires, et finissait par faire peser une charge excessive sur les mainteneurs pour remettre les contributions des autres au niveau d’un standard commun
La vraie revue de code est repoussée à un moment inconnu dans le futur, sans garantie qu’elle soit approfondie ni que quelqu’un en assume la responsabilité ou corrige les problèmes. Au final, cela ressemble à une recette pour le chaos, où l’on ne contrôle plus ce qui est livré aux utilisateurs
Il y a aussi le problème de la distribution de code malveillant. Cette question apparaît également dans les commentaires de l’article de blog, et Pieter y décrit exactement le même scénario que dans le cas de xz
« Supposons que Mallory soit patiente, trompeuse, et qu’elle se comporte suffisamment longtemps comme une contributrice légitime pour obtenir le contrôle du projet, puis introduise lentement une backdoor. Alors même une revue de code prudente n’aide pas. Mallory n’a qu’à gagner suffisamment de confiance pour devenir mainteneuse ; ce n’est pas une question de possibilité, mais de méthode. »
Il conclut que « la meilleure défense est la taille et la diversité de la communauté »
Mais je pense qu’une revue de code prudente peut réellement réduire la probabilité que cela se produise. Si toutes les contributions, qu’elles viennent de contributeurs de confiance ou de contributeurs externes, sont examinées en profondeur, on a davantage de chances de repérer plus tôt un comportement étrange, ou un commit qui prétend « faire A » alors qu’il fait en réalité B
Il est également discutable que l’Optimistic Merging mène à une communauté plus grande et plus diverse. Beaucoup de projets ont des communautés actives tout en appliquant des directives de contribution strictes. Et cela ne répond pas à la question de savoir quand ni comment détecter les patchs malveillants
Le problème de xz n’était pas une petite communauté, mais l’absence de communauté. Un acteur malveillant unique a obtenu le contrôle du projet, presque sans supervision de la part de qui que ce soit d’autre. Les directives de contribution n’étaient pas un facteur dans la taille de la communauté, et cela serait arrivé avec ou sans Optimistic Merging
[2]: http://hintjens.com/blog:106/comments/show#post-2409627
brew install caskou des extensions vi/emacs/vscode est parfaitement banalRust est sans doute le langage de programmation/la communauté où les valeurs par défaut sont les plus sûres, avec une conception axée sécurité qui empêche presque totalement les bidouilles de pointeurs. Et pourtant, le chemin d’installation le plus courant et recommandé est celui-ci, que j’utilise souvent moi-même en parfait hypocrite
https://www.rust-lang.org/tools/install
Ce n’est qu’un exemple. L’habitude de dire « faites un
curlde ceci et pipez-le danssh», donc d’ouvrir soi-même la porte à l’exécution de code distant, tout en débattant du blocunsafede quelqu’un, est devenue un réflexe musculaire chez beaucoup trop de gensJe suis désolé que cela soit arrivé, mais pas surpris. J’espère que de meilleurs outils pour faire face à ce genre d’acteurs malveillants verront le jour, et qu’ils seront eux aussi open source
Cette backdoor soulève plusieurs questions. Quelles autres backdoors la même équipe, ou une équipe similaire, a-t-elle implantées ? Combien d’équipes de ce genre sont actives ? Combien de dépendances sont vulnérables à ce type d’attaque par infiltration ? Quelle est la surface d’attaque de notre industrie pour ce genre d’opérations clandestines ciblées ?
Établir le graphe de tous les services réseau majeurs comme
apache httpd,postgres,mysql,nginx,openssh,dropbear ssh,haproxy,varnish,caddy,squid,postfix, de toutes leurs dépendances, ainsi que de tous les graphes de committers de ces dépendances, pourrait être une première étape pour déterminer où se trouvent les cibles les plus précieuses et les moins surveilléesIl est impossible que ce soit la première fois que quelqu’un tente une chose pareille. C’est seulement le premier cas qui a été révélé parce qu’il a échoué. On connaît des backdoors qui ont été tentées et découvertes dans le noyau Linux, mais ici il s’agit d’une attaque à distance, d’une nature totalement différente
Pourquoi ne pas avoir diffusé quelque chose d’apparemment anodin, qui aurait pu passer pour un bug en cas de détection, et avoir au contraire implémenté une backdoor pleinement fonctionnelle tout en dissimulant son mode de diffusion ?
Ce choix a forcément été délibéré. Sa raison pourrait donner un indice sur l’objectif visé
Cela semble signifier que, pour scanner l’exploit à distance, il nous faudrait la clé privée de l’attaquant, que nous n’avons pas. L’autre option consiste seulement à exécuter un script de détection en local
Tant qu’il n’est pas établi que ce problème s’est largement répandu sur des systèmes réels, cette approche paraît pire que les recommandations d’« experts » similaires qui exigeaient autrefois de changer de mot de passe chaque année, ce qui diminuait la sécurité réelle tout en améliorant seulement la sécurité sur le papier
La vérification de signature de la backdoor devrait prendre environ 100 µs, donc une clé dont l’empreinte correspond devrait être traitée avec ce délai supplémentaire par rapport aux autres. Cette différence de temps est réalistement détectable au moins sur un LAN, et pourrait aussi l’être à travers Internet si le scanner s’exécute à proximité de la cible
Les systèmes qui bloquent l’IP cliente après des échecs d’authentification répétés rendront le scan plus difficile
(https://bench.cr.yp.to/results-sign.html indique qu’une vérification Ed448 prend environ 400 000 cycles, ce qui correspond à 100 µs à 4 GHz)
sshdbackdooré émet un challenge que l’attaquant doit signer ?Ce sera peut-être une opinion impopulaire, mais je ne peux pas m’empêcher d’admirer l’ensemble de l’opération. Bien sûr, je la condamne, mais elle force quand même l’admiration. De la conception à l’exécution, c’était vraiment comme une œuvre d’art, et le fait qu’elle ait été repérée si tôt relève d’une chance incroyable
La prochaine fois, les attaquants créeront probablement un payload qui ne provoque pas de pics de latence étranges dans une opération qu’un humain attend en direct
Cela me rappelle curieusement la manière dont Kim Dotcom a découvert qu’il faisait l’objet d’écoutes illégales. Son ping avait soudainement fortement augmenté dans MW3. En enquêtant, il s’est avéré que seuls ses paquets à lui étaient physiquement routés via les bureaux du GCSB, situés très loin. Le GCSB n’a pas le droit de surveiller les résidents permanents néo-zélandais. Au final, il a reçu des excuses personnelles du Premier ministre néo-zélandais
À mon avis, la partie la plus brillante a été le choix du projet à infiltrer. Relire après coup la discussion de la pull request IFUNC de « Hans » fait mal au cœur, mais montre très bien pourquoi ce projet a été choisi
J’aimerais savoir combien de personnes se trouvaient derrière « Jia » et « Hans », et comment elles ont analysé et planifié les communications et les contributions de code. Certains aspects, comme ces sortes de troisièmes personnalités jouant la pression sur la mailing list, semblent avoir été construits de manière assez maladroite
Il reste donc possible que ce soit l’œuvre d’une petite équipe sophistiquée, voire d’une seule personne. S’il s’agissait d’un acteur étatique, j’imaginerais qu’il dispose de gens chargés à plein temps de créer et maintenir de fausses identités pour ce genre d’opération
Si quelqu’un s’était dit : « C’est bizarre, ces trois utilisateurs poussent un peu brutalement, qui sont-ils ? Leurs comptes ont tous été créés à peu près au même moment. Suspect. Pourquoi quelqu’un pousserait-il ça aussi fort avec de faux comptes ? Il faudrait enquêter », cela aurait posé problème. Par rapport à l’effort global engagé, cette partie était donc négligente, mal planifiée ou sous-financée
Pour ajouter une hypothèse dramatique, l’attaquant a peut-être pris peur devant la bombe informationnelle qu’il était sur le point de faire exploser et a saboté l’opération volontairement
On peut détester le résultat final tout en reconnaissant la complexité de l’attaque