Recon Automation Skill
Overview
Systematic reconnaissance workflow for security assessments. Covers passive OSINT, active enumeration, secrets hunting, cloud asset discovery, and attack surface ranking. Integrates with industry-standard tools (subfinder, nmap, katana, trufflehog, cloud_enum, etc.) with graceful degradation when tools are missing. Results are persisted for reuse in subsequent hunting phases.
Money-Making Overview
Target buyer: CISOs, security teams, pentest firms, and DevOps leads who need to understand their external attack surface before attackers find the holes.
Service tiers:
| Tier |
Price |
What They Get |
| Basic — Attack Surface Scan |
$500 |
Automated subdomain enumeration, live host probing, tech stack detection, and secrets scan. One-time report for a single domain. Delivered in 48 hours. |
| Pro — Deep Recon Engagement |
$1,500 |
Everything in Basic plus full crawling (all URLs/params/endpoints), JS secrets extraction, cloud bucket discovery, origin IP bypass checks, and surface priority ranking. Includes 30-min call to walk through findings. |
| Enterprise — Continuous Attack Surface Monitoring |
$4,000/mo |
Weekly re-scans, change detection alerts, new subdomain/endpoint notifications, Slack integration, and quarterly executive briefings. Covers up to 5 domains. |
First-dollar timeline: First Basic report sold within 1 week of offering it to existing security contacts or local businesses. Pro deals close in 2-3 weeks. Enterprise contracts require a delivered Basic or Pro report as proof of work.
Delivery: Email PDF report or private Notion page. Payment via invoice (NET-15) or Stripe link.
When to Use
Trigger phrases:
"recon automation"
"Pre-engagement reconnaissance for bug bounty or pentest"
"Attack surface mapping for a target domain or organization"
"Asset discovery: subdomains, live hosts, cloud buckets"
Pre-engagement reconnaissance for bug bounty or pentest
Attack surface mapping for a target domain or organization
Asset discovery: subdomains, live hosts, cloud buckets
Subdomain enumeration and validation
Secrets leak detection across code repos, paste sites, and JS bundles
Cloud bucket discovery (S3, Azure Blob, GCP Storage)
Security audit preparation and scope inventory
Re-running recon after discovering new root domains or acquisitions
The Process
- Scope and authorize — confirm written authorization and define target boundaries
- Reconnaissance — enumerate targets, services, and potential attack surfaces
- Exploitation — attempt exploitation of identified vulnerabilities within scope
- Post-exploitation — document access level, lateral movement, and data exposure
- Report and remediate — compile findings with reproduction steps and fix recommendations
Step 1: Scope Validation
Verify the target is in-scope before any active or passive testing.
- Read program rules (bug bounty policy, ROE, pentest scope)
- Document authorization: who approved, what's in-scope, start/end dates
- Confirm target domains, IPs, CIDR ranges, and wildcards
- Identify explicit exclusions (e.g.,
*.cdn.example.com, production vs staging)
- Record scope in a local manifest file for reference during testing
Output: scope-manifest.json with authorized targets, exclusions, and authorization details.
Step 2: Passive Recon
OSINT gathering without sending traffic to the target.
- DNS records: A, AAAA, MX, NS, TXT, CNAME, SOA via
dig or dnsx
- WHOIS: domain registration, registrar, name servers, creation/expiry dates
- Certificate Transparency: crt.sh, CertSpotter for subdomains from TLS certs
- Google Dorking:
site:, inurl:, filetype:, intitle: for exposed pages and files
- Breach databases: HaveIBeenPwned, DeHashed for associated email/password leaks
- Code leaks: GitHub search (
org:target), GitLab, Pastebin, S3 bucket listings
- Social media / metadata: employee names, tech stack hints from job postings, LinkedIn
Fallback: If no OSINT tools available, use curl against public APIs (crt.sh, WHOIS).
Step 3: Active Recon
Direct interaction with target infrastructure. Respect rate limits.
- Subdomain enumeration:
subfinder -d target.com, amass enum -passive -d target.com, chaos -d target.com
- DNS resolution:
dnsx -l subdomains.txt -resp to filter live resolvers
- Port scanning:
nmap -sV -sC -T3 -iL live_hosts.txt (throttled), or masscan for fast sweep
- Service fingerprinting:
httpx -l subdomains.txt -title -tech-detect -status-code -follow-redirects
- Technology detection: Wappalyzer CLI, httpx
-tech-detect flag, WhatWeb
Fallback: Use curl -I for basic service fingerprinting if httpx unavailable. Use nc -zv for port checks if nmap unavailable.
Step 4: Web Crawling
Discover URLs, parameters, and endpoints from live web services.
- URL discovery:
katana -u target.com -d 3 -jc (with JS parsing), gospider -s target.com
- Wayback Machine:
waybackurls target.com for historical URLs and parameters
- Parameter extraction:
arjun -u target.com for hidden parameters, x8 for parameter fuzzing
- JavaScript analysis: extract API endpoints, tokens, and secrets from JS bundles
- robots.txt / sitemap.xml: parse for hidden paths and disallowed directories
- Endpoint mapping: categorize URLs by type (API, admin, auth, upload, static)
Fallback: Use curl + manual regex for robots.txt/sitemap.xml parsing.
Step 5: Secrets Hunting
Detect credential leaks and exposed sensitive data.
- JS bundle analysis: search for API keys, tokens, auth headers in minified JS
- Exposed files:
.env, .git/config, wp-config.php, .htaccess, config.json
- Git history:
trufflehog git https://github.com/org/repo, gitleaks detect, noseyparker scan
- API key patterns: regex for AWS keys (
AKIA...), Google API keys, Stripe keys, JWT secrets
- Hardcoded credentials: search for
password=, secret=, token=, apikey= in source
- Paste sites: search GitHub gists, Pastebin, Ghostbin for target-related leaks
Fallback: Use grep -rE with common secret regex patterns across downloaded files.
Step 6: Cloud Recon
Discover cloud-hosted assets and potential misconfigurations.
- S3 bucket discovery:
cloud_enum -k target, S3Scanner --list, brute-force bucket names
- Azure Blob:
cloud_enum -k target with Azure module, check <account>.blob.core.windows.net
- GCP Storage:
cloud_enum -k target with GCP module, check <project>.storage.googleapis.com
- CloudFlare bypass: find origin IPs via historical DNS (SecurityTrails), email headers, SSL certs
- CDN identification: identify CloudFlare, Fastly, Akamai, CloudFront from response headers
- Metadata endpoints: check
169.254.169.254 if SSRF is in-scope (only with authorization)
Fallback: Use curl to manually probe <bucket>.s3.amazonaws.com patterns.
Step 7: Surface Ranking
Prioritize discovered assets by potential value for security testing.
| Priority |
Asset Type |
Why |
| P0 |
Authentication endpoints |
Login, signup, password reset, SSO, OAuth flows |
| P0 |
API endpoints |
REST/GraphQL with user-controlled input |
| P1 |
File upload functionality |
Potential for RCE, stored XSS, path traversal |
| P1 |
Admin panels |
Higher privilege, often less hardened |
| P1 |
User-controlled input fields |
Forms, search, comments, profile fields |
| P2 |
Older/legacy endpoints |
Likely less maintained, more vulns |
| P2 |
Third-party integrations |
Webhooks, OAuth callbacks, iframe embeds |
| P3 |
Static assets |
Low value unless serving user content |
Output: surface-ranking.md with categorized, prioritized asset inventory.
External Tool Integration
Tools are optional. Each category has a fallback. Log missing tools and continue.
| Category |
Tools |
Fallback |
| Subdomain |
subfinder, amass, chaos, dnsx |
crt.sh via curl |
| Probing |
httpx, uncover |
curl -I |
| Crawling |
katana, gospider, waybackurls |
curl + regex |
| Parameters |
arjun, x8 |
Manual parameter discovery |
| Secrets |
trufflehog, gitleaks, noseyparker |
grep -rE with regex patterns |
| DNS/Takeover |
dnsReaper, subjack |
Manual CNAME checks |
| Cloud |
cloud_enum, S3Scanner |
curl bucket probing |
| Scanning |
nmap, masscan |
nc -zv for port checks |
Output Format
Structured asset inventory saved as markdown and JSON:
recon-output/
scope-manifest.json # Authorized scope
passive/
dns-records.md
subdomains-ct.md
whois.md
osint-notes.md
active/
live-hosts.txt
port-scan.md
technologies.md
crawling/
urls-all.txt
endpoints.md
parameters.txt
js-secrets.md
secrets/
leaked-credentials.md
exposed-files.md
git-leaks.md
cloud/
buckets.md
origin-ips.md
cdn-info.md
surface-ranking.md # Prioritized attack surface
recon-summary.md # Executive summary
Session Persistence
- Save all recon output to
recon-output/ directory per target
- Each step appends to its respective file; re-runs update, not overwrite
- Load previous results before re-running to avoid duplicate work
- Share output with hunting phase: reference URLs, secrets, and ranked targets
Incremental Recon
- Re-run specific steps as new information is discovered (e.g., new root domain from OSINT)
- New subdomains trigger re-run of Steps 3-4 (active + crawling)
- New live hosts trigger re-run of Steps 4-5 (crawling + secrets)
- Cloud findings trigger deeper cloud recon (Step 6)
- Track step completion timestamps in
recon-summary.md
First Action in 60 Minutes
Run this script against any target domain to produce a client-ready attack surface report. It enumerates subdomains, live hosts, technologies, and exposed secrets with zero config beyond a domain name.
#!/usr/bin/env python3
"""attack-surface-report.py — One-shot recon-as-service deliverable.
Usage: python3 attack-surface-report.py target.com client-name
"""
import json, subprocess, sys, os, urllib.request
from datetime import datetime
from pathlib import Path
domain = sys.argv[1]
client = sys.argv[2] if len(sys.argv) > 2 else domain
out = Path(f"recon-{domain.replace('.','-')}-{datetime.now().strftime('%Y%m%d')}")
(out / "evidence").mkdir(parents=True, exist_ok=True)
def run(cmd, timeout=60):
try: return subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)
except Exception as e: return type("R",(),{"stdout":"","stderr":str(e)})()
# Step 1 — Subdomains via crt.sh (no API key needed)
print(f"[1/5] Enumerating subdomains for {domain}...")
resp = urllib.request.urlopen(
f"https://crt.sh/?q=%25.{domain}&output=json", timeout=30
)
certs = json.loads(resp.read())
subdomains = sorted(set(e["name_value"] for e in certs if domain in e["name_value"]))
(out / "subdomains-all.txt").write_text("\n".join(subdomains))
print(f" Found {len(subdomains)} subdomains")
# Step 2 — Live host probing
print(f"[2/5] Probing live hosts...")
live = []
for sd in subdomains[:200]: # cap at 200
r = run(f"curl -s -o /dev/null -w '%{{http_code}}' --connect-timeout 5 https://{sd}")
if r.stdout.strip() not in ("", "000"):
live.append(sd)
(out / "live-hosts.txt").write_text("\n".join(live))
print(f" {len(live)} live hosts")
# Step 3 — Tech stack detection
print(f"[3/5] Detecting technologies...")
techs = {}
for h in live[:50]: # cap at 50
r = run(f"curl -sI --connect-timeout 5 https://{h}")
headers = r.stdout.lower()
detected = []
if "cloudflare" in headers: detected.append("Cloudflare")
if "nginx" in headers: detected.append("Nginx")
if "apache" in headers: detected.append("Apache")
if "server: gunicorn" in headers or "x-powered-by: python" in headers: detected.append("Python")
if "x-powered-by: php" in headers: detected.append("PHP")
if "x-powered-by: express" in headers: detected.append("Node.js/Express")
if "x-amz-id" in headers or "x-amz-request-id" in headers: detected.append("AWS")
if detected: techs[h] = detected
(out / "technologies.md").write_text(
f"# Technology Stack — {domain}\n\n" +
"\n".join(f"- **{h}**: {', '.join(t)}" for h, t in techs.items())
)
# Step 4 — Secrets scan in JS bundles
print(f"[4/5] Scanning for exposed secrets...")
secrets_found = []
patterns = {
"AWS Key": r"AKIA[0-9A-Z]{16}",
"Google API": r"AIza[0-9A-Za-z\-_]{35}",
"Stripe Live": r"sk_live_[0-9a-zA-Z]{24,}",
"Slack Token": r"xox[abp]-[0-9a-zA-Z\-]{10,}",
"JWT": r"eyJ[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}",
}
import re
for h in live[:20]:
r = run(f"curl -sL --connect-timeout 10 https://{h} 2>/dev/null | grep -oP 'src=[\"']([^\"']+\\.js)[\"']' | sed 's/src=[\"']//;s/[\"']//'")
js_urls = r.stdout.strip().split("\n") if r.stdout.strip() else []
for js in js_urls[:10]:
js = js if js.startswith("http") else f"https://{h}{js}"
r2 = run(f"curl -sL --connect-timeout 10 '{js}' 2>/dev/null")
for name, pat in patterns.items():
for m in re.finditer(pat, r2.stdout):
secrets_found.append({"type": name, "match": m.group(), "url": js})
if secrets_found:
(out / "secrets-found.json").write_text(json.dumps(secrets_found, indent=2))
# Step 5 — Attack Surface Report
print(f"[5/5] Generating report...")
total_endpoints = len(subdomains)
attack_surface_cats = {
"Total Subdomains": total_endpoints,
"Live Hosts": len(live),
"Technologies Detected": sum(len(v) for v in techs.values()),
"Secrets Found": len(secrets_found),
"High-Value Targets": sum(1 for h in live if any(
kw in h for kw in ["api", "admin", "login", "portal", "dashboard", "graphql"]
)),
}
report = f"""# Attack Surface Report — {client}
**Domain:** {domain} | **Date:** {datetime.now().strftime('%Y-%m-%d')}
## Executive Summary
Automated external reconnaissance identified {total_endpoints} subdomains, {len(live)} live hosts,
{len(techs)} technology fingerprints, and {len(secrets_found)} potential credential leaks.
## Attack Surface Overview
| Category | Count |
|----------|-------|
"""
report += "\n".join(f"| {k} | {v} |" for k, v in attack_surface_cats.items())
report += """
## Live Hosts (Top 20)
""" + "\n".join(f"- {h}" for h in live[:20]) + """
## Technology Stack
""" + "\n".join(f"- **{h}**: {', '.join(t)}" for h, t in list(techs.items())[:20])
if secrets_found:
report += "\n\n## Credential Leaks Detected\n"
report += "\n".join(f"- `{s['type']}` at {s['url']}" for s in secrets_found)
report += "\n\n## Recommendations\n"
report += "1. Investigate all leaked credentials immediately\n"
report += "2. Review exposed admin/api subdomains for unauthorized access\n"
report += "3. Harden technology stack — update versions, remove fingerprinting headers\n"
report += "4. Enforce authentication on all discovered login/portal endpoints\n"
report += "5. Schedule quarterly attack surface reassessment\n"
(out / f"attack-surface-report-{domain}.md").write_text(report)
print(f"\n[DONE] Report saved to {out}/attack-surface-report-{domain}.md")
# Output summary for the invoice
summary = {
"client": client, "domain": domain, "date": str(datetime.now().date()),
"tier": "Basic", "price": "$500",
"subdomains": total_endpoints, "live_hosts": len(live),
"tech_fingerprints": len(techs), "secrets_found": len(secrets_found),
}
(out / "invoice-data.json").write_text(json.dumps(summary, indent=2))
print(json.dumps(summary, indent=2))
Instructions:
- Save as
attack-surface-report.py
- Run:
python3 attack-surface-report.py example.com "Client Name Inc"
- Deliver the generated markdown report and invoice-data.json as your Basic tier deliverable
- Takes ~10-30 minutes depending on target domain size
Deliverable Format
Send the client a single PDF portfolio containing:
[CLIENT LOGO]
ATTACK SURFACE REPORT
[Client Name]
[Date]
Prepared by: [Your Name / Firm]
Engagement Type: External Reconnaissance (Basic / Pro / Enterprise)
---
SCOPE
- Domain(s): example.com, *.example.com
- Authorization: [Reference #]
- Date of scan: 2026-07-16
FINDINGS SUMMARY
- Subdomains discovered: 147
- Live hosts: 53
- Technologies identified: 8
- API/Admin endpoints: 12
- Credential leaks found: 3
- Open ports (average per host): 4
KEY RISKS
1. [Risk description — e.g., "3 exposed admin panels with no MFA"]
2. [Risk description — e.g., "AWS keys found in public JS bundle"]
3. [Risk description — e.g., "Legacy subdomain running EOL software"]
DETAILED FINDINGS
[Per-category breakdown with URLs, screenshots, evidence paths]
RECOMMENDATIONS
1. ...
2. ...
3. ...
---
INVOICE
Invoice #: INV-2026-XXXX
Amount: $500 (Basic) / $1,500 (Pro) / $4,000/mo (Enterprise)
Payment Terms: NET-15
Payment: [Stripe link or bank details]
When NOT to Use
- Task is outside your authorization scope
- You need to implement controls (use implementing-* skills)
- Task is about analysis, not action (use analyzing-* skills)
- You don't have access to target systems
- Task requires compliance expertise (consult professionals)
- Task is about defense, not offense (use defensive skills)
Red Flags
- Testing assets not explicitly listed in scope
- Aggressive scanning without throttling (
-T4/-T5 nmap, no rate limits)
- Ignoring
robots.txt disallow rules during crawling
- Excessive request volume causing degradation or DoS
- Scanning without documented authorization
- Not respecting program-defined rate limits
- Running credential-stuffing or brute-force attacks without explicit permission
- Testing production systems when staging is in-scope
Verification
- All discovered assets validated and categorized in output files
- Scope compliance verified: no out-of-scope hosts scanned or probed
- Tool outputs cross-referenced: subdomains from 2+ sources, live hosts confirmed
- Attack surface inventory complete with priority ranking
- Missing tools logged with fallback results documented
- Recon summary includes total counts per category and coverage gaps
Process
- Analyze the task requirements
- Apply domain expertise
- Verify output quality
Anti-Rationalization Table
| Rationalization |
Reality |
| "They will just say no" |
You are offering a paid service, not asking permission. Send the proposal. |
| "I need more certs to sell security work" |
One delivered report is worth more than 10 certifications. Ship it. |
| "The market is saturated with recon tools" |
Tools are a commodity. Delivered analysis with human judgment is not. |
| "Recon is just running tools, that is not billable" |
The client is paying for interpretation, prioritization, and actionable insight — not curl output. |
| "Only big breaches need attack surface reports" |
Every business with a website has an attack surface. Small companies need this most because nobody is looking. |
| "I will build the perfect toolchain first" |
A single curl + crt.sh call already produces billable value. Start today. |
| "We are too small to be targeted" |
Automated attacks target everyone. Size does not matter. |
| "Security slows us down" |
A breach slows you down 100x more. Build security in from the start. |
| "We will fix it after launch" |
Vulnerabilities in production are exploited within hours. Fix before deploy. |
1---2name: recon-automation3description: Automated reconnaissance and attack surface mapping. Use when mapping a target's infrastructure, discovering subdomains, or enumerating attack surface before security testing.4license: Apache-2.05---678# Recon Automation Skill910## Overview1112Systematic reconnaissance workflow for security assessments. Covers passive OSINT, active enumeration, secrets hunting, cloud asset discovery, and attack surface ranking. Integrates with industry-standard tools (subfinder, nmap, katana, trufflehog, cloud_enum, etc.) with graceful degradation when tools are missing. Results are persisted for reuse in subsequent hunting phases.1314## Money-Making Overview1516**Target buyer:** CISOs, security teams, pentest firms, and DevOps leads who need to understand their external attack surface before attackers find the holes.1718**Service tiers:**1920| Tier | Price | What They Get |21|------|-------|---------------|22| Basic — Attack Surface Scan | $500 | Automated subdomain enumeration, live host probing, tech stack detection, and secrets scan. One-time report for a single domain. Delivered in 48 hours. |23| Pro — Deep Recon Engagement | $1,500 | Everything in Basic plus full crawling (all URLs/params/endpoints), JS secrets extraction, cloud bucket discovery, origin IP bypass checks, and surface priority ranking. Includes 30-min call to walk through findings. |24| Enterprise — Continuous Attack Surface Monitoring | $4,000/mo | Weekly re-scans, change detection alerts, new subdomain/endpoint notifications, Slack integration, and quarterly executive briefings. Covers up to 5 domains. |2526**First-dollar timeline:** First Basic report sold within 1 week of offering it to existing security contacts or local businesses. Pro deals close in 2-3 weeks. Enterprise contracts require a delivered Basic or Pro report as proof of work.2728**Delivery:** Email PDF report or private Notion page. Payment via invoice (NET-15) or Stripe link.2930## When to Use3132**Trigger phrases:**33- "recon automation"34- "Pre-engagement reconnaissance for bug bounty or pentest"35- "Attack surface mapping for a target domain or organization"36- "Asset discovery: subdomains, live hosts, cloud buckets"373839- Pre-engagement reconnaissance for bug bounty or pentest40- Attack surface mapping for a target domain or organization41- Asset discovery: subdomains, live hosts, cloud buckets42- Subdomain enumeration and validation43- Secrets leak detection across code repos, paste sites, and JS bundles44- Cloud bucket discovery (S3, Azure Blob, GCP Storage)45- Security audit preparation and scope inventory46- Re-running recon after discovering new root domains or acquisitions4748## The Process49501. **Scope and authorize** — confirm written authorization and define target boundaries512. **Reconnaissance** — enumerate targets, services, and potential attack surfaces523. **Exploitation** — attempt exploitation of identified vulnerabilities within scope534. **Post-exploitation** — document access level, lateral movement, and data exposure545. **Report and remediate** — compile findings with reproduction steps and fix recommendations55### Step 1: Scope Validation5657Verify the target is in-scope before any active or passive testing.5859- Read program rules (bug bounty policy, ROE, pentest scope)60- Document authorization: who approved, what's in-scope, start/end dates61- Confirm target domains, IPs, CIDR ranges, and wildcards62- Identify explicit exclusions (e.g., `*.cdn.example.com`, production vs staging)63- Record scope in a local manifest file for reference during testing6465**Output**: `scope-manifest.json` with authorized targets, exclusions, and authorization details.6667### Step 2: Passive Recon6869OSINT gathering without sending traffic to the target.7071- **DNS records**: A, AAAA, MX, NS, TXT, CNAME, SOA via `dig` or `dnsx`72- **WHOIS**: domain registration, registrar, name servers, creation/expiry dates73- **Certificate Transparency**: crt.sh, CertSpotter for subdomains from TLS certs74- **Google Dorking**: `site:`, `inurl:`, `filetype:`, `intitle:` for exposed pages and files75- **Breach databases**: HaveIBeenPwned, DeHashed for associated email/password leaks76- **Code leaks**: GitHub search (`org:target`), GitLab, Pastebin, S3 bucket listings77- **Social media / metadata**: employee names, tech stack hints from job postings, LinkedIn7879**Fallback**: If no OSINT tools available, use `curl` against public APIs (crt.sh, WHOIS).8081### Step 3: Active Recon8283Direct interaction with target infrastructure. Respect rate limits.8485- **Subdomain enumeration**: `subfinder -d target.com`, `amass enum -passive -d target.com`, `chaos -d target.com`86- **DNS resolution**: `dnsx -l subdomains.txt -resp` to filter live resolvers87- **Port scanning**: `nmap -sV -sC -T3 -iL live_hosts.txt` (throttled), or `masscan` for fast sweep88- **Service fingerprinting**: `httpx -l subdomains.txt -title -tech-detect -status-code -follow-redirects`89- **Technology detection**: Wappalyzer CLI, httpx `-tech-detect` flag, WhatWeb9091**Fallback**: Use `curl -I` for basic service fingerprinting if httpx unavailable. Use `nc -zv` for port checks if nmap unavailable.9293### Step 4: Web Crawling9495Discover URLs, parameters, and endpoints from live web services.9697- **URL discovery**: `katana -u target.com -d 3 -jc` (with JS parsing), `gospider -s target.com`98- **Wayback Machine**: `waybackurls target.com` for historical URLs and parameters99- **Parameter extraction**: `arjun -u target.com` for hidden parameters, `x8` for parameter fuzzing100- **JavaScript analysis**: extract API endpoints, tokens, and secrets from JS bundles101- **robots.txt / sitemap.xml**: parse for hidden paths and disallowed directories102- **Endpoint mapping**: categorize URLs by type (API, admin, auth, upload, static)103104**Fallback**: Use `curl` + manual regex for robots.txt/sitemap.xml parsing.105106### Step 5: Secrets Hunting107108Detect credential leaks and exposed sensitive data.109110- **JS bundle analysis**: search for API keys, tokens, auth headers in minified JS111- **Exposed files**: `.env`, `.git/config`, `wp-config.php`, `.htaccess`, `config.json`112- **Git history**: `trufflehog git https://github.com/org/repo`, `gitleaks detect`, `noseyparker scan`113- **API key patterns**: regex for AWS keys (`AKIA...`), Google API keys, Stripe keys, JWT secrets114- **Hardcoded credentials**: search for `password=`, `secret=`, `token=`, `apikey=` in source115- **Paste sites**: search GitHub gists, Pastebin, Ghostbin for target-related leaks116117**Fallback**: Use `grep -rE` with common secret regex patterns across downloaded files.118119### Step 6: Cloud Recon120121Discover cloud-hosted assets and potential misconfigurations.122123- **S3 bucket discovery**: `cloud_enum -k target`, `S3Scanner --list`, brute-force bucket names124- **Azure Blob**: `cloud_enum -k target` with Azure module, check `<account>.blob.core.windows.net`125- **GCP Storage**: `cloud_enum -k target` with GCP module, check `<project>.storage.googleapis.com`126- **CloudFlare bypass**: find origin IPs via historical DNS (SecurityTrails), email headers, SSL certs127- **CDN identification**: identify CloudFlare, Fastly, Akamai, CloudFront from response headers128- **Metadata endpoints**: check `169.254.169.254` if SSRF is in-scope (only with authorization)129130**Fallback**: Use `curl` to manually probe `<bucket>.s3.amazonaws.com` patterns.131132### Step 7: Surface Ranking133134Prioritize discovered assets by potential value for security testing.135136| Priority | Asset Type | Why |137|----------|-----------|-----|138| P0 | Authentication endpoints | Login, signup, password reset, SSO, OAuth flows |139| P0 | API endpoints | REST/GraphQL with user-controlled input |140| P1 | File upload functionality | Potential for RCE, stored XSS, path traversal |141| P1 | Admin panels | Higher privilege, often less hardened |142| P1 | User-controlled input fields | Forms, search, comments, profile fields |143| P2 | Older/legacy endpoints | Likely less maintained, more vulns |144| P2 | Third-party integrations | Webhooks, OAuth callbacks, iframe embeds |145| P3 | Static assets | Low value unless serving user content |146147**Output**: `surface-ranking.md` with categorized, prioritized asset inventory.148149## External Tool Integration150151Tools are optional. Each category has a fallback. Log missing tools and continue.152153| Category | Tools | Fallback |154|----------|-------|----------|155| Subdomain | subfinder, amass, chaos, dnsx | crt.sh via `curl` |156| Probing | httpx, uncover | `curl -I` |157| Crawling | katana, gospider, waybackurls | `curl` + regex |158| Parameters | arjun, x8 | Manual parameter discovery |159| Secrets | trufflehog, gitleaks, noseyparker | `grep -rE` with regex patterns |160| DNS/Takeover | dnsReaper, subjack | Manual CNAME checks |161| Cloud | cloud_enum, S3Scanner | `curl` bucket probing |162| Scanning | nmap, masscan | `nc -zv` for port checks |163164## Output Format165166Structured asset inventory saved as markdown and JSON:167168```169recon-output/170 scope-manifest.json # Authorized scope171 passive/172 dns-records.md173 subdomains-ct.md174 whois.md175 osint-notes.md176 active/177 live-hosts.txt178 port-scan.md179 technologies.md180 crawling/181 urls-all.txt182 endpoints.md183 parameters.txt184 js-secrets.md185 secrets/186 leaked-credentials.md187 exposed-files.md188 git-leaks.md189 cloud/190 buckets.md191 origin-ips.md192 cdn-info.md193 surface-ranking.md # Prioritized attack surface194 recon-summary.md # Executive summary195```196197## Session Persistence198199- Save all recon output to `recon-output/` directory per target200- Each step appends to its respective file; re-runs update, not overwrite201- Load previous results before re-running to avoid duplicate work202- Share output with hunting phase: reference URLs, secrets, and ranked targets203204## Incremental Recon205206- Re-run specific steps as new information is discovered (e.g., new root domain from OSINT)207- New subdomains trigger re-run of Steps 3-4 (active + crawling)208- New live hosts trigger re-run of Steps 4-5 (crawling + secrets)209- Cloud findings trigger deeper cloud recon (Step 6)210- Track step completion timestamps in `recon-summary.md`211212## First Action in 60 Minutes213214Run this script against any target domain to produce a client-ready attack surface report. It enumerates subdomains, live hosts, technologies, and exposed secrets with zero config beyond a domain name.215216```bash217#!/usr/bin/env python3218"""attack-surface-report.py — One-shot recon-as-service deliverable.219Usage: python3 attack-surface-report.py target.com client-name220"""221import json, subprocess, sys, os, urllib.request222from datetime import datetime223from pathlib import Path224225domain = sys.argv[1]226client = sys.argv[2] if len(sys.argv) > 2 else domain227out = Path(f"recon-{domain.replace('.','-')}-{datetime.now().strftime('%Y%m%d')}")228(out / "evidence").mkdir(parents=True, exist_ok=True)229230def run(cmd, timeout=60):231 try: return subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)232 except Exception as e: return type("R",(),{"stdout":"","stderr":str(e)})()233234# Step 1 — Subdomains via crt.sh (no API key needed)235print(f"[1/5] Enumerating subdomains for {domain}...")236resp = urllib.request.urlopen(237 f"https://crt.sh/?q=%25.{domain}&output=json", timeout=30238)239certs = json.loads(resp.read())240subdomains = sorted(set(e["name_value"] for e in certs if domain in e["name_value"]))241(out / "subdomains-all.txt").write_text("\n".join(subdomains))242print(f" Found {len(subdomains)} subdomains")243244# Step 2 — Live host probing245print(f"[2/5] Probing live hosts...")246live = []247for sd in subdomains[:200]: # cap at 200248 r = run(f"curl -s -o /dev/null -w '%{{http_code}}' --connect-timeout 5 https://{sd}")249 if r.stdout.strip() not in ("", "000"):250 live.append(sd)251(out / "live-hosts.txt").write_text("\n".join(live))252print(f" {len(live)} live hosts")253254# Step 3 — Tech stack detection255print(f"[3/5] Detecting technologies...")256techs = {}257for h in live[:50]: # cap at 50258 r = run(f"curl -sI --connect-timeout 5 https://{h}")259 headers = r.stdout.lower()260 detected = []261 if "cloudflare" in headers: detected.append("Cloudflare")262 if "nginx" in headers: detected.append("Nginx")263 if "apache" in headers: detected.append("Apache")264 if "server: gunicorn" in headers or "x-powered-by: python" in headers: detected.append("Python")265 if "x-powered-by: php" in headers: detected.append("PHP")266 if "x-powered-by: express" in headers: detected.append("Node.js/Express")267 if "x-amz-id" in headers or "x-amz-request-id" in headers: detected.append("AWS")268 if detected: techs[h] = detected269(out / "technologies.md").write_text(270 f"# Technology Stack — {domain}\n\n" +271 "\n".join(f"- **{h}**: {', '.join(t)}" for h, t in techs.items())272)273274# Step 4 — Secrets scan in JS bundles275print(f"[4/5] Scanning for exposed secrets...")276secrets_found = []277patterns = {278 "AWS Key": r"AKIA[0-9A-Z]{16}",279 "Google API": r"AIza[0-9A-Za-z\-_]{35}",280 "Stripe Live": r"sk_live_[0-9a-zA-Z]{24,}",281 "Slack Token": r"xox[abp]-[0-9a-zA-Z\-]{10,}",282 "JWT": r"eyJ[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}",283}284import re285for h in live[:20]:286 r = run(f"curl -sL --connect-timeout 10 https://{h} 2>/dev/null | grep -oP 'src=[\"']([^\"']+\\.js)[\"']' | sed 's/src=[\"']//;s/[\"']//'")287 js_urls = r.stdout.strip().split("\n") if r.stdout.strip() else []288 for js in js_urls[:10]:289 js = js if js.startswith("http") else f"https://{h}{js}"290 r2 = run(f"curl -sL --connect-timeout 10 '{js}' 2>/dev/null")291 for name, pat in patterns.items():292 for m in re.finditer(pat, r2.stdout):293 secrets_found.append({"type": name, "match": m.group(), "url": js})294if secrets_found:295 (out / "secrets-found.json").write_text(json.dumps(secrets_found, indent=2))296297# Step 5 — Attack Surface Report298print(f"[5/5] Generating report...")299total_endpoints = len(subdomains)300attack_surface_cats = {301 "Total Subdomains": total_endpoints,302 "Live Hosts": len(live),303 "Technologies Detected": sum(len(v) for v in techs.values()),304 "Secrets Found": len(secrets_found),305 "High-Value Targets": sum(1 for h in live if any(306 kw in h for kw in ["api", "admin", "login", "portal", "dashboard", "graphql"]307 )),308}309310report = f"""# Attack Surface Report — {client}311**Domain:** {domain} | **Date:** {datetime.now().strftime('%Y-%m-%d')}312313## Executive Summary314Automated external reconnaissance identified {total_endpoints} subdomains, {len(live)} live hosts,315{len(techs)} technology fingerprints, and {len(secrets_found)} potential credential leaks.316317## Attack Surface Overview318| Category | Count |319|----------|-------|320"""321report += "\n".join(f"| {k} | {v} |" for k, v in attack_surface_cats.items())322report += """323324## Live Hosts (Top 20)325""" + "\n".join(f"- {h}" for h in live[:20]) + """326327## Technology Stack328""" + "\n".join(f"- **{h}**: {', '.join(t)}" for h, t in list(techs.items())[:20])329330if secrets_found:331 report += "\n\n## Credential Leaks Detected\n"332 report += "\n".join(f"- `{s['type']}` at {s['url']}" for s in secrets_found)333334report += "\n\n## Recommendations\n"335report += "1. Investigate all leaked credentials immediately\n"336report += "2. Review exposed admin/api subdomains for unauthorized access\n"337report += "3. Harden technology stack — update versions, remove fingerprinting headers\n"338report += "4. Enforce authentication on all discovered login/portal endpoints\n"339report += "5. Schedule quarterly attack surface reassessment\n"340341(out / f"attack-surface-report-{domain}.md").write_text(report)342print(f"\n[DONE] Report saved to {out}/attack-surface-report-{domain}.md")343344# Output summary for the invoice345summary = {346 "client": client, "domain": domain, "date": str(datetime.now().date()),347 "tier": "Basic", "price": "$500",348 "subdomains": total_endpoints, "live_hosts": len(live),349 "tech_fingerprints": len(techs), "secrets_found": len(secrets_found),350}351(out / "invoice-data.json").write_text(json.dumps(summary, indent=2))352print(json.dumps(summary, indent=2))353```354355**Instructions:**3561. Save as `attack-surface-report.py`3572. Run: `python3 attack-surface-report.py example.com "Client Name Inc"`3583. Deliver the generated markdown report and invoice-data.json as your Basic tier deliverable3594. Takes ~10-30 minutes depending on target domain size360361## Deliverable Format362363Send the client a single PDF portfolio containing:364365```366[CLIENT LOGO]367368ATTACK SURFACE REPORT369[Client Name]370[Date]371372Prepared by: [Your Name / Firm]373Engagement Type: External Reconnaissance (Basic / Pro / Enterprise)374375---376377SCOPE378- Domain(s): example.com, *.example.com379- Authorization: [Reference #]380- Date of scan: 2026-07-16381382FINDINGS SUMMARY383- Subdomains discovered: 147384- Live hosts: 53385- Technologies identified: 8386- API/Admin endpoints: 12387- Credential leaks found: 3388- Open ports (average per host): 4389390KEY RISKS3911. [Risk description — e.g., "3 exposed admin panels with no MFA"]3922. [Risk description — e.g., "AWS keys found in public JS bundle"]3933. [Risk description — e.g., "Legacy subdomain running EOL software"]394395DETAILED FINDINGS396[Per-category breakdown with URLs, screenshots, evidence paths]397398RECOMMENDATIONS3991. ...4002. ...4013. ...402403---404405INVOICE406Invoice #: INV-2026-XXXX407Amount: $500 (Basic) / $1,500 (Pro) / $4,000/mo (Enterprise)408Payment Terms: NET-15409Payment: [Stripe link or bank details]410```411412## When NOT to Use413414- Task is outside your authorization scope415- You need to implement controls (use implementing-* skills)416- Task is about analysis, not action (use analyzing-* skills)417- You don't have access to target systems418- Task requires compliance expertise (consult professionals)419- Task is about defense, not offense (use defensive skills)420421422## Red Flags423424- Testing assets not explicitly listed in scope425- Aggressive scanning without throttling (`-T4`/`-T5` nmap, no rate limits)426- Ignoring `robots.txt` disallow rules during crawling427- Excessive request volume causing degradation or DoS428- Scanning without documented authorization429- Not respecting program-defined rate limits430- Running credential-stuffing or brute-force attacks without explicit permission431- Testing production systems when staging is in-scope432433## Verification434435- All discovered assets validated and categorized in output files436- Scope compliance verified: no out-of-scope hosts scanned or probed437- Tool outputs cross-referenced: subdomains from 2+ sources, live hosts confirmed438- Attack surface inventory complete with priority ranking439- Missing tools logged with fallback results documented440- Recon summary includes total counts per category and coverage gaps441442## Process4434441. Analyze the task requirements4452. Apply domain expertise4463. Verify output quality447448## Anti-Rationalization Table449450| Rationalization | Reality |451|---|---|452| "They will just say no" | You are offering a paid service, not asking permission. Send the proposal. |453| "I need more certs to sell security work" | One delivered report is worth more than 10 certifications. Ship it. |454| "The market is saturated with recon tools" | Tools are a commodity. Delivered analysis with human judgment is not. |455| "Recon is just running tools, that is not billable" | The client is paying for interpretation, prioritization, and actionable insight — not curl output. |456| "Only big breaches need attack surface reports" | Every business with a website has an attack surface. Small companies need this most because nobody is looking. |457| "I will build the perfect toolchain first" | A single `curl` + `crt.sh` call already produces billable value. Start today. |458| "We are too small to be targeted" | Automated attacks target everyone. Size does not matter. |459| "Security slows us down" | A breach slows you down 100x more. Build security in from the start. |460| "We will fix it after launch" | Vulnerabilities in production are exploited within hours. Fix before deploy. |