i have a security problem on a script. I have to pass it a username and password, but i can't give it a password not crypted.
This script is writed in bash.
#!/bin/bash
HOST=$1
USER=$2
PASSWORD=$3
#PASSWORD=`perl -e 'print pack "H*",$PASSWORD'`
wget -v $HOST --http-user=$USER --http-password=$PASSWORD --no-check-certificate
......
I have think to use something like this for generate cripted password:
perl -e 'print unpack "H*","yourpassword"'
and something like this for decript it
descrpt=`perl -e 'print pack "H*","encrypted password"'`
but it doesn't work. Someone could help me please?
Your command doesn't encrypt, it merely encodes the password as a hex string. Any programmer who sees the string will immediately know how to get the plaintext password back.
Instead, pass the password to wget in such a way that people can't just grab it from ps output. Here's one way of doing that:
wget -v "$HOST" --http-user="$USER" --no-check-certificate --config=/dev/stdin <<< "http_password = $PASSWORD"
Problem solved with:
echo $password | openssl enc -base64 -d
Related
I have a requirement where I am trying to write a shell script which is calling curl command internally. I have the password, username and url stored as variables in the script. However, since I want to avoid using user:password format of curl command in the script, I am just using curl --user command. My intention is to pass the password through stdin. So, I am trying something like this -
#!/bin/bash
user="abcuser"
pass="trialrun"
url="https://xyz.abc.com"
curl --user $user $url 2>&1 <<EOF
$pass
EOF
But this is not working. I know there are variations to this question being asked, but I didn't quite get the exact answer, hence posting this question.
You can use:
curl -u abcuser:trialrun https://xyz.abc.comp
In your script:
curl -u ${user}:${pass} ${url}
To read from stdin:
curl https://xyz.abc.com -K- <<< "-u user:password"
When using -K, --config specify - to make curl read the file from stdin
That should work for HTTP Basic Auth, from the curl man:
-u, --user <user:password>
Specify the user name and password to use for server authentication.
To expand on #nbari's answer, if you have a tool "get-password" that can produce a password on stdout, you can safely use this invocation:
user="abcuser"
url="https://xyz.abc.com"
get-password $user | sed -e "s/^/-u $user:/" | curl -K- $url
The password will be written to a pipe. We use sed to massage the password into the expected format. The password will therefore never be visible in ps or in the history.
I want to encode randomly generated token with aes-256-cbc in bash. When I write this code in shell:
echo -n 8724eb94-ff8f-441e-81a7-bc4282f7c342 | openssl enc -a -e -aes-256-cbc -nosalt -pass pass:fzJKp5/vYUWZUZ1hVSXycdmskKcSNtmZoFhPv5UtWGuoV9yH61JCjKzXUWmRCJJ9FITOi66ANSDpBJZKjrRFjA==
I get: HdkTpAnsJ+bHi0DggaQq3iJMh0mrgcohOiJDeGzpqLFdvZUEXaD3YBEqGa4rBB7Y - and it is the same as in Node.js crypto module.
But! When I write this code in bashscript:
hash=$(echo -n 8724eb94-ff8f-441e-81a7-bc4282f7c342 | openssl enc -a -e -aes-256-cbc -nosalt -pass pass:fzJKp5/vYUWZUZ1hVSXycdmskKcSNtmZoFhPv5UtWGuoV9yH61JCjKzXUWmRCJJ9FITOi66ANSDpBJZKjrRFjA==);
echo ${hash}
I get alphrNunU02O4Xxw+qVgaEEaZGTrdGenvgsGnt0lczOkGKX5l6rAQTY3EJ8VA0iB and I have no idea why and where is bug. I have tried using ``, but with same wrong encoded value.
I have never write anything in bash, so I have no idea about some "tricks".
Thank you for any answers!
I figured it out. I have using:
'sh script.sh'
to run my script. But when I have done this:
'bash script.sh'
everything works perfectly. I have no idea why (yet) and now I will look for answer for 'What is thy difference between 'sh' and 'bash' '.
Thank you for some suggestions!
i have a problem with my bash script. I read line by line the variable lvm_path_exec, that works. I confirmed it with echo "lvmpath".
But as soon as i place a sshpass command into the while statement the script only process the first line which got grepped.
If there is no sshpass command all lines of lvmpath_exec get processed.
Do you see the error?
lvmpath_exec=$(sshpass -p "${password[$i]}" ssh ${user[$i]}#${ip[$i]} -p ${port[$i]} lvdisplay | grep datatest -A 3 | grep Path | awk '{ print $3 }')
echo "$lvmpath_exec" | while read lvmpath
do
lvmname=datatest
snap=_snapshot
snapname=$lvmname$snap
lvcreate=$(sshpass -p "${password[$i]}" ssh ${user[$i]}#${ip[$i]} -p ${port[$i]} lvcreate -L20G -s -n $snapname $lvmpath)
snap_path=$(sshpass -p "${password[$i]}" ssh ${user[$i]}#${ip[$i]} -p ${port[$i]} lvdisplay | grep $snapname -A 3 | grep Path | awk '{ print $3 }')
transfer=$(sshpass -p "${password[$i]}" ssh ${user[$i]}#${ip[$i]} -p ${port[$i]} "dd if=$snap_path | gzip -c" > /tmp/$snapname)
delsnap=$(sshpass -p "${password[$i]}" ssh ${user[$i]}#${ip[$i]} -p ${port[$i]} lvremove -f $snap_path)
done
UPDATE
I fixed it:
replace
echo "$lvmpath_exec" | while read lvmpath
with
for lvmpath in $lvmpath_exec
But shouldnt it work with while read too?
sshpass works by manipulating stdin to fool ssh into thinking it is getting the password from an interactive user. When you use a ... | while style loop, the loop iterates for every line coming from stdin, which sshpass wipes out after the first call, that's why only the first line gets executed. The for loop doesn't use stdin, that's why it doesn't have this problem.
As man sshpass explains, this tool is inherently insecure and you should really be using public key authentication instead. Also keep in mind that it has other ways of passing the password, using the -p flag is the least safe method of all, and any other method would be safer, for example the -e flag seems trivially easy. I know you might insist you have a legitimate use case, but this is so important I'm just gonna quote from the man page:
First and foremost, users of sshpass should realize that ssh's insis‐
tance on only getting the password interactively is not without reason.
It is close to impossible to securely store the password, and users of
sshpass should consider whether ssh's public key authentication pro‐
vides the same end-user experience, while involving less hassle and
being more secure.
The -p option should be considered the least secure of all of sshpass's
options. All system users can see the password in the command line
with a simple "ps" command. Sshpass makes a minimal attempt to hide the
password, but such attempts are doomed to create race conditions with‐
out actually solving the problem. Users of sshpass are encouraged to
use one of the other password passing techniques, which are all more
secure.
have you tried this..have not tried though
export SSHPASS=password[$i]
sshpass -e ssh -oBatchMode=no user[$i]#{ip[$i]} ..
I want to write a bash script that will execute one command in the script, and the command need read some thing as password. So how can I pass the password to the command in the script?
$ota_gen -k $ota_key -i $1 -p $ota_tools $2 $ota_out_file
ota_key is a private key that need to be visited with a password, so how can I do it?
thank you.
ps: thanks hlovdal for help.
expect maybe what can help. But I don't know if it can interact with bash script, such as how to pass parameters from script to expect.
A quite common tool for feeding programs with proper input (like for instance passwords) non-interactively is the tool expect. The following example is given on the wikipedia page:
# Assume $remote_server, $my_user_id, $my_password, and $my_command were read in earlier
# in the script.
# Open a telnet session to a remote server, and wait for a username prompt.
spawn telnet $remote_server
expect "username:"
# Send the username, and then wait for a password prompt.
send "$my_user_id\r"
expect "password:"
# Send the password, and then wait for a shell prompt.
send "$my_password\r"
expect "%"
# Send the prebuilt command, and then wait for another shell prompt.
send "$my_command\r"
expect "%"
# Capture the results of the command into a variable. This can be displayed, or written to disk.
set results $expect_out(buffer)
# Exit the telnet session, and wait for a special end-of-file character.
send "exit\r"
expect eof
OK, I google and get the answer of how to interact with expect in bash script.
I have added lines bellow in my script.Ant it tack effect.
th
EXEC=$(expect -c "
spawn $ota_gen -k $ota_key -i $1 -p $ota_tools $2 $ota_out_file
expect \"Enter password for .... key>\"
send \"$PASSWD\r\"
interact
")
echo $EXEC
If you are passing sensitive information around and use it regularly you are probably best encrypting it.
Putting something like
#create key as follows - will prompt for password
#echo -n 'secret you want encrypted' | openssl enc -aes-256-cbc -a -salt -pbkdf2|base64
export MY_SECRET='VTJGc2RHVmtYMTlzVnBGWXNYUitLWlpYT3BWdStaQXJXeUVwc1JORnFsNWswZXJKT1dkRWpsWkxLWVFnK1hONQo='
Into your .bashrc will give you an encrypted environment variable that you can access where ever you need a secret, and you will be prompted for you passphrase/password that you used when creating the environment variable.
In the example above it is 'secret'
You access it is a command as follows
`echo $MY_SECRET|base64 --decode|openssl enc -aes-256-cbc -a -d -salt -pbkdf2 `
e.g.
xfreerpd /parameters.... /p:`echo $MY_SECRET|base64 --decode|openssl enc -aes-256-cbc -a -d -salt -pbkdf2`
For your query where $ota_key is the secret
$ota_gen -k $ota_key -i $1 -p $ota_tools $2 $ota_out_file
You can create the variable as follows
ota_key=`echo -n 'secret you want encrypted' | openssl enc -aes-256-cbc -a -salt -pbkdf2|base64`
Then use it as follows
$ota_gen -k `echo $ota_key|base64 --decode|openssl enc -aes-256-cbc -a -d -salt -pbkdf2 ` -i $1 -p $ota_tools $2 $ota_out_file
openssh will prompt you for a password to encrypt and decrypt each time, you can supply one as part of the command, but then you are just hiding things from the history etc. Have a look at https://www.tecmint.com/generate-encrypt-decrypt-random-passwords-in-linux/ for some info on using openssh for this. https://www.serverlab.ca/tutorials/linux/administration-linux/how-to-base64-encode-and-decode-from-command-line/ for base64 and How to assign an output to a shellscript variable? for different options on command substitution I have used back-tick ` above
PS Adding a function like
get-key()
{
echo -n "$1"|base64 --decode|openssl enc -aes-256-cbc -a -d -salt -pbkdf2
}
To your bashrc gives you quick access to the secret if you need it
The script below used to work on Mac OS X, but, since moving it to Ubuntu, it doesn't seem to read from the password file at all. Even when I run it from the command line, no matter what I do, I get a popup prompt asking me for the password. As this will run via cron, I don't want this to happen... I want it to read the password from the file with no prompt. To note, I did try using passphrase-fd and passphrase-file, neither of which worked...
#!/bin/sh
p=$(<pass.txt)
set -- $p
pass_phrase=$1
destination="/var/www/decrypted"
cd /var/sl_bin/
for FILE in *.pgp;
do
FILENAME=${FILE%.pgp}
gpg --passphrase "$pass_phrase" --output "$destination/$FILENAME" --decrypt "$FILE"
rm -f $FILE
done
This works:
gpg --no-use-agent --batch --passphrase-file pass.txt --output kkkk.tar.bz2 --decrypt kkk-data.tar.bz2.gpg
The --passphrase-file option seems to be broken / not honored. I had to use --passphrase-fd 0 instead, like so:
cat .password | gpg --passphrase-fd 0 --output foo --decrypt foo.gpg
Use option --no-use-agent. It won't prompt you using option --passphrase.
If you don't want to supply the file via standard input (eg, because you're plugging this into another command like git, which wants to supply the content to sign via standard input), then you can use another file descriptor:
gpg --passphrase-fd 3 <your command here> 3< pass.txt
Your problem is probably that $passphrase is null. On Ubuntu sh is symlinked to dash which doesn't understand $(<file_name) in the same way that Bash does (but doesn't issue an error either).
You can change your shebang to:
#!/bin/bash
or use $(cat pass.txt)
Also, why not combine the second, third and fourth lines?: pass_phrase=$(<pass.txt) (or pass_phrase=($(<pass.txt)) if you're trying to strip off all but the first "word" in the file).
Your previous question
use
#!/bin/bash
or
#!/usr/bin/env bash
as your first line instead of #!/bin/sh
As for your pass phrase problem, you should probably try to use some automatic mechanism. check the gpg documentation for information. I don't use gpg, but you can check out gpg-agent.
Two solutions (the first one solved my problem ;-))
http://www.roguedaemon.net/rephrase/
gpg uses --passphrase-fd not --passphrase
echo yourpw|gpg --passphrase-fd 0 --output out.txt -d file.txt
You're getting password prompt because you have DISPLAY variable set (if you click cancel the script will continue decrypting files). DISPLAY shouldn't be set in the cron environment, so you can probably ignore it, but to be sure or be able to test the script from command prompt add
unset DISPLAY
to the beginning of the script or run it before executing.
Also to be able to use $(<file) syntax you need to change
#!/bin/sh
to
#!/bin/bash
You should avoid using --passphrase option which could lead to revealing your password on multi-user system. You can use --passphrase-file instead. Here's how I would change your script:
#!/bin/sh
PASSFILE=$(pwd)/pass.txt
destination="/var/www/decrypted"
cd /var/sl_bin/
for FILE in *.pgp;
do
FILENAME=${FILE%.pgp}
gpg --passphrase-file $PASSFILE --output "$destination/$FILENAME" --decrypt "$FILE"
rm -f $FILE
done
To save location of the password file before changing current directory, I saved it in PASSFILE variable.
add --archive to read password from --passphrase-file
You must to use:
gpg --batch --passphrase-fd 1 --passphrase-file your_password_file -c your_file_to_encript.txt
Use below script
#! /bin/sh
gpg --pinentry-mode loopback --passphrase='PASSWORD' --output /output/outputFileName /input/inputFileName