J'écris une fonction UNIX Shell qui va exécuter une commande qui demandera à l'utilisateur un mot de passe. Je veux coder en dur le mot de passe dans le script et le fournir à la commande. J'ai essayé de canaliser le mot de passe dans la commande comme ceci:
function() {
echo "password" | command
}
Cela peut ne pas fonctionner pour certaines commandes car la commande peut vider le tampon d'entrée avant de demander le mot de passe.
J'ai également essayé de rediriger l'entrée standard vers un fichier contenant le mot de passe comme celui-ci, mais cela ne fonctionne pas non plus:
function() {
echo "password" > pass.tmp
command < pass.tmp
rm pass.tmp
}
Je sais que certaines commandes permettent de fournir le mot de passe comme argument, mais je préfère passer par l'entrée standard.
Je cherche un moyen rapide et sale de canaliser un mot de passe dans une commande en bash.
Jetez un oeil à autoexpect
(tutoriel décent [~ # ~] ici [~ # ~] ) . C'est à peu près aussi rapide et sale que possible sans recourir à la ruse.
Comment utiliser autoexpect pour diriger un mot de passe dans une commande:
Ces étapes sont illustrées avec un bureau Ubuntu 12.10. Les commandes exactes de votre distribution peuvent être légèrement différentes.
Ceci est dangereux car vous risquez d'exposer le mot de passe que vous utilisez à quiconque peut lire le fichier de script autoexpect.
N'exposez PAS votre mot de passe root ou les mots de passe des utilisateurs avec pouvoir en les canalisant comme cela. Les kits racine trouveront cela en un instant et votre boîte est la propriété.
EXPECT engendre un processus, lit le texte qui arrive puis envoie du texte prédéfini dans le fichier de script.
Assurez-vous que expect
et autoexpect
sont installés:
Sudo apt-get install expect
Sudo apt-get install expect-dev
Lisez-le:
man expect
man autoexpect
Accédez à votre répertoire personnel:
cd /home/el
L'utilisateur el
ne peut pas afficher un fichier à la racine et doit entrer un mot de passe:
touch testfile.txt
Sudo chown root:root testfile.txt
[enter password to authorize the changing of the owner]
Il s'agit de l'entrée de mot de passe que nous voulons automatiser. Redémarrez le terminal pour vous assurer que Sudo nous demande à nouveau le mot de passe. Accédez à nouveau à/home/el et procédez comme suit:
touch myfile.txt
autoexpect -f my_test_expect.exp Sudo chown root:root myfile.txt
[enter password which authorizes the chown to root]
autoexpect done, file is my_test_expect.exp
Vous avez créé my_test_expect.exp
fichier. Votre mot de passe super secret est stocké en clair dans ce fichier. Cela devrait vous rendre TRÈS inconfortable. Atténuez l'inconfort en restreignant autant que possible les autorisations et la propriété:
Sudo chown el my_test_expect.exp //make el the owner.
Sudo chmod 700 my_test_expect.exp //make file only readable by el.
Vous voyez ces sortes de commandes au bas de my_test_expect.exp
:
set timeout -1
spawn Sudo chown root:root myfile.txt
match_max 100000
expect -exact "\[Sudo\] password for el: "
send -- "YourPasswordStoredInPlaintext\r"
expect eof
Vous devrez vérifier que les commandes attendues ci-dessus sont appropriées. Si le script autoexpect est trop sensible ou pas assez sensible, il se bloquera. Dans ce cas, c'est acceptable car l'attente attend un texte qui arrivera toujours.
Exécutez le script attendu en tant qu'utilisateur el:
expect my_test_expect.exp
spawn Sudo chown root:root myfile.txt
[Sudo] password for el:
Le mot de passe contenu dans my_test_expect.exp a été inséré dans un chown à rooter par l'utilisateur el. Pour voir si le mot de passe a été accepté, consultez myfile.txt
:
ls -l
-rw-r--r-- 1 root root 0 Dec 2 14:48 myfile.txt
Cela a fonctionné car il est root et el n'a jamais entré de mot de passe. Si vous exposez votre mot de passe root, Sudo ou utilisateur expérimenté avec ce script, l'acquisition de root sur votre box sera facile. Telle est la pénalité pour un système de sécurité qui permet à tout le monde de ne poser aucune question.
Les commandes sécurisées ne le permettront pas, et à juste titre, je le crains - c'est un trou de sécurité dans lequel vous pourriez conduire un camion.
Si votre commande ne l'autorise pas à utiliser la redirection d'entrée, ou un paramètre de ligne de commande, ou un fichier de configuration, alors vous devrez recourir à de sérieuses astuces.
Certaines applications s'ouvriront en fait /dev/tty
pour vous assurer que vous aurez du mal à vaincre la sécurité. Vous pouvez contournez-les en prenant temporairement le contrôle /dev/tty
(créer le vôtre en tant que pipe, par exemple) mais cela nécessite de sérieux privilèges et même it peut être vaincu.
Vous pouvez utiliser le -S
drapeau à lire depuis l'entrée standard. Trouvez ci-dessous un exemple:
function shutd()
{
echo "mySuperSecurePassword" | Sudo -S shutdown -h now
}
Les programmes qui demandent des mots de passe mettent généralement le tty en mode "brut" et lisent les entrées directement depuis le tty. Si vous générez le sous-processus dans un pty, vous pouvez le faire fonctionner. C'est ce que fait Expect ...
Utilisez simplement:
echo "password" | Sudo -S mount -t vfat /dev/sda1 /media/usb/;
if [ $? -eq 0 ]; then
echo -e '[ ok ] Usb key mounted'
else
echo -e '[warn] The USB key is not mounted'
fi
Ce code fonctionne pour moi, et son dans /etc/init.d/myscriptbash.sh