Connexion avec un mot de passe de 257 caractères : un astérisque fait tomber des millions de serveurs

Connexion avec un mot de passe de 257 caractères : un astérisque fait tomber des millions de serveurs

CybersécuritéLinuxOpenSSHAlpineAnalyse de vulnérabilité

Sources:sshhole.com rapport de vulnérabilité + notes de version OpenSSH 10.6p2 · HN · Lobsters

Le 5 novembre 2026, l’écosystème Linux a dévoilé une faille de sécurité défiant les principes les plus élémentaires de la cryptographie. Sur des millions de conteneurs fondés sur Alpine, des comptes d’administration pourtant interdits de connexion par mot de passe ont été compromis. Il suffisait à un attaquant de saisir une chaîne aléatoire de 257 caractères dans le champ d’authentification pour obtenir immédiatement les privilèges système.

Le bon sens veut qu’un mot de passe soit d’autant plus sûr qu’il est long, et qu’une saisie démesurée soit interceptée par les barrières de protection. La réalité a pris le contrepied exact : un contrôle d’accès réputé inviolable a cédé sous la simple pression d’une suite arbitraire de caractères.

Une saisie démesurée perce la défense : intrusion avec 257 octets

Les conditions d’exploitation de la vulnérabilité sont à la fois précises et très répandues en production. Le serveur cible doit exécuter le démon OpenSSH compilé avec la bibliothèque C musl et sans module PAM actif. Lorsqu’un attaquant transmet un mot de passe compris entre 257 et 1024 octets, le contrôle d’accès valide immédiatement la session.

Une longueur de 257 octets dépasse de loin tout usage normal. Pourtant, cette anomalie a traversé les mécanismes de comparaison, conduisant le système à valider comme authentifié un compte censé rejeter toute connexion. La logique de protection s’est effondrée à cet instant précis.

Les comptes vulnérables présentent une caractéristique bien définie : dans /etc/shadow, le champ réservé au hachage du mot de passe ne contient que le caractère unique *. Dans la tradition UNIX, un astérisque indique qu’un compte n’accepte jamais de mot de passe. Les images de base fournies par les acteurs du cloud ou les comptes de déploiement reposant uniquement sur des clés SSH adoptent systématiquement cette configuration.

La cible la plus facile à exploiter se trouve directement dans le cloud : dans les images officielles d’Alpine pour AWS et Azure, l’utilisateur par défaut alpine applique cette règle et bénéficie en outre de droits doas sans mot de passe. Prendre le contrôle de ce compte équivaut à s’arroger un accès root instantané.

Il suffit qu’un autre compte disposant d’un hachage classique coexiste sur la machine pour que l’attaque réussisse à coup sûr. OpenSSH emprunte le sel (salt) de ce compte tiers afin de neutraliser les attaques par canal auxiliaire basées sur le temps. Plusieurs mécanismes de défense se sont ainsi cumulés pour, paradoxalement, livrer les clés de la machine.

Trois choix rationnels entrés en collision 46 ans plus tard

En retraçant l’évolution des systèmes UNIX, on découvre que cette porte dérobée résulte de trois décisions indépendantes prises sur près de cinquante ans. Chacune d’elles était rigoureuse et logique à son époque ; leur réunion finale s’est pourtant avérée catastrophique.

La première décision remonte à 1980. Bill Joy inséra un astérisque * dans le fichier de mots de passe de 3BSD pour le compte de service daemon. Les algorithmes de chiffrement de l’époque ne pouvaient pas produire un astérisque isolé, garantissant ainsi qu’aucun mot de passe saisi ne pourrait jamais correspondre.

Fichier de mots de passe original de 3BSD en 1980 Figure : Capture du fichier passwd original de 3BSD en 1980, montrant le champ mot de passe du compte daemon renseigné avec un astérisque. Source : sshhole.com

Cette convention simple consistant à verrouiller un compte à l’aide d’un astérisque a traversé 46 années, s’imposant comme la norme universelle de l’industrie.

La deuxième décision est intervenue en 1997. La spécification Single UNIX a établi que la fonction de chiffrement crypt() devait renvoyer un pointeur nul (NULL) en cas d’erreur de calcul. Or, nombre de programmes en C omettaient de vérifier les pointeurs nuls, provoquant des erreurs de segmentation et le plantage des services réseau lors d’un retour NULL.

En août 2012, les développeurs de la bibliothèque musl ont apporté une correction. Afin d’éliminer les risques de crash liés aux pointeurs nuls, le commit b3c4cc12 a modifié la fonction pour qu’elle renvoie un astérisque unique * en cas d’erreur de calcul, tout en supprimant l’ancien commentaire affirmant que les erreurs étaient impossibles.

Définition de l'astérisque comme retour d'erreur dans musl Figure : Commentaires d’en-tête de musl stipulant le renvoi direct d’un astérisque unique en cas d’erreur lors du calcul. Source : sshhole.com

Pour les auteurs de musl, l’astérisque signifiait un échec de calcul. Pour les administrateurs système, l’astérisque signifiait une interdiction de connexion. Deux mondes ont ainsi attribué un sens totalement opposé au même caractère.

La limite anti-déni de service percute la défense contre les canaux auxiliaires

La troisième décision a soudé les deux astérisques. Le 29 août 2012, à peine vingt jours après la modification précédente, musl a intégré le support de l’algorithme SHA-512.

Le hachage SHA-512 est particulièrement vorace en calculs et sa durée d’exécution augmente avec la taille des entrées. Afin de prémunir les serveurs contre les attaques par déni de service (DoS) par saturation CPU, musl a plafonné la taille des mots de passe à 256 octets. Dès qu’une saisie dépasse cette limite, le calcul est immédiatement refusé et renvoie l’astérisque d’erreur *.

Code source de musl imposant la limite de 256 octets Figure : musl libc imposant un plafond de 256 octets dans crypt_sha512.c pour empêcher l’épuisement des ressources du serveur. Source : sshhole.com

Ce plafond strict de 256 octets a rempli son rôle contre les surcharges et a fonctionné sans accroc en production pendant de nombreuses années.

Puis, en juillet 2016, OpenSSH a corrigé la vulnérabilité CVE-2016-6210 relative aux fuites de temporisation. Étant donné que le système répondait plus vite pour les comptes inexistants, les attaquants pouvaient énumérer les identifiants valides. Pour aligner les temps de réponse, OpenSSH a mis en place des calculs fictifs.

Lors d’une tentative de connexion sur un compte dépourvu de hash valide, le système emprunte le sel d’un autre compte pour exécuter une opération de chiffrement dans le seul but de consommer du temps. Les comptes désactivés par un astérisque ont ainsi été dirigés vers ce parcours de calcul fictif.

L’engrenage était complet. Un attaquant envoie un mot de passe de 257 octets au compte root. OpenSSH emprunte un sel et déclenche crypt(). musl constate le dépassement de la limite, interrompt le calcul et renvoie un *. OpenSSH compare cet astérisque avec la valeur présente dans /etc/shadow. Les deux correspondent parfaitement, et le système accorde l’accès sans autre forme de procès.

L’essor des conteneurs propulse un choix de niche sur des millions d’hôtes cloud

musl était autrefois cantonné aux routeurs et aux systèmes embarqués, où la surface d’exposition restait étroite. La généralisation des conteneurs a propulsé cette bibliothèque au cœur des infrastructures de serveurs modernes.

Avec une empreinte de seulement 5 Mo, Alpine Linux s’est imposé comme l’image de base incontournable du cloud. En 2019, voulant corriger une anomalie liée au mot de passe root vide dans ses images officielles, la distribution a verrouillé le compte avec un point d’exclamation !. Ce choix bloquait toutefois l’authentification par clé SSH dans les environnements sans PAM, perturbant les déploiements sur les clouds majeurs.

En 2022, Alpine 3.16 est revenue en arrière en réaffectant l’astérisque * au mot de passe root. L’accès par clé publique a été rétabli, mais cette modification a exposé toutes les versions ultérieures aux conditions d’exploitation de la faille.

La communauté technique s’est vite penchée sur l’ampleur du problème. Le développeur jbyers a rappelé que si la probabilité pour un conteneur donné de réunir tous les critères reste modérée, le volume colossal d’instances en service dans le monde porte le total de cibles potentielles à un niveau alarmant. Des millions d’images en production se trouvaient exposées sans le savoir.

La conformité aux standards a également suscité la controverse. Le développeur NewJazz a soutenu que musl s’était écarté des spécifications POSIX. D’autres lui ont rétorqué, citations à l’appui, que POSIX ne prévoyait qu’un code d’erreur unique et manquait de directives claires pour la gestion des cas exceptionnels.

Sur la plateforme Lobsters, le commentateur mort a critiqué la mise en scène dramatique des divulgations de vulnérabilités, rappelant que les bulletins de sécurité doivent aller à l’essentiel en exposant clairement le périmètre réel et les démarches de correction.

Mettre à jour les paquets ne suffit pas : redémarrer les services sans attendre

Le 5 novembre 2026, le projet OpenSSH a publié la version 10.6p2. Ce correctif introduit une règle de filtrage stricte rejetant les retours d’un seul caractère, empêchant la couche applicative d’interpréter naïvement les conventions de la bibliothèque système.

Cependant, la mise à jour des paquets ne représente que la moitié du chemin. La persistance des processus en mémoire sous Linux constitue un piège classique pour les administrateurs.

Si le gestionnaire de paquets remplace bien les fichiers sur le disque, les processus en cours d’exécution conservent l’ancien code en mémoire. Tant que les démons ne sont pas redémarrés, la vulnérabilité reste exploitable. Les équipes d’exploitation doivent relancer sans délai le service sshd ou reconstruire et redéployer les conteneurs actifs.

Avec le recul, aucune ligne de code impliquée n’a été écrite avec malveillance. En 1980, l’astérisque neutralisait les accès ; en 1997, la valeur de retour évitait les crashs mémoires ; en 2012, la limite de taille bloquait les dénis de service ; en 2016, les calculs fictifs empêchaient l’analyse temporelle. Chaque arbitrage représentait le choix le plus avisé de son époque.

Pourtant, ces couches de protection superposées au fil des décennies se sont percutées. Une infime divergence d’interprétation a creusé une brèche silencieuse d’élévation de privilèges. Dans les architectures logicielles complexes, des défenses empilées qui s’ignorent mutuellement engendrent souvent des faiblesses bien plus sournoises que de simples anomalies isolées.

Liens de référence :

  • Publication originale de la vulnérabilité et outil de diagnostic sur sshhole.com
  • Commit aports d’Alpine fbe926af : remplacement du point d’exclamation par un astérisque pour root
  • Annonce officielle de la version OpenSSH 10.6p2 et code source du correctif
  • Débat technique sur Hacker News concernant les codes de retour de musl crypt
  • Discussions sur Lobsters concernant la sécurité des conteneurs et les plans d’atténuation