| name | recon-sector-expansion |
| description | Multi-sector batch domain expansion — identify untested/under-tested sectors, generate candidate company domains (national chains, franchises, regionals), filter against existing test coverage, probe alive domains, and run the full testing pipeline across 20+ new targets in a single session. Complements per-sector recon-* skills by telling you WHICH sectors to expand into next. |
| version | 1.1.0 |
| revision_date | "2026-07-25T00:00:00.000Z" |
| license | MIT |
| category | redteam |
| tags | ["recon","sector","expansion","redteam"] |
RECON-SECTOR-EXPANSION — Batch Discovery Across Untapped Sectors
When to Use
Use within authorized engagements to expand coverage into fresh sectors — not dig deeper into a single known target, but find and test 20+ new company domains across 5-10 different sectors. Target list must be from authorized scope. Batch expansion is for scoped programs, not indiscriminate scraping.
Signals:
- "Discover 20 more domains in non-regulated sectors"
- "We need to expand coverage; what haven't we tested?"
- "Find fresh targets outside the usual sectors"
The Sector Expansion Workflow
Phase 1 — Coverage Audit
Before discovering new targets, know what's already been tested:
ALL_TARGETS="${OUTPUT_DIR:-./output}/sector-expansion/all_targets.txt"
ALL_MASSIVE="${OUTPUT_DIR:-./output}/sector-expansion/all_massive.txt"
grep -ohE '[a-zA-Z0-9][a-zA-Z0-9.-]*\.[a-z]{2,}' "$ALL_TARGETS" "$ALL_MASSIVE" | sort -u > /tmp/targets_deduped.txt
echo "Already tested: $(wc -l < /tmp/targets_deduped.txt) domains"
ls "${OUTPUT_DIR:-./output}"/sector-expansion/*_findings.md 2>/dev/null | wc -l
for sector in "dentist" "dental" "gym" "fitness" "baker" "auto_body" "carpet" "laundry" "daycare" "pest" "tree" "pet"; do
count=$(grep -l "$sector" "${OUTPUT_DIR:-./output}"/sector-expansion/*_findings*.md 2>/dev/null | wc -l)
echo "Sector '$sector': $count findings files"
done
Phase 2a — Source 1: crt.sh Certificate Transparency (Preferred for Local Business Sectors)
For local service sectors (roofing, landscaping, plumbing, pool services, HVAC) where no national chains exist, crt.sh is the primary discovery source. These businesses often have descriptive domain names like [name][SECTOR_EXAMPLE] or [city][SECTOR_EXAMPLE].
crt.sh Query Pattern
Use simple sector keywords with the HTML output mode (JSON API returns 502/503 on broad queries):
QUERY="roofing"
curl -s --max-time 40 --connect-timeout 10 \
"https://crt.sh/?q=${QUERY}&excluded=expired&dedup=Y" \
-H 'User-Agent: Mozilla/5.0' 2>/dev/null | \
grep -oE '>[A-Za-z0-9][A-Za-z0-9.-]*\.com<' | \
sed 's/^>//;s/<$//' | \
sort -u >> /tmp/all_crt_domains.txt
Parameters explained:
&excluded=expired — only current certificates
&dedup=Y — deduplicate certificates
-oE regex — BusyBox-compatible (no -P flag available)
- No
&output=json — JSON API is unreliable for broad queries
Sector Keyword Catalog
Query ALL these sectors to gather candidates:
SECTORS="roofing landscaping pestcontrol dentist dentist fitness \
cleaningservice movingcompany photography vetclinic realtor hvac \
treeservice lawncare plumbing poolcleaning windowcleaning petsalon \
barbershop daycare carpetcleaning handyman lawfirm concrete \
autorepair petgrooming autobody remodeling"
for sector in $SECTORS; do
curl -s --max-time 40 --connect-timeout 10 "https://crt.sh/?q=${sector}&excluded=expired&dedup=Y" \
-H 'User-Agent: Mozilla/5.0' 2>/dev/null | \
grep -oE '>[A-Za-z0-9][A-Za-z0-9.-]*\.com<' | \
sed 's/^>//;s/<$//' >> /tmp/all_crt_domains.txt
sleep 2
done
Filtering Noise from crt.sh Results
crt.sh returns many subdomains and infrastructure hosts. Strip these patterns:
import re
skip_patterns = [
'^autodiscover\\.', '^vpn\\.', '^api\\.', '^mail\\.', '^remote\\.',
'^webmail\\.', '^crm\\.', '^ftp\\.', '^test\\.', '^dev\\.',
'^exchange', '^hostmaster', '^owa\\.', '^smtp\\.',
'roofingcompany\\.com$', 'landscapingcompany\\.com$', 'vetclinic\\.com$',
]
Then associate domains with sectors by matching their name:
SECTOR_KEYWORDS = {
'roofing': ['roofing', 'roof', 'roofer'],
'landscaping': ['landscaping', 'landscape', 'lawn'],
'hvac': ['hvac', 'heating', 'cooling', 'air'],
'dental': ['dentist', 'dental'],
'pest-control': ['pest', 'mosquito'],
'daycare': ['daycare'],
'legal': ['lawfirm', 'lawfirm'],
'fitness': ['gym', 'fitness'],
'auto-repair': ['autorepair', 'auto', 'collision'],
'cleaning': ['cleaning', 'maid'],
'veterinary': ['vet', 'pet'],
'pool-services': ['pool', 'spa'],
}
Noise Subdomain Filtering
When using grep on crt.sh HTML output, you'll get entries from large hosting providers. Exclude:
autodiscover.*, vpn.*, api.*, mail.*, remote.* — infrastructure
.*\.hvacrightnow\.com, .*\.hvacbrain\.com — SaaS platforms (not actual targets)
.*\.theroofingprofessor\.com, .*\.bakerroofing\.com — large org subdomains
.*\.singaporepools\.com, .*\.devsingaporepools\.com — non-US
Piping through grep -v with exclusion patterns before dedup saves time.
Phase 2b — Source 2: Google / Manual (Preferred for National Chains)
For sectors dominated by national/regional chains (dental, gyms, bakeries, auto body), use Google searches because chain domain names rarely contain sector keywords:
| Sector | How to Find Candidates | Example Chains |
|---|
| Dental chains | Google "top dental chains USA" | Aspen Dental, Gentle Dental, Coast Dental, DentalWorks, Heartland Dental, Pacific Dental |
| Gym/fitness | Google "largest fitness chains USA" | F45, Barry's, CrossFit, Gold's Gym, 24 Hour Fitness, LA Fitness, OrangeTheory |
| Bakery chains | Google "largest bakery chains USA" | Cinnabon, Crumbl, Insomnia Cookies, Sprinkles, Nothing Bundt Cakes |
| Auto body/collision | Google "auto body repair chains USA" | ABRA, Caliber, Gerber, Service King, Fix Auto, Sterling, Crash Champions |
| Carpet cleaning | Google "carpet cleaning companies USA" | Chem-Dry, ServPro, Stanley Steemer, Rainbow International, Heaven's Best |
| Laundry services | Google "laundry delivery service USA" | Poplin, Rinse, Washlava, LaundryHeap |
| Daycare/childcare | Google "largest daycare chains USA" | Bright Horizons, KinderCare, Goddard, Primrose, Children of America |
| Pet grooming | Google "pet grooming chains USA" | Petco, PetSmart, Camp Bow Wow, Dogtopia |
| Pest control | Google "pest control companies USA" | Terminix, Orkin, Ehrlich, Bulwark, Arrow |
| Tree services | Google "tree service companies USA" | Davey, SavATree, Arbor Care, Bartlett |
Phase 3 — Batch Alive-Check (Curl Probe)
Once you have 50-60 candidate domains, filter against already-tested domains, then quick-check HTTP:
grep -v -f /tmp/targets_deduped.txt /tmp/candidates.txt | sort -u > /tmp/fresh_candidates.txt
echo "=== Checking all candidates with curl ==="
for domain in $(cat /tmp/fresh_candidates.txt); do
code=$(curl -sk -o /dev/null -w '%{http_code}' --connect-timeout 5 --max-time 8 "https://${domain}" 2>/dev/null)
echo "$domain => $code"
done > /tmp/curl_alive.txt
grep -v "=> 000" /tmp/curl_alive.txt | grep -v "^$" | cut -d' ' -f1 > /tmp/alive_domains.txt
echo "Alive: $(wc -l < /tmp/alive_domains.txt) / $(wc -l < /tmp/fresh_candidates.txt) candidates"
Phase 4 — Full Testing Pipeline
Then run the full 6-step pipeline on alive domains. The most efficient approach at scale (20+ targets) is a Python batch script:
"""Batch test targets: httpx → WP REST → CORS → XMLRPC → ports"""
import subprocess, json, sys, os, re, time
OUTPUT_DIR = os.environ.get("OUTPUT_DIR", "./output") + "/sector-expansion"
def run(cmd, timeout=15):
try:
r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)
return r.stdout + r.stderr
except subprocess.TimeoutExpired:
return f"TIMEOUT ({timeout}s)"
except Exception as ex:
return f"ERROR: {ex}"
def test_domain(domain, sector):
findings = {"domain": domain, "sector": sector, "wp": False, "wp_users": 0,
"cors_reflected": False, "xmlrpc_open": False}
r = run(f"httpx -sc -title -tech-detect -server -no-color -u https://{domain} -timeout 10")
findings["http"] = r.strip()
for path in ["/wp-json/wp/v2/users", "/wp-json/", "/?rest_route=/wp/v2/users"]:
r = run()
r []:
findings[] =
findings[] =
user_resp = run(, timeout=)
:
users = json.loads(user_resp)
(users, ):
findings[] = (users)
findings[] = [u.get(,) u users]
:
findings[]:
r = run(, timeout=)
r r:
findings[] =
target_url = findings[]
r = run(, timeout=)
r:
findings[] =
findings[] = r
r = run(, timeout=)
findings[] = (r.strip() == )
r = run(, timeout=)
ports = [line.split()[] line r.split() re.search(, line)]
findings[] = ports
score = ([findings[], (findings[] > ), findings[], findings[]])
findings[] = score >= ( score >= ( score >= ))
findings
domains = {: , : , ...}
domain, sector domains.items():
f = test_domain(domain, sector)
content =
(, ) out:
out.write(content)
Phase 5 — Results Analysis
Review findings for these high-signal patterns:
| Pattern | How to Spot | Severity |
|---|
| Credentialled CORS | Access-Control-Allow-Origin: http://evil.com + Access-Control-Allow-Credentials: true on /wp-json/wp/v2/users | HIGH |
| WordPress users exposed | REST API at /wp-json/wp/v2/users returns array of user objects with names, slugs, avatars | MEDIUM |
| Wildcard CORS | Access-Control-Allow-Origin: * (no credentials) | MEDIUM |
| XMLRPC open | /xmlrpc.php returns HTTP 200 (may be blocked at method-list level by WAF) | LOW-MEDIUM |
| Open ports on non-standard services | 21 (FTP), 3306 (MySQL), 3389 (RDP), 5900 (VNC), 6379 (Redis) | VARIES |
| PHPInfo exposed | /info.php, /test.php, etc reveal 400+ config entries | LOW |
Sector-Specific Chains Domain List
Curated list of US national/regional chain domains (verified alive as of 2026-06):
Dental
aspendental.com gentledental.com dentalworks.com coastdental.com
brightnow.com sagedental.com western-dental.com castledental.com
heartlanddental.com pacificdental.com dentalcarealliance.com
Gym / Fitness
[FITNESS_CHAIN] barrys.com crossfit.com goldsgym.com
24hourfitness.com lafitness.com orangetheory.com planetfitness.com
anytimefitness.com snapfitness.com crunch.com
Bakery
cinnabon.com crumbl.com insomniacookies.com sprinkles.com
bakery.example.com restaurant.example.com donut.example.com
Auto Body / Collision Repair
abracollision.com serviceking.com sterlingautobody.com crashchampions.com
fixauto.com true2form.com auto-body-shop.com
calibercollision.com carstar.com gerbercollision.com maaco.com
Carpet Cleaning
chemdry.com servpro.com rainbowintl.com heavenlycarpet.com
stanleysteemer.com zerorez.com coit.com
Laundry
poplin.com rinse.com washlava.com laundryheap.com
speedqueen.com spincyclelaundry.com
Daycare
brighthorizons.com childrenofamerica.com kindercare.com goddardschool.com
primroseschools.com montessori.com lajollamontessori.com tutortime.com
Pest Control
terminix.com orkin.com echols.com bulwarkpest.com
arrowpest-control.example.com dodsonbros.com massey-services.com
Tree Services
treecare.com arborcare.com davey.com savatree.com
bartlett.com allstatetree.com firstchoicetree.com
Roofing (Local/Regional — crt.sh Discovered)
aastro[SECTOR_EXAMPLE] abcarnes[SECTOR_EXAMPLE] americaschoiceroofers.com arvada[SECTOR_EXAMPLE]
bacon[SECTOR_EXAMPLE] baker[SECTOR_EXAMPLE] bricor[SECTOR_EXAMPLE] capitol[SECTOR_EXAMPLE]
charlottepro[SECTOR_EXAMPLE] coloradopro[SECTOR_EXAMPLE] eh[SECTOR_EXAMPLE] errdaddy[SECTOR_EXAMPLE]
fifthwall[SECTOR_EXAMPLE] freeman[SECTOR_EXAMPLE] ghatley.com hambro[SECTOR_EXAMPLE]
hollis[SECTOR_EXAMPLE] integrityrc.com kbfamily[SECTOR_EXAMPLE] mcas[SECTOR_EXAMPLE]
na[SECTOR_EXAMPLE] pabco[SECTOR_EXAMPLE] roofon.com roofwithfoster.com
sandiegocounty[SECTOR_EXAMPLE] springfield[SECTOR_EXAMPLE] tomtheroofer.com
universityroof.com vanguardroofingltd.com wallace[SECTOR_EXAMPLE]
Landscaping (Local/Regional — crt.sh Discovered)
delliquadrilandscape.com dundeedig.com guardyouryardpa.com
landscapingsi.com miles[SECTOR_EXAMPLE] moss[SECTOR_EXAMPLE]
mountainlandscapingkc.com sarasota[SECTOR_EXAMPLE] trinas[SECTOR_EXAMPLE]
moss[SECTOR_EXAMPLE] eo[SECTOR_EXAMPLE] brucewilson[SECTOR_EXAMPLE]
HVAC (Local/Regional — crt.sh Discovered)
airzonahvac.com bigfishhvac.com dormarhvac.com specializedhvac.com
General Contractors & Other (crt.sh Discovered)
allysonsflowers.com [INSURANCE_CO] canopyroofers.com
gelinc.com rvroofrepairflorida.com spartanroofingbc.com
Pitfalls
-
Don't rely on a single key file for "tested" domains. all_targets.txt and all_massive.txt may differ. Merge both and deduplicate with sort -u.
-
CloudFlare blocks WP REST API for some sites. If you get HTTP 403 on /wp-json/wp/v2/users, try /?rest_route=/wp/v2/users or check page source for /wp-content/ markers.
-
XMLRPC may return 200 but block system.listMethods. CloudFlare and other WAFs block the method-listing XML body but leave the endpoint open for system.multicall. Test separately.
-
Some 301/302 sites may still have CORS. Redirect responses can carry CORS headers (brighthorizons.com had wildcard CORS on its 301 response). Test the redirect target URL if the landing page differs.
-
BusyBox grep limitation. Minimal environments may provide BusyBox,
which lacks grep -P. Use grep -oE with extended patterns. BusyBox find
also lacks -printf; use -exec echo {} \; or shell loops instead.
-
crt.sh rate limiting. Returns HTTP 502/503 when hammered. Spread queries 3 seconds apart and if you get repeated errors, wait 15-30s. The JSON API (&output=json) is especially unreliable for broad queries — use HTML output mode (&excluded=expired&dedup=Y) instead.
-
Port scan timing. nmap --top-ports 20 -T4 takes ~3-5s per target. Parallelize across 5-7 targets in background.
-
CORS on non-WordPress sites. Generic static sites on CloudFront or S3 may also reflect CORS. Always test on both / and any known API endpoint.
-
Python JSON parsing edge case. The WP REST API user endpoint may return an object instead of a list for protected endpoints (HTTP 401 vs 200 response codes). Always check isinstance(users, list).
Verification
- Sector domain generation — confirm sector keywords produce candidate domains:
echo 'roofing landscaping pestcontrol' | tr ' ' '
' | wc -l
2. **crt.sh accessibility** — confirm crt.sh CDX endpoint reachable:
```bash
curl -s --max-time 10 --connect-timeout 10 -o /dev/null -w '%{http_code}' 'https://crt.sh/?q=test&excluded=expired&dedup=Y'
All tests verify sector expansion readiness.
Related Skills
web2-recon — The per-target technical testing pipeline (httpx, WP enum, CORS, XMLRPC, port scan, JS analysis)
recon-sector — Unified parameterized sector recon with 25 sectors in sectors.yaml