The title of my thread says mostly all of what I want to do. Basically I want to auto-ssh to a remote host, and run a program on it (VLC is just an example). I wrote a script which calls xterm and then runs expect on it. The code is as follow
and then one can easily see the password I put in the code.
The primary reason for the code is to create a ready-to-run program for non-tech people (who have no idea about unix, about ssh, and who are not given ssh account as well), and of course I do not want them to know my password. Of course, they might be so novice that they might not know that ps command, but I just want to have some security for myself.
Any idea or advice will be greatly appreciated,
PS: the host is linux (red hat), and clients are Mac OS X (so expect and ssh can be used)
Thanks danmero for your suggestion. I want to avoid this as well, because I want to create a ready-to-run program, no need to type anything else (pass phrase for example).
Whenever I post a script on my blog and include my email address, I obfuscate it with the tr command to thwart spambots. It could be used here too. If the pass was LinuxRules you could use
pass=$(echo "LinZxRZles | tr "Z" "u")'
You could also use parameter expansion to pick out the password from a longer random-looking string. None of this provides security, just a little confusion for curious novices.
Your tr'ing way is interesting fubaya. Honestly I have not heard of tr before. Anyway, that is just to protect the bash script itself, not the information produced by ps. The second way (which I thought of as well, by creating a complicated script to select the password that I want) does not help in case of ps either.
D.
---------- Post updated at 08:15 PM ---------- Previous update was at 08:12 PM ----------
shc is great, I just tried it and it works great for its purposes. Thanks for this information danmero, although again, it helps protecting the bash script, but the password still shows up when ps'ing.
D.
---------- Post updated at 08:23 PM ---------- Previous update was at 08:15 PM ----------
I am not sure if I miss something, but I am also using ssh without password in another box. Some points should be pointed out:
This method needs some setups on clients (creat and copy ssh key etc...)
This method needs passphrase each time a new shell is created on host (or first time user logs in), which is my case. Our remote host is a cluster, and each time I log on, a new shell is created.
The first point alone needs a lot of works, which is opposed to what I want to do: my program should be ready to run in any new client in the network without any complicated setup.
Thanks,
D.
---------- Post updated at 08:41 PM ---------- Previous update was at 08:23 PM ----------
I think of some solutions:
fool ps so that the processes showed by ps'ing (xterm, bash... ) are something else (fake name) or without parameters (such as xterm, or expect or bash only)
temporary disable ps (by chmod 500 `which ps` for example, which needs root privilege) or temporary link ps to a modified ps which does not show the processes I want to hide)
encrypted password so that ps shows only weird characters on password fields (not sure if this is doable)
Google gave me some change name or title of processes, but it seems to me that those work only for the script, not the processes called by the script (like ssh, expect etc...)
There's no "best" way. They all suffer from exactly the same problem: Anyone who can see the code will know how to crack your password, and they'll have unlimited tries to guess your obfuscation. You might have noticed that you already had to brute-force your way around ssh's security features with 'expect' to do what you want; that's a subtle hint, in mile-high neon letters You're really not supposed to do that. It's really not a good idea. If you can pre-share a password, why can't you pre-share a key?
That is so true Corona, and I should have quoted "Best" to imply what I really wanted when posting the question: I want to learn. Few days ago I still thought that ssh was impossible to be automated, and then I learned about expect. Now I want to learn a way (if there is one) to fool ps :).
Automated ssh without my presence using my account is already not allowed if strictly considering the account policy, and of course I am not allowed to share my password. But it is really a matter of knowledge that I like the solution so much so that I want to learn more... Everything is still in development, and that I have them all in my control.
You are not going to fool ps. ps gets its process data from the kernel. You'd have to modify the kernel to lie/obfuscate, then recompile it. Or, you'd have to modify and recompile ps to lie/hide/obfuscate. And, you can forget about any LD_PRELOAD tricks since ps is a SUID binary.
Wrong. Any C program can lie to ps and the kernel, simply by changing it's arguments. The only restriction is that the new contents may not be larger than the original if you just overwrite it (example available on request). But with just shell scripting, no, it's not possible.
Wrong. Any binary may query the kernel about running processes. On HP-UX:
$ ll `which ps`
-r-xr-xr-x 1 bin sys 147264 Dec 17 2008 /usr/bin/ps
Put the script in a separate expect script file, and use your bash script as a wrapper script. From bash, call the expect file. This will prevent the expect commands from appearing in ps.
Instead of hardcoding the password in the file, store the password in a separate file and protect the file so that only the authorised users can access it.
Instead of using a password, encode the password algorithm instead. For example your password may be month-based, e.g. mypasswdJul2010, so put the algorithm in the code to generate it.
expect is an ugly, last-resort solution for things that won't cooperate any other way, and tends to make insecure and unreliable solutions. If you think ssh can't be automated without it, you've learned the wrong lesson; there's a much better and more secure method built into ssh itself: authorized keys. It doesn't make much sense to say "my account policy says I can't automate this; therefore I'll automate it anyway, avoid the proper way since that's not allowed, and use the least secure and most contrived way imaginable instead!" Somehow I don't think that's what their security policy had in mind.
(Yeah, I have a lot of old machines lying around with outdated os installs ;))
Furthermore, in the BSD-ish cases (at least, perhaps others), the struct with the process info contains the original argv in addition to the current argv (which may differ as when deliberately modified by the process itself).
If you were referring to a different type of argv manipulation, or something altogether different, or if there's an error in my C code, I would appreciate the enlightenment.
memset() on the string pointed to by argv[1] works on osx 10.4.11, where modifying the pointer in argv[1] directly (as my code was doing) failed.
Incidentally, as an unprivileged user, copying the suid ps binary so that it is no longer suid seems to work fine. I only tested a few options, however, so it's possible there's a privileged code path that I did not visit, just waiting to blow things up, but if collecting the process info did not require privilege -- I took a brief peek at Apple's ps.c, and it's using sysctl to gather the info; so, not surprising that privilige is not required for that step -- I don't see what would.
Hi Corona, I think you got it wrong. I did mention that I knew authorized keys already (and I have been using it quite a while), but in my opinion it is not automation as expect (yes, I thought it wrong you may think), and that I did not hear of expect before.
Anyway, let us try not to diverge the main question of my post: how to fool ps or hide password in my script.
Thanks,
D.
---------- Post updated at 06:08 PM ---------- Previous update was at 06:02 PM ----------
Yes, I did. I tried it before combining my scripts to the script I posted. And the password still showed with ps.
I thought of this already, and it actually is a solution that a lot people recommend instead of passing password through arguments. But the permission of the file can be easily change by root, hence can be seen easily right?
And finally the decoded pass will be still passed to the argument of ssh or expect, or we can pass the encoded one?
Thanks,
D.
---------- Post updated at 06:14 PM ---------- Previous update was at 06:08 PM ----------
I found a post describing similar method, but I have no idea how to apply this to change (or fake) the name of the built-in process (such as expect or ssh) given its pid. If somehow ssh (or its argument) can be changed (or faked) then it is the solution, I think.
D.
---------- Post updated at 06:18 PM ---------- Previous update was at 06:14 PM ----------
Hi Alister,
I tried your code (modifying argv[1]) and it did not work on 10.6.3 either. Do you mean modifying memset() can change output of ps for built-in processes (xterm, expect, ssh, bash...) in my first post?
In what manner is it worse do you think? It may not be easy to explain to your customers or superiors but it is fully automatic and secure. Your method is not and cannot be made secure. The inventor of ssh knew people would try to butcher in stored plaintext passswords anyway and designed it to prevent that.
Not until you understand that the reason you have to use expect at all is because you're brute-forcing an insecure solution ssh was expressly designed to not just prevent but make obsolete.
You cannot do this from a shell script, though. Also, even if you could, there is a race condition present. The args could be visible from ps if ps is run at just the right time and the kernel's process scheduler conspires against you.
As Corona has made clear, there is no secure way to accomplish what you're trying to do. The best you can manage is a few obstacles to keep the undetermined at bay.