Explication de la commande de vérification de shellshock

32

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

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?

    
posée heemayl 28.09.2014 - 07:35
la source

2 réponses

45

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

Laissez-moi vous expliquer:

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

Cela affichera "OOPS" sur un système vulnérable, mais sortez en silence si bash a été corrigé.

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

Cela affichera "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 avait quelque chose à voir avec les variables d’environnement. Mais, pourquoi le code dans les variables d'environnement est-il exécuté? Eh bien, ce n'est pas censé être - mais, à cause d'une caractéristique que je suis tenté d'appeler un peu trop intelligent pour son propre bien, il y a de la place pour une faille. Bash est ce que vous voyez comme une invite de terminal, mais c'est aussi un langage de script et il a la capacité de définir des fonctions. Vous faites ça comme ça:

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

et puis vous avez une nouvelle commande. N'oubliez pas que echo n'est pas encore exécuté. il est juste enregistré comme ce qui se passera 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 géniale sous ce nom. 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 est inhérent à l'environnement - une collection de paires clé-valeur exportées du shell. (Ceci est un concept entier, si vous n'êtes pas familier avec cela, croyez-moi pour le moment.) Et, il s'avère que bash peut aussi exporter des fonctions. Donc:

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

Ce qui est bien, sauf que le mécanisme par lequel cela est fait est sorta dodgy . Fondamentalement, comme il n'y a pas de magie Linux / Unix pour faire des fonctions dans les variables d'environnement, la fonction d'exportation ne fait que créer une variable d'environnement régulière 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, c'est parfaitement sûr , car, rappelez-vous, la définition d’une fonction ne l’exécute pas . Sauf que - et c'est pourquoi nous sommes ici - il y avait un bogue dans le code où l'évaluation ne s'arrêtait pas lorsque la fin de la définition de la fonction était atteinte. Il ne fait que continuer.

Cela ne se produirait jamais lorsque la fonction stockée dans une variable d'environnement est créée de manière légitime, avec export -f . Mais pourquoi être légitime? Un attaquant peut simplement créer une ancienne variable d'environnement, et si elle ressemble à une fonction, les nouveaux shells bash le penseront!

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 fixons x à quelque chose qui ressemble à une fonction. La fonction n'est qu'un simple : , qui est en réalité une commande simple définie comme ne rien faire. Mais ensuite, après semi-colon qui signale la fin de la définition de la fonction, il y a une commande echo . Ce n'est pas censé être là, mais rien ne nous empêche de le faire.

Ensuite, la commande à 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 complètement sans danger.

Mais - oups! Lorsque ce nouveau shell démarre et lit l'environnement, il arrive à la variable x , et comme il ressemble à une fonction, il l'évalue. La définition de la fonction est inoffensivement chargée - et notre payload malveillant est également déclenché. Donc, si vous exécutez ce qui précède sur un système vulnérable, vous aurez à imprimer “OOPS” chez vous. Ou, un attaquant pourrait faire beaucoup plus que simplement imprimer des choses.

    
réponse donnée αғsнιη 28.09.2014 - 08:06
la source
2

Dans version non corrigée de bash , il stocke les définitions de fonctions exportées en tant que variables d'environnement.

Stocker une fonction x as,

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

Et vérifiez sa définition sous la forme,

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

On pourrait donc exploiter ceci en définissant ses propres variables d’environnement et en les interprétant comme des définitions de fonction. 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 patché a été lancée sous la forme bash -c "echo this is a test" , la variable d'environnement spécialement construite est traitée comme une fonction et chargée. En conséquence, on obtient la sortie

    vulnerable
    this is a 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 n'est qu'une étape pour que l'évaluation et l'exploit se produisent, 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, qui semble répondre aux contraintes qu'il connaît sur la définition d'une fonction, et évalue la ligne, exécutant involontairement l'écho (qui peut être n'importe quelle commande, malveillant ou non). . Voir également cette

    
réponse donnée souravc 28.09.2014 - 08:39
la source

Lire d'autres questions sur les étiquettes