web-dev-qa-db-fra.com

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

Contexte du bug: CVE-2014-6271

Bash prend en charge l'exportation non seulement des variables Shell, mais aussi des fonctions Shell vers d'autres instances bash, via l'environnement de processus vers des processus enfants (indirects). Les versions bash actuelles 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 à travers l'environnement. La vulnérabilité se produit car bash ne s'arrête pas après le traitement de la définition de fonction; il continue d'analyser et d'exécuter des commandes Shell 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/65

Quand le bogue a-t-il été introduit et quel est le correctif qui le corrige complètement? (Voir CVE-2014-7169 )

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

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

Des informations supplémentaires sont souhaitables.


Connexes: Que fait env x = '() {:;}; commande' bash et pourquoi n'est-il pas sûr?

122
Deer Hunter

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 plus (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 plus (patch 27 inclus)

Si votre bash affiche une version plus ancienne, votre fournisseur de système d'exploitation peut toujours l'avoir corrigé par lui-même, le mieux est donc de vérifier.

Si:

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

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

Détails.

Le bug était dans l'implémentation initiale de la fonction d'exportation/importation introduite le 5e d'août 1989 par Brian Fox, et publié pour la première fois en bash-1.03 environ un mois plus tard à une époque où bash n'était pas si répandu, avant que la sécurité ne soit une préoccupation majeure et que 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 cela est arrivé.

bash exporte les fonctions dans les vars env 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 doit pas l'interpréter aveuglément.

Il est également cassé en ce que dans bash (contrairement au Bourne Shell), les variables et fonctions scalaires ont un espace de nom différent. En fait, si vous avez

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

bash mettra heureusement les deux dans l'environnement (oui 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 préfixe d'espace de noms BASH_ Pour cela, car c'est env vars uniquement pertinent de bash à bash. rc utilise un préfixe fn_ 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 devrait encore être nettoyé, mais au moins cela ne pourrait pas être plus exploitable que $BASH_ENV Ou $SHELLOPTS ...

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

Cependant, bash interprète toujours le code là-dedans et tout bogue dans l'interpréteur pourrait être exploité. Un tel bug 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 renforcé qui empêche bash d'interpréter le code dans n'importe quelle variable (comme en utilisant l'approche BASH_FUNCDEFS 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.

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 tenus d'avoir des bogues dans leur analyseur pour les cas d'angle, cela n'aurait pas été un problème si cet analyseur n'avait pas 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 préconisé le correctif de durcissement. Dans leur correctif, ils ont changé 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 plus tard publié ce correctif en tant que patch bash officiel en amont .

Ce correctif de durcissement, ou des variantes de celui-ci, sont maintenant disponibles pour la plupart des principales distributions Linux et sont finalement arrivés à Apple OS/X.

Cela résout désormais le problème de toute variable arbitraire env exploitant l'analyseur via ce vecteur, y compris deux autres vulnérabilités dans l'analyseur (CVE-2014-627 {7,8}) qui ont été révélé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 eurent eu le temps d'installer le patch de durcissement

Les bogues de 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 même si la vulnérabilité de sécurité a été corrigée, il est probable que nous verrons des changements dans ce domaine. Le correctif initial pour CVE-2014-6271 a rompu la compatibilité descendante en ce qu'il arrête d'importer des fonctions avec . Ou : Ou / Dans leur nom. Ceux-ci peuvent toujours être déclarés par bash, ce qui entraîne un comportement incohérent. Étant donné que les fonctions avec . Et : Dans leur nom sont couramment utilisées, il est probable qu'un correctif restaurera en acceptant au moins celles de l'environnement.

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

C'est aussi quelque chose que je me demandais. Je peux offrir quelques explications.

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

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

  1. Regardez d'où bash obtient l'entrée et ce qu'elle en fait. Et l'environnement est évident.
  2. Regardez à quels endroits l'interpréteur bash est appelé et sur quelles données. Encore une fois, cela ressortirait.
  3. L'importation de fonctions exportées est l'une des fonctionnalités qui est désactivée lorsque bash est setuid/setgid, ce qui le rend encore plus évident endroit à 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.

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

Les scripts shell (pas l'interpréteur) sont souvent examinés de près du point de vue de la sécurité. La syntaxe de Shell est si maladroite et il y a tellement de mises en garde avec l'écriture de scripts fiables (jamais vu moi ou d'autres mentionnant 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 que vous ne devez pas écrire de scripts CGI Shell, ou les scripts setuid sont désactivés sur la plupart des Unices. Ou que vous devez être très prudent lorsque vous traitez des fichiers dans des répertoires accessibles en écriture (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 Shell à des données non fiables (alimenter des données étrangères en code Shell à interpréter) via eval ou . Ou l'appeler sur des fichiers fournis par l'utilisateur, mais vous n'avez pas besoin d'une vulnérabilité dans bash pour l'exploiter. Il est assez évident que si vous transmettez des données non stérilisées à un shell à interpréter, il les interprétera.

Le Shell est donc appelé dans des contextes sécurisés. On lui donne des scripts fixes à interpréter et le plus souvent (parce qu'il est si difficile d'écrire des scripts fiables) des données fixes à traiter.

Par exemple, dans un contexte Web, un Shell peut être invoqué dans quelque chose comme:

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

Qu'est-ce qui peut mal tourner avec ça? Si quelque chose de mal est envisagé, il s'agit des données fournies à ce sendmail, et non de la façon dont cette ligne de commande Shell elle-même est analysée ou des données supplémentaires qui sont fournies à ce shell. Il n'y a aucune raison que vous souhaitiez prendre en compte les variables d'environnement qui sont transmises à ce shell. Et si vous le faites, vous vous rendez compte que ce sont tous des vars env dont le nom commence par "HTTP_" ou qui sont des vars env CGI bien connus comme SERVER_PROTOCOL Ou QUERYSTRING dont aucun Shell ou sendmail n'ont rien à faire faire avec.

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 de nombreuses vulnérabilités dans le passé, là encore non pas contre le shell lui-même, mais contre les éléments 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 défini ou appelé par une commande setuid (pensez par exemple à mount qui appelle des assistants). En particulier, il ignore les fonctions exportées.

Sudo nettoie l'environnement: tous par défaut sauf une liste blanche, et s'ils ne sont pas configurés, au moins des listes noires connues pour affecter un Shell ou un autre (comme PS4, BASH_ENV, SHELLOPTS ...). Il répertorie également les variables d'environnement dont le contenu commence par () (C'est pourquoi CVE-2014-6271 ne permet pas l'escalade de 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é comme commande par un script Shell ou une ligne de commande. Et Apache2 ne définira jamais une variable echo ou BASH_ENV.

Il est assez évident que certaines variables d'environnement devraient ê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 fonction de leur contenu (sauf pour Sudo). Ou en d'autres termes, personne ne pensait que les variables env arbitraires pourraient être un vecteur pour l'injection de code.

Quant à savoir si des tests approfondis lors de l'ajout de la fonctionnalité auraient pu le détecter, 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 dans une invocation bash, elle est bien importée dans une autre. Un test très approfondi pourrait avoir repéré des problèmes lorsqu'une variable et une fonction du même nom sont exportées ou lorsque la fonction est importée dans un environnement local différent de celui dans lequel elle a été exportée.

Mais pour pouvoir détecter la vulnérabilité, ce n'est pas un test de fonctionnalité que vous auriez dû faire. L'aspect de la sécurité aurait dû être le principal objectif, et vous ne testeriez pas la fonctionnalité, mais le mécanisme et la manière dont il pourrait être utilisé à mauvais escient.

Ce n'est pas quelque chose que les développeurs (en particulier 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 en réseau.

205
Stéphane Chazelas

Selon la base de données NVD au NIST ( http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-6271 ), TOUTES LES VERSIONS de bash à partir de 1.14.0 sont vulnérables.

RedHat a eu vent du bug le 14 septembre .

Le correctif publié par Mr.Ramey (mainteneur bash) le 26 septembre 2014 corrige le bogue CVE-2014-7169 .

Appliquez ces correctifs et tous les correctifs précédents aux sources bash correspondantes:


Vulnérabilités supplémentaires dans bash


Un peu plus sur l'historique du bug (avec l'aimable autorisation de mikeserv )

Source: http://www.linuxmisc.com/12-unix-Shell/e3f174655d75a48b.htm

En 1994, Chet Ramey l'a décrit comme précédant de toute façon l'ancienne spécification POSIX 2 qui spécifiait les fonctions exportées. Ou, au moins, il a décrit le mécanisme de bash comme le faisant - si oui ou non il était aussi défectueux alors que maintenant je ne sais pas. Il discute également des exportations de fonctions de rc dans ce fil aussi.

19
Deer Hunter