When the Box Is Clean
The last note abused mistakes: a write bit in the wrong place.
This one is different. Here nothing is misconfigured, so you abuse the ways Linux is designed to let a program run as someone other than you.
Three mechanisms, three sections:
SUID binaries · sudo · the kernel itself.
The first two are features you turn against their owner. The last is a bug you exploit. All three end the same way: uid=0.
A Process Has Two Identities
Start with a puzzle. A normal user runs passwd to change their password. But passwd writes to /etc/shadow, a file only root can write.
So how does an unprivileged user change their own password?
The answer: a running process carries two user IDs.
| What it is | |
|---|---|
| Real UID | who launched the process (you, joe = 1000) |
| Effective UID | who it counts as when permissions are checked |
Normally they’re identical. But passwd carries a special flag, the SUID bit, that sets the effective UID to the file’s owner, root.
So while you launched it, passwd acts as root just long enough to edit /etc/shadow. Then it’s gone.
You spot the SUID bit in ls -l as an s sitting where the owner’s execute (x) normally is:
That
smeans “run as my owner, not as whoever launched me.” On a root-owned binary, that is a small, deliberate handover of root’s power.
Abusing SUID
Here’s the danger. A SUID-root binary is only safe if it cannot be talked into running your code. Plenty can.
The textbook case is find, which happens to have an -exec option and the SUID bit set. Then:
find runs as root, -exec launches a shell inside that root context, and the -p flag stops bash from dropping the effective UID. You land in a shell with euid=0.
The binary did exactly what it was built to do. The flaw was giving root’s identity to a program flexible enough to run anything.
Capabilities: SUID With a Scalpel
Full SUID-root is a sledgehammer: it hands over all of root’s power. Capabilities are the scalpel, they grant one specific privilege without full root.
A few examples:
| Capability | Grants the power to |
|---|---|
cap_net_raw | capture raw network traffic (e.g. ping) |
cap_net_bind_service | bind to privileged ports below 1024 |
cap_setuid | change its own UID, including to 0 |
That last one is as good as root. Hunt for capabilities across the system:
perl with cap_setuid can set its UID to 0 and hand you a shell:
A capability added for convenience becomes a root shell. The +ep on the end just means the capability is effective and permitted, switched on and usable.
GTFOBins: The Breakout Cheat Sheet
You don’t memorize these tricks. You look them up.
GTFOBins is a catalog of ordinary UNIX binaries and exactly how to abuse each one to break out to a shell, given SUID, sudo, or a capability.
Find a binary you can run with borrowed privilege, search its name on GTFOBins, and it hands you the precise command. find, perl, vim, tar, less, apt-get, the list is long, and it’s the single most useful reference in Linux privilege escalation.
Abusing sudo
sudo runs a command as another user (usually root), with the rules set per-user in /etc/sudoers. Your first move is to ask what you are allowed to run:
Now you check each allowed command against GTFOBins. A boring tool is still dangerous if it can spawn a shell. apt-get can:
apt-get changelog opens the changelog in a pager (less), and from inside a pager you can type !/bin/sh to spawn a shell, which runs as root because apt-get did.
The pattern never changes:
sudo -l→ look up each command on GTFOBins → break out.
One honest caveat, because the field isn’t frictionless:
A valid technique can still be blocked by another layer. The
tcpdumpsudo breakout above looks perfect, but on many systems AppArmor (a mandatory-access-control module that confines programs to a profile) deniestcpdumpthe right to execute your script. The command is “correct” and still fails. When a textbook escalation dies for no obvious reason, suspect AppArmor or SELinux.
Kernel Exploits: The Last Resort
When nothing is misconfigured, you attack the kernel itself. The payoff is the best there is, instant root, but it’s the same loaded gun as on Windows.
The workflow is precise, because a kernel exploit is built for one exact target:
1. Enumerate exactly. Kernel version, architecture, and OS flavor all have to match.
2. Find a match. Feed those details to a searchable exploit database:
3. Compile for the target. Use gcc, matching the target’s architecture. If the target has a compiler, build it on the target so the libraries line up:
A kernel exploit can crash the machine (a kernel panic). As with Windows, use exploits with source available so you can read them, test on a clone first, and respect the rules of engagement. Instability alerts admins faster than any alarm.
The Whole Climb
That closes Linux privilege escalation, and the escalation chapter with it. Step back and every technique across both operating systems was the same instinct:
Find something that runs with more power than you, and find the seam where you can influence it.
- a secret someone left behind
- a file you can write that something privileged runs
- a binary that borrows root’s identity: SUID, a capability, a sudo rule
- a bug in the kernel when nothing else gives
Windows or Linux, the security models differ completely, but the hunt never does. You look for the gap between what runs as root and what you can touch, and you climb through it.
Practice Boxes
- Linux PrivEsc - TryHackMe. A guided tour of nearly every vector here: SUID, sudo, capabilities, cron, and kernel exploits, on one box.
- Linux PrivEsc Arena - TryHackMe. A sandbox to drill each technique deliberately.
- Lin.Security - VulnHub. A box built entirely around misconfigured sudo, SUID, and capabilities.
- Shocker - HackTheBox. Foothold via Shellshock, then a clean
sudo perlbreakout straight to root.