1 points par GN⁺ 2024-07-02 | 1 commentaires | Partager sur WhatsApp
  • Une condition de concurrence dans le gestionnaire de signal du serveur OpenSSH sshd peut permettre à un client non authentifié de provoquer une exécution de code à distance sur un serveur en configuration par défaut s’il ne s’authentifie pas dans le délai de pré-authentification LoginGraceTime
  • Cette vulnérabilité est une régression de la CVE-2006-5051 de 2006, réapparue dans les versions 8.5p1 et ultérieures, jusqu’aux versions antérieures à 9.8p1, après qu’un commit d’OpenSSH 8.5p1 en octobre 2020 a supprimé une protection dans sigdie()
  • Sur Linux basé sur glibc, syslog() appelle des fonctions non async-signal-safe comme malloc() et free(), ce qui peut conduire à une RCE root sans authentification dans le code privileged non sandboxé de sshd
  • Les expériences ont été menées sur une machine virtuelle i386 et un réseau stable avec environ 10 ms de gigue de paquets ; sur Debian 12.5.0 avec OpenSSH 9.2p1, il a fallu en moyenne environ 10 000 tentatives et environ 6 à 8 heures jusqu’à obtenir un shell root, avec MaxStartups=100 et LoginGraceTime=120
  • OpenSSH a corrigé le problème le 6 juin 2024 avec le commit 81c1099 ; si la mise à jour ou la recompilation est difficile, définir LoginGraceTime 0 permet de bloquer la RCE, mais le risque de DoS par épuisement des connexions MaxStartups demeure

Où se produit la vulnérabilité

  • Le problème dans OpenSSH sshd commence dans le gestionnaire SIGALRM qui s’exécute avant l’authentification
    • Si le client ne s’authentifie pas dans LoginGraceTime, le gestionnaire SIGALRM est appelé de manière asynchrone
    • Ce gestionnaire appelle des fonctions qui ne sont pas async-signal-safe, comme syslog()
    • La valeur par défaut est LoginGraceTime=120 secondes ; dans les anciennes versions d’OpenSSH, elle était de 600 secondes
  • Cette vulnérabilité est une régression de CVE-2006-5051
    • CVE-2006-5051 est une condition de concurrence dans un gestionnaire de signal, signalée en 2006 par Mark Dowd dans OpenSSH antérieur à 4.4
    • En octobre 2020, le commit 752250c d’OpenSSH 8.5p1 a supprimé par erreur #ifdef DO_LOG_SAFE_IN_SIGHAND de sigdie()
  • Le périmètre d’impact est clairement distinct selon les versions
    • OpenSSH antérieur à 4.4p1 : vulnérable si les correctifs liés à CVE-2006-5051 ou CVE-2008-4109 n’ont pas été rétroportés
    • OpenSSH 4.4p1 et ultérieur, jusqu’aux versions antérieures à 8.5p1 : sigdie() a été remplacé par un appel sûr à _exit(1), et n’est donc pas vulnérable à cette condition de concurrence
    • OpenSSH 8.5p1 et ultérieur, jusqu’aux versions antérieures à 9.8p1 : redevenu vulnérable à cause de la suppression de la protection

Environnements affectés et exceptions

  • La cible d’exploitation à distance est Linux basé sur glibc
    • syslog() de glibc appelle en interne des fonctions non async-signal-safe comme malloc() et free()
    • Le code vulnérable se trouve dans le code privileged de sshd, non sandboxé et exécuté avec tous les privilèges
    • Il en résulte une exécution de code à distance en root sans authentification
  • Les autres libc ou systèmes d’exploitation n’ont pas été inclus dans l’étude
  • OpenBSD n’est pas vulnérable
    • Le gestionnaire SIGALRM d’OpenBSD appelle syslog_r() au lieu de syslog()
    • syslog_r() est une version async-signal-safer créée par OpenBSD en 2001

Hypothèses de la recherche sur l’exploitation à distance

  • Pour exploiter cette condition de concurrence à distance, trois problèmes doivent être résolus
    • Il faut un chemin de code qui laisse sshd dans un état incohérent lorsque SIGALRM intervient au bon moment
    • Il faut atteindre ce chemin de code et augmenter la probabilité d’être interrompu au bon moment
    • Il faut pouvoir obtenir ce timing même dans un environnement réseau distant
  • La recherche a commencé sur un environnement i386 avec d’anciennes versions d’OpenSSH, plutôt que d’affronter directement les protections modernes, puis a été étendue aux versions récentes
  • Les conditions expérimentales comportent des limites claires
    • Seules des machines virtuelles ont été ciblées, pas des serveurs bare-metal
    • Le réseau était un lien relativement stable avec environ 10 ms de gigue de paquets
    • Plusieurs parties de l’exploit peuvent encore être améliorées
    • Le travail sur un exploit amd64 a commencé, mais il est beaucoup plus difficile à cause d’un ASLR plus robuste

Expériences sur d’anciennes cibles OpenSSH

  • Debian 3.0r6, OpenSSH 3.4p1

    • La cible est SSH-2.0-OpenSSH_3.4p1 Debian 1:3.4p1-1.woody.3, un environnement Debian 3.0r6 de 2005
    • Cette version de Debian est la première version Debian où la séparation des privilèges est activée par défaut, et les principaux correctifs de vulnérabilité de l’époque y étaient appliqués
    • L’exploitation utilise une interruption de free() et un état incohérent du heap
      • Un appel à free() dans le code de parsing de clé publique est interrompu par SIGALRM
      • Ensuite, l’état incohérent du heap est exploité lors d’un autre free() dans packet_close()
    • glibc 2.2.5 ne disposait pas du durcissement contre la technique unlink() de Solar Designer
    • L’attaque écrase __free_hook pour rediriger le flux d’exécution vers l’adresse du shellcode dans le heap
    • Cette version de Debian n’a ni ASLR ni NX
    • Après amélioration du timing, environ 10 000 tentatives étaient nécessaires en moyenne
    • Avec MaxStartups=10 et LoginGraceTime=600, il fallait en moyenne environ une semaine pour obtenir un shell root à distance
  • Ubuntu 6.06.1, OpenSSH 4.2p1

    • La cible est SSH-2.0-OpenSSH_4.2p1 Debian-7ubuntu3, un environnement Ubuntu 6.06.1 de 2006
    • Il s’agit de la dernière version d’Ubuntu encore vulnérable à CVE-2006-5051
    • Comme glibc 2.3.6 prend un verrou obligatoire à l’entrée des fonctions de la famille malloc, l’approche consistant à exploiter un autre appel à malloc après interruption d’un malloc mène à un deadlock
    • Le chemin d’exploitation final utilise PAM
      • pam_start() définit le pointeur global sshpam_handle de sshd
      • Si _pam_add_handler() est interrompu, le champ next peut rester non initialisé
      • Lorsque pam_end() est appelé dans le gestionnaire SIGALRM, il peut passer un pointeur arbitraire à free()
    • L’ancienne technique unlink() de glibc étant bloquée, la version fastbin de House of Mind de Malloc Maleficarum est utilisée
    • Une fake arena est pointée vers .got.plt de sshd, et l’entrée _exit() est écrasée par l’adresse du shellcode dans le heap
    • Le heap de cette version d’Ubuntu est exécutable par défaut
    • Environ 10 000 tentatives étaient nécessaires en moyenne
    • Avec MaxStartups=10 et LoginGraceTime=120, il fallait en moyenne environ 1 à 2 jours pour obtenir un shell root à distance
    • Un attaquant malchanceux pouvait deadlocker les 10 connexions MaxStartups avant d’obtenir un shell root

Expérience sur Debian 12.5.0, OpenSSH 9.2p1

  • Chemin syslog() et malloc dans glibc

    • La cible est SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2, l’environnement stable actuel de Debian 12.5.0 en 2024
    • Cet environnement est vulnérable à la régression de CVE-2006-5051
    • Le gestionnaire SIGALRM de cette version n’appelle pas packet_close() ni pam_end(), mais mène au chemin syslog()
      • grace_alarm_handler() appelle sigdie()
      • sigdie() appelle syslog() via sshlogv() et do_log()
    • Dans Debian glibc 2.36, syslog() appelle malloc lors du premier appel
      • __tzfile_read() est appelé via le chemin __localtime64_r()
      • fopen() appelle malloc(304) pour la structure FILE
      • malloc(4096) est aussi appelé pour le buffer de lecture interne
    • Depuis octobre 2017, malloc de glibc ne prend plus de verrou obligatoire en situation monothread
    • Dans un processus monothread comme sshd, cela ouvre la possibilité d’exploiter une concurrence dans malloc
  • Conditions ASLR et contraintes i386

    • L’environnement Debian 12.5.0 i386 présente une faiblesse d’ASLR
    • Le PIE de sshd, le heap, la plupart des bibliothèques et la stack sont généralement randomisés
    • glibc elle-même est toujours mappée à 0xb7200000 ou 0xb7400000
    • L’adresse de glibc peut être devinée avec une probabilité d’une chance sur deux
    • L’exploit suppose que glibc est mappée à 0xb7400000
    • C’est parce que cette adresse était légèrement plus fréquente que 0xb7200000
  • Incohérence du heap et exploitation de la structure FILE

    • Le chemin malloc choisi est le chemin de split qui divise un gros chunk libre en deux
    • Il produit le chunk qui sera retourné et un remainder chunk
    • Si SIGALRM intervient après que le remainder chunk a été relié à l’unsorted list mais avant l’initialisation de son champ size, une incohérence du heap apparaît
    • L’attaquant contrôle le champ size du remainder chunk via les données résiduelles d’une allocation heap précédente
    • Le remainder chunk est rendu plus grand qu’il ne l’est réellement, afin de chevaucher un autre chunk du heap
    • Le malloc dans le gestionnaire SIGALRM utilise ce chunk, ce qui corrompt la mémoire du heap
    • La cible est la structure FILE allouée sur le heap par fopen() dans __tzfile_read()
      • Avec une corruption limitée du heap, un octet de _vtable_offset de la structure FILE est écrasé
      • Les fonctions libio de glibc cherchent alors le pointeur de vtable à un offset différent de la position par défaut
      • L’attaquant contrôle à cet emplacement le fake vtable pointer et le pointeur _codecvt via les données résiduelles d’une allocation heap précédente
    • Sur glibc i386, cette technique permet d’appeler un pointeur de fonction arbitraire __fct pendant __fread_unlocked()
    • glibc sur amd64 ne semble pas utiliser _vtable_offset
  • Layout du heap et 27 fenêtres de race

    • Comme il est difficile de gagner la condition de concurrence avec une seule petite race window, 27 paires de large hole et small hole sont créées
    • 28 paires dépasseraient PACKET_MAX_SIZE, soit 256 Ko
    • Le dernier paquet force la séquence malloc(~4KB), malloc(304), malloc(~4KB), malloc(304)
    • Si chaque split de large hole est interrompu au bon moment, le fopen() du gestionnaire SIGALRM alloue le small hole correspondant comme structure FILE
    • Le code de parsing de clés publiques de sshd est utilisé pour construire le layout du heap
      • Les chemins cert_parse() et cert_free() permettent d’exécuter des séquences quasi arbitraires de malloc() et free()
      • Faute d’avoir trouvé une fuite mémoire, des chunks tcache sont utilisés comme barrier chunks temporaires
    • Cinq types de paquets de clé publique sont envoyés
      • a/ Faire en sorte qu’une allocation heap non contrôlée entre dans un chunk tcache
      • b/ Créer 27 paires de large/small hole et des barrier chunks
      • c/ Écrire un fake header, un fake footer, une fake vtable et un pointeur _codecvt
      • d/ Allouer puis libérer une grande chaîne de presque 256 Ko pour déplacer les holes de l’unsorted list vers les bins malloc correspondants
      • e/ Forcer la dernière séquence de malloc afin d’ouvrir 27 petites race windows
  • Stratégie de timing pour les versions récentes

    • La stratégie de timing basée sur le feedback utilisée sur les anciennes versions n’a pas fonctionné contre OpenSSH 9.2p1
    • Le parsing de la cinquième clé publique prend environ 10 ms, ce qui rend la grande race window trop large
    • user_specific_delay(), introduit dans OpenSSH 7.8p1, retarde la réponse jusqu’à environ 9 ms, ce qui casse le feedback existant
    • La nouvelle stratégie compare les temps de réponse de deux types d’erreurs intentionnelles
      • Envoyer un paquet qui déclenche une erreur juste avant le parsing de la clé publique
      • Envoyer un paquet qui déclenche une erreur juste après le parsing de la clé publique
      • Mesurer le temps de parsing de la dernière clé publique à partir de la différence entre les deux temps de réponse
    • Avec cette stratégie, la condition de concurrence est gagnée en environ 10 000 tentatives en moyenne
    • Avec MaxStartups=100 et LoginGraceTime=120, il faut en moyenne environ 3 à 4 heures pour gagner la condition de concurrence
    • À cause de l’ASLR, il faut en moyenne environ 6 à 8 heures pour obtenir un shell root à distance

Avancement de l’exploit amd64

  • La cible amd64 retenue est Rocky Linux 9
    • L’image cible est Rocky-9.4-x86_64-minimal.iso
    • OpenSSH 8.7p1 est vulnérable à cette condition de concurrence dans le gestionnaire de signal
    • Comme glibc est mappée sur un multiple de 2 Mo en raison d’une faiblesse d’ASLR, le partial pointer overwrite devient plus puissant
  • syslog() de glibc 2.34 sur Rocky Linux 9 appelle __open_memstream() en interne
    • Il alloue une structure FILE sur le heap avec malloc()
    • Il appelle aussi calloc(), realloc() et free(), offrant des possibilités supplémentaires
  • Sur la base de la primitive de heap corruption, des deux structures FILE allouées sur le heap et des 21 bits fixes de l’adresse de glibc, l’exploitation sur amd64 est considérée comme possible
    • Le temps attendu est plus long que les 6 à 8 heures sur i386, mais inférieur à une semaine selon les auteurs
  • Il existe aussi une observation distincte concernant Ubuntu 24.04
    • Ubuntu 24.04 ne rerandomise pas l’ASLR du processus child sshd, et ne le randomise qu’une seule fois au démarrage
    • La cause a été attribuée à systemd-socket-activation.patch, qui désactive rexec_flag
    • C’est généralement un mauvais choix, mais dans cette vulnérabilité, cela empêche l’exploitation, car syslog() dans le gestionnaire SIGALRM n’est pas le premier appel à syslog() et n’appelle donc pas les fonctions malloc
    • Correctif associé : https://git.launchpad.net/ubuntu/+source/…

Correctif et mesures d’atténuation

  • OpenSSH a corrigé cette condition de concurrence le 6 juin 2024 avec le commit 81c1099
    • 81c1099 : ajoute une fonctionnalité permettant à sshd(8) de pénaliser les comportements problématiques des clients
    • Le code non async-signal-safe est déplacé du gestionnaire SIGALRM de sshd vers le processus listener, où il est traité de manière synchrone
  • Ce correctif repose sur le gros commit 81c1099 et sur le commit de defense-in-depth encore plus volumineux 03e3de4, ce qui peut compliquer son rétroportage
  • Si le rétroportage est difficile, il est possible de supprimer ou commenter le code non async-signal-safe dans sshsigdie() pour ne plus appeler que _exit(1)
  • Si la mise à jour ou la recompilation est impossible, LoginGraceTime peut être défini à 0 dans le fichier de configuration
    • Ce réglage bloque l’exécution de code à distance décrite dans cet advisory
    • En revanche, il laisse le système vulnérable à un DoS par épuisement de toutes les connexions MaxStartups

Calendrier de divulgation

  • 2024-05-19 : les développeurs d’OpenSSH ont été contactés, puis des correctifs et revues se sont succédé
  • 2024-06-20 : distros@openwall a été contacté
  • 2024-07-01 : publication à la date de coordinated release

1 commentaires

 
GN⁺ 2024-07-02
Avis sur Hacker News
  • Fait intéressant, le correctif du RCE semble avoir été « glissé » publiquement il y a presque un mois
    Quand PerSourcePenalties est activé, sshd(8) surveille l’état de sortie des processus de session enfants avant authentification, et consigne pendant un certain temps, sous forme de pénalité associée à l’adresse du client, des conditions comme des échecs d’authentification répétés ou des crashs de sshd
    https://github.com/openssh/openssh-portable/commit/81c1099d2...
    Plutôt qu’un patch qui pourrait être rétroanalysé et donner des indices à un attaquant, cela semble avoir pour effet secondaire de modifier la structure du binaire, supprimant une vulnérabilité précise et atténuant aussi toute cette famille d’exploits ; c’est assez malin

    • Ce n’est pas le correctif du RCE ; le vrai correctif du RCE est ici : https://news.ycombinator.com/item?id=40843865
      Le changement ci-dessus est une fonctionnalité annoncée pour gérer les connexions parasites, et il ne fait qu’atténuer cette vulnérabilité en rendant la condition de concurrence plus difficile à gagner
      Discussion précédente : https://news.ycombinator.com/item?id=40610621
    • Je me demande si ce correctif a déjà été intégré ou repris par les distributions
    • C’est intéressant de voir que ce commentaire est resté en tête pendant 2 jours, alors qu’il était erroné et a été corrigé juste en dessous
      Je me demande si les gens ne lisent que le premier commentaire du fil, votent pour lui, puis repartent avec une impression fausse
  • Un passage des notes de version d’OpenSSH est intéressant
    « Une exploitation réussie a été démontrée sur des systèmes Linux/glibc 32 bits avec ASLR activé. En conditions de laboratoire, l’attaque nécessite de maintenir des connexions en continu jusqu’au maximum autorisé par le serveur pendant 6 à 8 heures en moyenne. On pense qu’elle est aussi possible sur les systèmes 64 bits, mais cela n’a pas encore été démontré. De telles attaques ont de bonnes chances d’être améliorées. »
    https://www.openssh.com/releasenotes.html

  • En regardant le diff [1] qui a introduit le bug, le problème semble être, d’après l’analyse, que sigdie() était auparavant entouré de #ifdef DO_LOG_SAFE_IN_SIGHAND, puis a été refactoré pour que sshsigdie() appelle directement sshlogv(), avec la disparition du #ifdef
    Qu’est-ce qui aurait pu l’éviter ? Fallait-il davantage relire les pull requests ? Il est étonnant qu’un logiciel dont le monde entier dépend pour les connexions sécurisées semble être maintenu, en pratique, par deux personnes [2]
    [1] https://github.com/openssh/openssh-portable/commit/752250caa...
    [2] https://github.com/openssh/openssh-portable/graphs/contribut...

    • Avec le recul, il est facile de dire ce qui aurait pu l’empêcher
      Dans ce cas, un commentaire expliquant pourquoi le #ifdef était nécessaire aurait pu aider. Par exemple : « le code ici doit être async-signal-safe, et l’état des verrous peut être indéterminé »
      Cela dit, pour être honnête, getrlimit ne figure pas non plus dans cette liste : https://man7.org/linux/man-pages/man7/signal-safety.7.html
      Malgré tout, si du code accompagné de commentaires sur l’async-signal-safety avait été supprimé ou modifié, cela aurait peut-être attiré l’attention lors de la revue. Dans le code cité, seul SAFE_IN_SIGHAND suggère vraiment que ce code doit être sûr dans un gestionnaire de signal
    • Comme OpenBSD a refactoré son système pour utiliser une fonction syslog réentrante et async-signal-safe, l’auteur de ce code a peut-être simplement supposé que le changement était sûr
      Il a pu oublier, ou ignorer, que sur d’autres plateformes que les développeurs d’OpenSSH pour OpenBSD ne prétendent pas réellement prendre en charge, on utilise toujours des fonctions non sûres vis-à-vis des signaux asynchrones
    • C’est de l’open source. Si vous pensez pouvoir faire mieux, vous pouvez toujours forker
      Vous n’avez pas de droit à recevoir quoi que ce soit d’un développeur open source. Eux aussi peuvent se tromper, et c’est à eux de décider combien de mainteneurs ou de relecteurs ils veulent avoir
      https://gist.github.com/richhickey/1563cddea1002958f96e7ba95...
    • La phrase « un logiciel dont le monde entier dépend pour les connexions sécurisées est maintenu en pratique par deux personnes » fait obligatoirement penser à ce xkcd : https://xkcd.com/2347/
    • Il y avait plusieurs façons de l’éviter
      1. Utiliser un vrai langage de programmation qui empêche de définir une fonction arbitraire comme gestionnaire de signal. Dans une libc classique, c’est manifestement dangereux ; dans un langage sûr comme Rust ou Java, on ne peut pas faire ce genre de chose
      2. Utiliser une libc bien implémentée où l’appel à des fonctions non async-signal-safe provoquerait au pire un blocage, pas une corruption mémoire. C’est relativement facile si le code exécuté dans un signal est traité comme un thread séparé du point de vue de l’accès au stockage local de thread ; et on peut aussi éviter le blocage s’il n’y a pas de mutex global, ou si l’on peut reprendre du code interrompu alors qu’il détenait un mutex
      3. Réfléchir lors des modifications de code et de leur approbation. Ne pas faire comme ceux qui ont supprimé un #ifdef sans justification, comme dans [1]
      4. Utiliser, à la place d’OpenSSH, un logiciel simple et bien conçu écrit par de bons programmeurs
  • Les notes de publication valent aussi la lecture : https://www.openssh.com/releasenotes.html
    Il s’agit en fait d’une variante intéressante d’un bug de condition de concurrence liée aux signaux. Selon le rapport de vulnérabilité, « OpenBSD n’est notamment pas vulnérable, car son gestionnaire SIGALRM appelle syslog_r(), une version de syslog() plus sûre vis-à-vis des signaux asynchrones, créée par OpenBSD en 2001 »
    Autrement dit, une mesure d’atténuation pour la sûreté des signaux a conduit les développeurs d’OpenBSD à mettre du code non trivial dans un gestionnaire de signal, et ce code est devenu non sûr une fois porté vers d’autres systèmes. Si l’on avait refactoré pour réduire au minimum le code dans les gestionnaires de signal, conformément à la sagesse habituelle et aux conventions du code Unix, ce bug aurait été évité

    • Theo de Raadt a formulé une observation assez pertinente sur la prévention de ce bug et de bugs similaires : aucun gestionnaire de signal ne devrait appeler de fonction qui ne soit pas un appel système sûr vis-à-vis des signaux
      Avec le temps, il est trop facile qu’un appel non sûr vis-à-vis des signaux asynchrones se glisse quelque part dans les appels transitifs, et il n’est pas toujours évident que ce chemin soit atteignable depuis un contexte de signal
    • Il y a de bonnes chances que, parmi les jeunes administrateurs système ou stagiaires qui devront corriger cette vulnérabilité, bon nombre n’étaient même pas nés quand OpenBSD a implémenté cette solution
  • Après avoir mis à niveau mes instances OpenSSH, j’ai regardé si, comme elles sont liées à musl et non à glibc, le syslog(3) de musl effectue aussi des allocations, et donc s’il est facilement exploitable de la même manière
    À première vue, il ne semble pas : https://github.com/bminor/musl/blob/master/src/misc/syslog.c
    Tout ce qu’on y voit est soit sur la pile, soit des variables statiques dont la réentrée est empêchée par des verrous. Les appels à {d,sn,vsn}printf() n’allouent pas non plus avec musl, alors qu’ils peuvent le faire avec glibc. Est-ce que j’ai raté quelque chose ?

    • Confirmation de Rich : https://fosstodon.org/@musl/112711796005712271
    • Si l’analyse sur les allocations est correcte, le pire cas serait sans doute un interblocage, car le verrou n’est pas récursif
      Cela dit, un interblocage dans sigalrm pourrait empêcher le nettoyage des connexions et mener à un déni de service
  • Un correctif pour FreeBSD est sorti
    On ne sait pas clairement s’il est affecté. Les exploits connus ne fonctionnaient que sur glibc, et FreeBSD n’utilise pas glibc, mais mieux vaut être prudent
    https://www.freebsd.org/security/advisories/FreeBSD-SA-24:04...

  • Selon le rapport, si vous ne pouvez pas mettre à jour ou recompiler sshd, définir LoginGraceTime à 0 dans le fichier de configuration suffit à corriger cette condition de concurrence dans le gestionnaire de signal
    Dans ce cas, sshd devient vulnérable à un déni de service par épuisement de toutes les connexions MaxStartups, mais il est protégé contre l’exécution de code à distance décrite dans cet avis
    Il semble donc que définir LoginGraceTime 0 dans sshd_config constitue une atténuation

    • Attendez, https://www.man7.org/linux/man-pages/man5/sshd_config.5.html indique qu’une valeur de 0 signifie qu’il n’y a pas de limite de temps
      Ce n’est pas encore pire ?
    • Un contournement plus réaliste pourrait être d’allonger suffisamment le délai de grâce ou, à l’inverse, d’ajuster le nombre maximal de connexions afin que la probabilité de réussite d’une attaque soit repoussée assez loin dans le futur pour ne pas valoir la peine d’être tentée
    • Redémarrer sshd à froid toutes les heures pourrait-il aussi réduire la possibilité d’exploitation, ou la rendre plus difficile ?
  • Le correctif pour Debian 12 est disponible, et Debian 11 n’est pas affectée
    https://security-tracker.debian.org/tracker/CVE-2024-6387

    • Focal (20.04) ne semble pas être une version affectée, tandis que Jammy (22.04) semble l’être
    • Je viens de lancer apt update et upgrade sur un serveur Debian 12, et les seuls paquets mis à niveau étaient ceux d’OpenSSH
    • J’ai confirmé que Pi OS bullseye a également reçu une version mise à jour d’openssh
  • Très belle découverte
    Je ne suis pas moi-même en première ligne, mais dans la recherche en sécurité, on a souvent l’impression que pour « gagner », il ne suffit pas de trouver et corriger un problème isolé, ou d’obtenir une récompense : il faut trouver toute la chaîne qui mène jusqu’à l’accès à distance
    On pourrait penser qu’un seul trou, par exemple une corruption mémoire ou une sortie de sandbox, devrait déjà suffire. Aujourd’hui, il y a tellement de petits problèmes qu’il faut peut-être démontrer un piratage complet pour que les gens le prennent vraiment au sérieux ou qu’une bug bounty soit versée

    • Beaucoup d’aspirants chercheurs en sécurité trouvent des problèmes non exploitables et demandent un numéro CVE, une reconnaissance, voire même une récompense
      Par exemple, si une application plante lorsqu’elle reçoit une entrée de confiance mal formée, mais que, par sa nature, cette application n’est pas destinée à être exposée à un adversaire et qu’en pratique cela n’arrivera pas, la plupart des gens y verront simplement un bug, pas un bug de sécurité. Ce serait bien de le corriger, mais ce n’est pas du même niveau, et ce genre de chose n’est pas très difficile à trouver
      Il faut donc distinguer les « vrais » bugs de sécurité comme celui-ci des bugs sans impact sécurité, et il est très important de démontrer que le problème est exploitable
      Comme il existera toujours une infinité de bugs sans impact sécurité, cette exigence de démonstration ne semble pas près de disparaître
    • Pour prendre un autre point de vue, imaginons que j’aie créé une bibliothèque de sérialisation/désérialisation qui devient vulnérable si on lui fournit des données non fiables
      C’est voulu par conception, et les utilisateurs peuvent sérialiser et désérialiser n’importe quoi, y compris des fonctions lambda. Ma bibliothèque est uniquement destinée à traiter des données provenant de sources fiables
      À ma connaissance, personne ne l’utilise pour traiter des données non fiables. Une bibliothèque populaire utilise la mienne pour lire des fichiers de configuration, mais elle considère ces fichiers comme des données fiables. Et ce n’est pas mon rôle de contrôler la façon dont les autres utilisent ma bibliothèque
      Dans ce cas, est-il juste d’enregistrer une CVE de priorité maximale en affirmant que mon projet contient une vulnérabilité d’exécution de code à distance ?
    • J’ai déjà été du côté de ceux qui signalent des failles, et une « vulnérabilité exploitable » est très différente d’une « faiblesse de sécurité qui pourrait un jour mener à une vulnérabilité exploitable »
      Les récompenses sont toujours versées pour la première catégorie. Pour la seconde, sans preuve de concept ni démonstration d’exploitabilité, le signalement peut même nuire à la réputation ou au signal envoyé
      Les faiblesses qui ne deviennent exploitables que lorsque certaines conditions sont réunies existent presque toujours. Même dans des concours comme Pwn2Own, on voit souvent plusieurs vulnérabilités enchaînées pour finir par prendre le contrôle d’un appareil, certaines restant non corrigées pendant des années. Les chercheurs gardent parfois longtemps ce type de faiblesses sous le coude afin d’en maximiser l’impact
      C’est triste, mais c’est la réalité
    • Comme le dit l’adage en sécurité : POC || GTFO
    • L’acheteur paie pour le résultat. Le fournisseur, lui, paie aussi pour les maillons individuels de la chaîne
  • Notes de version d’OpenSSH : https://www.openssh.com/txt/release-9.8
    Correctif minimal pour ceux qui ne peuvent pas ou ne veulent pas mettre à niveau : https://marc.info/?l=oss-security&m=171982317624594&w=2

    • « L’exploitation sur les systèmes 64 bits est également considérée comme possible, mais elle n’a pas été démontrée à ce stade »