Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obfuscating stored passwords in bash

Tags:

bash

I have a bash script that I need to write my password to run a program. Other people can see it. Are there a way to write the password in a not too obvious way? Even if he can do the same command in bash and get the password, he can't read it in text.

Today I do this:

PASSWORD="1234567"
program --pass=$PASSWORD

I want to do this

PASSWORD="10101001001010010101010100101" #binary or other code
NEW_PASS=`decrypt $PASSWORD`
program --pass=$NEW_PASS

Any idea?

like image 325
Rodrigo Avatar asked Mar 22 '12 18:03

Rodrigo


2 Answers

What you're asking for is not only evil -- it simply won't work.

All a user has to do to see your password is to run bash -x your_script and the output will include

+program '--pass=decrypted-password-here'

...no matter how effective the obfuscation might have been.

What's the actual program you're trying to call that needs a password? Can you hide your password behind a setuid wrapper, such that the wrapper can read the password file even if the user who runs it can't? Can you (borrowing DigitalRoss's suggestion) set up a user account which has a copy of the stored password (or, better, a certificate or keypair), configure it only to be able to run your script and nothing else over SSH, and give the users who should be able to run the script permissions to SSH as that user (or sudo to that user for only the single command, or so forth)?

Etc.

In short: Aim for real security, not obfuscation.


Now, if you did want obfuscation -- the traditional approach is ROT-16:

obfuscated_password="qrpelcgrq-cnffjbeq-urer"
real_password="$(tr a-zA-Z n-za-mN-ZA-M <<<"$obfuscated_password")"

...but if it's a password you actually care about whatsoever, don't obfuscate -- use one of the approaches given above to avoid storing a password in a user-readable manner at all.

like image 149
Charles Duffy Avatar answered Sep 19 '22 14:09

Charles Duffy


You could use uuencode and uudecode, which are often installed (and always easily available via packages) on Unix systems. Since the encoding will be meaningless it might prevent an observer from easily memorizing the password, i.e., stealing the password via shoulder-surfing. But a well-chosen random clear-text password would accomplish about the same thing without the false illusion of security.

This exact problem is faced by everyone in DevOps these days as automated configuration management becomes more and more necessary.

Here are some better solutions:

  • have a secrets file on the system your script runs on. The script can read its secret at runtime out of the file. This way you can check the script in to source-code control without broadcasting the password, and you can use user permissions to protect the secrets file. You can reuse the script without propagating a password.

  • use no-passphrase ssh public key authentication to get to the remote system

  • use a combination of the above approaches with a role-restricted user. I usually create a user on the target system that can't do anything except what the script wants to do. Modern versions of ssh help with this, as they can ignore the incoming command (see forcecommand in sshd_config or use something like ssh-forcecommand) and just always do a specific thing.

  • authenticate the management agent client via a server-signed certificate. Real configuration-management systems like Puppet and Chef will do this for you.

  • if you are connecting to a web page, you may still be able to create a role-restricted user or at least one that's expendable. Perhaps you could log in by hand once and establish a persistent session. Curl can use cookies and cooperate with this approach.

like image 20
DigitalRoss Avatar answered Sep 20 '22 14:09

DigitalRoss