I'm running a software daemon that requires for certain actions to enter a passphrase to unlock some features which looks for example like that:
$ darkcoind masternode start <mypassphrase>
Now I got some security concerns on my headless debian server.
Whenever I search my bash history for example with Ctrl+R
I can see this super strong password. Now I imagine my server is compromized and some intruder has shell access and can simply Ctrl+R
to find my passphrase in the history.
Is there a way to enter the passphrase without it to be shown in bash history, ps
, /proc
or anywhere else?
Update 1: Passing no password to the daemon throws an error. This is no option.
Update 2: Don't tell me to delete the software or other helpful hints like hanging the developers. I know this is not a best-practice example but this software is based on bitcoin and all bitcoin based clients are some kind of json rpc server which listens to these commands and its a known security issue still being discussed (a, b, c).
Update 3: The daemon is already started and running with the command
$ darkcoind -daemon
Doing ps
shows only the startup command.
$ ps aux | grep darkcoin
user 12337 0.0 0.0 10916 1084 pts/4 S+ 09:19 0:00 grep darkcoin
user 21626 0.6 0.3 1849716 130292 ? SLl May02 6:48 darkcoind -daemon
So passing the commands with the passphrase does not show up in ps
or /proc
at all.
$ darkcoind masternode start <mypassphrase>
$ ps aux | grep darkcoin
user 12929 0.0 0.0 10916 1088 pts/4 S+ 09:23 0:00 grep darkcoin
user 21626 0.6 0.3 1849716 130292 ? SLl May02 6:49 darkcoind -daemon
This leaves the question where does the history show up? Only in .bash_history
?
Best Answer
Really, this should be fixed in the application itself. And such applications should be open source, so that fixing the issue in the app itself should be an option. A security related application which makes this kind of mistake might make other mistakes as well, so I wouldn't trust it.
Simple interposer
But you were asking for a different way, so here is one:
Compile this with
then run your process with
The interposer library will run this code before the
main
function from your application gets executed. It will replace the last command line argument by the actual password in the call to main. The command line as printed in/proc/*/cmdline
(and therefore seen by tools such asps
) will still contain the fake argument, though. Obviously you'd have to make the source code and the library you compile from it readable only to yourself, so best operate in achmod 0700
directory. And since the password isn't part of the command invocation, your bash history is safe as well.More advanced interposer
If you want to do anything more elaborate, you should keep in mind that
__libc_start_main
gets executed before the runtime library has been properly initialized. So I'd suggest avoiding any function calls unless they are absolutely essential. If you want to be able to call functions to your heart's content, make sure you do so just beforemain
itself gets invoked, after all initialization is done. For the following example I have to thank Grubermensch who pointed out how to hide a password passed as command line argument which broughtgetpass
to my attention.This prompts for the password, so you no longer have to keep the interposer library a secret. The placeholder argument is reused as password prompt, so invoke this like
Another alternative would read the password from a file descriptor (like e.g.
gpg --passphrase-fd
does), or fromx11-ssh-askpass
, or whatever.