Methodology — Phase 1

Recon & Enumeration

Discover every open port, hidden endpoint, and subdomain before touching the target. Good recon is the difference between missing a foothold and owning a box.

nmap rustscan gobuster ffuf wfuzz subfinder amass
Back to Home
Recon & Enum Initial Access Post-Exploitation
Table of Contents

Recon Workflow

01
Host Discovery

Ping sweeps & ARP scans to find live hosts on the network.

02
Port Scanning

Full 65535-port sweep, then targeted service + version scan.

03
Web Fuzzing

Directory, file, and extension brute-force on discovered services.

04
Subdomain Recon

Passive OSINT + active vhost fuzzing for hidden subdomains.

1. Network Scanning

Host Discovery
# Ping sweep — discover live hosts
nmap -sn 192.168.1.0/24 -oN host_discovery.txt

# ARP scan (more reliable on local network)
arp-scan --localnet
netdiscover -r 192.168.1.0/24
Step 1 — Full Port Discovery
Tip: Use --min-rate 1000 or lower on unstable/slow networks to avoid dropping packets and missing ports.
# Fast full-port scan — find all open ports
nmap -p- --open --min-rate 4000 192.168.1.10

# With output saved to file
nmap -p- --open --min-rate 4000 192.168.1.10 -oN full_portscan.txt

# Masscan — even faster (use before nmap)
masscan -p0-65535 192.168.1.10 --rate=10000 -oL masscan_out.txt

# Rustscan — auto-pipes into nmap
rustscan -a 192.168.1.10 -- -sV -sC -oN rustscan_out.txt
FlagDescription
-p-Scan all 65535 ports
--openOnly show open ports
--min-rate 4000Send ≥ 4000 packets/sec
-oNSave output in normal readable format
Step 2 — Targeted Service & Script Scan
# Targeted scan — SYN scan + version detection + default scripts
nmap -p 21,22,80,443,8080 -sS -sV -sC 192.168.1.10

# Save all output formats simultaneously
nmap -p 21,22,80,443,8080 -sS -sV -sC 192.168.1.10 -oA targeted_scan

# Add OS detection
nmap -p 21,22,80,443,8080 -sS -sV -sC -O 192.168.1.10

# Extract open ports from previous scan
grep "^[0-9]" full_portscan.txt | cut -d'/' -f1 | tr '\n' ',' | sed 's/,$//'
FlagDescription
-sSSYN scan — doesn't complete TCP handshake
-sVService + version detection
-sCRun default NSE scripts
-OOS fingerprinting
-oASave .nmap, .xml, .gnmap simultaneously
Useful NSE Scripts
# Vulnerability scan
nmap -p 80,443 --script vuln 192.168.1.10

# SMB enumeration
nmap -p 445 --script smb-enum-shares,smb-enum-users,smb-vuln-ms17-010 192.168.1.10

# HTTP enumeration
nmap -p 80,443 --script http-enum,http-title,http-methods 192.168.1.10

# FTP anonymous login
nmap -p 21 --script ftp-anon 192.168.1.10

# SNMP enumeration
nmap -p 161 -sU --script snmp-info,snmp-sysdescr 192.168.1.10

# MySQL empty password check
nmap -p 3306 --script mysql-info,mysql-empty-password 192.168.1.10

# RDP detection
nmap -p 3389 --script rdp-enum-encryption 192.168.1.10

# Banner grabbing
nmap -p 21,22,25,80,110,443 --script banner 192.168.1.10
Full Scan Workflow
# 1. Discover live hosts
nmap -sn 192.168.1.0/24 -oN host_discovery.txt

# 2. Full port scan on target
nmap -p- --open --min-rate 4000 192.168.1.10 -oN full_ports.txt

# 3. Extract port numbers
grep "^[0-9]" full_ports.txt | cut -d'/' -f1 | tr '\n' ',' | sed 's/,$//'

# 4. Targeted deep scan
nmap -p 21,22,80,443,8080 -sS -sV -sC -O 192.168.1.10 -oA targeted

# 5. Vuln scripts on web ports
nmap -p 80,443 --script vuln 192.168.1.10 -oN vuln_scan.txt

2. Web Content Discovery

Wfuzz — Directory & File Fuzzing
Tip: Use --hh <count> to filter responses by character count when status codes alone don't filter noise.
# Basic directory discovery
wfuzz -u http://$target/FUZZ --hc 404 -c -v -t 40 \
  -w /usr/share/seclists/Discovery/Web-Content/common.txt

# Large wordlist — broader coverage
wfuzz -u http://$target/FUZZ --hc 404 -c -v -t 40 \
  -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt

# Hide by character count
wfuzz -u http://$target/FUZZ --hh 402 -c -t 40 \
  -w /usr/share/seclists/Discovery/Web-Content/common.txt

# Fuzz with extensions
wfuzz -u http://$target/FUZZ.php --hc 404 -c -t 40 \
  -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt

# Multiple extensions simultaneously
wfuzz -u http://$target/FUZZ --hc 404 -c -t 40 \
  -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt \
  -z list,php-html-txt-bak-env-zip
FlagMeaning
--hc <code>Hide responses matching HTTP status code
--sc <code>Show only matching status code
--hh <chars>Hide responses with exactly N characters
--hw <words>Hide responses with exactly N words
--hl <lines>Hide responses with exactly N lines
--hs <regex>Hide responses matching body regex
Gobuster
# Standard directory scan
gobuster dir -u http://$target \
  -w /usr/share/seclists/Discovery/Web-Content/common.txt \
  -t 40 -o gobuster_common.txt

# Scan with multiple extensions
gobuster dir -u http://$target \
  -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt \
  -x php,html,txt,bak,env,zip,sql -t 40 -o gobuster_ext.txt

# HTTPS with insecure cert
gobuster dir -u https://$target \
  -w /usr/share/seclists/Discovery/Web-Content/common.txt \
  -k -t 40

# Recursive scan
gobuster dir -u http://$target \
  -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt \
  -r -t 40
FFUF — Fast Web Fuzzer
# Directory fuzzing
ffuf -u http://$target/FUZZ \
  -w /usr/share/seclists/Discovery/Web-Content/common.txt \
  -mc 200,301,302,403 -t 40

# File extension fuzzing
ffuf -u http://$target/indexFUZZ \
  -w /usr/share/seclists/Discovery/Web-Content/web-extensions.txt \
  -mc 200,301

# Filter by response size
ffuf -u http://$target/FUZZ \
  -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt \
  -fs 1234 -t 40

# POST parameter fuzzing
ffuf -u http://$target/login -X POST \
  -d "username=admin&password=FUZZ" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -w /usr/share/wordlists/rockyou.txt -fc 200 -t 40

# API endpoint discovery
ffuf -u http://$target/api/v1/FUZZ \
  -w /usr/share/seclists/Discovery/Web-Content/api/objects.txt \
  -mc 200,201,204 -t 40
Feroxbuster — Recursive Discovery
# Basic recursive scan
feroxbuster -u http://$target \
  -w /usr/share/seclists/Discovery/Web-Content/raft-large-files.txt -t 40

# With extensions and depth limit
feroxbuster -u http://$target \
  -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt \
  -x php,html,txt,bak,env --depth 3 -t 40 -o ferox_out.txt

# Filter specific status codes
feroxbuster -u http://$target \
  -w /usr/share/seclists/Discovery/Web-Content/common.txt \
  --filter-status 404,403 -t 40

3. Subdomain Enumeration

FFUF — Virtual Host Fuzzing
# Basic subdomain enumeration
ffuf -u https://FUZZ.example.com \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
  -H "Host: FUZZ.example.com"

# Filter by size to remove noise
ffuf -u http://example.com \
  -H "Host: FUZZ.example.com" \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
  -fs 0 -t 40

# Save results as JSON
ffuf -u http://example.com \
  -H "Host: FUZZ.example.com" \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt \
  -fs 1234 -t 40 -o ffuf_subdomains.json -of json
Passive Subdomain Enumeration (No Direct Contact)
# Subfinder — passive OSINT sources
subfinder -d example.com -o subfinder_out.txt
subfinder -d example.com -v -o subfinder_out.txt

# Amass — passive + active
amass enum -passive -d example.com -o amass_passive.txt
amass enum -active  -d example.com -o amass_active.txt
amass enum -brute   -d example.com \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt

# Assetfinder
assetfinder --subs-only example.com

# Certificate Transparency via crt.sh
curl -s "https://crt.sh/?q=%.example.com&output=json" | \
  python3 -c "import sys,json; [print(e['name_value']) for e in json.load(sys.stdin)]" | sort -u

# theHarvester
theHarvester -d example.com -b google,bing,yahoo,shodan -f harvester_out
DNS Enumeration
# dnsrecon
dnsrecon -d example.com -t std
dnsrecon -d example.com -t brt \
  -D /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt

# dnsx — fast DNS resolution
dnsx -d example.com \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
  -o dnsx_out.txt

# Manual DNS lookups
dig example.com ANY
dig example.com MX
dig example.com NS
dig example.com TXT
dig @8.8.8.8 example.com

# Zone transfer attempt (misconfigured DNS servers)
dig axfr @ns1.example.com example.com
host -t axfr example.com ns1.example.com
Gobuster DNS Mode
# DNS subdomain brute force
gobuster dns -d example.com \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
  -t 40 -o gobuster_dns.txt

# With specific resolver
gobuster dns -d example.com \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt \
  -r 8.8.8.8 -t 40

# Show IPs for discovered subdomains
gobuster dns -d example.com \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
  --show-ips -t 40
Recommended Workflow
# Step 1: Passive — no noise on target
subfinder -d example.com -o passive_subs.txt
curl -s "https://crt.sh/?q=%.example.com&output=json" | \
  python3 -c "import sys,json; [print(e['name_value']) for e in json.load(sys.stdin)]" \
  >> passive_subs.txt
sort -u passive_subs.txt -o passive_subs.txt

# Step 2: Resolve which are live
dnsx -l passive_subs.txt -o live_subs.txt

# Step 3: Active brute force
ffuf -u http://example.com -H "Host: FUZZ.example.com" \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt \
  -fs 1234 -t 40 -o ffuf_active_subs.json

# Step 4: Scan live subdomains
nmap -iL live_subs.txt -p 80,443,8080,8443 --open -oN sub_ports.txt

4. Wordlist Reference

Web Content Discovery
WordlistBest For
common.txtFast initial scan
directory-list-2.3-medium.txtMedium-depth dir brute
raft-medium-directories.txtMedium dir enum
raft-large-directories-lowercase.txtLarge lowercase list
big.txtLarge general-purpose
raft-large-files.txtExposed file discovery
raft-large-words.txtBroadest coverage
Subdomain & Passwords
WordlistBest For
subdomains-top1million-5000.txtFast subdomain scan
subdomains-top1million-20000.txtDeeper brute force
dns-Jhaddix.txtCommunity-compiled list
bitquark-subdomains-top100000.txtTop 100K subdomains
rockyou.txtPassword brute force
top-usernames-shortlist.txtCommon admin usernames
Get SecLists: git clone https://github.com/danielmiessler/SecLists /usr/share/seclists

Quick Reference

TaskToolKey Command
Full port scannmap-p- --open --min-rate 4000
Service version scannmap-p <ports> -sS -sV -sC
Aggressive scannmap-A -T4
Fast port scanrustscan-a <ip> -- -sV -sC
Ultra-fast port scanmasscan-p0-65535 --rate=10000
Directory bruteforcewfuzz-u http://target/FUZZ --hc 404
Filter by char countwfuzz--hh <count>
File discoverygobusterdir -x php,bak,env,git
Recursive discoveryferoxbuster--depth 3
Subdomain fuzz (vhost)ffuf-H "Host: FUZZ.domain.com"
DNS subdomain brutegobusterdns -d domain.com
Passive subdomainssubfinder-d domain.com
Certificate transparencycurlcrt.sh/?q=%.domain.com
Zone transferdigaxfr @ns1.domain.com domain.com
Live host discoverynmap-sn 192.168.1.0/24
ARP sweepnetdiscover-r 192.168.1.0/24
Home Initial Access