Lesson 15 / 20
Privilege Escalation
The superuser's privilege of bypassing checks, the difference between switching users and delegating privilege per command, the structure of a privilege-delegation policy, and the principle of least privilege.
Contents
The previous lesson rejected an ownership transfer with “Operation not permitted.” Some operations require root privilege — but logging in as root and working all day means every typo can affect the whole system.
This lesson covers how privilege is taken temporarily and narrowly. The subject is less about learning a command and more about applying a principle: the narrowest privilege needed for an operation, taken for the shortest time needed.
The Superuser
The account whose user ID is zero is the superuser. Its privilege comes from the kernel bypassing most permission checks for this identity: file permissions are not consulted, ownership can be changed, privileged network ports can be opened, file systems can be mounted.
The privilege is not unlimited. Even root cannot write to a filesystem mounted read-only, or to a hardware write-protected device. These are not permission checks, so they cannot be bypassed.
Working continuously as root has three concrete downsides.
Blast radius. A destructive command run in the wrong directory stays confined to an ordinary user’s own files; for root there is no boundary.
Audit trail. An action taken in a root session does not record which person did it. On systems with multiple administrators, this makes finding the source of a problem impossible.
Accidental permanent effect. Files created under root belong to root. A file created in a home directory while running as root leaves behind a remnant an ordinary user cannot access.
Most setups have no password defined for the root account and cannot be logged into directly. Privilege is taken by one of the two methods below.
Switching Users
The su command switches to a target user within the current session and opens a new
shell. Authentication asks for the target user’s password.
$ su - Password: su: Authentication failure
The leading dash matters: when given, the target user’s login environment is also set up —
home directory, PATH, and other environment variables are set to the target account’s.
Without it, the user changes but the environment stays the old user’s, which is a common
source of confusion.
The approach has two weaknesses. First, it requires sharing the root password; anyone who knows it can do anything, and it must be redistributed to everyone whenever it changes. Second, actions taken in the opened shell are not logged individually.
Delegating Privilege Per Command
sudo is a different model: the user is authenticated with their own password and runs
commands defined in a policy file with the authority of a defined account.
$ sudo id [sudo] password for student: uid=0(root) gid=0(root) groups=0(root)
The command ran with root identity. The password asked for belongs to student; the root
password is unknown and was not needed.
Authentication is cached for a while: a second command given shortly after, in the same
session, does not ask for the password again. The cache is cleared with sudo -k; in the
examples above this was done before each attempt.
Comparing the two models:
| Criterion | su |
sudo |
|---|---|---|
| Password asked | Target account’s | Own account’s |
| Scope | Entire shell session | Single command |
| Restrictable | No, full privilege | Command-level, by policy |
| Logging | Session-level | Command-level |
| Password sharing | Required | Not required |
Reading the Policy
Which commands a user can run can be asked directly:
$ sudo -l
[sudo] password for student:
Matching Defaults entries for student on host:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
use_pty
User student may run the following commands on host:
(root) /usr/bin/id, /usr/bin/chown
The last line is the policy’s core. The root in parentheses shows which account’s authority
the command will run with; what follows are the full paths of the permitted commands. This
user can run only two programs with root authority.
Policy lines have a general four-part shape: which user, on which machine, as which account, which commands. A group name can be written instead of a user; administrative privilege is most often granted through membership in a specific group. There is also a flag that allows running without a password prompt, used for automatically run jobs.
The policy file is not edited directly. A policy with a syntax error can leave no one on the system able to get privilege, so the file is edited with a dedicated tool that checks syntax before saving.
The Principle of Least Privilege
Keeping the policy narrow shows up directly on a command that is not permitted:
$ sudo cat /etc/shadow [sudo] password for student: Sorry, user student is not allowed to execute '/usr/bin/cat /etc/shadow' as root on host.
The principle of least privilege says every actor should be given the narrowest privilege needed to do its job. In practice this means listing specific commands in the policy instead of “all commands.”
The principle is harder to apply than it looks, because some commands look narrow but carry broad privilege.
Commands that can open a shell. Most text editors and pagers carry a feature for running commands from inside them. An editor allowed to run with root privilege is equivalent to handing over a root shell.
Commands with unrestricted arguments. In the policy above, chown’s argument is not
restricted; the user can change the owner of any file they choose, and so can transfer
ownership of system files to themselves. The policy looks narrow, but its effect is broad.
Commands that write files. A command that can write to any file with root privilege can add a line to the account file and create a new privileged user.
The question to ask when writing a policy is not “is this command harmful,” it is “can a root shell be obtained through this command.”
Cleaning the Environment
The env_reset and secure_path settings in the policy output are a quiet but critical part
of privilege delegation. The shadowing from the command path lesson would turn into an attack
right here:
$ printf '#!/bin/sh\necho fake identity\n' > /tmp/demo/id $ chmod +x /tmp/demo/id $ PATH="/tmp/demo:$PATH" $ id fake identity $ sudo id [sudo] password for student: uid=0(root) gid=0(root) groups=0(root)
In the user’s own session, the name id resolved to the fake program. Under privileged
execution, the real program ran: the delegation tool ignored the user’s PATH value and used
the safe list defined in the policy.
Without this, a policy of the form “may only run id” would mean nothing; the user would run
their own program named id with root privilege. Resetting environment variables rests on the
same reasoning: variables like a library search path can change a running program’s behavior
from the outside.
The same reasoning produces a good habit for ordinary users too: commands to be run with privilege are written with their full paths.
Summary
- The superuser bypasses most of the kernel’s permission checks; it does not bypass non-permission restrictions like a read-only mount.
- Working continuously as root enlarges the blast radius, destroys the audit trail, and leaves inaccessible remnants.
suasks for the target account’s password and delegates the whole session;sudoasks for its own password and grants privilege per command, restricted by policy.- A policy has four parts: user, machine, the account acted as, and permitted commands.
- Under the principle of least privilege, the criterion is not whether a command looks harmful, but whether a root shell can be obtained through it.
- The privilege-delegation tool resets
PATHand environment variables; otherwise the command name could be shadowed and the policy rendered ineffective.
Next Step
Privilege delegation was an externally configured way to run a command under a different
identity. The same effect has a form embedded directly in a file’s own metadata: the s in
the -rwsr-xr-x string seen in the users lesson. The next lesson closes the topic by covering
these three extra bits — two that change the identity a program runs as, and one that narrows
delete permission in directories.
To keep your progress and take notes, Log in
My notes
Log in to take notes.