What guards against the "su password fishing" hack?

(Don't know whether this is the correct subforum, or even a topic suitable for discussion here. If not, moderators please fix.)

As we all know, it is unsafe to use the root account more than absolutely necessary, and it is particularly unsafe to enable direct ssh login into the root account. We also know that the root password needs to be guarded with utmost care (and not posted on the console on a yellow sticky note), and that enabling passwordless login into root (using ssh keys) is dangerous. In contrast, direct ssh login to user accounts is necessary and acceptable (even passwordless with ssh keys), because after all normal users can't do that much damage, other to their own accounts; so if a normal user is hacked, at least the overall system survives.

This means that sys admin tasks are done by a human with their own account, who logs in (probably usually via ssh), has their own password or ssh keys, and then switches to being root by using su or sudo. For all but pre-arranged tasks, that means typing the root password. If you look at the statements above, this should be considered pretty safe: the unprivileged account that the human uses doesn't need to be guarded too closely, since after all the human has to re-authenticate with the root password before they can do something seriously harmful.

Unfortunately, there is a hack that allows privilege amplification, and it works as follows: If an attacker has hacked into the regular (non-root) account of the human admin, then deposit a small "su" executable in their bin directory. That executable accepts the root password from the user, deposits it somewhere where the hacker can find it (mails it, sends it over a socket, puts it in a file, ...), deletes itself, and then fork/execs to the real su executable to execute the command. The human admin won't even notice that they just gave the root password away. The reason this is privilege amplification: A hacker only has to get into an unprivileged account and wait until that human issues su or sudo, and then can amplify their privilege to be root.

In FreeBSD, is there anything that guards against this? The only ideas I have for preventing it: Have the periodic security scans look for executables named "su" or "sudo" stored in places other than the real official one. But that means there will be a long delay until the hack has been found (periodic runs at best nightly). Or maybe the real su and sudo commands are written to not accept passwords from anything other than a real tty device, in which case the fake "su" program would have to pretend that the password was invalid (after it snags it), and the human user should notice that they had to type their password twice.
 
Unfortunately, there is a hack that allows privilege amplification, and it works as follows: If an attacker has hacked into the regular (non-root) account of the human admin, then deposit a small "su" executable in their bin directory. That executable accepts the root password from the user, deposits it somewhere where the hacker can find it (mails it, sends it over a socket, puts it in a file, ...), deletes itself, and then fork/execs to the real su executable to execute the command.
And how does it make sure that the password doesn't have to be typed twice?

As far as I know su doesn't accept any password (-like) arguments, thus making it pretty much impossible to 'pass the password'. Also see the su(1) manualpage.

Code:
macron:/home/peter $ echo "mysecretpassword" | su
Password:
su: Sorry
However... it is for this very reason why the use of security/sudo is completely banned from all the servers I administer (even the ones which aren't mine, I honestly take it this far by actually sending out serious warnings against its use), because the scenario you describe here is very well possible when using sudo. As elitist as this may sound: it's also why I personally consider sudo to be a P.O.S. where security is concerned, an opinion I don't vent often because I know it's quite popular and easy to use (I've been using it quite a while myself, though never on my FreeBSD servers) and the risks are somewhat limited.

Still... Check the sudo(8) manualpage:

Code:
    -S, --stdin
         Write the prompt to the standard error and read the password
         from the standard input instead of using the terminal device.
         The password must be followed by a newline character.
Notice: "read the password from the standard input", are you kidding me? :eek:

And to add insult to injury sudo has a whole section on how it uses plugins to prevent abuse by restricting certain parameters and such. This gets explained in sudoers(5). There you'll learn that this protection mostly consists of blocking environment variables but not so much restricting commandline parameters such as -S.

Of course things change, but for reasons stated above I'm not exactly very motivated and enthusiastic to keep track of what's happening with sudo, instead I simply block(ed) it and moved on ;)

(edit)

I made some grotesque statements and well, I figured that since I have a VirtuaBox instance sitting around I might as well run # pkg install sudo and see what happens... I'm not going to spend too much time on this, but just an example of what I meant above:

Code:
peter@fbsd_vm $ echo "peter\n" | sudo -p "Password please:" -S sh
Password please:Sorry, try again.
Password please:
sudo: 1 incorrect password attempt
Examples like that don't impress me where security is concerned ;) I hope I don't have to explain the possibilities which even the mere -p parameter can give an attacker: "Please type your password twice (account verification):".

Just for context: I used default settings. So I installed security/sudo, copied /usr/local/etc/sudoers.sample to sudoers, enabled access for the wheel group and I set the password timeout to 0.
 
With most (all?) configuration management tools/frameworks/however you want to call them you could just set up a "staging" machine where Admins have their normal, unprivileged accounts and use the CM tool of choice for managing/configuring the servers, never even logging in to them. Depending on the config management you have chosen, either there is a cleint module that runs (partly) as a privileged user, or login as/switching to root (with keys) is completely managed by the CM. ssh access to these servers could even be restricted to the staging machine(s).

I'm using Ansible with such a setup, mainly because I'm lazy and don't want to connect to multiple machines and type in the password for my ssh-key every time...
When times get rough I still log in locally and just get root with su, because as ShelLuser already pointed out - you'd need sudo as a helper for such a script, because su doesn't allow throwing passwords at it from everywhere...

I never liked sudo as IMHO it is way too complex for being used for such a sensitive task (I always put it in the same category with systemd...) and it breaks with many proven security practices. It's absolutely horrible how sudo is used in the wild, even on some default setups of some linux distros - e.g. using a root account without any password just to get sudo su working and of course sudo is set up passwordless as well, so the poor user isn't bothered with typing in his password again to become root...
Oh, and I absolutely hate documentations or "how-tos" that are written with sudo-code - seriously: are there "Admins" out there typing 'sudo' hundreds of times a day? It's not added security, you just have to type type more and added a huge attack surface to your root account...
 
Notice: "read the password from the standard input", are you kidding me? :eek:

Oh, and I absolutely hate documentations or "how-tos" that are written with sudo-code - seriously: are there "Admins" out there typing 'sudo' hundreds of times a day? It's not added security, you just have to type type more and added a huge attack surface to your root account...

sudo can function as an interactive su replacement, but it's intended purpose was to enable limited privilege escalation in scripts. You're supposed to create a user without a login shell and configure sudo to allow that user to run a single process that requires root privileges. It's useful for things like automated full-system backups, where a read-only process still requires escalation to read every file.

The popularity of Ubuntu has led to a whole generation of *nix users that type sudo <command> same way some people reflexively click "Yes" when a UAC dialog pops up: just an extra annoyance that gets ignored. But that's not what it was made for, and if it's used in a limited capacity it can be fine.

That said, even a relatively reputable operation like DigitalOcean can abuse sudo in the stupidest way.
 
Contrary to others, my systems allow root access using only public/private key authentication. So, only people with the correct key will be able to login as root. Of course there are other levels of protection like VPN's or a firewall that will allow certain IP addresses to access the machine. I never liked sudo because it has many gotchas.
 
OK: It does seem that everyone (including me) is of the opinion that over-use of sudo is a bad idea, in particular where it is used to allow non-privileged users to do anything root can do (at which point you might as well log in as root and get on with life).

And it seems that su does read its password from the tty device, not from stdin. That's good. So getting back to my original question, about the trojan horse su exploit: At least the user will have to type the password twice into a trojan horse, which will perhaps (?) give them a clue that something is wrong (but no guaranteed that they're paying attention, after all sometimes one does really mistype a password, and at that point it is too late and the password has already been stolen). There is no other method to prevent the bad su hack from happening in the first place?
 
There is no other method to prevent the bad su hack from happening in the first place?
Dozens of methods.

For example don't put ~/bin (or any other user directory) in your PATH and additionally sign your shell profile and check said signature during its execution (so the moment someone messed with your profile (to change the path) you'd get a warning).

Create an alias for su which points to /usr/bin/su and use that to execute it. Optionally you can define this alias in a script outside your main profile ('security through obscurity' though).

Set up your own su2 file which also directly points to the original and is located 'somewhere else', maybe /usr/local/sbin/su2. An attacker might target su but won't know you don't use that to begin with. This file could be a simple symlink (though that might be too obvious) or a shell script which only root and a specific group (wheel would be my choice) can read.

Only allow su usage on specific (local) consoles. This could be very user-unfriendly but if you allow your users to keep a tmux (or screen) session then you might be able to set it up so that they can only use su from within that specific session. Might not be very useful but it would be secure.

Disallow file execution from /home entirely but do allow it from another remote location (your average script kiddie won't be able to find out, though this is once again 'security through obscurity').

And there might be more ideas which I haven't thought of yet ;)
 
Well if you are that paranoid, then do not share the root password with anyone. Which means that su is useless, like in the systems I manage.
 
I really like the opensolaris/illumos approach to this problem by role based access control. There is no actual user root, but the role can be assigned to specific users, which then can elevate their privilege with su by entering their own password.
Instead of using the full root privileges, theres also the administrative role, which is allowed to do most/all administrative day-to-day tasks, but most commands that can actually hose a system still require root privileges. Privileged commands have to be prefixed with pfexec.
It takes a while to get used to this approach and managing/delegating the roles, but I started to like it on our SmartOS hosts, as you can really easy add or remove privileges from users and never have to give away any sensitive password. In fact you could set an insanely long/complicated root password and put it in a safe, as it isn't needed during normal operations anymore... Its especially handy for scripting or automation, because you can easily add a distinct user for everything, apply a role to it and never have to use a sensitive password/key in any configuration file. In case of fire, just remove the role from the user (or the whole account).


Oh, and to add some insult to injury on sudo:
http://seclists.org/fulldisclosure/2017/Jun/3
 
Back
Top