2 points par GN⁺ 2024-04-10 | 1 commentaires | Partager sur WhatsApp
  • En 2008, un travail visant à corriger le goulot d’étranglement des connexions SSH de GitHub a mis en lumière des collisions anormales où des utilisateurs différents avaient la même empreinte de clé SSH
  • Pour éviter le problème de recherche linéaire dans un fichier authorized_keys devenu énorme, GitHub a patché OpenSSH afin de rechercher les empreintes de clés dans MySQL
  • Après le déploiement du patch, des accès en SSH aux dépôts d’autres utilisateurs sont apparus, mais la répétition des collisions d’empreintes rendait peu probable un simple bug du patch
  • Le 13 mai 2008, la publication de DSA-1571-1 a confirmé que l’OpenSSL de Debian avait généré pendant environ 18 mois des clés privées prévisibles, réduisant le nombre de clés possibles à un peu plus de 32 000 par utilisateur
  • Les grands incidents de sécurité commencent souvent par un petit signal disant « c’est étrange », et la vraie différence vient du temps et des compétences permettant de suivre cette piste jusqu’au bout

Un incident parti d’un goulot d’étranglement sur les connexions SSH de GitHub

  • En mars 2008, l’auteur, alors chez Engine Yard, a été amené à aider GitHub, client de cette société d’hébergement centrée sur Rails, sur un problème de performance des connexions SSH
  • GitHub fournissait l’accès aux dépôts Git via une connexion SSH à git@github.com, suivie d’une authentification par clé publique
  • À l’époque, la gestion des clés reposait sur la méthode classique via le fichier ~/.ssh/authorized_keys
    • Quand SSH reçoit une demande d’authentification par clé publique, il ouvre le fichier authorized_keys et effectue une recherche linéaire pour trouver une entrée correspondant à la clé soumise
    • Pour un compte classique avec seulement quelques clés, ce n’est pas un gros problème, mais chez GitHub, en pleine croissance, toutes les clés SSH s’accumulaient dans un seul gros fichier et le temps de connexion ralentissait visiblement

Patch OpenSSH et recherche des clés dans MySQL

  • Après avoir étudié plusieurs solutions, l’équipe GitHub et l’auteur ont choisi de patcher OpenSSH pour rechercher les clés dans une base de données MySQL à partir de leur empreinte
  • Ce n’était pas une modification à prendre à la légère
    • Modifier OpenSSH pouvait avoir des conséquences de sécurité critiques en cas d’erreur
    • Les autres options étaient encore pires, donc cela a été jugé comme la solution « la moins mauvaise »
  • Une grande partie du travail a consisté à vérifier que la modification ne compromettait pas la sécurité
  • Après le déploiement au début d’avril 2008, les connexions SSH sont devenues plus rapides et le problème semblait réglé pour un bon moment

Un symptôme apparemment impossible : des empreintes de clés dupliquées

  • Début mai 2008, l’équipe GitHub a signalé que certains utilisateurs pouvaient accéder en SSH aux dépôts d’autres utilisateurs
  • Comme le problème touchait directement à l’authentification par clé SSH et qu’un patch OpenSSH venait juste d’être déployé, le code écrit par l’auteur est devenu le principal suspect
  • Le débogage a fini par montrer que deux utilisateurs différents avaient la même empreinte de clé
    • C’était pratiquement impossible à moins que les utilisateurs ne partagent volontairement la même clé
    • Les utilisateurs concernés ne se connaissaient pas et affirmaient n’avoir jamais rendu leur clé publique
  • Peu après, la même empreinte de clé a été observée chez une autre paire d’utilisateurs, avec cette fois une valeur différente de la première
    • Il devenait difficile d’expliquer cela par un simple hasard ou par un bug de l’application web
  • Une fois suffisamment établi que le patch OpenSSH n’était pas en cause, l’auteur s’est moins impliqué directement
    • Il n’était pas employé par GitHub et devait aussi s’occuper d’autres clients d’Engine Yard
    • L’équipe GitHub a continué à interroger les utilisateurs et a découvert un point commun : les clés SSH avaient été générées sur des systèmes Debian ou Ubuntu

La divulgation de la vulnérabilité Debian OpenSSL révèle la cause

  • Le 13 mai 2008, la publication de DSA-1571-1 a clarifié la situation
  • Le paquet OpenSSL de Debian générait depuis environ 18 mois des clés privées prévisibles
  • La cause venait d’un nettoyage du code de génération aléatoire d’OpenSSL au cours duquel un mainteneur Debian avait involontairement fortement réduit l’espace de clés possible
    • Le nombre de clés possibles qu’un utilisateur donné pouvait générer est passé d’un nombre « astronomique » à un peu plus de 32 000
    • Comme de nombreux utilisateurs rejoignaient GitHub, certains ont pu générer une nouvelle clé séparée, comme le recommandaient les bonnes pratiques, et cela pouvait produire des collisions
  • Cette divulgation a apporté la preuve décisive que le patch OpenSSH de l’auteur n’était pas responsable

Les travaux ultérieurs autour des weak keys de Debian

  • L’auteur a ensuite eu d’autres occasions de travailler sur les weak keys de Debian
  • Il exploite pwnedkeys.com, qui gère un vaste dépôt de clés compromises connues
  • Il a aussi utilisé ces clés pour identifier une autorité de certification défaillante

Le temps de suivre jusqu’au bout ce qui « semble étrange »

  • L’auteur n’a pas réussi à déterminer exactement quand et comment Luciano Bello a découvert la vulnérabilité devenue CVE-2008-0166
  • Comme la version stable de Debian contenant le code vulnérable était sortie un an avant la divulgation, il est possible qu’il y ait eu du temps pour voir des collisions de clés, se dire « c’est étrange », puis creuser davantage
  • Le backdoor XZ récent est lui aussi présenté comme un cas révélé à partir d’une observation disant « c’est étrange », suivie d’une enquête approfondie
  • Le point crucial est d’avoir réellement la capacité et le temps de mener ce type d’enquête poussée
    • L’auteur n’a pas pu mener lui-même cette investigation en profondeur à l’époque
    • L’équipe GitHub était occupée par le développement produit et la gestion des incidents sur un service en forte croissance
    • Lui-même traitait aussi des tickets de support chez Engine Yard
  • Une vraie différence se produit quand, au bon moment, quelqu’un ayant les compétences, le temps et l’énergie peut suivre une piste jusqu’au bout

1 commentaires

 
GN⁺ 2024-04-10
Avis de Hacker News
  • À propos du passage « on n’a pas trouvé exactement quand ni comment Luciano Bello a découvert la vulnérabilité qui deviendrait plus tard CVE-2008-0166 », les logs IRC de l’époque indiquent ceci
    17:23 < luciano> has really an accident. I was needing many primes numbers... 0:-)
    17:23 < Sesse> and you got the same numbers every time?
    17:25 < luciano> Sesse, not every time :P

    • À en juger par ces seuls logs, Luciano semble avoir trouvé étrange d’obtenir plus de collisions que prévu en générant des clés en masse
  • La phrase selon laquelle « le secteur a eu de la chance qu’une personne avec les bonnes compétences, le temps et l’énergie soit là au bon moment » rend très concrètes les statistiques derrière les nombreux regards et l’idée que « la lumière du soleil est le meilleur désinfectant »
    Aussi improbable que puisse paraître le fait que quelqu’un tombe par hasard sur un bug, cela peut arriver, donc cela arrive réellement
    Dans du code propriétaire/fermé, cette probabilité est proche de zéro

    • Je considère que l’affaire xz a été une grande victoire de l’open source
      Quelqu’un a remarqué quelque chose d’anormal et, avec le code source, a pu vérifier la situation réelle et constater qu’il s’était passé quelque chose de suspect
      Les experts sécurité des principales distributions ont été contactés pour un examen plus poussé, et eux aussi ont confirmé le problème de sécurité puis ont pu réagir immédiatement
      Après la divulgation publique, des personnes expertes dans divers domaines du logiciel et de la sécurité ont pu décortiquer ce qui avait été fait, comment, et quels étaient les risques
      Des commits suspects laissés par le même développeur dans d’autres logiciels ont aussi été retrouvés et vérifiés, et l’analyse de leur impact se poursuit
      Chaque distribution est devenue plus attentive aux détails de la façon dont une compromission peut se produire autour des archives de build, et a commencé à chercher comment détecter et empêcher des cas similaires à l’avenir
      Par rapport au closed source, il est très probable que des signalements du type « le logiciel est un peu lent » auraient reçu peu d’attention avant une exploitation réelle
      Même si l’entreprise finissait par comprendre, elle ne publierait sans doute qu’une explication très prudente, ne révélant qu’un minimum d’informations, ce qui nuirait fortement à la capacité de tout le secteur à éviter que cela se reproduise
    • Des bugs sont aussi constamment découverts dans le closed source. Beaucoup peuvent être trouvés même sans le code
      Le problème, c’est qu’il est plus probable qu’on ne puisse pas les corriger, ou qu’aucune mesure ne soit prise
      La plupart des gens ne savent pas quoi faire lorsqu’ils découvrent un bug. C’était aussi mon cas il y a très longtemps, et ce n’est que plus tard que j’ai compris que ce que j’avais vu était des bugs
      Les détails sont flous, car cela remonte à presque 30 ans, mais je me souviens qu’en bricolant Microsoft NetMeeting sous Windows, je pouvais le faire planter avec une erreur de dépassement de tampon
      À l’époque, j’étais débutant en informatique et je ne comprenais pas qu’un buffer overflow dans une application réseau était une très mauvaise chose. Beaucoup de personnes présentes depuis longtemps dans le secteur semblaient être dans le même cas
      Signaler un problème de sécurité était aussi beaucoup plus difficile à l’époque, et parfois même risqué
      Au final, plusieurs choses sont nécessaires : tomber sur le problème, comprendre suffisamment l’informatique en profondeur pour reconnaître qu’il est grave, disposer d’un moyen de signaler le bug à un endroit où des gens le regarderont, et avoir une culture de la sécurité qui sait quand et comment traiter ces signalements
    • Dans le code propriétaire/fermé aussi, les gens découvrent tout le temps des bugs logiciels
    • Il n’y a pas de désaccord sur le fait que l’open source est préférable au closed source
      Mais en lisant cette même phrase, je me demandais combien de bugs de sécurité critiques comme Heartbleed, CVE-2008-0166 ou l’affaire xz se produisent sans être découverts ni rendus publics
  • Un fait important que je n’ai appris que récemment à propos de cette vulnérabilité, c’est que ce changement n’a pas été fait dans la précipitation
    Le mainteneur a publié sur la liste de diffusion OpenSSL le problème qu’il observait, a demandé des retours en proposant un correctif, et a reçu quelques réponses, y compris de l’upstream
    Le résultat a été une vulnérabilité terrible, mais cela ressemble davantage à une malchance extraordinairement mauvaise, où tout le monde est passé à côté du problème

    • À l’époque, j’avais l’impression que Debian recevait beaucoup de critiques pour ce bug, mais comme indiqué plus haut, il y avait bien eu une tentative de collaboration
      En plus, le code upstream d’OpenSSL invoquait un comportement indéfini. Un compilateur aurait donc pu légitimement effectuer exactement la même transformation que celle faite par le mainteneur Debian
      À ce moment-là, cela me semblait très théorique. Je me disais qu’un compilateur ne serait sûrement pas aussi malveillant
      Depuis, on comprend mieux qu’il faut éviter purement et simplement le comportement indéfini
      Puis, 8 ans plus tard, Heartbleed a été découvert, et tout le monde a soudain compris à quel point OpenSSL était mal maintenu
      Pour sa défense, c’était quasiment du bénévolat, et heureusement, le financement arrivé ensuite a amélioré la situation
    • Plutôt que de la malchance, je me demande si ce n’était pas surtout un manque de couverture de tests automatisés
      Pour du code de génération aléatoire critique pour la sécurité, il me semble vraiment nécessaire d’avoir un test qui génère une énorme quantité de nombres aléatoires puis vérifie qu’ils sont tous uniques
  • Quand je lis ce genre de chose, je me demande quelle est la probabilité que ce soit déjà arrivé, ou que cela arrive un jour, dans la fonction de génération de seed de l’un des wallets matériels Bitcoin populaires
    Et je me demande aussi quelles en seraient les conséquences

    • https://www.unciphered.com/blog/randstorm-you-cant-patch-a-h...
      Au cours des 22 derniers mois, Unciphered a travaillé sur une vulnérabilité affectant BitcoinJS, largement utilisé pour générer des wallets crypto dans le navigateur, ainsi que les produits et projets créés avec ce logiciel
      Au fil des années, cette vulnérabilité a entraîné la création d’un nombre considérable de wallets crypto vulnérables
    • Un tel problème serait probablement découvert assez vite
      Dans le cas de la vulnérabilité SSH, il faut vérifier activement si le serveur auquel on tente d’accéder possède l’une des mauvaises empreintes, alors que côté wallet cela permettrait automatiquement, depuis le réseau, d’accéder aux fonds d’autres personnes
    • https://news.ycombinator.com/item?id=6195493
    • Le hack de Wintermute à 160 millions de dollars a été causé par une génération de clés non sûre dans une bibliothèque publique
      Cela dit, dans ce cas, il est peu probable que cela ait été introduit intentionnellement
    • Si l’on considère que chaque clé peut être générée de manière déterministe à partir d’une seed key, et qu’une seed key n’est pas infinie, ce n’est au fond qu’une question de temps
      Avec la technologie actuelle, il faudrait des millions d’années de calcul, mais pour un acteur étatique capable de dépenser des sommes quasi illimitées afin de faire tourner autant de calculs en quelques semaines, ce n’est peut-être pas hors de portée
      Il pourrait finir par arriver un moment où toute personne connaissant une adresse pourra accéder à n’importe quel wallet
      Si quelqu’un doté d’intelligence et d’argent peut vous prendre pour cible, Bitcoin n’est pas vraiment un endroit sûr pour stocker de la valeur
  • La phrase « Ezra Zygmuntowitz m’a mis en relation avec GitHub, et m’a permis de prendre le temps de creuser le problème avec l’équipe GitHub » m’a fait rire
    Comme je ne suis pas locuteur natif, je l’ai aussi lue comme si elle voulait dire qu’il y avait un gros problème avec l’équipe GitHub elle-même, et je m’attendais à ce que les phrases suivantes creusent ce point
    Le passage « je me demande combien de temps il aurait fallu pour que quelqu’un le découvre si Luciano ne l’avait pas trouvé » me fait penser que seuls GitHub ou peut-être un gros fournisseur cloud seraient tombés dessus par hasard
    Parce qu’il n’y a pas beaucoup d’endroits qui stockent des milliers ou dizaines de milliers de clés utilisateur

    • En syntaxe, on appelle cela un problème d’attachement de groupe prépositionnel
      La question est de savoir s’il faut lire la phrase comme (creuser le problème) (avec l’équipe GitHub), ou comme creuser (le problème concernant l’équipe GitHub)
      Le traiter correctement est réputé être assez difficile
    • Les deux lectures sont possibles, mais s’il y avait eu une virgule après « problem », l’ambiguïté aurait disparu
  • Si j’ai bien compris, le générateur de nombres aléatoires d’OpenSSL était seedé avec de la mémoire de pile non initialisée et le PID, et Debian l’a fait seeder uniquement avec le PID
    Mais même sans le patch Debian, ce n’était pas déjà assez dangereux ?

    • Ce malentendu semble assez répandu. Mais en réalité, ce n’est pas ce qui s’est passé
      Dans le code d’OpenSSL, il y avait deux endroits où des blocs d’octets étaient copiés, et l’un d’eux pouvait copier des valeurs indéfinies non initialisées. C’était bien une erreur
      Quelqu’un a écrit un patch pour corriger cela, puis, sans l’aide d’un LLM et uniquement par pure incompétence humaine, quelqu’un a dit : « il y a une autre copie similaire juste à côté, il faut aussi la supprimer »
      Debian a intégré un patch appliquant les deux changements
      Résultat : OpenSSL ne copiait désormais plus aucun octet
      Ne pas copier de données non initialisées, c’est bien, mais il ne copiait plus non plus de vraie entropie aléatoire dans le pool. Oups
    • C’est faux. OpenSSL seedait aussi le générateur de nombres aléatoires avec des données lues depuis /dev/urandom
  • Dans le passage « après avoir examiné plusieurs solutions possibles, nous avons conclu que l’option la moins mauvaise était de patcher OpenSSH pour qu’il recherche les clés dans une base MySQL indexée par empreinte de clé », pourquoi MySQL et pas sqlite ?
    Il s’agissait d’accélérer l’accès à ~/.ssh/authorized_keys, et c’est précisément le genre de cas pour lequel MySQL est censé briller
    Il me semble qu’il aurait demandé moins de travail de patcher OpenSSH pour qu’il consulte ~/.ssh/authorized_keys.db plutôt que de le patcher pour utiliser MySQL

    • Il y avait probablement beaucoup de machines concernées, et il est généralement plus simple de maintenir une seule base de données que plusieurs
      Il est aussi très probable que MySQL était déjà en production. Dans ce cas, il n’y aurait même pas eu de coût initial pour y stocker les données
      De toute façon, la base de données des utilisateurs devait déjà exister quelque part
  • Indépendamment de la découverte d’un petit nombre de clés faibles, il est intéressant que des temps de connexion SSH lents soient un indice qui mérite d’être tiré pour plusieurs raisons

  • Un autre épisode intéressant est celui où l’on a détecté des clés RSA partageant un facteur p ou q commun à l’aide du plus grand commun diviseur : https://factorable.net/weakkeys12.extended.pdf

  • Je me demande si GitHub exécute encore un openssh patché

    • Si vous le voulez, il n’est pas très difficile de regarder quelque chose d’assez proche du code source de GitHub
      Il suffit d’acheter une copie de GitHub Enterprise, de désobfusquer les fichiers et de fouiller. La désobfuscation est un défi amusant, et pas si difficile
      Malheureusement, ce n’est pas open source, donc on ne peut pas partager le code, en parler, ni mettre de lien vers GitHub
      Mais si GitHub Enterprise utilise encore ce patch, il y a de fortes chances que le GitHub en production l’utilise aussi
    • Au minimum, ils ne sont probablement pas revenus à une méthode consistant à remettre toutes les clés dans ~/.ssh/authorized_keys
    • GitHub utilise quelque chose appelé babeld
      Si l’on se connecte en telnet au port 22 de github.com, la chaîne de version s’affiche immédiatement
    • En 2015, ils utilisaient libssh
      Correction : j’avais d’abord dit golang, mais après vérification, c’était Bitbucket qui utilisait golang
    • Depuis OpenSSH 6.2, sorti en 2013, AuthorizedKeysCommand a été ajouté, donc aucun patch n’est nécessaire