TL; DR
La vulnérabilité de shellshock est entièrement corrigée dans
- Sur la branche bash-2.05b: 2.05b.10 et plus (patch 10 inclus)
- Sur la branche bash-3.0: 3.0.19 et ultérieure (patch 19 inclus)
- Sur la branche bash-3.1: 3.1.20 et plus (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 plus (patch 41 inclus)
- Sur la branche bash-4.1: 4.1.14 et plus (patch 14 inclus)
- Sur la branche bash-4.2: 4.2.50 et plus (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é lui-même, il est donc préférable de le vérifier.
Si:
env xx='() { echo vulnerable; }' bash -c xx
montre "vulnérable", vous êtes toujours vulnérable. C’est le seul test pertinent (que l’analyseur bash soit toujours exposé au code dans une variable d’environnement).
Détails.
Le bogue a été dans la mise en œuvre initiale de la fonction exportation / importation introduite sur les 5 e de Août 1989 par Brian Fox, et sorti en bash-1,03 un mois plus tard à un moment où bash n'a pas été dans une telle généralisation, avant la sécurité était ce souci et HTTP et le Web ou Linux existaient même.
À partir du journal des modifications de la version 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é là-bas.
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 =
remplacement par un espace ... sauf qu'il ne devrait pas l'interpréter aveuglément.
Il est également cassé dans le fait qu'en bash
(contrairement au shell Bourne), les variables scalaires et les fonctions ont un espace de nom 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 ayant le même nom de variable), mais de nombreux outils (y compris de nombreux shells) ne les propagent pas.
On pourrait également avancer que bash devrait utiliser un BASH_
préfixe d'espace de nom pour cela, car il ne s'agit que d'envars qui ne sont pertinents que de bash à bash. rc
utilise un fn_
préfixe pour une fonctionnalité similaire.
Un meilleur moyen de le mettre en œuvre aurait été de placer la définition de toutes les variables exportées dans une variable telle que:
BASH_FUNCDEFS='f1() { echo foo;}
f2() { echo bar;}...'
Cela aurait encore besoin d'être assaini mais au moins, cela ne pourrait pas être plus exploitable que $BASH_ENV
ou $SHELLOPTS
...
Il existe un correctif 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 celui qui contient été appliqué dans toutes les mises à jour de sécurité des différentes distributions Linux.
Cependant, bash interprète toujours le code et tout bogue de l’interpréteur pourrait être exploité. Un tel bogue a déjà été trouvé (CVE-2014-7169) bien que son impact soit beaucoup plus petit. Il y aura donc un autre patch à venir.
Jusqu'à ce qu'un correctif de sécurité empêchant bash d'interpréter le code dans une variable (comme avec l' BASH_FUNCDEFS
approche ci-dessus), nous ne saurons pas avec certitude si nous ne sommes pas vulnérables à un bogue de l'analyseur bash. Et je crois qu’un tel correctif de durcissement sera publié tôt ou tard.
Edit 2014-09-28
Deux bogues supplémentaires dans l'analyseur ont été trouvés (CVE-2014-718 {6,7}) (notez que la plupart des obus sont voués à avoir des bogues dans leur analyseur pour les cas de coin, ce qui n'aurait pas été un problème si cet analyseur avait pas été exposé à des données non fiables).
Tandis que les 3 bogues 7169, 7186 et 7187 ont été corrigés dans les correctifs suivants, Red Hat a demandé le correctif de renforcement. Dans leur patch, ils ont changé le comportement afin que les fonctions soient exportées dans des variables appelant BASH_FUNC_myfunc()
plus ou moins 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 des variantes de celui-ci, sont maintenant disponibles pour la plupart des grandes distributions Linux et ont finalement été intégrés à Apple OS / X.
Cela résout maintenant le problème de toute variable arbitraire exploitant l’analyseur via ce vecteur, y compris deux autres vulnérabilités de l’analyseur (CVE-2014-627 {7,8}) révélées ultérieurement par Michał Zalewski (CVE-2014-6278 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 dans l'analyseur seront également corrigés, mais ils ne posent plus vraiment problème maintenant que l'analyseur n'est plus si facilement exposé à des entrées non fiables.
Notez que, bien que la vulnérabilité de la sécurité ait été corrigée, il est probable que des modifications soient apportées dans ce domaine. Le correctif initial pour CVE-2014-6271 a rompu la compatibilité en amont dans la mesure où 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 crée 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 suis demandé. Je peux donner quelques explications.
Premièrement, 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 les suivantes:
- Regardez d'où
bash
vient l'apport et ce qu'il en fait. Et l'environnement est une évidence.
- Regardez à quels endroits l'
bash
interprète est appelé et sur quelles données. Encore une fois, cela se démarquerait.
- L'importation de fonctions exportées est l'une des fonctionnalités désactivées lorsque
bash
setuid / setgid, ce qui en fait un endroit encore plus évident à regarder.
Maintenant, je soupçonne que personne ne pensait considérer bash
(l'interprète) comme une menace ou que la menace aurait pu venir de cette façon.
L' bash
interpréteur n'est pas destiné à traiter des entrées non fiables.
Les scripts shell (et non l'interpréteur) sont souvent examinés de près du point de vue de la sécurité. La syntaxe du shell est tellement maladroite et il y a tellement de mises en garde à écrire des scripts fiables (jamais vu par moi-même ou par d'autres qui mentionnent 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 traités données non fiables.
C'est pourquoi vous entendez souvent qu'il ne faut pas écrire de scripts shell CGI, sinon les scripts setuid sont désactivés sur la plupart des Unices. Ou que vous deviez être particulièrement prudent lorsque vous traitez des fichiers dans des répertoires accessibles en écriture ( par exemple, voir CVE-2011-0441 ).
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 (alimenter des données étrangères sous forme de code de shell à interpréter) via eval
ou .
ou en l'appelant sur des fichiers fournis par l'utilisateur, mais vous n'avez alors pas besoin d'une vulnérabilité bash
pour l'exploiter. Il est bien évident que si vous transmettez des données non normalisées à un shell pour interprétation, il les interprétera.
Donc, le shell est 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 appelé de la manière suivante:
popen("sendmail -oi -t", "w");
Qu'est-ce qui peut éventuellement aller mal avec ça? Si quelque chose de mal est envisagé, il s’agit des données envoyées à sendmail, et non de la manière dont la ligne de commande du shell elle-même est analysée ou des données supplémentaires fournies à ce shell. Il n'y a aucune raison pour que vous souhaitiez prendre en compte les variables d'environnement transmises à ce shell. Et si vous le faites, vous réalisez que ce sont tous des envs dont le nom commence par "HTTP_" ou sont bien connus, comme le vars env SERVER_PROTOCOL
ou ceux QUERYSTRING
du shell ou de sendmail.
Dans les 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é, pas encore 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
n'approuve pas l'environnement lorsqu'il est setuid ou appelé par une commande setuid (pensez mount
par exemple qui appelle des helpers). En particulier, il ignore les fonctions exportées.
sudo
ne nettoie l'environnement: tout par défaut , sauf pour une liste blanche, et si configuré pour ne pas, au moins listes noires quelques qui sont connus pour affecter une coquille ou d'une autre (comme PS4
, BASH_ENV
, SHELLOPTS
...). Il met également en liste noire les variables d'environnement dont le contenu commence par ()
(c'est pourquoi CVE-2014-6271 n'autorise pas l'escalade de privilèges via sudo
).
Mais là encore, il s’agit de contextes dans lesquels l’environnement ne peut pas être sécurisé: toute variable portant un nom ou une valeur quelconque peut être définie par un utilisateur malveillant dans ce contexte. Cela ne s'applique pas aux serveurs Web / ssh ni à tous les vecteurs exploitant 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; }"
parce que HTTP_FOO
ne sera appelé comme commande par aucun script shell ou ligne de commande. Et apache2 ne va jamais définir une variable echo
ou BASH_ENV
.
Il est assez évident que certaines variables d'environnement doivent figurer sur une liste noire dans certains contextes en fonction de leur nom , mais personne ne pensait qu'elles devraient l'être sur la base de leur contenu (à l'exception de sudo
). Autrement dit, personne ne pensait que des variables env arbitraires pourraient être un vecteur d’injection de code.
Pour ce qui est de savoir si des tests approfondis avec l'ajout de la fonctionnalité ont 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 dans une bash
invocation, elle est bien importée dans une autre. Des tests très approfondis auraient pu permettre de 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 langue différente de celle dans laquelle elle a été exportée.
Mais pour pouvoir repérer la vulnérabilité, il ne vous aurait pas fallu faire un test de fonctionnalité. La sécurité aurait dû être au centre des préoccupations, et vous ne testeriez pas la fonctionnalité, mais le mécanisme et la manière dont il pourrait être utilisé de manière abusive.
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é pour penser que son logiciel n’est pas susceptible d’être exploitable en réseau.