web-dev-qa-db-fra.com

Explication de la commande pour vérifier le shellshock

Voici la commande que j'ai utilisée pour vérifier le shell Shellshock sur mon shell bash:

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

Quelqu'un peut-il s'il vous plaît expliquer la commande en détail?

32
heemayl

Cette réponse est un dérivé d'un article original sur Fedora Magazine de Matthew Miller, sous licence Creative Commons Attribution-Share Alike 4. licence .

Laisse-moi expliquer:

env x='() { :;}; echo OOPS' bash -c :

Ceci imprimera “OOPS” sur un système vulnérable, mais se fermera silencieusement si bash a été corrigé.

env x='() { :;}; echo OOPS' bash -c "echo this is a test"

Ceci imprimera “OOPS” sur un système vulnérable, mais imprimera “this is a test” si bash a été corrigé.

Et vous avez probablement entendu dire que cela a quelque chose à voir avec les variables d'environnement. Mais pourquoi le code des variables d’environnement est-il exécuté? Eh bien, ce n’est pas censé l’être - mais, à cause d’une fonction que je suis tenté d’appeler un peu trop habile pour son bien, il ya de la place pour un défaut. Bash est ce que vous voyez comme une invite de terminal, mais il s'agit également d'un langage de script permettant de définir des fonctions. Vous faites ça comme ça:

$ Ubuntu()  { echo "Ubuntu is awesome."; }

et alors vous avez une nouvelle commande. Gardez à l’esprit que le echo n’est pas encore exécuté; C’est juste ce qui va se passer lorsque nous exécuterons notre nouvelle commande. Ce sera important dans une minute!

$ Ubuntu
 Ubuntu is awesome.

Utile! Mais, disons, pour une raison quelconque, nous devons exécuter une nouvelle instance de bash, en tant que sous-processus, et vouloir exécuter ma nouvelle commande impressionnante dans ce contexte. L'instruction bash -c somecommand fait exactement ceci: exécute la commande donnée dans un nouveau shell:

$ bash -c Ubuntu
  bash: Ubuntu: command not found

Ooh. Triste. L’enfant n’a pas hérité de la définition de la fonction. Mais cela fait partie de l’environnement - une collection de paires clé-valeur qui ont été exportées à partir du shell. (C’est un concept complètement fou; si vous n’êtes pas familier avec cela, croyez-moi pour le moment.) Et il s’avère que bash peut également exporter des fonctions. Alors:

$ export -f Ubuntu
$ bash -c Ubuntu
  Ubuntu is awesome.

Ce qui est très bien - sauf que le mécanisme par lequel cela est accompli est en quelque sorte louche . Fondamentalement, comme il n’existe pas de magie Linux/Unix pour exécuter des fonctions dans des variables d’environnement, la fonction d’exportation crée en réalité une variable d’environnement ordinaire contenant la définition de la fonction. Ensuite, lorsque le second shell lit l'environnement "entrant" et rencontre une variable dont le contenu ressemble à une fonction, il l'évalue.

En théorie, ceci est parfaitement sûr , car, rappelez-vous, la définition d'une fonction ne l'exécute pas réellement . Sauf - et c’est pourquoi nous sommes ici - il y avait un bogue dans le code où l’évaluation ne s’est pas arrêtée lorsque la fin de la définition de la fonction a été atteinte. Cela ne fait que commencer.

Cela ne se produirait jamais lorsque la fonction stockée dans une variable d’environnement est légitimement créée avec export -f. Mais pourquoi être légitime? Un attaquant peut créer n'importe quelle ancienne variable d'environnement, et si cela ressemble à une fonction, les nouveaux shell bash penseront que c'est le cas!

Donc, dans notre premier exemple:

env x='() { :;}; echo OOPS' bash -c "echo this is a test"

La commande env exécute une commande avec un jeu de variables donné. Dans ce cas, nous définissons x sur quelque chose qui ressemble à une fonction. La fonction est juste un seul :, qui est en fait une simple commande qui est définie comme ne rien faire. Mais ensuite, après le semi-colon qui marque la fin de la définition de la fonction, il existe une commande echo. Ce n’est pas censé être là, mais rien ne nous empêche de le faire.

Ensuite, la commande donnée pour s'exécuter avec ce nouvel environnement est un nouveau shell bash, toujours avec une commande "echo this is a test" ou "ne rien faire :", après quoi il se fermera de manière totalement inoffensive.

Mais - oups! Lorsque ce nouveau shell démarre et lit l'environnement, il passe à la variable x et, comme il ressemble à une fonction, il l'évalue. La définition de la fonction est chargée de manière inoffensive - puis notre charge utile malveillante est également déclenchée. Ainsi, si vous exécutez ce qui précède sur un système vulnérable, vous recevrez “OOPS”. Ou bien, un attaquant pourrait faire bien pire que simplement imprimer des choses.

45
αғsнιη

Dans version non corrigée de bashname __ , il stocke les définitions de fonction exportées sous forme de variables d’environnement.

Stocker une fonction xas,

$ x() { bar; }
$ export -f x

Et vérifiez sa définition comme,

$ env | grep -A1 x
x=() {  bar
}

Donc, on pourrait exploiter cela en définissant ses propres variables d'environnement et les interpréter comme des définitions de fonctions. Par exemple, env x='() { :;}' serait traité comme

x() { :;
}

Que fait la commande pour vérifier Shellshock,

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

De man env,

  1. env- exécute un programme dans un environnement modifié.

  2. : ne fait que quitter avec le statut de sortie 0. voir plus

  3. Lorsqu'une nouvelle instance de bash non corrigée est lancée sous la forme bash -c "echo this is a test", la variable d'environnement construite est traitée comme une fonction et chargée. En conséquence on obtient la sortie

 vulnérable 
 ceci est un test 

Remarque: L'écho en dehors de la définition de la fonction a été exécuté de manière inattendue lors du démarrage de bash. La définition de la fonction est juste une étape pour obtenir l'évaluation et l'exploitation, la définition de la fonction elle-même et la variable d'environnement utilisée sont arbitraires. Le shell examine les variables d’environnement, voit x, ce qui donne l’impression qu’il répond aux contraintes qu’il connaît sur la définition d’une fonction, et il évalue la ligne en exécutant involontairement aussi l’écho (qui peut être n’importe quelle commande, malveillante ou non). . Voir aussi this

2
souravc