On a linux machine, a non-root user open a file,
$ sudo vi /etc/hosts
and quit saying
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?
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
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.
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
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.