GNU/Linux >> Tutoriels Linux >  >> Linux

Quand le bogue Shellshock (cve-2014-6271/7169) a-t-il été introduit et quel est le correctif qui le corrige complètement ?

Contexte du bogue :CVE-2014-6271

Bash prend en charge l'exportation non seulement des variables shell, mais également des fonctions shell
vers d'autres instances bash, via l'environnement de processus vers
des processus enfants (indirects). Les versions actuelles de bash utilisent une variable d'environnement
nommée par le nom de la fonction et une définition de fonction
commençant par "() {" dans la valeur de la variable pour propager les définitions de fonction
dans l'environnement. La vulnérabilité se produit parce que
bash ne s'arrête pas après le traitement de la définition de la fonction ; il
continue d'analyser et d'exécuter les commandes shell en suivant la définition de la fonction. Par exemple, un paramètre de variable d'environnement de

  VAR=() { ignored; }; /bin/id

exécutera /bin/id lorsque l'environnement sera importé dans le processus bash
.

Source :http://seclists.org/oss-sec/2014/q3/650

Quand le bogue a-t-il été introduit et quel est le correctif qui le résout entièrement ? (Voir CVE-2014-7169)

Quelles sont les versions vulnérables au-delà de celles notées dans le CVE (initialement) (3.{0..2} et 4.{0..3}) ?

Le code source bogué a-t-il été réutilisé dans d'autres projets ?

Des informations supplémentaires sont souhaitables.

En relation :Que fait env x='() { : ;} ; command' bash do et pourquoi n'est-il pas sécurisé ?

Réponse acceptée :

TL;DR

La vulnérabilité shellshock est entièrement corrigée dans

  • Sur la branche bash-2.05b :2.05b.10 et supérieur (patch 10 inclus)
  • Sur la branche bash-3.0 :3.0.19 et supérieur (patch 19 inclus)
  • Sur la branche bash-3.1 :3.1.20 et supérieur (patch 20 inclus)
  • Sur la branche bash-3.2 :3.2.54 et supérieur (patch 54 inclus)
  • Sur la branche bash-4.0 :4.0.41 et supérieur (patch 41 inclus)
  • Sur la branche bash-4.1 :4.1.14 et supérieur (patch 14 inclus)
  • Sur la branche bash-4.2 :4.2.50 et supérieur (patch 50 inclus)
  • Sur la branche bash-4.3 :4.3.27 et supérieur (patch 27 inclus)

Si votre bash affiche une version plus ancienne, votre fournisseur de système d'exploitation l'a peut-être encore corrigé lui-même, il est donc préférable de vérifier.

Si :

env xx='() { echo vulnerable; }' bash -c xx

montre "vulnérable", vous êtes toujours vulnérable. C'est le seul test pertinent (si l'analyseur bash est toujours exposé au code dans any variable d'environnement).

Détails.

Le bogue était dans l'implémentation initiale de la fonction d'exportation/importation introduite le 5 août 1989 par Brian Fox, et publiée pour la première fois dans bash-1.03 environ un mois plus tard à une époque où bash n'était pas aussi répandu, avant que la sécurité ne soit cela était une grande préoccupation et HTTP et le Web ou Linux existaient même.

Depuis le ChangeLog en 1.05 :

Fri Sep  1 18:52:08 1989  Brian Fox  (bfox at aurel)

       * readline.c: rl_insert ().  Optimized for large amounts
         of typeahead.  Insert all insertable characters at once.

       * I update this too irregularly.
         Released 1.03.
[...]
Sat Aug  5 08:32:05 1989  Brian Fox  (bfox at aurel)

       * variables.c: make_var_array (), initialize_shell_variables ()
         Added exporting of functions.

Certaines discussions dans gnu.bash.bug et comp.unix.questions à cette époque mentionnent également la fonctionnalité.

Il est facile de comprendre comment il en est arrivé là.

bash exporte les fonctions dans env vars comme

foo=() {
  code
}

Et à l'importation, tout ce qu'il a à faire est d'interpréter cela avec le = remplacé par un espace… sauf qu'il ne faut pas l'interpréter aveuglément.

C'est aussi cassé en cela dans bash (contrairement au shell Bourne), les variables scalaires et les fonctions ont un espace de noms différent. En fait, si vous avez

foo() { echo bar; }; export -f foo
export foo=bar

bash mettra volontiers les deux dans l'environnement (oui, les entrées avec le même nom de variable) mais de nombreux outils (y compris de nombreux shells) ne les propageront pas.

On dirait également que bash devrait utiliser un BASH_ préfixe d'espace de noms pour cela car c'est env vars uniquement pertinent de bash à bash. rc utilise un fn_ préfixe pour une fonctionnalité similaire.

Une meilleure façon de l'implémenter aurait été de mettre la définition de toutes les variables exportées dans une variable comme :

BASH_FUNCDEFS='f1() { echo foo;}
  f2() { echo bar;}...'

Cela aurait encore besoin d'être nettoyé mais au moins cela ne pourrait pas être plus exploitable que $BASH_ENV ou $SHELLOPTS

Il existe un patch qui empêche bash d'interpréter autre chose que la définition de la fonction (https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html), et c'est celle qui a été appliquée dans toute la sécurité mises à jour des différentes distributions Linux.

Cependant, bash interprète toujours le code qu'il contient et tout bogue dans l'interpréteur pourrait être exploité. Un bogue de ce type a déjà été trouvé (CVE-2014-7169) bien que son impact soit beaucoup plus faible. Il y aura donc bientôt un autre patch.

Jusqu'à un correctif de durcissement qui empêche bash d'interpréter le code dans n'importe quelle variable (comme l'utilisation de BASH_FUNCDEFS approche ci-dessus), nous ne saurons pas avec certitude si nous ne sommes pas vulnérables à un bogue dans l'analyseur bash. Et je pense qu'un tel correctif de durcissement sera publié tôt ou tard.

Connexe :Comment trouver des fichiers avec un certain sous-chemin ?

Modifier 2014-09-28

Deux bogues supplémentaires dans l'analyseur ont été trouvés (CVE-2014-718{6,7}) (notez que la plupart des shells sont susceptibles d'avoir des bogues dans leur analyseur pour les cas extrêmes, cela n'aurait pas été un problème si cet analyseur n'avait pas n'a pas été exposé à des données non fiables).

Alors que les 3 bogues 7169, 7186 et 7187 ont été corrigés dans les correctifs suivants, Red Hat a poussé pour le correctif de durcissement. Dans leur patch, ils ont modifié le comportement afin que les fonctions soient exportées dans des variables appelées BASH_FUNC_myfunc() plus ou moins préemptant la décision de conception de Chet.

Chet a ensuite publié ce correctif en tant que correctif bash officiel en amont.

Ce correctif de renforcement, ou ses variantes, est désormais disponible pour la plupart des principales distributions Linux et a finalement été intégré à Apple OS/X.

Cela corrige désormais le problème de toute variable d'environnement arbitraire exploitant l'analyseur via ce vecteur, y compris deux autres vulnérabilités dans l'analyseur (CVE-2014-627{7,8}) qui ont été divulguées plus tard par Michał Zalewski (CVE-2014-6278 étant presque aussi mauvais que CVE-2014-6271) heureusement après que la plupart des gens aient eu le temps d'installer le correctif de durcissement

Les bogues dans l'analyseur seront également corrigés, mais ils ne sont plus vraiment un problème maintenant que l'analyseur n'est plus aussi facilement exposé à des entrées non fiables.

Notez que bien que la faille de sécurité ait été corrigée, il est probable que nous verrons des changements dans ce domaine. Le correctif initial pour CVE-2014-6271 a rompu la rétrocompatibilité en ce sens qu'il arrête d'importer des fonctions avec . ou : ou / en leur nom. Ceux-ci peuvent toujours être déclarés par bash, ce qui entraîne un comportement incohérent. Parce que fonctionne avec . et : en leur nom sont couramment utilisés, il est probable qu'un patch restaurera en acceptant au moins ceux de l'environnement.

Pourquoi n'a-t-il pas été trouvé plus tôt ?

C'est aussi quelque chose que je me suis demandé. Je peux offrir quelques explications.

Tout d'abord, je pense que si un chercheur en sécurité (et je ne suis pas un chercheur en sécurité professionnel) avait spécifiquement recherché des vulnérabilités dans bash, il l'aurait probablement trouvée.

Par exemple, si j'étais chercheur en sécurité, mes approches pourraient être :

  1. Regardez où bash reçoit des données et ce qu'il en fait. Et l'environnement est une évidence.
  2. Regardez à quels endroits le bash l'interpréteur est invoqué et sur quelles données. Encore une fois, cela se démarquerait.
  3. L'import de fonctions exportées est l'une des fonctionnalités qui est désactivée lorsque bash est setuid/setgid, ce qui en fait un endroit encore plus évident à regarder.

Maintenant, je soupçonne que personne n'a pensé à considérer bash (l'interprète) comme une menace, ou que la menace aurait pu venir de cette façon.

Le bash l'interpréteur n'est pas destiné à traiter les entrées non fiables.

Shell scripts (pas l'interprète) sont souvent examinés de près du point de vue de la sécurité. La syntaxe du shell est si délicate et il y a tellement de mises en garde concernant l'écriture de scripts fiables (vous avez déjà vu moi ou d'autres mentionner l'opérateur split+glob ou pourquoi vous devriez citer des variables par exemple ?) qu'il est assez courant de trouver des failles de sécurité dans les scripts qui traitent données non fiables.

C'est pourquoi vous entendez souvent dire que vous ne devriez pas écrire de scripts shell CGI, ou que les scripts setuid sont désactivés sur la plupart des Unix. Ou que vous devez être très prudent lors du traitement de fichiers dans des répertoires accessibles en écriture par tout le monde (voir CVE-2011-0441 par exemple).

L'accent est mis sur cela, les scripts shell, pas l'interpréteur.

Vous pouvez exposer un interpréteur de shell à des données non fiables (alimentant des données étrangères en tant que code shell à interpréter) via eval ou . ou l'appeler sur des fichiers fournis par l'utilisateur, mais alors vous n'avez pas besoin d'une vulnérabilité dans bash pour l'exploiter. Il est tout à fait évident que si vous transmettez des données non épurées à un shell à interpréter, il les interprétera.

Ainsi, le shell est appelé dans des contextes de confiance. On lui donne des scripts fixes à interpréter et le plus souvent (car il est si difficile d'écrire des scripts fiables) des données fixes à traiter.

Par exemple, dans un contexte Web, un shell peut être appelé dans quelque chose comme :

popen("sendmail -oi -t", "w");

Qu'est-ce qui peut mal tourner avec ça ? Si quelque chose ne va pas est envisagé, il s'agit des données transmises à ce sendmail, pas de la façon dont cette ligne de commande shell elle-même est analysée ou des données supplémentaires qui sont transmises à ce shell. Il n'y a aucune raison pour que vous vouliez considérer les variables d'environnement qui sont passées à ce shell. Et si vous le faites, vous vous rendez compte que ce sont toutes les variables d'environnement dont le nom commence par "HTTP_" ou sont des variables d'environnement CGI bien connues comme SERVER_PROTOCOL ou QUERYSTRING ni le shell ni sendmail n'ont à voir avec.

Connexes :Utiliser un transistor pour illuminer " complètement " une lampe ?

Dans des contextes d'élévation de privilèges comme lors de l'exécution de setuid/setgid ou via sudo, l'environnement est généralement pris en compte et il y a eu beaucoup de vulnérabilités dans le passé, encore une fois pas contre le shell lui-même mais contre les choses qui élèvent les privilèges comme sudo (voir par exemple CVE-2011-3628).

Par exemple, bash ne fait pas confiance à l'environnement lorsqu'il est setuid ou appelé par une commande setuid (pensez à mount par exemple qui invoque des aides). En particulier, il ignore les fonctions exportées.

sudo nettoie l'environnement :tout par défaut sauf pour une liste blanche, et si configuré non, au moins en liste noire quelques-uns qui sont connus pour affecter un shell ou un autre (comme PS4 , BASH_ENV , SHELLOPTS …). Il met également sur liste noire les variables d'environnement dont le contenu commence par () (c'est pourquoi CVE-2014-6271 n'autorise pas l'élévation des privilèges via sudo ).

Mais encore une fois, c'est pour les contextes où l'environnement n'est pas fiable :toute variable avec n'importe quel nom et valeur peut être définie par un utilisateur malveillant dans ce contexte. Cela ne s'applique pas aux serveurs web/ssh ou à tous les vecteurs qui exploitent CVE-2014-6271 où l'environnement est contrôlé (au moins le nom des variables d'environnement est contrôlé…)

Il est important de bloquer une variable comme echo="() { evil; }" , mais pas HTTP_FOO="() { evil; }" , car HTTP_FOO ne sera pas appelée en tant que commande par un script shell ou une ligne de commande. Et apache2 ne va jamais définir un echo ou BASH_ENV variables.

C'est assez évident certains les variables d'environnement doivent être mises sur liste noire dans certains contextes en fonction de leur nom , mais personne ne pensait qu'ils devraient être mis sur liste noire en raison de leur contenu (sauf pour sudo ). Ou en d'autres termes, personne ne pensait que des env vars arbitraires pourraient être un vecteur d'injection de code.

Quant à savoir si des tests approfondis lors de l'ajout de la fonctionnalité auraient pu l'attraper, je dirais que c'est peu probable.

Lorsque vous testez la fonctionnalité , vous testez la fonctionnalité. La fonctionnalité fonctionne bien. Si vous exportez la fonction en un seul bash invocation, il est bien importé dans un autre. Un test très approfondi aurait pu détecter des problèmes lorsqu'une variable et une fonction portant le même nom sont exportées ou lorsque la fonction est importée dans une locale différente de celle dans laquelle elle a été exportée.

Mais pour pouvoir repérer la vulnérabilité, ce n'est pas un test de fonctionnalité que vous auriez dû faire. L'aspect sécurité aurait dû être l'objectif principal, et vous ne testeriez pas la fonctionnalité, mais le mécanisme et comment il pourrait être abusé.

Ce n'est pas quelque chose que les développeurs (surtout en 1989) ont souvent à l'esprit, et un développeur shell pourrait être excusé de penser que son logiciel est peu susceptible d'être exploitable sur le réseau.


Linux
  1. Dans Bash, quand créer un alias, quand créer un script et quand écrire une fonction ?

  2. Qu'advient-il de la sortie d'un processus qui a été désavoué et a perdu son terminal ?

  3. Le Point Of The Bash Null-operator ":", Deux-points ?

  4. Quelle est la signification de caddr_t et quand est-il utilisé ?

  5. Quelle est la différence entre #!/usr/bin/env bash et #!/usr/bin/bash ?

Quelle est la différence entre Linux et Unix ?

Suivi et correction d'un bogue d'installation

Quelle est la différence entre &> et >&en bash ?

Quelle était la méthode de compression SquashFS ?

Quelles sont les applications de système de fichiers racine minimales requises pour démarrer complètement Linux ?

Quel est le contenu de /bin/bash, et que dois-je faire si je les écrase accidentellement