Sitemap

External Attack Surface Management (EASM): The professional industry level Reconnaissance Methodology. For Better understanding:

14 min readAug 18, 2026

--

https://www.reddit.com/r/Hacking_Tutorials/comments/1vqmj96/external_attack_surface_management_easm_the/

Dont know the proper way to publish (First post on Medium) if you want to read this in a proper way, use above link

External Attack Surface Management (EASM)

Professional Reconnaissance Methodology & Execution Plan

Table of Contents

Passive Reconnaissance (OSINT)

Active Reconnaissance & Subdomain Enumeration

Directory and File Enumeration

Data Synthesis & Attack Surface Mapping

Toolchain Summary

1. Passive Reconnaissance (OSINT):-

1.1 WHOIS & Domain Registration Intelligence

Goal: Identify registrant identity, registration timeline, registrar, and nameservers. Historical WHOIS data often reveals previously used infrastructure.

bash

# Current WHOIS
whois TARGET_DOMAIN
# Historical WHOIS (via CLI or web)
# Web: https://whoisology.com | https://who.is | https://domaintools.com
# Extract key fields
whois TARGET_DOMAIN | grep -iE "registrant|name server|creation|expiry|registrar|email"

What to extract:

  • Registrant name and email (may reveal person or org behind the domain)
  • Creation/expiry dates (old domains may have forgotten subdomains)
  • Nameservers (reveals DNS provider — Cloudflare? Route53? Self-hosted?)
  • Historical registrant data via DomainTools (pivotable to other domains owned by the same person)

1.2 DNS Record Enumeration

Goal: Map the full DNS footprint. Each record type reveals different infrastructure.

bash

# Full DNS record dump
dig TARGET_DOMAIN ANY +noall +answer
dig TARGET_DOMAIN A # IPv4 addresses
dig TARGET_DOMAIN AAAA # IPv6 addresses
dig TARGET_DOMAIN MX # Mail servers → reveals email provider
dig TARGET_DOMAIN TXT # SPF, DMARC, verification tokens, API keys
dig TARGET_DOMAIN NS # Authoritative nameservers
dig TARGET_DOMAIN CNAME # Aliases → reveals CDN, third-party services
dig TARGET_DOMAIN SOA # Zone authority → admin email, serial number
dig TARGET_DOMAIN CAA # Certificate authorities allowed to issue certs
# Using dnsx for bulk resolution
echo "TARGET_DOMAIN" | dnsx -a -aaaa -mx -txt -ns -resp -silent
# SPF analysis — identifies all authorized mail senders
dig TARGET_DOMAIN TXT | grep spf
# DMARC policy check — reveals email security posture
dig _dmarc.TARGET_DOMAIN TXT
# DKIM discovery (try common selectors)
for selector in google default mail dkim k1 selector1 selector2 smtp; do
dig ${selector}._domainkey.TARGET_DOMAIN TXT +short
done

Record interpretation table:

RecordWhat it revealsA / AAAAHosting provider, CDN, IP block ownershipMXEmail provider (Google Workspace? Exchange Online? Self-hosted?)TXT / SPFAll authorized mail senders — third-party services in useCNAMECDN usage (Cloudflare, Akamai, Fastly), third-party integrationsNSDNS provider — potential zone transfer targetSOAAdmin email, zone serial (useful for tracking DNS changes)CAAAllowed CAs — constrains cert issuance, useful for CT log filtering

1.3 ASN & IP Range Mapping

Goal: Identify the full IP space owned by or associated with the target organization. ASN discovery expands scope far beyond a single domain.

bash

# Find ASN from domain IP
whois $(dig +short TARGET_DOMAIN) | grep -iE "asn|origin|route|netname|orgname"
# Dedicated ASN lookup
curl -s "https://api.bgpview.io/search?query=TARGET_ORG_NAME" | python3 -m json.tool
# Enumerate all IP prefixes for an ASN
curl -s "https://api.bgpview.io/asn/AS[NUMBER]/prefixes" | python3 -m json.tool | grep prefix
# amass for ASN intelligence
amass intel -asn AS[NUMBER]
amass intel -org "Target Organization Name"
# Hurricane Electric BGP Toolkit (web)
# https://bgp.he.net/search?search[search]=TARGET_DOMAIN

What to do with IP ranges:

  • Feed ranges into Shodan: net:203.0.113.0/24
  • Feed into Masscan for fast port sweeps of the org’s entire address space
  • Cross-reference with abuse contacts for ownership confirmation

1.4 Certificate Transparency (CT) Log Analysis

Goal: Every TLS certificate ever issued for a domain is logged publicly. This reveals subdomains — including internal, staging, and development environments — that are never linked from public pages.

bash

# crt.sh — primary CT log search interface
curl -s "https://crt.sh/?q=%25.TARGET_DOMAIN&output=json" | \
jq -r '.[].name_value' | \
sed 's/\*\.//g' | \
sort -u | \
anew ct_subdomains.txt
# Exclude wildcard entries and clean output
curl -s "https://crt.sh/?q=%25.TARGET_DOMAIN&output=json" | \
jq -r '.[].name_value' | \
grep -v "^\*\." | \
sort -u
# subfinder with CT log sources enabled
subfinder -d TARGET_DOMAIN -sources certspotter,crtsh -silent -o ct_subfinder.txt
# certspotter CLI
certspotter TARGET_DOMAIN

Indicators of interest in CT results:

  • dev., staging., uat., test., preprod. — likely less hardened
  • vpn., remote., citrix., sslvpn. — remote access infrastructure
  • api., api-v2., graphql. — API attack surface
  • admin., portal., dashboard. — administrative interfaces
  • jenkins., gitlab., jira., confluence. — internal DevOps tools

1.5 Search Engine Dorking

Goal: Use advanced search operators to find content the target has accidentally exposed: sensitive documents, login portals, configuration files, error pages, and backup files.

Google Dork Categories

# Administrative and login interfaces
site:TARGET_DOMAIN inurl:admin
site:TARGET_DOMAIN inurl:login OR inurl:signin OR inurl:portal
site:TARGET_DOMAIN intitle:"admin panel" OR intitle:"control panel"
site:TARGET_DOMAIN inurl:dashboard
# Exposed sensitive files
site:TARGET_DOMAIN ext:env OR ext:config OR ext:conf
site:TARGET_DOMAIN ext:log OR ext:bak OR ext:old
site:TARGET_DOMAIN ext:sql OR ext:db
site:TARGET_DOMAIN filetype:pdf OR filetype:xlsx OR filetype:docx
# Exposed directory listings
site:TARGET_DOMAIN intitle:"index of"
site:TARGET_DOMAIN intitle:"index of /" "parent directory"
# Error pages that reveal internals
site:TARGET_DOMAIN intext:"Warning: mysql_fetch" OR intext:"ORA-01756"
site:TARGET_DOMAIN intext:"stack trace" OR intext:"exception"
site:TARGET_DOMAIN "PHP Parse error" OR "PHP Warning" OR "PHP Notice"
# Subdomains via site: operator
site:*.TARGET_DOMAIN -www
# API documentation
site:TARGET_DOMAIN inurl:swagger OR inurl:api-docs OR inurl:openapi
site:TARGET_DOMAIN intitle:"Swagger UI" OR intitle:"API documentation"
# Cached or removed pages
cache:TARGET_DOMAIN/sensitive-path
# Employee and contact information
"@TARGET_DOMAIN" site:linkedin.com
"@TARGET_DOMAIN" filetype:pdf

Bing-Specific Operators

# Bing sometimes indexes content Google doesn't
site:TARGET_DOMAIN filetype:xml
site:TARGET_DOMAIN ip:[IP_ADDRESS]

Reference: GHDB (Google Hacking Database) — thousands of categorized dorks by vulnerability class.

1.6 Threat Intelligence Platforms

Shodan:-

bash

# Install Shodan CLI
pip install shodan
shodan init YOUR_API_KEY
# Search by domain
shodan search "hostname:TARGET_DOMAIN"
# Search organization's IP space
shodan search "org:\"Target Organization\""
# Find all certs issued for domain
shodan search "ssl.cert.subject.cn:TARGET_DOMAIN"
# Find services on non-standard ports
shodan search "hostname:TARGET_DOMAIN" --fields ip_str,port,org,hostnames
# Specific technology searches
shodan search "hostname:TARGET_DOMAIN http.title:\"Grafana\""
shodan search "hostname:TARGET_DOMAIN product:\"Apache Tomcat\""

Censys

bash

# Install Censys CLI
pip install censys
censys config # enter API credentials
# Search by domain
censys search "TARGET_DOMAIN" --index-type hosts
# Find all certificates
censys search "parsed.names:TARGET_DOMAIN" --index-type certificates

GitHub OSINT & Secret Scanning

bash

# GitHub Dorking — search on github.com directly:
# "TARGET_DOMAIN" password
# "TARGET_DOMAIN" api_key OR apikey OR api_secret
# "TARGET_DOMAIN" secret_key OR secret
# "TARGET_DOMAIN" db_password OR database_password
# "TARGET_DOMAIN" AWS_ACCESS_KEY
# org:TARGET_ORG_NAME private OR internal OR secret
# filename:.env "TARGET_DOMAIN"
# filename:config.yml "TARGET_DOMAIN"
# truffleHog — scan GitHub repos for committed secrets
trufflehog github --org=TARGET_ORG_NAME --only-verified
# GitLeaks — scan specific repo
gitleaks detect --source=https://github.com/TARGET_ORG/REPO --report-path leaks.json
# gitrob — automated GitHub recon
gitrob analyze TARGET_ORG_NAME

Additional OSINT Sources

bash

# Wayback Machine — find historically exposed URLs
waybackurls TARGET_DOMAIN | tee wayback_urls.txt
# VirusTotal — passive DNS and subdomain data
curl -s "https://www.virustotal.com/vtapi/v2/domain/report?apikey=APIKEY&domain=TARGET_DOMAIN"
# AlienVault OTX — threat intel
curl -s "https://otx.alienvault.com/api/v1/indicators/domain/TARGET_DOMAIN/passive_dns"
# Pastebin / paste sites
# Search: site:pastebin.com "TARGET_DOMAIN"
# Search: site:ghostbin.com "TARGET_DOMAIN"
# LinkedIn for employee intel (via Google):
site:linkedin.com "TARGET_ORGANIZATION" (developer OR engineer OR devops OR security)
# Hunter.io — email format discovery
# https://hunter.io/domain-search/TARGET_DOMAIN

2. Active Reconnaissance & Subdomain Enumeration

2.1 Subdomain Enumeration — Full Pipeline

Goal: Maximize subdomain coverage by combining passive aggregation with active brute-forcing, then resolving and probing what’s actually live.

Step 1: Passive Aggregation (Multiple Sources)

bash

# subfinder — queries 50+ passive sources
subfinder -d TARGET_DOMAIN \
-sources shodan,certspotter,crtsh,virustotal,dnsdumpster,hackertarget \
-silent \
-o subfinder_out.txt
# assetfinder — fast, lightweight
assetfinder --subs-only TARGET_DOMAIN | tee assetfinder_out.txt
# amass passive mode — graph-based, comprehensive
amass enum -passive -d TARGET_DOMAIN -o amass_passive.txt
# Merge and deduplicate all passive sources
cat subfinder_out.txt assetfinder_out.txt amass_passive.txt | \
sort -u | \
anew all_passive_subs.txt

Step 2: Active Brute-Forcing

bash

# amass active brute-force
amass enum -active -brute -d TARGET_DOMAIN \
-w /opt/SecLists/Discovery/DNS/subdomains-top1million-20000.txt \
-o amass_brute.txt
# dnsx for fast brute-force resolution
dnsx -d TARGET_DOMAIN \
-w /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt \
-o dnsx_brute.txt
# puredns — extremely fast, permutation-aware
puredns bruteforce /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt \
TARGET_DOMAIN \
-r resolvers.txt \
-o puredns_out.txt

Step 3: Permutation Generation

bash

# gotator — generates intelligent permutations from found subdomains
gotator -sub all_passive_subs.txt \
-perm /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt \
-depth 2 \
-silent | \
dnsx -silent -o permutation_subs.txt
# alterx — fast permutation engine (ProjectDiscovery)
cat all_passive_subs.txt | alterx | dnsx -silent | tee alterx_out.txt

Step 4: Live Host Probing

bash

# Resolve all discovered subdomains
cat all_subs_combined.txt | dnsx -silent -a -resp -o resolved_subs.txt
# Probe for live HTTP/HTTPS services
cat resolved_subs.txt | httpx \
-silent \
-status-code \
-title \
-tech-detect \
-content-length \
-web-server \
-o live_http_hosts.txt
# Screenshot all live hosts
cat live_http_hosts.txt | gowitness file -f - \
--write-db \
--screenshot-path ./screenshots/
gowitness report generate

2.2 DNS Zone Transfer Attempts

Goal: A misconfigured nameserver may respond to AXFR requests, handing over the complete zone file — every subdomain and record in one response.

bash

# Identify authoritative nameservers
dig NS TARGET_DOMAIN +short
# Attempt zone transfer against each nameserver
dig axfr .TARGET_DOMAIN TARGET_DOMAIN
dig axfr .TARGET_DOMAIN TARGET_DOMAIN
# Automated zone transfer attempt with fierce
fierce --domain TARGET_DOMAIN
# dnsx zone transfer check
dnsx -d TARGET_DOMAIN -axfr

2.3 Reverse DNS Lookups

Goal: Given an IP range, discover hostnames that point to those IPs. Often reveals internal naming conventions and forgotten hosts.

Get Yahyamasoodi’s stories in your inbox

Join Medium for free to get updates from this writer.

bash

# Single IP reverse lookup
dig -x 203.0.113.10
# Reverse DNS on entire subnet with dnsx
dnsx -ptr -l ip_range.txt -resp-only -silent
# Masscan to find all live IPs in range first, then reverse lookup
masscan 203.0.113.0/24 -p80,443 --rate=1000 -oL masscan_results.txt
awk '/open/ {print $4}' masscan_results.txt | dnsx -ptr -resp-only -silent

2.4 Port Scanning

Goal: Map the full service exposure of discovered IP addresses. Optimize flags for the appropriate balance of speed, coverage, and stealth.

Strategy 1: Fast Wide Sweep (full port coverage)

bash

# Naabu — fastest option, Go-based, designed for recon pipelines
naabu -l resolved_ips.txt \
-port - \
-rate 1000 \
-silent \
-o naabu_open_ports.txt
# Pass results directly to Nmap for service detection
naabu -l resolved_ips.txt -port - -silent | \
nmap -sV -iL - -oA nmap_services

Strategy 2: Stealthy Nmap (minimal footprint)

bash

# SYN scan — half-open, less likely to be logged than full TCP
# -sS: SYN scan | -sV: version detection | -O: OS detection
# -T2: polite timing | --open: only show open ports
# -Pn: skip host discovery (assume up) | --randomize-hosts: vary order
sudo nmap -sS -sV -O -T2 \
--open \
--randomize-hosts \
-p- \
-Pn \
--defeat-rst-ratelimit \
TARGET_DOMAIN \
-oA nmap_stealth_full
# Fragment packets to evade basic packet inspection
sudo nmap -sS -f -T1 -p 80,443,22,8080,8443 TARGET_DOMAIN

Strategy 3: Targeted Service Nmap (post wide sweep)

bash

# After identifying open ports from naabu, run deep Nmap on those specific ports
# -sC: default scripts | -sV: version | -A: aggressive (OS + traceroute + scripts)
nmap -sC -sV -A \
-p 22,80,443,8080,8443,3306,5432,6379,27017 \
-T4 \
--open \
TARGET_DOMAIN \
-oA nmap_targeted
# Run specific NSE scripts for common services
nmap -p 445 --script smb-vuln-* TARGET_DOMAIN
nmap -p 21 --script ftp-anon,ftp-syst TARGET_DOMAIN
nmap -p 3306 --script mysql-info,mysql-empty-password TARGET_DOMAIN
nmap -p 27017 --script mongodb-databases TARGET_DOMAIN
nmap -p 6379 --script redis-info TARGET_DOMAIN

High-value ports to prioritize:

Port(s) ServiceWhy it matters22SSHDefault creds, old versions25, 587, 465SMTPMail relay, open relay check80, 443HTTP/HTTPSWeb application surface3306MySQLExposed without auth5432PostgreSQLExposed without auth6379RedisCommonly exposed, no auth by default27017MongoDBHistorically misconfigured with no auth9200, 9300ElasticsearchUnauthenticated data exposure5601KibanaAdmin UI, often no auth3000Grafana / Node appsDefault creds common8080, 8443Alt HTTP/HTTPSDev/staging apps2181ZooKeeperConfig data exposure9092KafkaMessage queue access5000Docker API / FlaskCode execution possible2375, 2376Docker daemonCritical — container escape389, 636LDAPDirectory services, enumeration3389RDPBrute force surface

2.5 Web Server Fingerprinting

Goal: Identify the technology stack — web server, framework, language, CMS, CDN — to inform vulnerability research and wordlist selection.

bash

# WhatWeb — CLI fingerprinting
whatweb -a 3 https://TARGET_DOMAIN # aggression level 3
# httpx with technology detection (ProjectDiscovery)
echo "https://TARGET_DOMAIN" | httpx -tech-detect -title -status-code -web-server
# Manual header inspection
curl -sI https://TARGET_DOMAIN | grep -iE "server:|x-powered-by:|via:|x-generator:|x-drupal|x-wordpress"
# TLS/SSL configuration analysis
# Check cipher suites, protocol versions, certificate chain
nmap --script ssl-enum-ciphers -p 443 TARGET_DOMAIN
openssl s_client -connect TARGET_DOMAIN:443 -servername TARGET_DOMAIN 2>&1 | head -30
# testssl.sh — comprehensive TLS analysis
./testssl.sh --quiet --severity MEDIUM TARGET_DOMAIN:443
# Nikto — web server misconfiguration scanner
nikto -h https://TARGET_DOMAIN -Format htm -output nikto_report.html

Technology detection interpretation:

FindingImplicationServer: Apache/2.4.49Known CVE-2021-41773 (path traversal)X-Powered-By: PHP/7.2EOL PHP, check for deserialisation, older vulnsX-Generator: Drupal 7Drupalgeddon — critical RCE vulnerabilityWordPress in HTMLCheck /wp-login.php, XML-RPC, user enumerationVia: CloudflareCDN in front — find origin IP via historical DNSNo X-Frame-OptionsClickjacking potentialNo Content-Security-PolicyXSS attack surface wider

3. Directory and File Enumeration

3.1 Technology-Driven Wordlist Selection

Core principle: Use wordlists matched to the discovered technology stack. Generic wordlists waste time; targeted lists find more in less time.

TechnologyRecommended WordlistGeneral / Unknownraft-large-directories.txtPHP appsPHP.fuzz.txtWordPresswordpress.fuzz.txtDrupalCMS/drupal.txtJoomlaCMS/joomla.txtApache Tomcattomcat.txtSpring Bootspring-boot.txtAPI endpointsapi/api-endpoints.txtBackup filesraft-large-extensions.txtConfig filesraft-medium-files.txt

All from: /opt/SecLists/Discovery/Web-Content/

3.2 ffuf — Fast Web Fuzzer

bash

# Basic directory brute-force
ffuf -u https://TARGET_DOMAIN/FUZZ \
-w /opt/SecLists/Discovery/Web-Content/raft-large-directories.txt \
-mc 200,301,302,403 \
-o ffuf_dirs.json \
-of json
# Filter by response size to remove false positives
ffuf -u https://TARGET_DOMAIN/FUZZ \
-w /opt/SecLists/Discovery/Web-Content/raft-large-directories.txt \
-mc 200,301,302,403 \
-fs [FALSE_POSITIVE_SIZE]
# File extension fuzzing (target PHP app)
ffuf -u https://TARGET_DOMAIN/FUZZ \
-w /opt/SecLists/Discovery/Web-Content/raft-medium-files.txt \
-e .php,.bak,.old,.backup,.sql,.log,.conf,.env,.git,.htaccess \
-mc 200,301,403 \
-o ffuf_files.json
# Virtual host discovery
ffuf -u https://TARGET_DOMAIN \
-H "Host: FUZZ.TARGET_DOMAIN" \
-w /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt \
-mc 200,301,302 \
-fs [DEFAULT_RESPONSE_SIZE] \
-o ffuf_vhosts.json
# API endpoint fuzzing
ffuf -u https://api.TARGET_DOMAIN/api/v1/FUZZ \
-w /opt/SecLists/Discovery/Web-Content/api/api-endpoints.txt \
-mc 200,201,401,403 \
-o ffuf_api.json
# Recursive fuzzing — follow found directories
ffuf -u https://TARGET_DOMAIN/FUZZ \
-w /opt/SecLists/Discovery/Web-Content/raft-medium-directories.txt \
-recursion \
-recursion-depth 2 \
-mc 200,301,302,403

3.3 Gobuster

bash

# Directory mode
gobuster dir \
-u https://TARGET_DOMAIN \
-w /opt/SecLists/Discovery/Web-Content/raft-large-directories.txt \
-x php,html,js,txt,json,xml \
-t 50 \
-o gobuster_dirs.txt \
--no-error
# DNS mode — subdomain brute-forcing
gobuster dns \
-d TARGET_DOMAIN \
-w /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt \
-t 50 \
-o gobuster_dns.txt
# VHOST mode
gobuster vhost \
-u https://TARGET_DOMAIN \
-w /opt/SecLists/Discovery/DNS/subdomains-top1million-5000.txt \
-t 30 \
-o gobuster_vhosts.txt

3.4 dirsearch

bash

# Smart detection with extensions
dirsearch -u https://TARGET_DOMAIN \
-e php,html,js,txt,json,xml,config,conf,bak,old,log,sql \
-w /opt/SecLists/Discovery/Web-Content/raft-medium-directories.txt \
-t 30 \
--format json \
-o dirsearch_out.json
# Recursive with max depth
dirsearch -u https://TARGET_DOMAIN \
-e php,html,txt \
-r \
--max-recursion-depth 3

3.5 High-Value File & Path Targets

Always check for these explicitly — they are among the most critical findings in web recon:

bash

# Exposed Git repository (critical — allows source code reconstruction)
curl -s https://TARGET_DOMAIN/.git/HEAD
curl -s https://TARGET_DOMAIN/.git/config
# If exposed, dump with:
git-dumper https://TARGET_DOMAIN/.git ./dumped_repo/
# Environment files (credentials, API keys, DB passwords)
curl -sI https://TARGET_DOMAIN/.env
curl -sI https://TARGET_DOMAIN/.env.local
curl -sI https://TARGET_DOMAIN/.env.production
# Backup and archive files
for ext in bak old backup zip tar.gz 7z; do
curl -sI https://TARGET_DOMAIN/backup.$ext
curl -sI https://TARGET_DOMAIN/TARGET_DOMAIN.$ext
done
# Configuration files
curl -sI https://TARGET_DOMAIN/config.php
curl -sI https://TARGET_DOMAIN/wp-config.php
curl -sI https://TARGET_DOMAIN/database.yml
curl -sI https://TARGET_DOMAIN/settings.py
curl -sI https://TARGET_DOMAIN/application.properties
# Cloud metadata (SSRF pivot target)
# Internal only — useful if SSRF is found:
# http://169.254.169.254/latest/meta-data/ (AWS)
# http://metadata.google.internal/ (GCP)
# http://169.254.169.254/metadata/ (Azure)
# Common sensitive paths
curl -sI https://TARGET_DOMAIN/robots.txt # reveals hidden paths
curl -sI https://TARGET_DOMAIN/sitemap.xml # all indexed pages
curl -sI https://TARGET_DOMAIN/crossdomain.xml # Flash policy files
curl -sI https://TARGET_DOMAIN/phpinfo.php # PHP config disclosure
curl -sI https://TARGET_DOMAIN/.DS_Store # macOS dir listing
curl -sI https://TARGET_DOMAIN/package.json # Node.js project details
curl -sI https://TARGET_DOMAIN/composer.json # PHP dependencies
# API documentation (unauthenticated access = critical)
for path in swagger swagger-ui.html api-docs openapi.json v1/api-docs api/swagger.json; do
curl -sI https://TARGET_DOMAIN/$path
done
# Admin panels
for path in admin administrator wp-admin phpmyadmin adminer.php manager/html; do
curl -sI https://TARGET_DOMAIN/$path
done

3.6 JavaScript Analysis for Hidden Endpoints

bash

# Extract all JS file URLs from a live site using katana
katana -u https://TARGET_DOMAIN -jc -d 3 -silent | grep "\.js$" | tee js_files.txt
# LinkFinder — extract endpoints from JS files
cat js_files.txt | while read url; do
python3 linkfinder.py -i "$url" -o cli 2>/dev/null
done | sort -u | tee js_endpoints.txt
# SecretFinder — hunt for hardcoded secrets in JS
python3 SecretFinder.py -i https://TARGET_DOMAIN -e -o js_secrets.html
# Manually review interesting JS endpoints found
grep -iE "api|secret|token|key|password|auth|admin" js_endpoints.txt

4. Data Synthesis & Attack Surface Mapping

4.1 Asset Inventory Matrix

Consolidate all discovered assets into a single structured format. This becomes the master reference for the engagement.

Recommended format (CSV / SQLite / Notion database):

AssetTypeIPPortsTech StackStatus CodeTitleSourcePrioritytarget.comApex domain203.0.113.1080,443Nginx, React200HomeDNSMediumapi.target.comSubdomain203.0.113.11443Node.js200API v2CT logHighdev.target.comSubdomain10.0.0.580Apache, PHP200Dev PortalCT logCriticaljenkins.target.comSubdomain203.0.113.158080Jenkins200JenkinsShodanCritical203.0.113.20IP—6379Redis——NmapCritical

Tool to automate this:

bash

# httpx with all fields → structured JSON
cat all_live_hosts.txt | httpx \
-json \
-status-code \
-title \
-tech-detect \
-web-server \
-content-length \
-ip \
-cname \
-silent \
-o httpx_full.json
# Convert JSON to CSV with jq
jq -r '[.url, .status_code, .title, .webserver, .ip, (.tech // [] | join("|"))] | u/csv' \
httpx_full.json > asset_inventory.csv

4.2 Target Prioritization Framework

Assign priority scores based on the attack surface risk profile.

Priority: Critical 🔴

Immediate investigation required — highest likelihood of impact

  • Staging / development environments (dev., staging., test., uat.)
  • Exposed DevOps tooling (Jenkins, GitLab, Jira, Confluence)
  • Unauthenticated APIs or API endpoints returning sensitive data
  • Exposed databases (Redis, MongoDB, Elasticsearch on public IPs)
  • Exposed .git, .env, phpinfo.php, or backup files
  • Administrative panels accessible without authentication
  • Services with known critical CVEs in detected version

Priority: High 🟠

Investigate within the first session

  • Login portals on non-production subdomains
  • APIs with HTTP (not HTTPS) — credential interception risk
  • Services on non-standard ports (Docker, Kubernetes API)
  • Old or unmaintained subdomains with outdated tech stacks
  • Third-party services with org SSO (pivot to main tenant)
  • Interesting JS endpoints pointing to undocumented API routes

Priority: Medium 🟡

Investigate systematically

  • Main production web application
  • Subdomains running known CMS (WordPress, Drupal)
  • Public-facing APIs with proper authentication
  • Missing security headers (CSP, HSTS, X-Frame-Options)
  • Interesting CORS policy configurations

Priority: Low 🟢

Document and note — revisit if high-priority paths exhaust

  • Static content delivery (CDN, S3 buckets with public read)
  • Informational pages with metadata leakage
  • SPF/DMARC misconfigurations (email security posture)

4.3 Correlation Workflow — Connecting the Dots

The most valuable findings come from correlating data across sources:

Step 1: Domain → WHOIS → registrant email
Step 2: Registrant email → other domains registered → expanded scope
Step 3: Domain → CT logs → subdomains → dev.TARGET_DOMAIN found
Step 4: dev.TARGET_DOMAIN → httpx → Apache/2.2 detected (EOL)
Step 5: Apache/2.2 → CVE database → multiple known vulnerabilities
Step 6: api.TARGET_DOMAIN → Shodan → port 8080 open
Step 7: Port 8080 → Nmap NSE → Jenkins 2.235 detected
Step 8: Jenkins 2.235 → nuclei → unauthenticated RCE template fires
Step 9: GitHub dorking → "TARGET_DOMAIN" api_key in commit history
Step 10: API key → test against discovered API endpoints → valid!

4.4 Visualization — Network Map

bash

# Generate a visual network graph with amass
amass viz -d TARGET_DOMAIN -o amass_graph.dot
dot -Tsvg amass_graph.dot -o attack_surface_map.svg
# Maltego (GUI) — import all discovered IPs/domains for link analysis
# Export amass results as JSON and import via Maltego import entities
# SpiderFoot — automated OSINT aggregation with web dashboard
spiderfoot -s TARGET_DOMAIN -t 4 -o report.html

4.5 Final Reporting Structure

recon_TARGET_DOMAIN/
├── 00_scope.txt # Defined scope and rules of engagement
├── 01_passive/
│ ├── whois.txt
│ ├── dns_records.txt
│ ├── ct_subdomains.txt
│ ├── shodan_results.json
│ └── github_findings.txt
├── 02_subdomains/
│ ├── all_subdomains.txt # Deduplicated master list
│ ├── resolved_subdomains.txt # Only DNS-resolvable
│ └── live_http_hosts.txt # Only responding to HTTP/S
├── 03_ports/
│ ├── naabu_all_ports.txt
│ └── nmap_service_scan.xml
├── 04_web/
│ ├── screenshots/ # gowitness output
│ ├── crawled_urls.txt
│ ├── js_endpoints.txt
│ └── js_secrets.txt
├── 05_content_discovery/
│ ├── ffuf_results.json
│ ├── interesting_files.txt
│ └── exposed_paths.txt
├── 06_analysis/
│ ├── asset_inventory.csv # Master asset matrix
│ ├── attack_surface_map.svg # Visual network graph
│ └── priority_targets.md # Prioritized finding list
└── 07_report/
└── recon_report.md # This document

5. Toolchain Summary

CategoryToolInstallPurposeSubdomain discoverysubfindergo install subfinderPassive, 50+ sourcesSubdomain discoveryamassapt install amassGraph-based, passive+activeSubdomain discoveryassetfindergo install assetfinderFast, lightweightDNS resolutiondnsxgo install dnsxBulk DNS, zone transferDNS brute-forcepurednsGitHub releaseFast, permutation-awarePort scanningnaabugo install naabuFast, pipeline-friendlyPort scanningnmapapt install nmapService detection, NSEHTTP probinghttpxgo install httpxBulk HTTP, tech detectScreenshotsgowitnessgo install gowitnessMass screenshots, galleryVulnerability scannucleigo install nucleiTemplate-based, fastCrawlingkatanago install katanaJS-aware, SPA supportURL collectiongaugo install gauHistorical URLsURL filteringgfgo install gfPattern-based filteringDirectory fuzzffufapt install ffufFast, flexible fuzzerDirectory fuzzgobusterapt install gobusterDNS + dir + vhostParam discoveryarjunpip install arjunHidden HTTP parametersJS analysisLinkFinderGitHub + pipEndpoint extractionSecret scanningSecretFinderGitHubAPI keys in JSSecret scanningtruffleHogpip install trufflehogGit secret scanningDeduplicationanewgo install anewAppend new lines onlyFull pipelinereconftwGitHub cloneOrchestrates ~50 toolsTLS analysistestssl.shGitHub cloneFull TLS auditOSINT aggregationspiderfootpip install spiderfootAutomated OSINT

End of Report — Replace [TARGET_DOMAIN] with the actual authorized target before execution.

--

--