Pour rassurer quelques-uns, je n'ai pas trouvé le bogue en observant des exploits, je n'ai aucune raison de croire qu'il a été exploité avant d'être divulgué (bien que je ne puisse bien sûr pas l'exclure). Je ne l'ai pas trouvé non plus en regardant bash
le code de.
Je ne peux pas dire que je me souviens exactement de mon train de pensées à l'époque.
Cela est venu plus ou moins d'une réflexion sur certains comportements de certains logiciels que je trouve dangereux (les comportements, pas les logiciels). Le genre de comportement qui vous fait réfléchir: cela ne semble pas être une bonne idée .
Dans ce cas, je réfléchissais à la configuration commune de ssh qui permet de passer des variables d'environnement non autorisées du client à condition que leur nom commence par LC_
. L'idée est que les gens puissent continuer à utiliser leur propre langue lorsqu'ils ssh
entrent dans d'autres machines. Une bonne idée jusqu'à ce que vous commenciez à considérer à quel point la gestion de la localisation est complexe, en particulier lorsque UTF-8 est introduit dans l'équation (et à voir à quel point elle est gérée par de nombreuses applications).
En juillet 2014, j'avais déjà signalé une vulnérabilité dans la gestion de la localisation de la glibc qui, combinée à cette sshd
configuration, et deux autres comportements dangereux du bash
shell
permettaient aux attaquants (authentifiés) de pirater des serveurs git à condition qu'ils puissent y télécharger des fichiers et qu'ils soient bash
utilisés comme shell de connexion de l'utilisateur git unix (CVE-2014-0475).
Je pensais que c'était probablement une mauvaise idée d'utiliser bash
comme shell de connexion des utilisateurs offrant des services sur ssh, étant donné que c'est un shell assez complexe (quand tout ce dont vous avez besoin est juste d'analyser une ligne de commande très simple) et a hérité de la plupart des erreurs de conception de ksh. Comme j'avais déjà identifié quelques problèmes avec l' bash
utilisation dans ce contexte (pour interpréter ssh ForceCommand
s), je me demandais s'il y en avait potentiellement plus.
AcceptEnv LC_*
autorise toute variable dont le nom commence par LC_
et j'ai eu le vague souvenir que les bash
fonctions exportées (une caractéristique dangereuse mais utile à l'époque) utilisaient des variables d'environnement dont le nom ressemblait à quelque chose
myfunction()
et se demandaient s'il n'y avait pas quelque chose d'intéressant à regarder là-bas.
J'étais sur le point de le rejeter au motif que la pire chose à faire serait de redéfinir une commande appelée LC_something
qui ne pourrait pas vraiment être un problème car ce ne sont pas des noms de commande existants, mais j'ai alors commencé à me demander comment bash
importaient ces variables d'environnement.
Et si les variables étaient appelées LC_foo;echo test; f()
par exemple? J'ai donc décidé de regarder de plus près.
UNE:
$ env -i bash -c 'zzz() { :;}; export -f zzz; env'
[...]
zzz=() { :
}
a révélé que mon souvenir était faux en ce que les variables n'étaient pas appelées myfunction()
mais myfunction
(et c'est la
valeur qui commence par ()
).
Et un test rapide:
$ env 'true;echo test; f=() { :;}' bash -c :
test
bash: error importing function definition for `true;echo test; f'
a confirmé ma suspicion que le nom de la variable n'a pas été nettoyé et que le code a été évalué au démarrage .
Pire, bien pire, la valeur n'était pas non plus aseptisée:
$ env 'foo=() { :;}; echo test' bash -c :
test
Cela signifiait que toute variable d'environnement pouvait être un vecteur.
C'est à ce moment-là que j'ai réalisé l'étendue du problème, confirmé qu'il était également exploitable sur HTTP ( HTTP_xxx
/ QUERYSTRING
... env vars), d'autres comme les services de traitement du courrier, plus tard DHCP (et probablement une longue liste) et l'ai signalé (soigneusement) .