Linux privilege escalation – techniques and hardening – Secured Me

Linux privilege escalation – techniques and hardening

How attackers escalate from a local user shell to root on Linux: SUID, capabilities, sudo, cron, and kernel – with the hardening that stops each one.

Once an attacker has a low-privileged shell on a Linux host — through a web app vuln, a phished SSH key, a leaked container token, or a compromised service account — privilege escalation to root or to another user is usually the next step. Linux has a rich set of mechanisms for delegating power (SUID binaries, capabilities, sudo, cron, systemd, NFS, containers), and almost all of them have well-known misuse patterns. Understanding what attackers look for, and the corresponding hardening, makes Linux hosts substantially harder to fully compromise.

Enumeration: what attackers look at first

Privilege escalation is mostly a hunt for misconfigurations. Tooling like linpeas, LinEnum, and pspy automates the enumeration, but the underlying questions are the same as those a careful sysadmin would ask:

GTFOBins (gtfobins.github.io) is the standard reference for "I can run X as root via sudo or SUID — how do I get a shell?" Almost every common Unix binary has at least one entry.

SUID, SGID, and capabilities

SUID binaries run with the file owner's privileges regardless of who invokes them. They exist for a reason (/usr/bin/passwd must update /etc/shadow), but a misconfigured or unnecessary SUID binary is one of the most common escalation paths. The classic pattern is something like /usr/bin/find with the SUID bit set, where find . -exec /bin/sh \; gives an immediate root shell. Anything in GTFOBins flagged for SUID misuse — vim, less, awk, python, perl, nmap (old versions), cp, tar — is an instant win if marked SUID root.

Capabilities are a finer-grained alternative to "all-or-nothing root", but they are equally dangerous when misused. capsetuid+ep on /usr/bin/python3 lets any user become root with a one-liner. capdacreadsearch lets the binary read any file on the system. Hardening:

Sudo, cron, and "trusted" scripts

The single most common Linux escalation vector is a misconfigured sudoers file. Specific anti-patterns:

Hardening: keep sudo rules minimal, prefer specific binaries with specific arguments, never grant NOPASSWD to shell-capable binaries, and review /etc/sudoers and /etc/sudoers.d/ regularly with visudo -c. Consider sudo replacements like doas for simpler audit.

Cron jobs and systemd timers are the other classic path. If a cron job runs /usr/local/bin/backup.sh as root and that script is writable by anyone, or sources files from a writable directory, you are one append away from root. The same applies to systemd unit files in writable paths. Always check:

pspy quietly watches for short-lived processes, and is invaluable for spotting cron jobs and timers from a low-privileged shell.

Kernel exploits and container escapes

When userspace misconfigurations are dead ends, attackers turn to the kernel. Old kernels accumulate exploitable CVEs (Dirty Pipe CVE-2022-0847, Dirty COW CVE-2016-5195, OverlayFS issues, nftables, iouring, eBPF verifier bugs). On unpatched systems, a public exploit and a few minutes of work is often enough to go from nobody to root.

Containers add another dimension. Even a "non-privileged" container can sometimes escape if:

Hardening at this layer: keep the kernel patched (or use live-patching like kpatch/livepatch), restrict who can read /proc/kallsyms and load kernel modules, disable unused subsystems where you can, run containers non-privileged with dropped capabilities and a seccomp profile, and never mount the Docker/Containerd socket into a workload.

A practical hardening baseline

You will not eliminate every escalation path, but a focused baseline catches most of them.

Most Linux compromises rely on something boring: a forgotten SUID binary, a sudo wildcard, a writable cron script, an unpatched kernel, or a developer-friendly container that turned out to be a foothold. Working through this list on every host and image you ship eliminates the great majority of those paths, and turns the rest into noisy, detectable events.