Linux privesc decision tree
TL;DR. You have a Linux shell. This playbook turns the usually-overwhelming linpeas / lse output into a sequenced decision tree.
Step 1 — orient
flowchart TD
A[Shell as low-priv user] --> B[whoami; id; hostname; uname -a]
B --> C[Read /etc/os-release; sudo -V]
C --> D{Container or VM?}
D -- container --> E[Open container-escape-techniques branch below]
D -- VM / bare metal --> F[Standard enumeration]
F --> G[Run linpeas.sh / lse.sh; tee output for review]
Step 2 — easy wins first
flowchart TD
A[Enum results in hand] --> B{Any of these true?}
B -- "sudo -l shows ANY entry" --> C[Open sudo-misconfig]
B -- "SUID binaries with GTFOBins entry" --> D[Open suid-sgid-binaries]
B -- "Writable /etc/passwd or /etc/shadow" --> E[Open writable-passwd-shadow — instant root]
B -- "User in 'docker' / 'lxd' / 'disk' / 'shadow' group" --> F[Group → root path; see <a class="wikilink" href="/learnfromscratch/learn/topics/linux/linux-privesc-vectors/">linux-privesc-vectors</a>]
B -- "Cap-listed binary with cap_setuid+ep or cap_dac_read+ep" --> G[Open capabilities-privesc]
B -- "Mounted NFS no_root_squash share" --> H[Open nfs-no-root-squash]
B -- "Writable cron / systemd / init script as root" --> I[Open cron-jobs]
B -- "LD_PRELOAD env_keep in sudoers" --> J[Open ld-preload-abuse]
B -- "World-writable directory on root's PATH" --> K[Open path-hijacking]
B -- "None of the above" --> L[Step 3 — harder paths]
Step 3 — harder paths
flowchart TD
A[No easy win] --> B[Check kernel version vs known exploits]
B --> C{Kernel exploit looks viable?}
C -- yes --> D[Open kernel-exploits-linux; verify in lab first]
C -- no --> E[Check /var/backups, /home, /opt for creds]
E --> F{Credentials / SSH keys found?}
F -- yes --> G[su / ssh to another user; restart from Step 1]
F -- no --> H[Look at running processes — pspy]
H --> I{Root process accepting input you control?}
I -- yes --> J[Privesc via that process - input fuzz / file plant]
I -- no --> K[Step 4 — container / namespace surface]
Step 4 — container / namespace escape
flowchart TD
A[In a container] --> B[Check capabilities: capsh --print]
B --> C{CAP_SYS_ADMIN, CAP_DAC_READ_SEARCH, or CAP_SYS_PTRACE?}
C -- yes --> D[Open container-escape-techniques — release_agent / proc-mount]
C -- no --> E{Mounted host paths?}
E -- "/var/run/docker.sock" --> F[Open container-escape-techniques — docker.sock branch]
E -- "host /" --> G[chroot . sh — done]
E -- "/proc or /sys exposed" --> H[Specific escape per mount]
C -- "User namespace bug?" --> I[Open user-namespace-attacks]
Step 5 — pivot, don’t escalate
If you can’t root the box, sometimes the foothold is enough.
flowchart TD
A[Local escalation stuck] --> B{What does this user / box let you reach?}
B -- "Other hosts via SSH key reuse" --> C[Try, restart enum on new host]
B -- "Service the user owns" --> D[Compromise the service — config write, restart]
B -- "Cloud metadata reachable" --> E[Open ssrf-to-cloud / aws-instance-metadata]
B -- "Internal-only web service" --> F[Open web-triage]
B -- "Database with sensitive data" --> G[Document — sometimes the bug is data access]
Where to go next
- Got root → linux-enumeration for post-ex (creds, persistence).
- Got pivot creds → restart at Step 1 on the next host.
- Stuck and time-boxed → write up what you found; partial wins still count.
Anti-patterns
- Reading 40 GTFOBins entries before running
sudo -l. - Compiling a kernel exploit without a matching lab kernel first.
- Running aggressive enumeration scripts when the host has EDR — see ad-recon-low-noise for the principle.