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.
Ping sweeps & ARP scans to find live hosts on the network.
Full 65535-port sweep, then targeted service + version scan.
Directory, file, and extension brute-force on discovered services.
Passive OSINT + active vhost fuzzing for hidden subdomains.
# 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
--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
| Flag | Description |
|---|---|
-p- | Scan all 65535 ports |
--open | Only show open ports |
--min-rate 4000 | Send ≥ 4000 packets/sec |
-oN | Save output in normal readable format |
# 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/,$//'
| Flag | Description |
|---|---|
-sS | SYN scan — doesn't complete TCP handshake |
-sV | Service + version detection |
-sC | Run default NSE scripts |
-O | OS fingerprinting |
-oA | Save .nmap, .xml, .gnmap simultaneously |
# 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
# 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
--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
| Flag | Meaning |
|---|---|
--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 |
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
| Wordlist | Best For |
|---|---|
common.txt | Fast initial scan |
directory-list-2.3-medium.txt | Medium-depth dir brute |
raft-medium-directories.txt | Medium dir enum |
raft-large-directories-lowercase.txt | Large lowercase list |
big.txt | Large general-purpose |
raft-large-files.txt | Exposed file discovery |
raft-large-words.txt | Broadest coverage |
| Wordlist | Best For |
|---|---|
subdomains-top1million-5000.txt | Fast subdomain scan |
subdomains-top1million-20000.txt | Deeper brute force |
dns-Jhaddix.txt | Community-compiled list |
bitquark-subdomains-top100000.txt | Top 100K subdomains |
rockyou.txt | Password brute force |
top-usernames-shortlist.txt | Common admin usernames |
git clone https://github.com/danielmiessler/SecLists /usr/share/seclists
| Task | Tool | Key Command |
|---|---|---|
| Full port scan | nmap | -p- --open --min-rate 4000 |
| Service version scan | nmap | -p <ports> -sS -sV -sC |
| Aggressive scan | nmap | -A -T4 |
| Fast port scan | rustscan | -a <ip> -- -sV -sC |
| Ultra-fast port scan | masscan | -p0-65535 --rate=10000 |
| Directory bruteforce | wfuzz | -u http://target/FUZZ --hc 404 |
| Filter by char count | wfuzz | --hh <count> |
| File discovery | gobuster | dir -x php,bak,env,git |
| Recursive discovery | feroxbuster | --depth 3 |
| Subdomain fuzz (vhost) | ffuf | -H "Host: FUZZ.domain.com" |
| DNS subdomain brute | gobuster | dns -d domain.com |
| Passive subdomains | subfinder | -d domain.com |
| Certificate transparency | curl | crt.sh/?q=%.domain.com |
| Zone transfer | dig | axfr @ns1.domain.com domain.com |
| Live host discovery | nmap | -sn 192.168.1.0/24 |
| ARP sweep | netdiscover | -r 192.168.1.0/24 |