8

On a linux machine, a non-root user open a file,

$ sudo vi /etc/hosts

and quit saying :sh

to get root access.

1) With above, How a non-root user becomes a root user?

2) Why Linux allow such hacking approach to breach security?

overexchange
  • 1,536
  • 7
    Non-root users have that privilege because root gave it to them in the sudoers configuration files. If you have users on your system that you don't trust with such access, edit the sudoers files. See man visudo and man sudoers for more info. (As for why some distributions provides such privileges as a default, I'll leave that to someone else to explain/defend.) – John1024 Mar 10 '18 at 01:40
  • 8
    What am I missing that a non-root user has sudo vi access and you don't expect him to get root? It occurs to me that even if :sh didn't work getting root by opening vi or vi filename is easy. – Joshua Mar 10 '18 at 02:53
  • 6
    If they have access to sudo, they don't even need to go through Vi, they can just directly do sudo bash and, poof, root. "sudo" means "super user do"; if people have access to that, they may as well be root, because they can do anything root can. –  Mar 10 '18 at 04:15
  • 3
    Who configured sudo vi to be allowed without understanding they were giving the user full root privileges? – Charles Duffy Mar 10 '18 at 18:26
  • @NicHartley Instead of sudo vi /etc/hosts, let us say, sudo apt-get install emacs24 then I do not get root access, I do not get root access. How do I understand this? – overexchange Mar 11 '18 at 04:13
  • @overexchange Root access is given to apt. Installing software via package management on Linux requires root. What apt does with its root access is up to it, usually it installs software. Similarly, vi can do whatever it does. A much simpler way of becoming root with sudo is sudo su. Sudo is designed to give users temporary, limited root access, so if that's not what you want, don't. – timuzhti Mar 11 '18 at 10:59
  • @Alpha3031 I need temporary root access, yes. But, my question is, why sudo apt-get make me get root access, when I say whoami? Unlike sudo vi – overexchange Mar 11 '18 at 14:10
  • @overexchange apt does whatever software management and exits. The :sh command in vi opens a shell under whatever user spawned it. That's just what the commands do. You may as well ask why gksu xterm gives you a root terminal while gksu gedit doesn't. – timuzhti Mar 11 '18 at 14:58
  • 1
    @overexchange Because sudo command runs command as root. If that's the command bash, it starts a new terminal as root. If that's the command apt-get install emacs24, it runs apt-get with those arguments, and it runs it as root. –  Mar 11 '18 at 22:52
  • 1
    @Alpha3031 OK. sudo -l -U user1 has entry (root) NOPASSWD: /bin/vi /etc/hosts, but not (root) NOPASSWD: /bin/bash. But, am able to say :sh command in sudo vi /etc/hosts that open a shell under whatever user spawned it. Why :sh command allow launching /bin/bash with root? – overexchange Mar 12 '18 at 13:52
  • 1
    @overexchange Because vi, as root, is allowed to do anything it wants, and the users that launch it are allowed to whisper sweet nothings to it through stdin. Now, while something like ls or dir, they will happily ignore any input and get on with the job, vi will do anything the user wants. Why does gksudo xterm allow a sudoer to launch /bin/sh as root? Because those are things that users can do with vi and xterm. – timuzhti Mar 12 '18 at 14:46
  • User privilege limitations won't apply to programs launched with sudo, because once they're launched, they are root. Why is sudo apt allow to install software when user isn't? Why can sudo rm -rf /* allowed to remove files that the user definitely has no write permission for? Why does sudo vi launch what may as well be a root shell? Why does (a graphical extension of)-sudo xterm launch what is a root shell? Because the process launched by sudo runs as root. – timuzhti Mar 12 '18 at 14:59

2 Answers2

34

The non-root user became root as soon as they successfully ran sudo (given the assumed root target user); they started running vi as root. When you ask vi for a shell, it dutifully runs a shell, as the current user -- root! I should clarify that you should not "quit" vi with the :sh command, as that's asking for a shell. Quit with :q instead.

Linux allows such functionality because that's specifically what sudo is intended to do! Perhaps you've seen the lecture that sudo gives:

We trust you have received the usual lecture from the local System Administrator. It usually boils down to these three things:

#1) Respect the privacy of others.

#2) Think before you type.

#3) With great power comes great responsibility.

sudo offers a limited "speed bump" to this when it comes to granting "ALL" access, in the form of the ! negation operator, often demonstrated as:

jill        SERVERS = /usr/bin/, !SU, !SHELLS

where jill is granted permission to run programs from /usr/bin, but not anything listed in the SU or SHELLS aliases.

The sudoers man page has a whole "Security Notes" section when it comes to granting large-scale access via sudo and then trying to restrict it.

Limitations of the ‘!’ operator

It is generally not effective to “subtract” commands from ALL using the ‘!’ operator. A user can trivially circumvent this by copying the desired command to a different name and then executing that.

and

In general, if a user has sudo ALL there is nothing to prevent them from creating their own program that gives them a root shell (or making their own copy of a shell) regardless of any ‘!’ elements in the user specification.

and more pertinently:

Preventing shell escapes

Once sudo executes a program, that program is free to do whatever it pleases, including run other programs. This can be a security issue since it is not uncommon for a program to allow shell escapes, which lets a user bypass sudo's access control and logging. Common programs that permit shell escapes include shells (obviously), editors, paginators, mail and terminal programs

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
  • 1
    Thank you for including the "preventing shell escapes" bit. It's a lesser-known feature. You might want to include an example showing how to do a positive program restriction, rather than just warn against the negative cases; one way to show this is with the classic example of a "backup" group which is only allowed to run dump and tar. – Warren Young Mar 10 '18 at 04:29
  • 6
    @WarrenYoung if I can pass any arguments I want to tar then I can almost certainly use it to overwrite some files in a way that will give me more permissions. It's very hard to give someone "just a little bit" of root. – hobbs Mar 10 '18 at 07:29
  • 1
    @WarrenYoung Exactly as hobbs says. I would get root with a tar; you just replace passwd, the easiest way to do it. – Rui F Ribeiro Mar 10 '18 at 08:09
  • 1
    @RuiFRibeiro Or by replacing /etc/sudoers with a less restricted configuration. –  Mar 10 '18 at 09:46
  • 1
    @RuiFRibeiro: Or much less intrusively, by adding an suid-root program that starts a root shell. If you don't want everyone to be able to become root, put it inside a directory where only you have rwx permission on the directory. – Peter Cordes Mar 10 '18 at 20:31
  • 2
    @PeterCordes That´s more or less one of the ways I hacked a server at faculty in an age without much common sense. Then I played some harmless pranks with the classmates, and as the professors told you will be graded by computer time, stole all logins less than 2 minutes to my account. The professors knew...I was invited as sysadmin a couple of years later on for an associated organisation. – Rui F Ribeiro Mar 10 '18 at 21:27
16

If sudo vi /etc/hosts is successful, it means that the system administrator has allowed the user to run vi /etc/hosts as root. That's the whole point of sudo: it lets the system administrator authorize certain users to run certain commands with extra privileges.

Giving a user the permission to run vi gives them the permission to run any vi command, including :sh to run a shell and :w to overwrite any file on the system. A rule allowing only to run vi /etc/hosts does not make any sense since it allows the user to run arbitrary commands.

There is no “hacking” involved. The breach of security comes from a misconfiguration, not from a hole in the security model. Sudo does not particularly try to prevent against misconfiguration. Its documentation is well-known to be difficult to understand; if in doubt, ask around and don't try to do things that are too complicated.

It is in general a hard problem to give a user a specific privilege without giving them more than intended. A bulldozer approach like giving them the right to run an interactive program such as vi is bound to fail. A general piece of advice is to give the minimum privileges necessary to accomplish the task. If you want to allow a user to modify one file, don't give them the permission to run an editor. Instead, either:

  • Give them the permission to write to the file. This is the simplest method with the least risk of doing something you didn't intend.

    setfacl u:bob:rw /etc/hosts
    
  • Give them permission to edit the file via sudo. To do that, don't give them the permission to run an editor. As explained in the sudo documentation, give them the permission to run sudoedit, which invokes an editor as the original user and then uses the extra privileges only to modify the file.

    bob ALL = sudoedit /etc/hosts
    

    The sudo method is more complicated to set up, and is less transparent for the user because they have to invoke sudoedit instead of just opening the file in their editor, but has the advantage that all accesses are logged.

Note that allowing a user to edit /etc/hosts may have an impact on your security infrastructure: if there's any place where you rely on a host name corresponding to a specific machine, then that user will be able to point it to a different machine. Consider that it is probably unnecessary anyway.