LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Security (https://www.linuxquestions.org/questions/linux-security-4/)
-   -   echo "${SUDO_PASSWORD}" | ssh sudo -S command (https://www.linuxquestions.org/questions/linux-security-4/echo-%24%7Bsudo_password%7D-%7C-ssh-sudo-s-command-4175445668/)

r0tty 01-15-2013 03:32 AM

echo "${SUDO_PASSWORD}" | ssh sudo -S command
 
Hi,

I'm just trying to work out how insecure this is?

I want to write a script that will use SSH to call sudo on a remote machine. I have SSH keys set-up so that I do not need to enter a password to issue commands on my (non-root) account on the remote machine. The script uses 'read -s SUDO_PASSWORD' to get the sudo password - so it's not hard-coded anywhere or written to command history.

So, my question is about how insecure is it to use this within the script:

echo "${SUDO_PASSWORD}" | ssh ${REMOTE_MACHINE} "sudo -S sh -c id"

NB: 'id' is only an example command - in the script this would be a variable.

I presume that 'echo' is a built-in so it won't show up in 'ps' command output on the local machine. Everything happening on the remote machine is via SSH so I presume that is secure (in this case 'secure' means secure enough - it is always possible to argue things are not 100% secure in my experience). Finally the password is present in memory as $SUDO_PASSWORD on the local machine, but I presume that is reasonably secure from anyone unless they already have root access?

Incidentally I did solve the problem another way - by using 'expect' to inject the password when prompted. This works fine, and is probably what I will use as it has slightly less of the security concerns mentioned above. It still has some though and I'm interested to know what the security issues are with the 'echo | ssh sudo' solution.

Thanks in advance for any assistance with this.

Rotty

linosaurusroot 01-15-2013 06:24 AM

In this variant you give the password direct to sudo without an intermediate script and then call sudo a 2nd time (relying on the sudo cache - assumimg you use default settings) to execute your payload. That keeps the password out of a shell variable so I suggest this is a minor improvement.

Code:

echo "${SUDO_PASSWORD}" | ssh ${REMOTE_MACHINE} "sudo -S id && sudo command"
There is also the NOPASSWD option that could be applied to the relevant command in the sudoers file.

mina86 01-16-2013 12:37 PM

Quote:

Originally Posted by r0tty (Post 4870374)
I'm just trying to work out how insecure this is?

For one, you give out your password to anyone who has access to the machine you are running this on.

I'd recommend using a setuid wrapper that runs a shell script that does what you need. Here's how you do that:
Code:

$ mkdir -m700 ~/foobar
$ cat >foobar.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define HOME "/home/you" /* change this accordingly */

int main(void) {
        if (setuid(0)) {
                perror("setuid");
        } else {
                execl("/bin/sh", HOME "/foobar/foobar.sh", (const char*)0);
                perror("exec: /bin/sh");
        }
        return EXIT_FAILURE;
}
< press ctrl+d >
$ cat >foobar.sh
#!/bin/sh
: write your command here
< press ctrl+d >
$ gcc -o foobar foobar.c
$ sudo chown root:users foobar foobar.sh
$ sudo chmod 4750 foobar
$ sudo chmod 700 foobar.sh

With that, your command on local machine will be:
Code:

ssh "$remote" foobar/foobar
But NOPASSWD suggested by linosaurusroot is also an option so choose whichever you prefer.

Quote:

Originally Posted by linosaurusroot (Post 4870479)
That keeps the password out of a shell variable so I suggest this is a minor improvement.

Uh? Could you elaborate cause your explanation makes no sense to me.

r0tty 01-17-2013 05:01 AM

@mina86 - thanks for the reply.

Quote:

Originally Posted by mina86 (Post 4871571)
For one, you give out your password to anyone who has access to the machine you are running this on.

How would they do that though? If I am signed on as a normal user and run that command I don't see where is shows up for a another normal user. Because echo is a built-in they cannot see it in the output from ps (even if it did they would only see the command not the args). They won't have access to /procs. Even if a user with root privilege can do it I would be very interested to know how.

The setuid C program is not an option as part of the idea of this is to do remote admin, so any variety of commands could be entered. Also, the 'NOPASSWD' option in sudoers is not an option - I want to have the requirement to enter a password in case someone with sudo access leaves a terminal session unguarded.

@linosaurusroot - I didn't really understand either, but I think I may have made my question too complicated. I extracted the command example from my script so that the question wasn't too long, but I should have tidied up more. The actual command I am using is this:

Code:

echo "${SUDO_PASSWORD}" | ssh -o StrictHostKeyChecking=no ${1} "sudo -Sp '' sh -c '${2}'"
The reason for "sh -c '${2}'" is that if ${2} is "whoami; whoami" it should return "root" twice, but without the "sh -c" it would give "root" and then "rotty", because the second command wouldn't run as root. I don't think using another shell makes it any less secure - if someone get the password from one, then they can get it from them all, I would think.

Rotty

linosaurusroot 01-17-2013 07:37 AM

Quote:

Originally Posted by r0tty (Post 4872037)
I don't think using another shell makes it any less secure - if someone get the password from one, then they can get it from them all, I would think.

When you have read the password into a shell variable to use it with sudo it may be available via a debugger or /proc to another process run with the same UID and may not be wiped when you have finished with it. Because sudo is setuid and carefully programmed these risks do not exist if you get the password directly into sudo with no shell involved.

Of course Unix doesn't do a lot to help you if you are being attacked from the same UID.

mina86 01-18-2013 03:25 AM

Quote:

Originally Posted by r0tty (Post 4872037)
Because echo is a built-in they cannot see it in the output from ps

Right, that's true and you might get away with this.

Quote:

Originally Posted by r0tty (Post 4872037)
(even if it did they would only see the command not the args).

That's not true. ps shows the whole command. Even if it doesn't there's “/proc/self/cmdline” which has the whole command line.

Quote:

Originally Posted by r0tty (Post 4872037)
The setuid C program is not an option as part of the idea of this is to do remote admin, so any variety of commands could be entered.

The setuid program can be rewritten to allow arbitrary command, but yeah, than you'll just reimplement sudo.

Quote:

Originally Posted by linosaurusroot
When you have read the password into a shell variable to use it with sudo it may be available via a debugger or /proc to another process run with the same UID

The first part is irrelevant (since it's true any time you enter password anywhere) and the second is not true if the variable is not exported.

Quote:

Originally Posted by linosaurusroot
and may not be wiped when you have finished with it.

“unset SUDO_PASSWORD” after the line in question should solve the problem.

However, why don't you just do something like:
Code:

ssh $1 sudo sh -c "$2"
and let the remote sudo prompt for password. This has additional advantage of leaving stdin intact.

linosaurusroot 01-18-2013 05:59 AM

Quote:

Originally Posted by mina86 (Post 4872719)
The first part is irrelevant (since it's true any time you enter password anywhere) and the second is not true if the variable is not exported.

Unprivileged processes won't be able to attach to sudo because setuid. Processes with the same UID as this user can attach to his shell.


Quote:

“unset SUDO_PASSWORD” after the line in question should solve the problem.
That's not going to wipe the memory like a securely-written program would - to protect against copying of the memory.
http://etutorials.org/Programming/se...mory+Securely/

r0tty 01-18-2013 06:26 AM

@mina86

You're right about other users seeing the args. But, as you said, using a built-in may mitigate this.

I can't just use the simple command you suggest as the whole point of this exercise is to run a command against multiple servers. So, I will be on my local machine and run "myscript servera,serverb,serverc,etc mycommand" and it will prompt for a password once and then inject it into the remote command when necessary.

@linosaurusroot

I can't find much to suggest bash* isn't written securely. The fact that bash provides 'read -s' must mean that the authors were aware they were getting themselves into the realm of handling secure data. I guess the key question is - how would someone extract the password from the memory I'm using when I'm running the script (running as a non-root user, possibly the same user).

* just to be clear - /bin/sh is a link to /bin/bash on all servers here.

Rotty

PS, just wanted to say thanks to you guys for contributing responses to this. You've prompted me to think more about how a shell handles memory and found this interesting http://security.stackexchange.com/qu...ility-in-linux. I think my current thinking is that my script is 'secure enough', but that users should be made aware that 'root' and their own user account could be used to steal their password.


All times are GMT -5. The time now is 03:52 AM.