Pourquoi la capacité de définir des fonctions dans une variable environnementale n'est-elle pas un risque de sécurité en soi?


9

Si je comprends bien, il est généralement considéré comme sûr de laisser quiconque fournir des informations qui seront stockées dans une variable environnementale. La vulnérabilité shellshock est un problème ici car elle signifie que le code à la fin d'une définition de fonction à l'intérieur d'une variable d'environnement sera exécuté lorsqu'une nouvelle instance de bash se lancera et vous ne voulez évidemment pas que quelqu'un exécute le code qu'il souhaite sur votre serveur . Les définitions de fonctions elles-mêmes ne sont cependant pas un risque pour la sécurité et sont autorisées car elles doivent être explicitement appelées pour que leur code soit exécuté.

Ma question est pourquoi un utilisateur malveillant ne peut-il pas simplement définir une fonction, contenant son code malveillant comme une commande commune, lset espérer ensuite que le script (ou quoi que ce soit en cours d'exécution) utilisera cette commande à un moment donné?

Un exemple de ce que j'ai en tête:

$ export ls='() { echo "doing bad things..."; }'
$ bash -c ls
doing bad things...

Réponses:


10

C'est un risque pour la sécurité. C'est généralement pourquoi vous ne pouvez pas le faire lorsque vous passez à un autre contexte (contrôle à distance d'un système, changement d'utilisateurs, etc.).

Si vous avez la possibilité de créer n'importe quelle variable d'environnement que vous souhaitez, il existe un certain nombre de façons possibles d'exécuter du code arbitraire.
Prenons $LD_PRELOADl'exemple. Si vous avez la possibilité de définir cette variable, vous pouvez remplacer les fonctions de bibliothèque et y coller votre code. Vous pouvez définir la $DISPLAYvariable et rediriger l'affichage X auquel le programme se connecte pour que vous puissiez contrôler l'application.

C'est pourquoi des choses comme sudodépouiller l'environnement de toutes les variables. sudone permet que de sélectionner quelques variables. Et de ces variables, il les nettoie (il passe à travers la $TERMvariable, mais il ne le fera pas s'il contient des caractères inhabituels).


Wow, je me suis toujours demandé pourquoi certains énormes scripts que je fais en BASH auraient des échecs arcanes étranges lorsqu'ils étaient démarrés avec sudo, en particulier autour des chemins, ce qui m'a amené à vérifier les démarrages sudo et à les bloquer, mais je n'ai jamais su pourquoi cela s'est produit et était un problème, merci pour la bonne explication concernant la suppression des variables d'environnement par sudo.
Lizardx

3

Je dirais que oui, quand bash est votre / bin / sh. Ce n'est pas une fonction du shell bourne, et je parierais que ce n'est pas une fonctionnalité du shell posix non plus, en fait, ils pourraient vouloir l'interdire expressément.

Bash est vraiment plus un shell dérivé de korn, qu'un shell de bourne, malgré son nom, et c'est le seul shell de type Korn qui a la fonctionnalité, et à mon avis, c'est la fonctionnalité kinkensink qui n'a aucune vertu pratique. Les développeurs qui évitent les fonctionnalités bash pour les standards, comme le shell bourne, le shell posix ou le sous-ensemble ksh88 que les shells modernes ont en commun, ou en d'autres termes, se sont engagés dans les bonnes pratiques et les idiomes standard, sont choqués lorsque leur logiciel est activé linux et mac et maintenant potentiellement vulnérable, puisque les auteurs d'exploit sont libres d'utiliser les «bashismes», malgré leurs intentions. En ce qui concerne la compatibilité améliorée, lorsqu'elle est invoquée en tant que / bin / sh, par rapport aux autres dérivés du shell korn, ce n'est que si / bin / sh est votre shell de connexion, ou shell interactif, lorsque bash se comporte plus comme un shell bourne, qu'un shell korn,

J'essaierai de vous convaincre que c'est une fonction d'évier de cuisine, avec 2 cas: vous êtes un développeur intégré, qui fabrique des appareils comme des routeurs, le stockage attaché au réseau 1er plus gros env, signifie plus, de la mémoire, donc, plus de coût, donc moins de profits, donc, si c'était une raison d'envisager d'utiliser cette fonctionnalité de bash, ne devriez-vous pas plutôt utiliser FPATH et le chargement automatique, les fonctionnalités de ksh88? au lieu de passer la fonction entière octet par octet dans l'environnement? Vous pouvez même envisager d'analyser et d'élaguer l'environnement en gros, avant qu'il n'atteigne un script shell qui pourrait mal analyser une variable, comme simplement filtrer ^ $ (. *) $, Etc.

Cela souligne ce qui est unique à ce sujet, peu importe la variable, et le script n'a pas à référencer ou à utiliser la variable, il pourrait toujours être vulnérable.

#!/bin/sh
exec /usr/local/myapp/support/someperlscript.pl

Pour tout le reste sous le soleil, ce qui précède est aussi sûr que le script perl, vous n'utilisez pas les variables, comment pourriez-vous les mal interpréter? Changer pour

#!/bin/bash -norc
exec /usr/local/myapp/support/someperlscript.pl

Cela n'aide pas non plus, cela n'a rien à voir avec ENV ou quelque chose comme ça - tout le monde est brûlé parce que bash doit être unique. Le fait que bash version 2 a la question, me prouve que personne ne l' utilise cette fonction pour leurs applications, car sinon il devrait ne pas avoir autour rôdait cette longue. Et ce qui est pire, il est fondamentalement impossible d'éviter cette fonctionnalité . Voici un exemple avec: avec 'su -', qui si vous demandez à quelqu'un, l'explication serait qu'il rejette l'environnement, consultez la page de manuel, et vous trouverez seulement 99,9%. J'ai testé de cette façon, car sur ce système / bin / sh est le shell de connexion de root et / bin / sh est bash MAIS , dans cet exemple, j'essaiepour durcir mon .bash_profile. J'ai renommé mon existant pour root (qui est activé), mais ma pensée était de savoir si su, puis éventuellement sudo, de toute façon, je suis passé à ceci:

exec env -i TERM=vt102 LOGNAME=root USER=root HOME=/var/root /bin/ksh -i

Donc, je lance complètement l'environnement et utilise un env minimal, puis j'exécute un shell qui ne devrait pas avoir le problème, à la place du processus actuel. Ensuite, à la place de l'exemple standard, essayez:

%dock='() { echo -e "\e[2t\c"; echo dockshock;} ; dock' su 

Cela illustre comment cela n'a rien à voir avec l'analyse d'une fonction particulière, et un exploit peut faire référence à et utiliser la fonction. Vous pouvez imaginer la fonction ayant une logique pour tester si root, etc. Dans ce cas, c'est juste une forme modifiée d'une fonction pour iconifier ou ancrer une fenêtre de terminal, en utilisant une séquence d'échappement, c'est assez standard, donc après avoir cliqué sur pour désiconifier, je voir dockshock - mais alors quoi? Maintenant, essayez ceci:

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su - 

Et devine quoi? La fenêtre est aspirée dans le quai. Voici à quoi ça ressemble après ...

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su -
Password:
dockshock
# env
_=/usr/bin/env
HOME=/var/root
LOGNAME=root
TERM=vt102
USER=root
# echo $0
/bin/ksh
#

Alors, tant pis pour ça! Les fonctions exportées ont en fait la priorité sur les scripts rc. Vous ne pouvez pas l'esquiver.


1
POSIX autorisait les fonctions exportables dans le projet 2 et les refusait par la suite. La fonctionnalité est folle.
mikeserv
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.