Hacker News new | past | comments | ask | show | jobs | submit login
/bin/false is not security (2005) (semicomplete.com)
110 points by jessaustin on Dec 28, 2017 | hide | past | favorite | 65 comments



I recall reading of one Unix implementation that when executing /bin/false noticed that the spawned shell (/bin/false) had failed (because that’s what /bin/false does, by design) and helpfully launched /bin/sh so you could debug it. True or false (pun intended), this is why I use /bin/true to stand in as a shell in this capacity.


Modern ssh implementations won't let a user with a shell that isn't in /etc/shells access via ssh.

Clearly you'll only be accepting public key authentication too.


This article is completely irrelevant and outdated. The only reason this works on Solaris because it is so ancient it predates the /etc/shells system.


the article it from 2005, you're not wrong.


Disable root authentication over ssh should be the default too. This is literally ssh 101.


I don’t really see the benefit of disabling root logon vs. allowing user login + sudo to root, if you only allow login via keypairs. This seems to me to be one of those cases where there might be some theoretical benefits, but those benefits don’t matter in practice.

Edit: I see several other people posted this while I was typing :)


I configured it so I can only sudo with my password. So even if someone gets hold of my private key, they'd have to guess my password for sudo access. Also, as someone pointed out you can restrict sudo commands, which is the sensible thing to do.


they'd have to guess my password for sudo access.

SSH to your account, add an alias to sudo in .bashrc (or equivalent for your shell) that records the password in a hidden file before passing it to the real sudo.


Is there a practical way to prevent this kind of attack? Also, what the name for this class of exploitation so I can read more?


I'm not security pro, but I think the best way is to use a separate account that you'd login to directly (on the physical TTY or via SSH) just to run the root commands. Going through your regular account is always more dangerous if you assume it might be compromised.

By the way, this is why Microsoft invented the UAC prompt: rather than a password, which can be intercepted, it generates a window which (presumably) cannot, thanks to User Interface Privilege Isolation.


Use the absolute path to any */sbin utilities :-)


Doesn't help much. Once the attacker took over the account, nothing you do or see can be assumed to be real.

For example, the attacker could inject a LD_PRELOAD library that redirects execve() calls from /usr/bin/sudo to a fake version of sudo.


You can't LD_PRELOAD on a SUID binary like sudo. That said, I agree with your main point - one should use a different account altogether.


I meant preloading it in the shell. The real /usr/bin/sudo would be never executed, so it wouldn't matter if it's suid or not.


How can you preload in the shell? Isn't it launched by sshd, which you can't configure?


You can't configure which shell is run, but you can usually configure the shell (in ~/.profile or a similar file).

Or, if the server is running Debian, you can set environment variables the .pam_environment file:

https://bugs.debian.org/761600


I don't think .profile runs before the shell is spawned, does it?

The .pam_environment one is interesting, thanks for the link.


You can still exec into a new shell, for example.


Well, let me explain to you it then.

It's a little bit of a mix of security through obscurity and security in event of sshd having the vulnerability. It won't save you from a targeted attack but will save from blanket "scan 22 port and try root" attacks.

The same way moving ssh from 22 port to something else helps. If you see someone brute-forcing your root you can dismiss it since it's just someone found open 22 port, but if your actual username is being used in attack then you can detect the targeted attack.

Now having password-less sudo is almost the same as using root.


it's not more secure/less secure if you enable root over pubkey only. I mean if I can login with a user that has sudo rights (probably with no password, the default on most cloud providers) there is no real benefit in having a user called ubuntu or centos that can login and gain full sudo rights than using root directly.


Some admins allow only certain command to be executed with sudo vs root can execute anything with root.


I have never seen anyone implement such a policy for sysadmins that actually prevents an attacker from running arbitrary commands. As soon as you permit running e.g. vi on some file, you can just shell out from vi. Or if you can sudo apt-get install, you can downgrade a package to a vulnerable version and then exploit it. Or if you can sudo tcpdump, you can write a dump file to /etc/cron.d and send a valid cron command surrounded by newlines over the network. Or lots of other things.

sudo is useful for allowing generally non-root users to run specific commands or better yet specific scripts (that they can't write to) with elevated privileges - e.g., letting someone "sudo systemctl restart apache2" but nothing else. But it's not particularly useful for auditing people that you want to have mostly-full control over the machine. It can keep honest people honest, sure, but so can .bash_history.


10+ years ago I was setting up a new web server, Apache running on a Linux box.

I was not in the sysadmin team, I was in the web team, so I was not allowed root access, even though the box belonged to the web team.

I asked for root access (via sudo) so I could do stuff like restart Apache.

The manager of the sysadmin team said no way was I getting full access to root, but I could get sudo to run specific commands.

So one of the sysadmins wrote a helper script to do the things I needed, and I could use sudo to run that script (and that script alone) as root.

I told him, it wasn't secure, I could use his helper script to get full root access. He challenged me to prove it.

So I wrote a program which dropped a setuid root shell in my home directory. I used the CustomLog directive in Apache to pipe Apache's logs to that program. Then I used his helper script to restart Apache.

When Apache started, it ran my program as root. I then used the setuid binary it had dropped to become root, and created a file in the sysadmin's home directory to prove it.

When I showed this to the sysadmin, he decided to abandon the helper script. Instead, he just told me the root password.


Shouldn't apache have been running under the "apache" user instead of root?


Apache starts as root so it can bind ports 80 and 443, then switches to the apache user. But the logging subsystem starts before the setuid to apache, so a piped CustomLog binary runs as root.

More secure options would be to use CAP_NET_BIND_SERVICE instead of root, or to make Apache bind an unprivileged port and then use something like iptables (or an external load balancer) to redirect 80/443 to the privileged ports. But, for reasons I can't quite recall (it was 10+ years ago) we didn't take up any of those more secure options.


When the binary in question is setuid, it doesn't matter what user runs it. It'll run as the owner and group of the file itself.


The setuid binary was created (indirectly) by the Apache CustomLog directive, which is able to spawn programs to use as log targets. So it matters which user Apache runs as, because that controls which user creates the setuid binary and thereby which privileges you can gain.


Rereading the comment it also seems more like Apache is starting something that can become root somehow, I really don't think it is implied Apache is running as root.


Apache usually starts up as root so it can do setup that requires root, and then drops privileges to a user/group specified in Apache configuration. Most commonly the required setup is just binding to privileged ports, but one of the supported setup steps is opening log pipes. See the security note here:

http://httpd.apache.org/docs/current/mod/mod_log_config.html...


By default, only root can bind to ports 80 and 443. You can change this policy, but that's considered unsecure because then any program can bind to the so called "privileged ports."


You can be more specific than that and allow only a specific user/program to bind a specific privileged port. This is accomplished with a combination of SELinux and the capabilities API in 2.6.24 and newer.


Even if you do that, I think Apache still starts as root to do things like open SSL certificates and log files (and logging configuration is the thing exploited here). Is there a common config - e.g. an initscript / systemd unit on an SELinux distro - that starts Apache as a dedicated user?

I know Apache supports being started as an unprivileged user (I do this myself a lot when I need something a little more featureful than SimpleHTTPServer) but my impression was that that's not very common for production deployments.


Or alternatively, rewrite incoming traffic with iptables, https://www.cyberciti.biz/faq/linux-port-redirection-with-ip...


On macOS an administrator (someone in the admin group) cannot create, delete, or move files in the system domain. That makes it harder to completely fuck up the computer, but as you say it won't really stop an attacker from running almost any arbitrary command.


Hopefully all admins does that. Never allow a user to run any command if you intend for them to run just one.

SSH public keys have the exact same feature however. Look at "command=" under "Authorized Keys File Format" in the man page. This is a good idea for batch jobs that uses SSH to execute on remote machines.

With SSH keys you even have the option of limiting keys not just to certain commands but to certain IP addresses. By limiting the SSH keys you also don't have to give your keys access to an unprivileged shell where you don't need it.


If the password used for the user, in the remote machine, is different from that of the machine he/she is connecting from, the attacker will not be able to gain root access, even if the account has permission to escalate priviledges.


The attacker can still do things like

- attach to an existing screen session that has an existing process under sudo inside it

- edit .bashrc to alias sudo to something that records the password, then come back later

- spawn a background process that waits for the user to run sudo, then opens the pty and uses TIOCSTI to type commands at it

Also, if the attacker actually has control over the sysadmin's local machine, they can do a lot more damage, like any of the above locally, or

- send an email from the admin's account to the team saying "Hi, I'm trying to run this command but I left my RSA token at home, can anyone help?"

- add a browser extension that rewrites all <pre> tags to include a https://thejh.net/misc/website-terminal-copy-paste -style attack

- commit to code or configuration-management repos adding a back door and trigger a deployment

None of these are technically difficult attacks. Requiring a separate sudo password might slow down a script kiddie, but that's about it.


Thanks, kind stranger. You taught even me some I didn't know!


I don't see how the authentication used for a user on a local machine has anything to do with the authentication of a user on a remote machine unless both are using the same domain authentication (RADIUS, Active Directory, etc). Even then, there can be cache involved.


There could be a local compromise that exposes the SSH keys (for login) but not the remote password (for sudo).


My parent comment indicates that the password needs to be different. Your comment does not support that.

First, sudo should not be cached for this very reason. Second, agent caching should never be enabled for this very reason. Third, agent forwarding should never be enabled for this very reason.

Indeed, using key authentication to log in and then using a password to upgrade to sudo is, I think, very reasonable.


> Indeed, using key authentication to log in and then using a password to upgrade to sudo is, I think, very reasonable.

which most often is not the default on vps/root/clouds, that's basically my point. if you use sudo, use it with a password.


what's wrong with public key auth as root? The "alternative" would be making a sudo-enabled login account. Another indirection, and probably not fully transparent...


If you have more than one person logging in, it's far easier to identify who did something as root by looking at the username that logged in.

Also far better to encourage running sudo for every command, gives a nice simple audit log of what happened, right there in your syslog, so you can identify and undo mistakes, and also eliminate lines of enquiry.

Clearly you can cover your tracks with the old sudo vi / !bash and similar tricks, but the goal isn't to protect against hostile privileges users, its to know what happened so that when John is on holiday you can see what he did to fix the problem you had last week.


If your sudoers policy allows you to run vi then you've already failed.

sudoedit(8) has been around for a long time and it solves this problem.


Failed at what? I want my sysadmins to have full access, I just want to know what they did. I'm not trying to defend against malicious staff members - I trust them, otherwise they wouldn't have sudo access.


If you can trust your administrators then you don't need to worry about shell escapes in editors.

The idea for sudoedit is that it allows you to allow non-root users to safely edit files, and if they shell out of their editor then they've not gained root rights - they edit a temporary file as a regular user and then sudo moves the file into place after it is edited.


Use of shared accounts eliminates individual accountability if humans are using them.

Unless you have an system with its own auth and audit capability connecting as root, shared accountability is bad. People do dumb shit, including illegal shit.


If you run any command it will run with the root privilege when you are root. It happened to me many times, where I ran a command and it asked for root then I investigated why the particular command needs root and figured that this is not what I want in the first place.

So, account with sudo capabilities is better than then one which is sudo by default.


In my personal opinion, there's nothing wrong with that, as long as key is not compromised, of course.

However, it's somewhat less secure than sudo-enabled account with password requirement. If your SSH key is somehow compromised (unpassworded keyfile or attacker had gained access to ssh-agent's socket, or you've ran a network-listening daemon from your account that had an exploitable RCE) you're a little bit more safe if attackers won't get root access. This only works well for noexec $HOME, of course, as attacker can't mess with your .*shrc and trick you into entering the password.


Back in 2005 it was standard for SSH servers to check /etc/shells. Maybe the RIT admins had put /bin/false in /etc/shells for some reason.


FWIW, I tried that DoS idea on a little digitalocean machine. It capped the number of open file descriptors for the SSH daemon at 1024. Only about 3000 file descriptors were in use after it stopped allocating channels, and file-heavy operations like apt-get still succeeded.


You'll probably hit the ulimit maximum file descriptors for the process. This might cause problems for the sshd process, or it might not since it might just hit the maximum for a process that's dedicated to your ssh connection.

It would take a lot more processes to hit the maximum for the entire system


SSH best priactices [0] says:

  - Use public key authentication
  - Encrypt your private keys
  - Check the Host keys
  - Use SSH Agent
  - Use a different key for every computer
  - Disable password authentication
  - Do not SSH cross-server
  - Use safe algorithms
  - Use agent forwarding at appropriate times
  - Use SSH certificates
  - Use a smartcard
  - Remove all system passwords
  - Use Two-factor Authentication
[0] https://blog.0xbadc0de.be/archives/300


Your list is almost entirely client hygiene and does not seem to have any connection to the priblems with port forwarding outlined linked article. Am I missing something?


IMO, that list puts the entire issue usefully in context.


fail2ban [1] would take care of this by automatically firewalling off IPs that fail to authenticate too frequently.

[1] https://www.fail2ban.org/


Would it? My understanding is the authentication worked just fine, it’s just spawning a shell that doesn’t. That could be intentional: eg for SFTP hosts or jump hosts.


Simple and straightforward article that exposes one of many usual misbehaviors of so called sysadmins these days: they think they know their tools, but haven't even completely read the manual for the programs they rely on production environments. Systems administration is something to be taken seriously; recently a friend of mine, that knows nothing about network perimeter security and didn't enforced adequate credentials on production environments, got a RANSOMWARE on a machine with a critical for business instance of a CRM database, chiefs on the organization refused to pay for the bitcoins asked, and probably my friend will be fired for incompetence; the infrastructure department personnel doesn't even have backups of such server, it's clear the information is lost forever.


"These days"? What you describe has happened for decades, though of course with different details.

You never knew about sys admins who put "." in the PATH for root? That was one of the warnings that I remember learning back in the early 1990s.

Remember the good old days when someone's .finger could be used for an escape sequence injection? Even if you read the manual for your terminal, that doesn't mean you change all your habits.

Or sys admins using "xhost +" for easy access to other machines in the local network?

And sys admins forgetting to do backups? That's certainly nothing new.


Early SGI systems, maybe as late as IRIX 5.x, actually shipped with "xhost +" as the default! I remember people putting these on the internet with no firewall (of course... this was the mid 90's) not realizing they could be key logged remotely...


I had a IRIX 5.x box and I remember having to do "xhost +". Which I did, because ... easy.


What you described is not a sysadmin, but a bad sysadmin instead. Also, if you look at the situation 'these days' it's not even a bad sysadmins, it's mostly developers who don't even really know how their computers or operating systems work, but they're allowed to build entire infrastructures using cloud/terraform/k8s/toy-of-the-week ;)


Nobody has time to read the manuals for everything, come on.


and what of those so called developers who wrote the code in the first place and never documented anything? :)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: