---
title: 'Privilege Escalation'
source: 'https://academia.sh/en/courses/introduction-to-linux/privilege-escalation'
course: 'Introduction to Linux'
language: en
updated: '2026-08-17T18:09:57+00:00'
license: 'CC BY-SA 4.0'
---

# 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.

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.
- `su` asks for the target account's password and delegates the whole session; `sudo` asks
  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 `PATH` and 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.
