0

I am using bash script below to test whether sudo is available on a remote host.

I'm obtaining the password from user input. I understand (to a limited extent) that using passwords inside a script will involve security trade-offs, so I have a question about a particular aspect of this.

Please see script below, which uses sshpass and then tests if the user is able to run sudo --stdin --validate successfully.

To mitigate exposing the password (as best as I know?) I've opted to use sshpass with -e instead of -p, but just wondering about the second part---the echo \"${SSHPASS}\" | sudo --stdin --validate line.

After running this script and then looking through history on the remote host, I could not see the password 'echoed' on the command line both in the user account or as root.

So my question is: Does echoing like this at the remote end expose the password anywhere (and if so, where?), or is this method below "fairly safe"?

User environment on both ends is Ubuntu 18 or 20.

#!/bin/bash

# obtain username and host from user input
read -p "Enter username@host: " remote

# obtain password from user input
read -r -s -p "Enter password: " SSHPASS

# set password as environment variable for `sshpass` below, it requires this for `-e`
export SSHPASS

echo
echo -n "Testing if can sudo on ${remote}... "

if result=$( sshpass -e ssh -o PasswordAuthentication=yes "${remote}" "echo \"${SSHPASS}\" | sudo --stdin --validate" 2>&1 ); then
    echo "YES!"
else
    echo "FAILED"
    echo "${result}"
fi

unset SSHPASS
nooblag
  • 175
  • 2
  • 6
  • 1
    Only thing I can think about is your environment variable. Couldn't you unset it inside the bash script? Do you see this variable when using "printenv" after script execution? For your concerns regarding echo command. I don't see it as a problem, since echo stdout is directly passed to stdin of sudo command. But generally speaking I would suggest you to think about using a configuration mangament software for this task. – Lorem ipsum Sep 12 '20 at 15:44
  • Thanks for your suggestions. I'll make that change. And regardless, no, I can't see the SSHPASS variable when running `printenv` on the remote host both as root and as normal user, and same on the local machine... – nooblag Sep 12 '20 at 15:51

3 Answers3

2

While it doesn't look like it, the password is actually exposed on the local and remote server.

The reason in both cases is that it is part of the command line of the processes, either sshpassor the more implicit bash -c as outlined below.

When you run a command via ssh <host> <command>, the command part is passed to the login shell via -c. This implies that any user that is able to list processes can see bash -c "echo "<password>" | sudo --stdin --validate".

If you want to test it out, a simple while ! ps aux | grep '[s]udo'; do :; done as any other user in the remote system should work. Note that this is an active wait loop and will spike CPU usage.

To fix that, you should echo the password and pipe it to your SSH instead of having it echoed remotely: echo "${SSHPASS}" | sshpass -e ssh -o PasswordAuthentication=yes "${remote}" "sudo --stdin --validate" 2>&1.

Ginnungagap
  • 2,595
  • 10
  • 13
  • `sshpass` seems to do some funky stuff with the tty, I'll look into it tomorrow. I assume you're on macOS, try `ps -A` instead of `ps aux`. – Ginnungagap Sep 14 '20 at 23:01
  • Edited the answer to fix the "testing it out". I just tested `echo passwd | sshpass -e ssh $host 'sudo --stdin --validate'` and it works for me on Ubuntu 20.04. What's your sshpass version? Can you try replacing `sudo --stdin --validate` with `hexdump -c` in both scenarios to compare? – Ginnungagap Sep 15 '20 at 06:15
1

Limit exposure more with GPG encryption and PIPE the output directly rather than to a plain text file / string:

gpg -d -q .sshpasswd.gpg | sshpass -P pass ssh -i ~/.ssh/key.pem -ttR xxx.xxx.xxx.xxx

-P pass

option searches for e.g a "password..." or "passphrase" prompt to fill.

social
  • 111
  • 3
0

try to run sshpass at local (for remote sudo), but failed

1. test

sudo without ssh //ok

$ SSHPASS=your_passwd sshpass -e sudo id
uid=0(root) gid=0(root) groups=0(root)

sudo with ssh //fail

SSHPASS=your_passwd sshpass -v -e  ssh localhost -t 'sudo id' 
[sudo] password for xxx:

2. reason

$ ssh root@localhost  >/dev/null
root@localhost's password:

$ sudo id >/dev/null
[sudo] password for xxx:
$ ssh -t localhost sudo id 
[sudo] password for xxx:

$ ssh -t localhost sudo id >/dev/null
//nothing

the reason 'sshpass' can't work via ssh + sudo is that: normal sudo or ssh send prompt to tty, but ssh + sudo send prompt to stdout, but sshpass wait prompt at tty.


I guess the topology like that:

[local pty]  <---> ssh <--(stdio)--> [remote pty] <---> sudo


workaround

so sudo --stdin is the easy way: //echo at local for safe

echo your_pass | ssh localhost 'sudo --stdin id'

or //run sshpass at remote

$ ssh localhost 'SSHPASS=your_pass sshpass -e sudo id'


I remember that bash only record commands history that executed in interactive mode,
and cmd start with space also not record: ls 1(record) vs ls 2 (not record)

yurenchen
  • 193
  • 1
  • 5