Privilege Escalation · beginner · ~10 min
**What you will learn** - Define privilege escalation and distinguish **vertical** (higher privilege) from **horizontal** (sideways to a peer account) movement. - Explain why privesc is **enumeration-driven** — you hunt misconfigurations, you rarely write an exploit. - Recognise the one recurring pattern behind nearly every technique: *high-privilege code trusting something a low-privilege user controls.* - Read your own identity and privileges safely (`id`, `whoami /priv`, `sudo -l`) and reason about what each result means. - Apply the inverse **defensive** view: least privilege, safe trust boundaries, and the logs that reveal escalation attempts. - Set up a legal, isolated lab and follow an authorization checklist before running any check.
Security objective. The asset we are protecting is the privilege boundary on a host — the line between a normal, low-privileged user and a powerful account like root on Linux or SYSTEM/Administrator on Windows. The threat is an attacker (or malware, or a compromised service) who already has a low-privileged foothold and wants to cross that line to read every file, install persistence, or pivot deeper into the network. In this lesson you learn to detect and reason about the misconfigurations that let that happen — and, more importantly, how a defender prevents and logs them.
What privilege escalation is. It turns limited access into control. You start as an ordinary user and end as an administrator. It is almost always the step right after an initial foothold: a phished login, a web-app bug, a reused password. The foothold gets you in; escalation gets you power.
Two directions.
alice to bob), often to reach data or to set up a later vertical jump.Why it is enumeration-first. Most escalation is not a memory-corruption exploit. It is finding a misconfiguration — a writable file a root job trusts, a sudo rule that is too broad, a password left in a script. So the dominant skill is systematic enumeration: methodically asking who am I, what do I control, what trusts it?
How this connects to your prereqs. You already studied Files, directories, and permissions — read/write/execute bits, owners, and the setuid bit. Privesc is that knowledge weaponised for review: a world-writable file owned by root is no longer trivia, it is a finding. You also studied The Windows privilege model: UAC and tokens — integrity levels, access tokens, and privileges like SeImpersonatePrivilege. Privesc is where those tokens become the thing you enumerate. This lesson is the map; the next lesson, Linux privesc: sudo and SUID binaries, is the first concrete technique.
In authorized professional work — penetration tests, red-team engagements, and internal security reviews — privilege escalation is the near-universal second phase. A report that says "we phished one user" is far less impactful than "...and from that single low-privileged user we reached Domain Admin because of three misconfigurations." Escalation is what demonstrates real business risk to a client.
It matters because it is overwhelmingly about configuration, not exploits. That is good news for defenders: the same misconfigurations that let an attacker escalate are findable and fixable before anyone attacks. A blue-team engineer who understands the enumeration mindset can run the same checks and remediate the writable service binary, tighten the sudo rule, and delete the plaintext credential — closing the door proactively.
One lens ties the dozens of techniques together: high-privilege code that trusts attacker-controlled input. Once you carry that lens, the techniques stop feeling like a random checklist and become instances of a single idea — which is exactly what makes both attacking (in a lab) and defending (in production) systematic instead of lucky.
Finally, this is a foundational skill for hardening, compliance, and incident response. When an incident responder asks "how did they get from a web shell to root?", the answer is almost always a privesc path that should have been caught by a review.
This lesson is conceptual: it builds the mental model the rest of the track hangs on. Each concept below has a definition, a plain explanation, how it works, when it applies, and a pitfall.
chmod mistake beats an exploit almost every time.| Vertical | Horizontal | |
|---|---|---|
| Direction | Up a privilege level | Sideways, same level |
| Example | user → root/SYSTEM |
alice → bob |
| Typical goal | Full control of the host | Reach another user's data, or stage a later vertical jump |
| Detection signal | A low-priv account suddenly running root actions | Access to files/sessions of an unrelated peer |
sudo group). TRUST BOUNDARY (privilege line)
LOW PRIVILEGE | HIGH PRIVILEGE
---------------- | -------------------------------
Attacker as | root cron job
local user --->| SYSTEM service <-- ASSETS: root/SYSTEM
(the foothold) | setuid-root binary control of the host,
| | scheduled task all files, persistence
| |
ENTRY POINTS the low side controls that the high side trusts:
* a world-writable file the root job reads/executes
* a script on a PATH the root job searches
* an over-broad sudo rule ( user may run X as root )
* a credential left in a config/history/env variable
* a service binary the user can overwrite
Attack = supply malicious input across the boundary.
Defense = least privilege + validate/refuse untrusted input
+ LOG every privileged action and every denial.
Knowledge check.
sudo/auth logs, process-execution auditing, and file-integrity alerts on privileged binaries — covered in the safety section.)The core of enumeration is a handful of read-only, lab-safe identity commands. None of these change the system; they answer "who am I and what am I trusted to do?" Run them only in your own lab.
# Linux — read-only identity checks
id # your UID/GID and group memberships (are you in sudo/adm/docker?)
whoami # current username
sudo -l # what may THIS user run via sudo (prompts for YOUR password)
groups # group list, shorthand for the groups in id
:: Windows (PowerShell / cmd) — read-only identity checks
whoami /priv # your token's privileges (look for SeImpersonatePrivilege etc.)
whoami /groups # group SIDs and integrity level
whoami /user # your account SID
Annotated: sudo -l is the single most valuable Linux enumeration command — it prints exactly which commands your account may run as another user, revealing over-broad rules. On Windows, whoami /priv reveals dangerous enabled privileges. Reading this output is enumeration; acting on a finding is the actual escalation and must stay inside the lab.
Privilege escalation turns a limited foothold — a low-privileged user — into a powerful one: root on Linux, SYSTEM or admin on Windows. It is almost always the step right after gaining initial access.
Most privilege escalation is not a memory-corruption exploit. It is finding a misconfiguration — for example:
So the dominant skill is systematic enumeration. Work through questions like these:
id, whoami /priv)Automated helpers (LinPEAS and WinPEAS, conceptually) sweep these checks for you. But understanding why each check is dangerous is what lets you act on the output.
Every technique in this track is one shape of the same idea: a low-privileged user controls something a high-privileged context trusts. Find that, and you escalate.
The defenses are the inverse:
The example is conceptual (this is a concept-track lesson): a tiny, self-contained lab misconfiguration showing the universal pattern, then the secure fix, then a verification that the fix rejects the abuse and still allows legitimate use.
A root-owned scheduled job that trusts a world-writable script. This is the classic "high-privilege code trusts a low-privilege-controlled resource."
# Setup, as root, INSIDE A THROWAWAY LAB VM/CONTAINER ONLY:
cat >/opt/report.sh <<'EOF'
#!/bin/sh
echo "nightly report: $(date)" >>/var/log/report.log
EOF
chmod 0777 /opt/report.sh # <-- THE BUG: world-writable
# root runs it on a schedule (simulate the trusted, privileged execution):
# * * * * * root /opt/report.sh
# A low-privileged lab user can now rewrite what root will execute:
echo 'id > /tmp/who_ran_me' >/opt/report.sh # legal ONLY in your own lab
# On the next run, root executes attacker-controlled content.
Why it works: the file is executed by root but writable by everyone. The privilege line is crossed because the trusted resource is attacker-controllable.
Remove the write capability of low-privileged users over anything a privileged context executes, and keep ownership with root.
# As root:
chown root:root /opt/report.sh
chmod 0755 /opt/report.sh # owner root may write; others read+exec only
# Store privileged scripts outside world-writable dirs; never 0777.
# REJECTS bad input: a normal user can no longer tamper.
$ whoami
labuser
$ echo 'evil' >>/opt/report.sh
sh: /opt/report.sh: Permission denied # expected: write is refused
# ACCEPTS good input: root's scheduled run still works.
$ sudo /opt/report.sh && tail -n1 /var/log/report.log
nightly report: <current date/time> # expected: legitimate run succeeds
# Audit check: confirm no privileged file is world-writable.
$ find /opt /usr/local -perm -0002 -type f -ls # expect: no output
Expected outcome. After the fix, the tamper attempt is denied (Permission denied), the legitimate scheduled task still runs, and the audit find returns nothing — the misconfiguration is closed and verified.
Walkthrough of the lab example above.
cat >/opt/report.sh <<'EOF' ... EOF — root creates a small script the scheduler will run nightly. This is the privileged context.chmod 0777 /opt/report.sh — the defect. 0777 = rwxrwxrwx: any user can write the file. The trusted resource is now low-privilege-controlled.* * * * * root /opt/report.sh — root executes the file on a schedule. Root never re-checks who last edited it; it simply trusts the path.echo 'id > /tmp/who_ran_me' >/opt/report.sh — the low-privileged lab user overwrites the file. Nothing has escalated yet; the payload is just sitting there.id proves the code ran with root's UID. The privilege boundary was crossed.Trace of the security-relevant state:
| Step | Actor | File writable by | Who runs it | Effective privilege of the payload |
|---|---|---|---|---|
| 1–2 | root | everyone (0777) |
scheduler as root | — (no payload yet) |
| 4 | labuser | everyone | — | payload staged |
| 5 | scheduler | everyone | root | root — escalation |
After the fix:
chmod 0755 — rwxr-xr-x: only the owner (root) may write. Others may read and execute but not modify.labuser's write returns Permission denied (abuse rejected); sudo /opt/report.sh still logs a report (legitimate use accepted); the find -perm -0002 audit returns nothing (no world-writable privileged files remain). The same pattern — remove the low-privileged control over the trusted resource — is the fix for the entire category.Real mistakes learners and teams make, and how to correct them.
WRONG: jumping straight to exploits / kernel 0-days. Why wrong: wastes time, is noisy, and misses the 90% of paths that are pure misconfiguration. Corrected: enumerate first (id, sudo -l, whoami /priv), map what you control, then act. Recognise/prevent: if you have not run identity checks yet, you are guessing.
WRONG: dismissing horizontal movement as unimportant. Why wrong: the peer account you ignored may be the one in the sudo or docker group — it is your vertical path. Corrected: treat every reachable account as a possible stepping stone. Recognise/prevent: always check the groups/privileges of any account you reach.
WRONG: trusting automated-scanner output blindly. Why wrong: LinPEAS/WinPEAS flag candidates; not every yellow line is exploitable, and a clean run does not prove security. Corrected: understand why each check matters and confirm findings manually. Recognise/prevent: if you cannot explain why an item is a risk, you cannot report it responsibly.
WRONG (defender): fixing one world-writable file and calling it done. Why wrong: the pattern usually repeats across cron, services, and PATH. Corrected: sweep the whole class (find ... -perm -0002, audit sudoers, review service binary permissions). Recognise/prevent: remediate the category, then re-verify with an audit command.
WRONG: testing on a system you do not own "just to look." Why wrong: unauthorized enumeration of privilege boundaries is illegal and unethical, even without a payload. Corrected: use your own lab VM/container or a sanctioned CTF; get written authorization for any real target. Recognise/prevent: no scope document, no testing.
When a lab check or a fix does not behave as expected:
sudo -l asks for a password you do not know. That is expected — it needs your password. In a lab, log in as a user whose password you set. Never attempt to bypass it on a real system.whoami /priv shows a privilege but it is Disabled. Disabled ≠ absent, but it also is not automatically usable. Note the state; do not assume an enabled capability.crontab -l / /etc/crontab), the script is executable, and the schedule field is valid. Add a line that appends a timestamp to a log so you can confirm it runs at all.ls -l and namei -l /opt/report.sh (a writable parent directory also lets a user replace the file even if the file itself is 0755). Directory permissions are a common blind spot.find -perm -0002 returns things you did not expect. That is the point — investigate each. Confirm whether a privileged context executes them.Questions to ask when a privesc reasoning task fails. Who executes the resource, and with what privilege? Who can write the resource or its parent directory? Does the privileged code use an absolute path or search PATH? Did I verify the fix both rejects abuse and accepts legitimate use?
Security & safety — detection and logging. This lesson has no C memory concerns; the equivalent discipline is making escalation visible and auditable.
What to log for every privileged action or denial:
Concrete sources that detect the patterns in this lesson:
sudo/auth.log (or journalctl _COMM=sudo) — every sudo invocation, including denials and "command not allowed" events.NEVER log: passwords, the contents of a sudo password prompt, session cookies/tokens, private keys, full credential files, or unnecessary PII. Log that an event happened and its decision — not the secret involved.
Which events signal abuse: a low-privileged account suddenly running many sudo commands or hitting repeated "not allowed" denials; a root-executed script whose hash changed outside a deployment; a normal user acquiring an unusual token privilege; execution of a shell from a service account.
How false positives arise: legitimate admins genuinely use sudo; deployment pipelines legitimately change scripts (so integrity alerts must be correlated with change tickets); backup or monitoring agents run as root by design. Tune by baselining normal behaviour and correlating with the correlation id and change records before escalating an alert — an alert is a lead, not a verdict.
Authorized use case. During a sanctioned internal penetration test, a tester lands a low-privileged web-app foothold. Enumeration (id, sudo -l, a review of cron and service permissions) reveals a root cron job running a world-writable script — exactly the pattern in this lesson. The tester documents the path, demonstrates impact once in scope, and the report recommends chown root:root + chmod 0755 plus a file-integrity monitor. The blue team fixes it and re-tests. This is privesc used to drive hardening, not damage.
Professional best-practice habits:
PATH.sudo rules, never ALL.0755 and root-owned; secrets in a vault, never in config/history/env; drop privileges as early as possible.sudo, process execution, and integrity of privileged binaries; alert on the abuse signals above.Beginner vs advanced.
| Beginner | Advanced | |
|---|---|---|
| Focus | Read identity safely; recognise the one pattern; fix a single world-writable file and verify | Chain enumeration findings into a full path; automate category-wide audits; tune detection to cut false positives |
| Tooling | id, sudo -l, whoami /priv, ls -l |
auditd/Sysmon rules, FIM, sudoers policy review, CI checks that reject 0777 in privileged paths |
| Mindset | "What do I control that something trusts?" | "How do I make every crossing of the privilege boundary logged, least-privileged, and verified?" |
All tasks are lab-only — run them on your own throwaway VM/container or a sanctioned CTF. Authorization checklist before starting: (1) you own the machine or have written permission; (2) it is isolated (no production data, no third-party network); (3) you have a snapshot to restore; (4) you know the cleanup steps. Every task ends by remediating and verifying, never by leaving a hole open. Cleanup/reset: revert the VM snapshot, or undo each change (restore original permissions, remove test files, clear test cron entries) and re-run the audit command to confirm a clean state.
Beginner 1 — Read your identity.
id, groups, and sudo -l (Linux) or whoami /priv and whoami /groups (Windows). Write, for each output line, one sentence on why a defender would care.sudo/docker/adm, or an enabled SeImpersonatePrivilege.Beginner 2 — Classify the direction.
Intermediate 1 — Reproduce and fix the world-writable pattern.
0777 script (as in the lesson), confirm a low-priv user can rewrite it, then fix with chown/chmod. Input/output: before the fix a low-priv write succeeds; after, it returns Permission denied.find -perm -0002 -type f to confirm no siblings remain.Intermediate 2 — Detection.
auth.log/journalctl _COMM=sudo, or add an auditd execve rule / enable Windows 4688) and repeat the intermediate-1 scenario; capture the log lines that reveal the tamper and the privileged execution.Challenge — Mini enumeration report.
sudo -l, world-writable privileged files, a stored-credential grep of your own test config). Pick the single most impactful misconfiguration and write a finding: title, severity (justified by exploitability/access/impact — not automatically critical), affected component, preconditions, safe reproduction, evidence, impact, remediation, retest.API_KEY=<development-placeholder>); lab-only.Main concepts. Privilege escalation converts a low-privileged foothold into root/SYSTEM. It comes in two directions — vertical (up a level) and horizontal (sideways to a peer, often to unlock a later vertical jump). It is overwhelmingly enumeration-driven: you hunt misconfigurations, you rarely write an exploit. Every technique is one shape of a single pattern — a low-privileged user controls something a high-privileged context trusts — and its inverse is the defense: least privilege plus never trusting writable/low-integrity input in a privileged process.
Key commands (read-only enumeration). id, groups, sudo -l (Linux); whoami /priv, whoami /groups (Windows). The remediation pattern is chown root:root + a non-world-writable mode, verified with find -perm -0002.
Common mistakes. Reaching for exploits before enumerating; dismissing horizontal moves; trusting scanner output blindly (a clean scan does not prove security, and decoding is not verifying); fixing one file instead of the whole category; and — most importantly — testing anything outside a system you own or are authorized to test.
What to remember. Enumerate first. Find what you control that something privileged trusts. Fix by removing that control and applying least privilege. Verify the fix both rejects abuse and accepts legitimate use, and log every privileged action and denial. Nothing is ever "completely secure" — only better-hardened and better-monitored.