jfroebe has asked for the wisdom of the Perl Monks concerning the following question:
Hi,
I know about using md5 for obtaining a hash for a password and such but that isn't what I'm after.
What I'm trying to figure out without the caffeine roaring through my bloodstream, is how to hide a password in this circumstance:
I have a script that I enter my login/password once but will contact an arbitrary number of other machines via ssh/telnet/rlogin/etc. The problem is that if I force perl to core dump (i.e. kill -4), I can scan the core dump for my login & password because it was in memory.
Remember that I want to enter the login/password only once, hide the password (encryption of some sort) and keep the window where the password is in cleartext in memory to a minimum amount of time (used for the remote connection login).
So far, I haven't found any way to do this without significant holes:
- encrypting a hash or other memory region requires the key to be stored which could be retrieved to unencypt the password in the core file.
- Storing the password in a file (encrypted or not) poses a similar risk.
- Storing the password in memory using a 1 way hash requires the user to reenter the password
Obviously, this is a worst case scenerio with no easy answers that I can determine.
Jason L. Froebe
Team Sybase member No one has seen what you have seen, and until that happens, we're all going to think that you're nuts. - Jack O'Neil, Stargate SG-1
Re: hiding passwords
by idsfa (Vicar) on Jun 14, 2005 at 16:20 UTC
|
This is a lost cause. root can always read system memory anyway (even w/o a core dump). If you do not trust root on the system, don't use that system for this. If you do trust root, set your umask to 077.
The intelligent reader will judge for himself. Without examining the facts fully and fairly, there is no way of knowing whether vox populi is really vox dei, or merely vox asinorum. -- Cyrus H. Gordon
| [reply] [d/l] |
Re: hiding passwords
by jasonk (Parson) on Jun 14, 2005 at 16:10 UTC
|
If the requirement really is an arbitrary number of machines, the only way you can avoid keeping it in memory is to switch to a non-password based authentication. The program will need the password whenever it has to login so your options are really either to keep the password around or open all the connections up front (which doesn't work with an arbritrary number, but could be an option if your requirements are actually fewer machines). By opening all the connections up front you can then discard the password that was in memory (and hope none of the connections dies so you require it again). What you should really look at though is if there are alternative ways to accomplish the goal, things like ssh keys and kerberos can allow you to access machines without keeping passwords around.
We're not surrounded, we're in a target-rich environment! |
---|
| [reply] |
Re: hiding passwords
by salva (Canon) on Jun 14, 2005 at 16:17 UTC
|
how about using ulimit to instruct the program to not core dump?
$ ulimit -c 0
$ perl script.pl
but anyway, all this is useless, because somebody able to send signals to the process would also be able to attach a monitor (i.e., strace or truss) and inspect all the IO including the passwords. | [reply] [d/l] |
Re: hiding passwords
by fauria (Deacon) on Jun 14, 2005 at 16:52 UTC
|
As process and memory management is a matter of the OS itself, not the programming language you are using, maybe a more robust layer of security whithing the kernel can improve the security of your application.
Having the plain text password in memory, even for a short period of time, is not a good idea becasue it just creates a false sense of security (even a minimum window of opporunity or a strange race condition can be dangerous).
If you are using Linux (and i mean the kernel), maybe grsecurity patches can help you by improving the whole system security policies.
Your problem could be solved by using a chroot environment provided by grsecurity, which features "No attaching shared memory outside of chroot", "No kill outside of chroot", and "No ptrace outside of chroot (architecture independent)" among others. | [reply] |
Re: hiding passwords
by thundergnat (Deacon) on Jun 14, 2005 at 16:07 UTC
|
Hmmm... If you imediately write garbage to the $password variable just after it is used and before it goes out of scope, I don't see how anyone can recover it from a core dump.
Really, I can't see that as a large security risk anyway. I would be more concerned that someone untrusted had physical access to my machine in general. If a serious cracker has physical access to the machine, he ownz it.
| [reply] |
|
Writing garbage to the $password variable would allow for a one time login to a remote machine.
I'm not even sure that there is an answer to this. The closest we've been able to figure out is to use ssh-agent prior to running the script which would allow for logins to a server that has the login by key enabled. Not all machines do for some reason here.
I guess I was just hoping that someone had thought of some thing I hadn't already thought of.
Jason L. Froebe
Team Sybase member No one has seen what you have seen, and until that happens, we're all going to think that you're nuts. - Jack O'Neil, Stargate SG-1
| [reply] |
Re: hiding passwords
by omega_monk (Scribe) on Jun 14, 2005 at 17:03 UTC
|
Just because I didn't see anyone toss in that using telnet and rlogin are larger security risks than someone getting a password from a core dump.
update: spelling | [reply] |
Re: hiding passwords
by ikegami (Patriarch) on Jun 14, 2005 at 16:12 UTC
|
I don't see how encrypting it would help. If the attacker has access to the core image, he would surely have access to the decryption key as well. | [reply] |
Re: hiding passwords
by traveler (Parson) on Jun 14, 2005 at 16:15 UTC
|
With SSH you can stick a certificate on the target machine (once) and then log in without a password. Some SSH clients require a local password to open the local certificate, but it would not be in memory on the client longer than to open the cert. It may even be possible to authenticate to another program (e.g. with PuTTY/Pagent on Win32).
HTH, --traveler | [reply] |
Re: hiding passwords
by ambrus (Abbot) on Jun 14, 2005 at 21:46 UTC
|
If your program is set[gu]id, it can never produce a core dump.
If your program is not setid, that there is no way to
stop the user running it from looking at its core,
at least in vanilla linux.
You can always read the password when it's transmitted,
or read the memory of the process by attaching a debugger,
or watching as it outputs or reads the password.
Other users, however, have no way to make it dump core,
as they can not send a signal to them.
However, you can prohibit the creation of a core file
with the getrlimit syscall (or the ulimit
builtin command in a shell, but that would be difficult to
use securely in such an application). I don't know
of any perl interface for this syscall, but you could
call syscall directly, search in CPAN for a module,
or write wrapper code yourself.
(There's yet another issue here: if your machine has a
swap partition, the memory containing the password can
be swapped out, and if someone gains access to the hard disk,
he could find the password there.
There is a solution for this, the mlock system
call, but it would be very hard to use from perl,
and it requires setuid root.
The best solution against this is not allowing physical
access for untrusted people to your hard disk, or,
if that's impossible, not using swap partition
or using an encrypted swap partition (linux does not have
these, but some bsd systems do).)
| [reply] |
|
the best solution against this is not allowing physical access for untrusted people to your hard disk, or, if that's impossible, not using swap partition or using an encrypted swap partition (linux does not have these, but some bsd systems do).)
AFAIK, you *can* encrypt even the swap using kernel 2.6 (don't know about 2.4).
Below are some pointers, surely there are others floating around on the net.
(Gentoo) A Structured Approach to Hard Disk Encryption
And a better approach here:
HOWTO dm-crypt HOWTO for Debian unstable and testing
Have fun ;-)
| [reply] |
Re: hiding passwords
by spurperl (Priest) on Jun 14, 2005 at 17:16 UTC
|
I just want to inject some paranoidal input into this discussion, hanging on to the OP's mentioning of MD5 in his post.
The MD5 hash algorithm has been recently subjected to several successful attacks, and is now generally believed to be compromised and not safe in the cryptographic community.
SHA-256 may be used to be secure, via the Digest::SHA module. | [reply] |
|
None of the attacks on MD5 so far are relevant for one-way hashes of passwords, though moving to SHA-256 may not be a bad idea anyways.
| [reply] |
Re: hiding passwords
by Anonymous Monk on Jun 15, 2005 at 10:49 UTC
|
I have never tried this myself, but I think it would work:
- Obtain unencrypted password.
- Set umask to 777 (backup original umask)
- Open/create ".mypassword" (clobber existing file)
- Delete ".mypassword".
- Restore umask.
- Write unencypted password to file.
- Trash the memory resident copy of the password.
Whenever the password is needed, a seek() and read() can be performed to obtain it. Do *not* close the file descriptor until it is known the password is never required again.
No other user can open this file since it has no read or write permissions. Secondly, it will only exist on the file system for an extremely short period of time. If it were created in a directory with excessively restricted permissions then only root would ever be able to get to it.
If your program dumps core, the .mypassword file will not be available since it has already been unlinked. Not until the last file descriptor is closed will the space be reclaimed. As far as I know, this is true of all unix file systems, not sure how it works with Windows. If you are concerned about core dumps, then I think Windows is irrelevant.
For the majority of the runtime, all the core dump will contain is evidence of a file descriptor, which gives away zero information.
For the remainder of the runtime, there is a slight chance a core dump might contain the password. This could be eliminated if the authentication mechanism allowed for passwords to be sent byte at a time, but I have never seen such a system.
Alternatively, rotating the passwords might avoid this problem too.
-Frank
| [reply] |
|
Wow, this sounds really convoluted, but might work...
But this seems to be largely a waste of time and effort, because, as lots of people are trying to tell you above, the problem is "where is the weakest part of the security"? It's not the system, or it's memory. It's on the network itself. A sniffer can easily capture a clear text password. Until clear text passwords are done away with, the scripts' system's memory is (very likely) not worth worrying about.
OP, there are lots of guesses going on above about why you are worrying about a core dump scenario, could you enlighten us as to your actual reasons?
-Scott
| [reply] |
Re: hiding passwords
by Meetch (Initiate) on Jun 15, 2005 at 08:49 UTC
|
Who needs a core file?
How about in the environment that launches the script (this is for Linux):
ulimit -c 0
- limits core files to 0 bytes, hence nothing to snoop on. | [reply] |
|
|