Sécurité sérieuse : GnuTLS suit OpenSSL, corrige un bug d'attaque temporelle

Sécurité sérieuse : GnuTLS suit OpenSSL, corrige un bug d'attaque temporelle

Nœud source: 1956368

La semaine dernière, nous avons écrit sur un tas de bogues de gestion de la mémoire qui ont été corrigés dans la dernière mise à jour de sécurité de la célèbre bibliothèque de chiffrement OpenSSL.

Parallèlement à ces bogues de mémoire, nous avons également signalé un bogue appelé CVE-2022-4304 : Synchronisation d'Oracle dans le déchiffrement RSA.

Dans ce bogue, tirer le même message chiffré encore et encore sur un serveur, mais en modifiant le rembourrage à la fin des données pour rendre les données invalides, et provoquer ainsi une sorte de comportement imprévisible…

… ne prendrait pas un temps constant, en supposant que vous étiez proche de la cible sur le réseau et que vous pouviez deviner de manière fiable combien de temps la partie transfert de données du processus prendrait.

Toutes les données ne sont pas traitées de la même manière

Si vous lancez une requête, chronométrez la durée de la réponse et soustrayez le temps consommé dans l'envoi et la réception de bas niveau des données réseau, vous savez combien de temps le serveur a mis pour effectuer son calcul interne pour traiter la requête. .

Même si vous n'êtes pas sûr du temps utilisé sur le réseau, vous pouvez rechercher des variations dans les temps d'aller-retour en lançant de nombreuses requêtes et en collectant de nombreux échantillons.

Si le réseau est suffisamment fiable pour supposer que la surcharge réseau est en grande partie constante, vous pouvez utiliser des méthodes statistiques pour déduire quel type de modification de données entraîne quel type de délai de traitement supplémentaire.

À partir de là, vous pourrez peut-être en déduire quelque chose sur la structure, voire le contenu, des données originales non cryptées qui sont censées être gardées secrètes à l'intérieur de chaque demande répétée.

Même si vous ne pouvez extraire qu'un seul octet de texte en clair, eh bien, ce n'est pas censé se produire.

Soi-disant attaques de synchronisation de ce type sont toujours gênants, même si vous devrez peut-être envoyer des millions de faux paquets et les chronométrer tous pour avoir une chance de récupérer un seul octet de données en clair…

… parce que les réseaux sont plus rapides, plus prévisibles et capables de gérer beaucoup plus de charge qu'ils ne l'étaient il y a quelques années à peine.

Vous pourriez penser que des millions de paquets traîtres qui vous ont été envoyés dans, disons, l'heure suivante se démarqueraient comme un pouce de tri.

Mais "un million de paquets par heure de plus ou de moins que d'habitude" n'est tout simplement plus une variation particulièrement importante.

Bogue "oracle" similaire dans GnuTLS

Eh bien, la même personne qui a signalé le bogue de synchronisation du dernier bogue corrigé dans OpenSSL a également signalé un bogue similaire dans GnuTLS à peu près au même moment.

Celui-ci a l'identifiant de bogue CVE-2023-0361.

Bien que GnuTLS ne soit pas aussi populaire ou largement utilisé qu'OpenSSL, vous avez probablement un certain nombre de programmes dans votre parc informatique, ou même sur votre propre ordinateur, qui l'utilisent ou l'incluent, y compris éventuellement FFmpeg, GnuPG, Mplayer, QEMU , Rdesktop, Samba, Wget et Wireshark.

Ironiquement, le défaut de synchronisation dans GnuTLS est apparu dans le code qui était censé enregistrer les erreurs d'attaque de synchronisation en premier lieu.

Comme vous pouvez le voir sur la différence de code (diff) ci-dessous, le programmeur savait que tout conditionnel (if ... then) utilisée pour vérifier et traiter une erreur de déchiffrement peut produire des variations de temps, car les processeurs prennent généralement un temps différent selon la direction dans laquelle votre code suit une instruction de "branchement".

(C'est particulièrement vrai pour une branche qui va souvent dans un sens et rarement dans l'autre, car les processeurs ont tendance à se souvenir, ou à mettre en cache, le code qui s'exécute de manière répétée afin d'améliorer les performances, ce qui rend le code rarement utilisé plus lent.)

Différence de code de gnutls-3.7.8/lib/auth/rsa.c contre 3.7.9

Mais le programmeur voulait toujours enregistrer qu'une attaque pourrait se produire, ce qui se produit si le if (ok) test ci-dessus échoue et se ramifie dans le else { ... } .

À ce stade, le code appelle le _gnutls_debug_log() fonction, ce qui pourrait prendre un certain temps pour faire son travail.

Par conséquent, le codeur a inséré un appel délibéré à _gnutls_no_log() dans l' then { ... } partie du code, qui prétend enregistrer une "attaque" alors qu'il n'y en a pas, afin d'essayer d'égaliser le temps que le code passe dans les deux sens que le if (ok) l'instruction de branche peut prendre.

Apparemment, cependant, les deux chemins de code n'étaient pas suffisamment similaires dans le temps qu'ils ont utilisé (ou peut-être le _gnutls_debug_log() fonction seule n'était pas suffisamment cohérente pour traiter différents types d'erreurs), et un attaquant pouvait commencer à distinguer les témoins de décryptage après environ un million d'essais.

Que faire?

Si vous êtes programmeur : la correction de bogue ici était simple et suivait le principe "moins c'est plus".

Le code en rose ci-dessus, qui était réputé ne pas donner de toute façon des données de détection d'attaques très utiles, a simplement été supprimé, au motif que le code qui n'y est pas ne peut pas être compilé par erreur, quels que soient vos paramètres de construction…

… et le code qui n'est pas compilé ne peut jamais s'exécuter, que ce soit par accident ou à dessein.

Si vous êtes un utilisateur GnuTLS : la version récemment publiée 3.7.9 et la « nouvelle saveur du produit » 3.8.0 avoir ce correctif, ainsi que divers autres, inclus.

Si vous utilisez une distribution Linux, recherchez les mises à jour de toute version de bibliothèque partagée gérée de manière centralisée de GnuTLS, ainsi que les applications qui apportent leur propre version.

Sous Linux, recherchez les fichiers portant le nom libgnutls*.so pour trouver toutes les bibliothèques partagées qui traînent et rechercher gnutls-cli pour trouver toutes les copies de l'utilitaire de ligne de commande qui est souvent inclus avec la bibliothèque.

Tu peux courir gnutls-cli -vv pour savoir quelle version de libgnutls il est dynamiquement lié à :

 $ gnutls-cli -vv gnutls-cli 3.7.9 <-- ma distribution Linux a reçu la mise à jour vendredi dernier (2023-02-10)

Horodatage:

Plus de Sécurité nue