2

I want to make my script password protected. If I use this code it works:

ACTUAL="sam123"
read -s -p "Password: " enteredpass

I also want to protect the script from being read with cat and vi. I tried to use vim -x <script> to encrypt it but then it won't allow me to run it.

I am using a generic user and haven't gotten anywhere.

3
  • You can't do this in a way that will actually stick (can't be trivially circumvented) without help from your sysadmin. Commented Aug 15, 2018 at 17:55
  • ...basically, you need to have the script run as a completely different user from the shared account, and set up a mechanism (be it a C wrapper with the setuid bit set, or an appropriate /etc/sudoers configuration) allowing that script to be invoked from the shared account; only when it's on the other side of a privilege boundary is it secure against someone reading its text, tracing its execution, etc. Commented Aug 15, 2018 at 17:57
  • 2
    ...well, you could just have a wrapper for the script that's plaintext, and the content actually be encrypted. That'll work up to a point, the point being when another user in the shared account runs strace -p yourpid -f to trace what your shell does when you invoke the script and enter the password to decrypt it. Commented Aug 15, 2018 at 17:59

2 Answers 2

1

You can't do this securely without your sysadmin's help, but you can do something sorta-kinda-maybe-not-really-adequate without it.

So, let's say you create your script like so:

cat >myscript <<EOF
echo "Doing something super secret here"
EOF

...but you don't want anyone who doesn't know the password to run it, even if they're using a shared account. You can do this by encrypting it:

gpg -ac <myscript >myscript.asc

...and then embedding that plaintext into a script:

#!/usr/bin/env bash
{ gpg -d | bash -s "$@"; } <<'EOF'
-----BEGIN PGP MESSAGE-----

jA0EBwMCBogTuO9LcuZg0lsB2wqrsPU8Bw2DRzAZr+hiecYTOe//ajXfcjPI4G6c
P3anEYb0N4ng6gsOhKqOYpZU9JzVVkxeL73CD1GSpcQS46YlKWJI8FKcPckR6BE+
7vqkcPWwcS7oy4H2
=gmFu
-----END PGP MESSAGE-----
EOF

That said, other users in the shared account can still collect your password if they connect to and trace your process while it's running -- running strace on the copy of bash -s will show the text being fed into its stdin. In general, you shouldn't rely on shared accounts for anything that needs to remain confidential.

Sign up to request clarification or add additional context in comments.

Comments

1

Late answer for posterity, how about using openssl? here's my scriptencrypt.sh

It generates a new .sh file that requires a password

#!/bin/bash

if [ -z "$1" ]; then echo "usage: $(basename $0) script"; exit 1; fi

script=$(cat "$1")
checksum="$(echo "$script" | md5sum | awk '{ print $1 }')"
extension=$([[ "$(basename $1)" =~ .\.. ]] && echo ".${1##*.}" || echo "")

cat << EOF > "${1%.*}.enc${extension}"
#!/bin/bash

read -r -d '' encrypted_script << EOF2
$(openssl aes-256-cbc -a -salt -in /dev/stdin -out /dev/stdout <<< "${script}")
EOF2

read -s -p "Enter script password: " password
echo
unencrypted_script=\$(openssl aes-256-cbc -d -a -salt -in /dev/stdin -out /dev/stdout <<< "\${encrypted_script}" -pass pass:"\${password}" 2>/dev/null | tr -d '\000')
clear
checksum="\$(echo "\$unencrypted_script" | md5sum | awk '{ print \$1 }')"
if [ "\${checksum}" = "${checksum}" ]; then
    eval "\${unencrypted_script}"
    exit 0
else
    echo "Wrong password inserted"
    exit 1
fi
EOF

9 Comments

Hmm. The <<<"${script}" is the only place you're doing an unquoted expansion in your outer heredoc, right? Considered changing from <<EOF to <<'EOF' and passing that through the environment instead of expanding its text?
I would also strongly suggest switching from == to = inside [ for the sake of encouraging standards-compliant usage by default. Sure, the shebang is bash, but folks who see == used inside [ or do so themselves are more likely to continue to follow the practice in code that needs to be compatible with /bin/sh.
@CharlesDuffy it's not, the whole $(openssl aes-256-cbc -a -salt -in /dev/stdin -out /dev/stdout <<< "${script}") expansion is done in the outer script for the first heredoc; there's also the second ${checksum} expansion. I'll change the == though
@CharlesDuffy BTW did you mean changing EOF2 to 'EOF2'?
No, I meant <<EOF to <<'EOF'. Clearly you do want the command substitution inside the EOF2 heredoc to be run.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.