needhelp
← Retour au blog

ssh-keysign-pwn : Lire les fichiers root via un bug logique dans ptrace

par xingwangzhe
Linux
Kernel
Sécurité
Qualys
ptrace
CVE

ssh-keysign-pwn : Un bug logique vieux de six ans dans __ptrace_may_access(), rapporté par Qualys et corrigé par Linus Torvalds le 14 mai 2026. Les utilisateurs non privilégiés peuvent lire les fichiers root, y compris les clés privées SSH host et /etc/shadow. Tous les noyaux antérieurs à 31e62c2ebbfd sont affectés.


Encore une

Mai 2026 n’a pas été tendre avec le noyau Linux. Dirty Frag, Fragnesia, et maintenant—ssh-keysign-pwn—divulgué par Qualys le 14 mai et corrigé par Linus Torvalds le jour même.

Celle-ci est différente de la famille « copier quelque chose dans le cache de pages ». C’est un pur bug logique dans __ptrace_may_access(), la fonction du noyau qui décide si un processus peut en inspecter un autre.

MétriqueValeur
Rapporté parQualys Security Advisory
Corrigé parLinus Torvalds
Commit de correction31e62c2ebbfd
Caché pendant~6 ans
Détecté d’abord parJann Horn (Google), octobre 2020
PoC publié par_SiCk
ImpactLire les fichiers root en tant qu’utilisateur non privilégié
Complexité d’exploitation100–2000 tentatives par vol réussi

Comment ça marche

Le bug se trouve dans __ptrace_may_access(). Cette fonction est la gardienne de l’introspection des processus—elle vérifie si un processus a le droit de fouiller dans l’état d’un autre.

Il y a un cas spécial : quand task->mm == NULL (le processus cible n’a pas de descripteur mémoire — cela arrive quand un thread est en train de sortir, ou pour les threads noyau), la fonction saute complètement la vérification dumpable.

Le chemin de code qui rend cela exploitable :

  1. Un processus appelle do_exit() pour se terminer
  2. do_exit() exécute exit_mm() en premier — détruit le descripteur mémoire (mm)
  3. Puis exécute exit_files() — mais les descripteurs de fichiers sont toujours vivants
  4. Avec task->mm == NULL mais les fds encore ouverts, pidfd_getfd(2) peut les voler si l’uid de l’appelant correspond

Normalement, les vérifications d’accès ptrace empêcheraient un processus moins privilégié d’atteindre les handles de fichiers ouverts d’un processus root. Mais le contournement mm == NULL saute la vérification dumpable, et pidfd_getfd(2) fait le reste.

C’est un TOCTOU classique, mais la fenêtre est suffisamment large—le PoC réussit en 100–2000 tentatives.

Cibles de l’Exploit

Deux outils ont été publiés :

sshkeysign_pwn — attaque ssh-keysign, un binaire auxiliaire qui signe les défis d’authentification host. Il ouvre les fichiers de clés SSH host (/etc/ssh/ssh_host_{ecdsa,ed25519,rsa}_key, mode 0600) avant d’appeler permanently_set_uid() pour baisser les privilèges. Ensuite il vérifie si EnableSSHKeysign est défini dans sshd_config — si non, il se termine avec les fds des clés toujours ouverts. Ce design est dans OpenSSH depuis 2002.

chage_pwn — attaque chage -l <user>. Il ouvre /etc/shadow via spw_open(O_RDONLY), puis appelle setreuid(ruid, ruid) — baissant tous les privilèges. Dans la fenêtre entre la baisse de privilèges et la fermeture du fichier, le fd peut être volé.


Chronologie

DateÉvénement
~2020Jann Horn identifie le motif de vol de FD et propose un correctif (non fusionné)
2026-05-14Qualys rapporte la vulnérabilité ; Linus Torvalds applique la correction (31e62c2ebbfd)
2026-05-14Brad Spengler (@spendergrsec) publie l’analyse
2026-05-14_SiCk publie les PoCs sur GitHub
2026-05-15Qualys envoie la divulgation à oss-security

L’écart entre la proposition de correctif de Jann Horn en 2020 et le rapport de Qualys en 2026 est remarquable. Le correctif avait été rédigé il y a cinq ans mais n’a jamais été fusionné.


La Correction

Linus a appliqué la correction avec le commit 31e62c2ebbfd. Son message de commit notait :

« nous avons un cas spécial étrange : ptrace_may_access() utilise ‘dumpable’ pour vérifier diverses choses complètement indépendantes de MM (typiquement en utilisant des flags comme PTRACE_MODE_READ_FSCREDS), y compris pour les threads qui n’ont plus de VM (et peut-être n’en ont jamais eu, comme la plupart des threads noyau). Ce n’est pas pour cela que ce flag a été conçu, mais c’est comme ça. »

Le correctif ajuste le comportement de ptrace pour gérer correctement le cas mm == NULL. Il ferme effectivement la fenêtre de contournement.

Vérifiez votre Noyau

uname -r
# Les noyaux corrigés incluent le commit 31e62c2ebbfd
# Tous les noyaux antérieurs au 2026-05-14 sont vulnérables

Ce Qui Rend Ceci Intéressant

Trois choses ressortent :

  1. Corrigé le jour même du rapport. Linus l’a résolu en quelques heures. C’est inhabituellement rapide pour un correctif du noyau, suggérant que le correctif était direct une fois le bug compris.

  2. Jann Horn l’a trouvé en 2020. La communauté avait une proposition de correctif dans les archives de la liste de diffusion depuis cinq ans. Le motif de vol de FD était connu, mais personne ne l’a poussé.

  3. Les cibles sont anciennes. Le motif de fds ouverts de ssh-keysign date de 2002. La séquence spw_open + setreuid de chage est tout aussi ancienne. Ce n’est pas un bug dans SSH ou shadow-utils — c’est un bug du noyau qui weaponize des motifs existants de gestion de fds dans des binaires privilégiés.

C’est aussi la troisième vulnérabilité majeure du noyau Linux en mai 2026, après Copy Fail et Dirty Frag. Le rythme de divulgation s’accélère — en partie parce que les outils d’audit assistés par IA trouvent les vieux bugs plus rapidement, et en partie parce que l’écosystème de divulgation se fragmente.


Références

Partager cette page