Any security risks with sudo password from standard input over ssh? - shell

I want to execute sudo over ssh on remote servers and supply the password over standard input. The following code is in a shell script on a secured server with restricted access. The password is asked beforehand and the servers use all the same sudo password. The someaction can surely take some seconds to execute.
Here is the shell script extract:
read -s -p "please enter your sudo password" PASSWORD
ssh user#host1 -t "echo '$PASSWORD' | sudo -S someaction"
ssh user#host2 -t "echo '$PASSWORD' | sudo -S someaction"
My question: Is it safe to use echo with a pipe? And are here any security problems that might occur, like logging the echo result on the remote server, etc?
Maybe somebody has a better suggestion?
Note: I know other tools can do this, like ansible etc. I am not looking for another similar tool, just want to know whether using ssh/echo/sudo in the mentioned way is safe.

Yes!
As long as the command is running anybody that can view all processes can view that password, by running ps aux | grep echo:
root [..] zsh -c echo topsecret | sudo -C action
You could configure sudo to not ask the password for a specific task for a user, that would certainly increase security over this solution.

Related

change root password using bash script

SO, when I order a VPS, I get a random password from them which I need to change,
I basically use centos 6 x64
I was thinking to make a bash script which when I run will change the password of the VPS to a default common password which I would like to use with all my VPS.
So, my question - Is it possible?
I am thinking to use this inside the bash .sh script, is my code correct,
#!/bin/bash
passwd
echo jadaruine
If not what should be the code?
You want the chpasswd command:
sudo sh -c 'echo username:password | chpasswd'
You might also want to look at chage for password expiry settings.
You can do the following to change the password on centos
#!/bin/bash
echo "jadaruine" | passwd --stdin user

Pass password to sudo for command that expects input

I am trying to create a Shell script and (to avoid typing, furthermore ignoring security related issues for now) want to directly pass the password to the "sudo" command, e.g.,
pword="mypassword"
echo $pword | sudo -S whoami
This works just fine. But now when the command itself expects an input, this method seems to fail, e.g.,
echo $pword | sudo -S cat<<<"Hello"
This would lead to an 'incorrect password' error. Currently, my solution is to run a "dummy command" like in example one first, and use the fact that for the second command the system does not prompt for a password again. However, does anyone know a better solution to get it to work?
You can defer the activation of the "here document" (the <<< construct) by doing something like this:
echo $pw | sudo -S sh -c ' cat <<<"Hello" '
A better solution is to use sudo -A instead of sudo -S, after first defining a $SUDO_ASKPASS environment variable to refer to a program that will emit your password. Then you won't have to worry about competing for stdin with the rest of the command line. You should create that askpass program (it can be a shell script) to be readable, writable and executable only by yourself so that your password will be securely hidden inside the program.
The -v flag of sudo is also useful if you have just entered your password for the SSH connection, -v updates the cache and doesn't ask for a password again:
sudo -v -u UserName && bash -c 'cat <<<"Hello"'

Remote SSH without reentering Password

I am trying to loop through a list of remote servers, ssh to them and get hardware info, but this requires sudo password, and I don't want to have to type in password for each loop, and unsure how to accomplish that. My script below:
#!/bin/bash
for i in $(cat server-list.txt); do
ssh -t username#${i} 'sudo -s <dmidecode -t 1>';
done
Note: all system commands require sudo password.

Shell Script to run on Local and Remote machine

I am new to shell scripting,
I am trying to write a script that'll run on my local machine.
Few of it's commands are to run on my local and then a few on the remote server.
Below is a sample script -
The 1st two will run on my local system,
rest of them are to run on the remote server.
eg -
scp -i permissions.pem someJar.jar ubuntu#ip:/var/tmp
ssh -i permissions.pem ubuntu#ip
sudo su
service someService stop
rm -rf /home/ubuntu/someJar.jar
rm -rf /home/ubuntu/loggingFile.log
mv /var/tmp/someJar.jar .
service someService start
As the script will run on my local machine,
How do make sure the 3rd and further commands take effect on the remote server and not on my machine?
Here's my sample.sh file -
scp -i permissions.pem someJar.jar ubuntu#ip:/var/tmp
SCRIPT="sudo su; ps aux | grep java; service someService stop; ps aux | grep java; service someService start; ps aux | grep java;"
ssh -i permissions.pem ubuntu#ip $SCRIPT
The scp is working, nothing is displayed after that.
You need to pass the reset of the script as a parameter to SSH. Try this format:
SCRIPT="sudo su; command1; command2; command3;"
ssh -i permissions.pem ubuntu#ip $SCRIPT
See: http://linuxcommand.org/man_pages/ssh1.html
Hope this helps.
Update:
The reason why you don't see anything after running the command is because sudo expects the password. To avoid this there are three solutions:
Give ubuntu user needed permissions to perform all the tasks in the script.
Pass the password to sudo under SCRIPT: echo 'password' | sudo su; ...
Modify sudo-er file and allow ubuntu user to sudo without prompting for password. Run sudo visudo and add the following line: ubuntu ALL = NOPASSWD : ALL
Each system admin will have a different approach to this problem. I think everyone will agree that option 2 is the least secure. The reset is up to debate. In my opinion option 3 is slightly more secure. Yet, entire server is compromised if your key is compromised. The most secure is option 1. While it is painful to assign individual permissions, by doing so you are limiting your exposure to assigned permissions in case if your key is compromised.
One more note: It might be beneficial to replace ; with && in the SCRIPT. By doing so you will ensure that second command will run only if the first one finished successfully, third will run only if second finished successfully and so on.

How to provide password to a command that prompts for one in bash?

I'm writing a UNIX shell function that is going to execute a command that will prompt the user for a password. I want to hard-code the password into the script and provide it to the command. I've tried piping the password into the command like this:
function() {
echo "password" | command
}
This may not work for some commands as the command may flush the input buffer before prompting for the password.
I've also tried redirecting standard input to a file containing the password like this, but that doesn't work either:
function() {
echo "password" > pass.tmp
command < pass.tmp
rm pass.tmp
}
I know that some commands allow for the password to be provided as an argument, but I'd rather go through standard input.
I'm looking for a quick and dirty way of piping a password into a command in bash.
How to use autoexpect to pipe a password into a command:
These steps are illustrated with an Ubuntu 12.10 desktop. The exact commands for your distribution may be slightly different.
This is dangerous because you risk exposing whatever password you use to anyone who can read the autoexpect script file.
DO NOT expose your root password or power user passwords by piping them through expect like this. Root kits WILL find this in an instant and your box is owned.
EXPECT spawns a process, reads text that comes in then sends text predefined in the script file.
Make sure you have expect and autoexpect installed:
sudo apt-get install expect
sudo apt-get install expect-dev
Read up on it:
man expect
man autoexpect
Go to your home directory:
cd /home/el
User el cannot chown a file to root and must enter a password:
touch testfile.txt
sudo chown root:root testfile.txt
[enter password to authorize the changing of the owner]
This is the password entry we want to automate. Restart the terminal to ensure that sudo asks us for the password again. Go to /home/el again and do this:
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
You have created my_test_expect.exp file. Your super secret password is stored plaintext in this file. This should make you VERY uncomfortable. Mitigate some discomfort by restricting permissions and ownership as much as possible:
sudo chown el my_test_expect.exp //make el the owner.
sudo chmod 700 my_test_expect.exp //make file only readable by el.
You see these sorts of commands at the bottom of 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
You will need to verify that the above expect commands are appropriate. If the autoexpect script is being overly sensitive or not sensitive enough then it will hang. In this case it's acceptable because the expect is waiting for text that will always arrive.
Run the expect script as user el:
expect my_test_expect.exp
spawn sudo chown root:root myfile.txt
[sudo] password for el:
The password contained in my_test_expect.exp was piped into a chown to root by user el. To see if the password was accepted, look at myfile.txt:
ls -l
-rw-r--r-- 1 root root 0 Dec 2 14:48 myfile.txt
It worked because it is root, and el never entered a password. If you expose your root, sudo, or power user password with this script, then acquiring root on your box will be easy. Such is the penalty for a security system that lets everybody in no questions asked.
Take a look at autoexpect (decent tutorial HERE). It's about as quick-and-dirty as you can get without resorting to trickery.
You can use the -S flag to read from std input. Find below an example:
function shutd()
{
echo "mySuperSecurePassword" | sudo -S shutdown -h now
}
Secure commands will not allow this, and rightly so, I'm afraid - it's a security hole you could drive a truck through.
If your command does not allow it using input redirection, or a command-line parameter, or a configuration file, then you're going to have to resort to serious trickery.
Some applications will actually open up /dev/tty to ensure you will have a hard time defeating security. You can get around them by temporarily taking over /dev/tty (creating your own as a pipe, for example) but this requires serious privileges and even it can be defeated.
with read
Here's an example that uses read to get the password and store it in the variable pass. Then, 7z uses the password to create an encrypted archive:
read -s -p "Enter password: " pass && 7z a archive.zip a_file -p"$pass"; unset pass
But be aware that the password can easily be sniffed.
Programs that prompt for passwords usually set the tty into "raw" mode, and read input directly from the tty. If you spawn the subprocess in a pty you can make that work. That is what Expect does...
Simply use :
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
This code is working for me, and its in /etc/init.d/myscriptbash.sh
That's a really insecure idea, but:
Using the passwd command from within a shell script

Resources