Il est temps de repenser la sécurité d'OpenBSD

OpenBSD se positionne comme un OS sécurisé. Cependant, au cours des derniers mois, un certain nombre de vulnérabilités ont été détectées dans le système. Bien sûr, cela n'a rien d'extraordinaire. Bien que certaines vulnérabilités soient assez inhabituelles. Vous pourriez même dire critique. Les développeurs d'OpenBSD ont plusieurs directives sur la façon d'assurer la sécurité. En voici deux:

  • éviter les erreurs;
  • minimiser le risque d'erreurs.

Tout le monde n'est pas d'accord pour dire que ces principes sont suffisants pour construire des systèmes sécurisés. Il me semble qu'il est logique d'étudier si l'approche OpenBSD fonctionne, ou si elle est initialement vouée à l'échec.

Par exemple, je n'ai pas tout sélectionné, mais seulement quelques bugs intéressants qui coïncident accidentellement avec le sujet de notre conversation.

libc auth


Les fonctions d' authentification exécutent des assistants sans vérification d'argv. Rapport . Patch .

Il s'agit d'une erreur étonnamment simple, mais elle ne semblait probablement pas trop évidente lors de la révision du code. Il me semble, en partie, que la raison d'une certaine confusion est de savoir qui est responsable de la vérification des données d'entrée. Vous pouvez appeler chacun des trois composants impliqués: un programme, une bibliothèque ou login_passwd - et il est raisonnable de supposer que quelqu'un d'autre vérifie. Au final, je pense que la bibliothèque a été reconnue coupable, car c'est pour elle qu'un correctif est apparu, mais personnellement, à première vue, son code ne semble pas clairement faux.

Une partie plus intéressante de l'histoire est que même avec l'erreur libc mentionnée, la fonction login_passwdJe ne serais pas vulnérable de cette façon s'il n'y avait pas eu un autre bug. En 2001, login_passwd a été réécrit pour prendre en charge les kerberos, et c'est peut-être à ce moment-là qu'ils ont introduit la véritable cause de l'erreur. Une offre d'authentification de type demande-réponse (comme dans le système s / key) renvoie un état authentifié, pas un silence. Plusieurs années plus tard, le code Kerberos a été supprimé, mais une partie du code pour le prendre en charge est restée, ainsi que l'erreur introduite.

Si le code Kerberos était nettoyé à fond, le bogue d'authentification resterait (il y avait d'autres problèmes liés à l'analyse argv), mais son effet serait certainement considérablement réduit.

Il n'est pas facile d'analyser correctement argv dans un contexte de sécurité. De nombreux conseils et approches logiques ne fonctionnent pas ici. Je noterai seulement que cette vulnérabilité est apparue aprèsune autre discussion du problème avec les noms de fichiers sous Unix / Linux / POSIX , bien que le signe moins (trait d'union) ne fasse pas vraiment référence au nom de fichier.

ld.so


Les variables d'environnement incorrectes n'ont pas été supprimées du code ld.so. Rapport . Patch .

Quelque chose comme une erreur de mémoire. Mais non. Le bogue ici est de lier le succès d'une opération - le fractionnement de la variable d'environnement - à la suppression de cette variable. Très confiant.

Bien sûr, les partisans de divers systèmes de dactylographie s'assureront qu'ils traiteront ces opérations dans le bon ordre, mais pas le fait que cela aidera. Le code C ne s'est pas bloqué en raison d'un manque de gestion des erreurs ou parce que l'erreur d'allocation de mémoire est restée invisible.

ftp


ftp suit les redirections vers les fichiers locaux. Rapport . Patch .

Le bogue de redirection ftp de NetBSD est depuis longtemps un exemple typique de fonctions non contrôlées . Et là encore la même erreur (heureusement, avec des conséquences mineures)! Les gars, bien, asseyez-vous à la maison. N'ajoutez pas de fonctionnalités supplémentaires à vos programmes.

smtpd de


smtpd ne peut pas vérifier certaines adresses d'expéditeur. Rapport . Patch . Commentez .

Je pense que tout est dit dans le commentaire de Gilles, mais je rappellerai le fond. Il était une fois, tout le courrier était stocké localement pour chaque utilisateur dans / var / maildans les fichiers mbox. Ce n'est pas très cool, car il y a un risque de dommage si mua supprime l'e-mail tandis que mda en remet un nouveau (sans parler d'autres problèmes comme la distorsion du champ De). Par conséquent, le fichier mbox doit être verrouillé. Mais le verrouillage sur un système de fichiers réseau ne fonctionne pas de manière fiable. Donc, au lieu de verrouiller, nous utilisons des fichiers de verrouillage. Cependant, vous devez vous mettre d'accord sur un protocole de blocage spécifique, car l'utilisateur possède les fichiers mbox et la racine elle-même possède le répertoire. Ainsi, afin de modifier réellement le fichier mbox, vous devez exécuter la fonction d'aide setuid à chaque fois. Eh bien, c'est le premier problème. Une autre relique de l'ancien temps est les paramètres mda, qui peuvent être utilisés non seulement comme programme, mais comme pipeline shell. Les gens prescrivent quelque chose commespam-assassin | mail.mdaet vous ne pouvez pas simplement le transmettre execve().

Il y a beaucoup de difficultés qui ont leur origine dans le passé. Et, malheureusement, ce code problématique ne peut pas simplement être remplacé. Le courrier électronique est utilisé il y a longtemps et des systèmes et des workflows très complexes sont construits sur cette base, il est donc très difficile de simplement découper un morceau de code - et d'en insérer un nouveau. Malgré les différents niveaux de ségrégation des privilèges, un processus parent au niveau racine dépend encore fortement de ses processus enfants moins privilégiés. Il exécutera les commandes et les arguments qu'il recevra.

Éviter cela semble aussi simple que de passer au format de stockage maildir, mais cela nécessite diverses modifications à de nombreux endroits. Mua mail standardne comprend pas ce format. Quant à moi, mbox a longtemps survécu à sa vie, mais il convient toujours à de nombreuses personnes, et la procédure de mise à jour peut ne pas être complètement transparente et ne fonctionnera pas automatiquement.

lecture smtpd


La lecture en dehors de la portée dans smtpd peut être utilisée pour exécuter des commandes. Rapport . Patch .

Il s'agit vraiment d'un problème de sécurité de la mémoire. En envoyant des barres d'état amusantes, le serveur smtp distant peut injecter des commandes dans la file d'attente smtpd pour exécution. Lorsqu'un e-mail est mis en file d'attente pour être remis, smtpd ajoute des informations de destination à l'en-tête pour savoir quelle commande exécuter (voir ci-dessus). Cette attaque est similaire à la «contrebande» de requêtes http . Si vous pouvez générer une «merde» avec des commandes inattendues dans l'en-tête, smtpd les exécutera lorsque vous essayez de livrer à nouveau.

Comme ci-dessus, l'un des problèmes est que les parties les plus sensibles de smtpd sont trop proches de la surface d'attaque. Il me semble que le vrai problème est que smtpd stocke ses propres métadonnées dans les données de messagerie. De ce fait, une analyse de l'attaque hors synchronisation devient possible. Si la réponse citée du serveur était stockée complètement séparée du fichier avec les instructions de livraison, alors la lecture en dehors des frontières ne ferait pas beaucoup de mal.

Cette vulnérabilité me semble indicative, car nous voyons ici le danger de mélanger les données avec différents niveaux de confiance. Ce danger n'a jamais été discuté. Et elle l'est définitivement.

résultats


Bien sûr, la conclusion était claire dès le début, mais nous en parlerons quand même.

Je pense que certaines de ces erreurs aident à démontrer comment des principes tels que la suppression des interfaces obsolètes et la réduction de la complexité du code sont essentiels à la sécurité . Pour l'essentiel, l'échec est dû au fait que ces principes n'ont pas été suivis jusqu'au bout, et non pas parce que les principes eux-mêmes sont corrompus ou intenables. Certaines choses disparaissent, mais je ne suis pas d'accord pour dire que les développeurs ont besoin d'une sorte de vigilance surhumaine. Il est facile de donner des conseils inutiles, comme faire attention, ne pas se tromper et git gud [expression d'argot gamer signifie «aller bien», c'est-à-dire «aller mieux, aller vite» - env. trans.]. Mais je pense que OpenBSD a des problèmes plus graves.

Même OpenBSD peut risquer la sécurité pour des raisons pratiques utilitaires. C'est pourquoi certains projets obsolètes n'ont pas été modifiés depuis longtemps. Ainsi, peut-être la leçon est que les principes efficaces doivent toujours être respectés, et pas seulement quand cela est commode. Bien qu'il soit souvent difficile de faire le bon choix.

Les trois vulnérabilités les plus graves, auth et deux smtpd, sont plus ou moins adaptées à l'exploitation uniquement en raison de problèmes architecturaux qui dépassent la portée du bogue d'origine. Ils auraient dû rester des défauts mineurs qui démontrent que dans un système bien protégé, il n'est pas nécessaire de rechercher le code parfait, c'est-à-dire que des erreurs mineures sont autorisées - et qu'elles n'affectent pas la sécurité. Hélas, il peut être difficile d'identifier les défauts de conception sous une forme abstraite. Et toutes les parties du système semblent protégées individuellement, mais si elles sont combinées, des faiblesses peuvent apparaître.

La séparation des privilèges est un élément clé de la sécurité d'OpenBSD, et elle est basée sur la communication interprocessus. Il est logique d'examiner de plus près quels problèmes peuvent survenir avec des processus endommagés. Les navigateurs protégés renforcent de plus en plus la protection et entravent les attaques. En particulier, smtpd doit être protégé contre la corruption de mémoire dans les tâches réseau. Mais la facilité avec laquelle il est capable de contrôler le processus parental est alarmante.

Une seule erreur a pu être évitée en utilisant un langage plus sécurisé. Oui, probablement, il existe une sorte d'idiome de programme, qui dans certains cas peut aider si vous le suivez avec persévérance religieuse. Mais je ne suis pas encore sûr que par défaut chaque programmeur encodera correctement tous les invariants correspondants.

Écrire un serveur de messagerie est une affaire délicate. Surtout si les cadres existants vous resserrent.




All Articles