The Analyzer v2.0 — 30 attack vectors, 9 new exploiters

New vectors added:
- 22: SSRF Proof — cloud metadata exfiltration (CRITICAL)
- 23: Prototype Pollution — Node.js client/server (HIGH)
- 24: WebSocket Hijack — WS origin bypass + injection (HIGH)
- 25: Mass Assignment — protected field modification (HIGH)
- 26: HTTP Parameter Pollution — WAF bypass (HIGH)
- 27: Insecure Deserialization — PHP/Java/Node (CRITICAL)
- 28: OAuth Takeover — redirect_uri / state / CSRF (CRITICAL)
- 29: Web Cache Poisoning — unkeyed header injection (HIGH)
- 30: CRLF Injection — HTTP response splitting (CRITICAL)

All vectors PROVE exploitation by dumping data/credentials,
not just detecting config issues.
This commit is contained in:
drjones
2026-06-21 07:20:21 -07:00
parent ab130a88c8
commit d2bc52905d
23 changed files with 2699 additions and 4 deletions

280
engine/autobounty.py Normal file
View File

@@ -0,0 +1,280 @@
#!/usr/bin/env python3
"""
AutoBounty — Autonomous Bug Bounty Pipeline
Discovers subdomains → tech-detect → CVE scan → The Analyzer exploit
No API keys needed (Shodan DNS is free tier)
"""
import subprocess, json, sys, os, time
from pathlib import Path
from collections import Counter
ANALYZER_DIR = os.path.expanduser("~/the-analyzer")
REPORTS_DIR = f"{ANALYZER_DIR}/reports"
HTTPX = os.path.expanduser("~/go/bin/httpx")
NUCLEI_TEMPLATES = os.path.expanduser("~/nuclei-templates")
SHODAN_KEY = "8IPLCrASad9cLHqo6xwzGNxOPcldnGDG"
os.makedirs(f"{ANALYZER_DIR}/targets", exist_ok=True)
def log(msg): print(f"\033[94m[*]\033[0m {msg}")
def ok(msg): print(f"\033[92m[✓]\033[0m {msg}")
def bad(msg): print(f"\033[91m[✗]\033[0m {msg}")
def run(cmd, timeout=120):
try:
r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)
return r.stdout, r.stderr, r.returncode
except subprocess.TimeoutExpired:
return "", "TIMEOUT", 124
def shodan_subdomains(domain):
"""Enumerate subdomains using free Shodan DNS API"""
log(f"Enumerating subdomains for {domain}...")
try:
import urllib.request, json, ssl
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
url = f"https://api.shodan.io/dns/domain/{domain}?key={SHODAN_KEY}"
r = urllib.request.urlopen(url, context=ctx, timeout=10)
data = json.loads(r.read().decode())
subdomains = data.get("subdomains", [])
results = []
for sd in subdomains:
fqdn = f"{sd}.{domain}"
# Filter out wildcard/mass-provisioned subdomains
if not any(x in sd for x in ["clients6", "prod-dynamite", "preprod-dynamite", "client-channel"]):
results.append(fqdn)
if results:
ok(f"Found {len(results)} subdomains")
return results
else:
log(f"No clean subdomains found")
return []
except Exception as e:
bad(f"Shodan DNS error: {e}")
return []
def probe_targets(domains, output_file):
"""Probe targets with httpx tech detection"""
if not domains:
return None
# Write targets
target_file = "/tmp/autobounty_targets.txt"
with open(target_file, "w") as f:
f.write("\n".join(domains))
log(f"Probing {len(domains)} targets with tech detection...")
stdout, stderr, rc = run(
f"cat {target_file} | {HTTPX} -rl 20 -timeout 5 -tech-detect -j -o {output_file} -silent 2>/dev/null",
timeout=180
)
count = 0
if os.path.exists(output_file):
with open(output_file) as f:
count = sum(1 for _ in f)
ok(f"{count} live hosts detected")
return output_file
def run_cve_scan(targets_file, severity="all"):
"""Run targeted CVE scan on live targets"""
if not targets_file or not os.path.exists(targets_file):
return None, 0
# Extract just URLs
url_file = "/tmp/autobounty_urls.txt"
run(f"python3 -c 'import json; [print(json.loads(l).get(\"url\",\"\")) for l in open(\"{targets_file}\") if l.strip()]' > {url_file}")
live_count = 0
with open(url_file) as f:
live_count = sum(1 for _ in f)
if live_count == 0:
return None, 0
log(f"Running CVE scan on {live_count} live hosts...")
findings_file = f"{REPORTS_DIR}/autobounty_cve_{int(time.time())}.json"
if severity == "all":
stdout, stderr, rc = run(
f"nuclei -l {url_file} -j -rl 15 -c 8 "
f"-t {NUCLEI_TEMPLATES}/http/cves/ "
f"-severity critical,high,medium "
f"-o {findings_file} "
f"-silent 2>/dev/null",
timeout=180
)
else:
stdout, stderr, rc = run(
f"nuclei -l {url_file} -j -rl 15 -c 8 "
f"-t {NUCLEI_TEMPLATES}/http/cves/ "
f"-severity critical,high "
f"-o {findings_file} "
f"-silent 2>/dev/null",
timeout=120
)
count = 0
if os.path.exists(findings_file):
with open(findings_file) as f:
count = sum(1 for l in f if l.strip())
return findings_file, count
def print_tech_summary(tech_file):
"""Print technology summary"""
techs = Counter()
with open(tech_file) as f:
for line in f:
try:
d = json.loads(line)
url = d.get("url", "")
for t in d.get("tech", []):
techs[t] += 1
print(f" {url:60} {', '.join(d.get('tech', ['-']))}")
except: pass
if techs:
print(f"\n Technology breakdown:")
for tech, cnt in techs.most_common(10):
print(f" {tech:35} {cnt} targets")
def print_findings(findings_file):
"""Print CVE findings in readable format"""
if not findings_file or not os.path.exists(findings_file):
return
findings = []
with open(findings_file) as f:
for line in f:
if not line.strip(): continue
try:
d = json.loads(line)
cve = "N/A"
for ref in d.get("info", {}).get("classification", {}).get("cve", []):
cve = ref.get("id", "N/A")
break
findings.append({
"url": d.get("matched-at", "?"),
"cve": cve,
"severity": d.get("info", {}).get("severity", "?"),
"name": d.get("info", {}).get("name", "?"),
"template": d.get("template-id", ""),
})
except: pass
if findings:
icons = {"critical": "🔴", "high": "🟠", "medium": "🟡"}
print(f"\n CVEs found:")
for f_data in findings:
icon = icons.get(f_data["severity"], "")
print(f" {icon} {f_data['cve']:20} {f_data['name'][:60]}")
print(f" {f_data['url']}")
# ============================================================
# MAIN — Hunt a specific target domain
# ============================================================
def hunt_target(domain):
"""Full pipeline for a single target domain"""
print()
print(f"╔═══════════════════════════════════════════╗")
print(f"║ AUTOBOUNTY — {domain:40}")
print(f"╚═══════════════════════════════════════════╝")
print()
# Phase 1: Subdomain enumeration
log("Phase 1: Subdomain enumeration")
subdomains = shodan_subdomains(domain)
all_targets = [domain] + (subdomains if subdomains else [])
if not all_targets:
bad("No targets to scan")
return
ok(f"Total targets: {len(all_targets)}")
# Phase 2: Tech detection
print()
log("Phase 2: Tech detection")
tech_file = f"/tmp/autobounty_tech_{domain.replace('.', '_')}.json"
tech_file = probe_targets(all_targets, tech_file)
if not tech_file:
bad("No live hosts found")
return
print()
print_tech_summary(tech_file)
# Phase 3: CVE scan
print()
log("Phase 3: CVE scanning")
findings_file, count = run_cve_scan(tech_file)
print()
if count > 0:
ok(f"Found {count} CVEs!")
print_findings(findings_file)
else:
log("No CVEs detected on these subdomains")
# Phase 4: The Analyzer exploit
if count > 0 and findings_file:
print()
log("Phase 4: Ready for deep exploitation")
log("Run: ./analyzer <vulnerable-url> deep")
print()
print("=" * 60)
print(f" Target: {domain}")
print(f" Subdomains: {len(subdomains) if subdomains else 0}")
print(f" Live: {sum(1 for _ in open(tech_file)) if os.path.exists(tech_file) else 0}")
print(f" CVEs: {count}")
print("=" * 60)
# ============================================================
# CONTINUOUS SCAN (cron-ready)
# ============================================================
def scan_known_targets():
"""Scan all known bug bounty targets for new subdomains"""
targets = [
"google.com", "facebook.com", "twitter.com", "instagram.com",
"github.com", "gitlab.com", "atlassian.com", "slack.com",
"shopify.com", "stripe.com", "paypal.com", "discord.com",
"reddit.com", "twitch.com", "spotify.com", "cloudflare.com",
"digitalocean.com", "magento.com", "salesforce.com", "hubspot.com",
]
for target in targets:
print(f"\n{'='*60}")
hunt_target(target)
def print_usage():
print("Usage:")
print(" python3 autobounty.py <domain> # Hunt a specific target")
print(" python3 autobounty.py all # Scan all known targets")
print(" python3 autobounty.py watch <domain> # Setup daily cron scan")
if __name__ == "__main__":
if len(sys.argv) < 2:
print_usage()
sys.exit(1)
mode = sys.argv[1]
if mode == "all":
scan_known_targets()
elif mode == "watch" and len(sys.argv) >= 3:
domain = sys.argv[2]
print(f"Would setup cron for daily scan of {domain}")
hunt_target(domain)
else:
hunt_target(mode)

561
engine/hunter.py Normal file
View File

@@ -0,0 +1,561 @@
#!/usr/bin/env python3
"""
No-API Vulnerability Hunter
Discovers vulnerable websites using only free/open data sources
Pipeline: Target Discovery → Tech Detection → CVE Scanning → Exploitation
"""
import subprocess, json, sys, os, time
from pathlib import Path
from collections import Counter
from urllib.parse import urlparse
ANALYZER_DIR = os.path.expanduser("~/the-analyzer")
REPORTS_DIR = f"{ANALYZER_DIR}/reports"
TARGETS_DIR = f"{ANALYZER_DIR}/targets"
WORK_DIR = "/tmp/analyzer-hunter"
HTTPX = os.path.expanduser("~/go/bin/httpx")
NUCLEI_TEMPLATES = os.path.expanduser("~/nuclei-templates")
os.makedirs(WORK_DIR, exist_ok=True)
os.makedirs(REPORTS_DIR, exist_ok=True)
os.makedirs(TARGETS_DIR, exist_ok=True)
def log(msg): print(f"\033[94m[*]\033[0m {msg}")
def ok(msg): print(f"\033[92m[✓]\033[0m {msg}")
def warn(msg): print(f"\033[93m[!]\033[0m {msg}")
def bad(msg): print(f"\033[91m[✗]\033[0m {msg}")
def run(cmd, timeout=120):
"""Run a shell command and return output"""
try:
r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)
return r.stdout, r.stderr, r.returncode
except subprocess.TimeoutExpired:
return "", "TIMEOUT", 124
# ============================================================
# PHASE 1: TARGET DISCOVERY
# ============================================================
def discover_tranco_deep(count=2000, offset=50000):
"""Get mid-tier sites from Tranco (50K-52K range)"""
log(f"Fetching Tranco sites (offset={offset}, count={count})...")
# Download if not cached
csv_file = f"{WORK_DIR}/top-1m.csv"
if not os.path.exists(csv_file):
out, _, _ = run("curl -skL https://tranco-list.eu/top-1m.csv.zip -o /tmp/t1m.zip && unzip -o /tmp/t1m.zip -d /tmp/tranco/ 2>/dev/null && echo OK", timeout=30)
if "OK" in out:
os.system("cp /tmp/tranco/top-1m.csv " + csv_file)
if os.path.exists(csv_file):
targets = []
with open(csv_file) as f:
for i, line in enumerate(f):
if i < offset: continue
if i >= offset + count: break
parts = line.strip().split(",")
if len(parts) >= 2:
targets.append(parts[1].strip())
outfile = f"{WORK_DIR}/tranco_deep_targets.txt"
with open(outfile, "w") as f:
f.write("\n".join(targets))
ok(f"{len(targets)} targets from Tranco (offset {offset})")
return outfile
def discover_bug_bounty_targets():
"""Add known bug bounty targets for subdomain recon"""
targets = [
# High-value targets that often have bug bounty programs
"hackerone.com", "bugcrowd.com", "intigriti.com",
"yeswehack.com", "synack.com", "cobalt.io",
# Major platforms with bounty programs
"facebook.com", "twitter.com", "instagram.com", "linkedin.com",
"github.com", "gitlab.com", "atlassian.com", "slack.com",
"shopify.com", "stripe.com", "square.com", "paypal.com",
"discord.com", "reddit.com", "twitch.com", "spotify.com",
"cloudflare.com", "digitalocean.com", "heroku.com",
# E-commerce (user's niche)
"magento.com", "shopware.com", "woocommerce.com",
"bigcommerce.com", "salesforce.com", "hubspot.com",
# Google
"google.com", "youtube.com", "gmail.com", "android.com",
# Microsoft
"microsoft.com", "office.com", "azure.com", "live.com",
# Apple
"apple.com", "icloud.com",
]
# Also add targets from the Analyzer's list
analyzer_targets = f"{TARGETS_DIR}/top50.txt"
if os.path.exists(analyzer_targets):
with open(analyzer_targets) as f:
targets.extend([l.strip() for l in f if l.strip()])
outfile = f"{WORK_DIR}/bb_targets.txt"
with open(outfile, "w") as f:
f.write("\n".join(sorted(set(targets))))
return outfile
def discover_commoncrawl_vuln_patterns():
"""Search CommonCrawl for URLs matching vulnerable software patterns"""
log("Searching CommonCrawl for vulnerable software patterns...")
CC_INDEX = "CC-MAIN-2026-21"
BASE = f"http://index.commoncrawl.org/{CC_INDEX}-index"
patterns = [
("phpMyAdmin", "phpmyadmin"),
("WordPress admin", "wp-admin"),
("WordPress plugins", "wp-content/plugins"),
("Jenkins", "jenkins"),
("phpinfo()", "phpinfo.php"),
("Server status", "server-status"),
(".env files", ".env"),
("Actuator/Spring", "actuator"),
("Git exposure", ".git/config"),
("Laravel debug", "laravel/debug"),
]
targets = set()
for name, pattern in patterns:
try:
import urllib.request, urllib.parse, json
url = f"{BASE}?url=*.{pattern}/*&output=json&limit=20"
r = urllib.request.urlopen(url, timeout=10)
data = r.read().decode()
for line in data.strip().split("\n"):
if not line.strip(): continue
try:
d = json.loads(line)
u = d.get("url", "")
if u:
parsed = urlparse(u)
domain = parsed.netloc or parsed.path.split("/")[0]
targets.add(domain)
except: pass
except Exception as e:
pass
if targets:
outfile = f"{WORK_DIR}/commoncrawl_targets.txt"
with open(outfile, "w") as f:
f.write("\n".join(sorted(targets)))
ok(f"{len(targets)} targets from CommonCrawl patterns")
return outfile
else:
warn("CommonCrawl returned no targets (API limiting)")
return None
# ============================================================
# PHASE 2: SUBDOMAIN ENUMERATION
# ============================================================
def enumerate_subdomains_shodan(domain):
"""Use free Shodan DNS API for subdomain discovery"""
try:
import urllib.request, json
key = "8IPLCrASad9cLHqo6xwzGNxOPcldnGDG"
url = f"https://api.shodan.io/dns/domain/{domain}?key={key}"
r = urllib.request.urlopen(url, timeout=10)
data = json.loads(r.read().decode())
subdomains = data.get("subdomains", [])
full_domains = [f"{sd}.{domain}" for sd in subdomains]
if full_domains:
ok(f"Found {len(full_domains)} subdomains for {domain}")
return full_domains
return []
except Exception as e:
warn(f"Shodan DNS for {domain}: {e}")
return []
# ============================================================
# PHASE 3: TECH DETECTION
# ============================================================
def tech_detect(targets_file, output_file=None):
"""Run httpx tech detection on targets"""
log(f"Tech detection on targets from {targets_file}...")
if not output_file:
output_file = f"{WORK_DIR}/tech_detected.json"
stdout, stderr, rc = run(
f"cat {targets_file} | {HTTPX} -rl 30 -timeout 5 -tech-detect -j -o {output_file} -silent 2>/dev/null",
timeout=180
)
count = 0
if os.path.exists(output_file):
with open(output_file) as f:
count = sum(1 for _ in f)
return output_file, count
def tech_summary(tech_file):
"""Summarize detected technologies"""
techs = Counter()
targets = []
with open(tech_file) as f:
for line in f:
try:
d = json.loads(line)
url = d.get("url", "?")
targets.append(url)
for t in d.get("tech", []):
techs[t] += 1
except: pass
return targets, techs
# ============================================================
# PHASE 4: TARGETED CVE SCANNING
# ============================================================
def scan_with_nuclei(targets_file, severity="critical,high", output_file=None):
"""Run nuclei CVE scan on targets"""
log(f"Nuclei CVE scan (severity: {severity})...")
if not output_file:
output_file = f"{REPORTS_DIR}/hunt_scan_{int(time.time())}.json"
stdout, stderr, rc = run(
f"nuclei -l {targets_file} -j -rl 15 -c 8 "
f"-t {NUCLEI_TEMPLATES}/http/cves/ "
f"-severity {severity} "
f"-o {output_file} "
f"-silent 2>/dev/null",
timeout=300
)
count = 0
if os.path.exists(output_file):
with open(output_file) as f:
count = sum(1 for _ in f)
return output_file, count
def tech_targeted_scan(tech_file):
"""Run technology-specific CVE scans based on detected tech"""
log("Running tech-targeted CVE scans...")
# Read tech data
tech_targets = {}
with open(tech_file) as f:
for line in f:
try:
d = json.loads(line)
url = d.get("url", "")
for t in d.get("tech", []):
tech_targets.setdefault(t, []).append(url)
except: pass
# Map tech to relevant CVE template tags
tech_cve_map = {
"WordPress": ["wordpress", "cves"],
"Apache HTTP Server": ["apache", "cves"],
"Nginx": ["nginx", "cves"],
"PHP": ["php", "cves"],
"Jenkins": ["jenkins", "cves"],
"jQuery": [],
"Bootstrap": [],
"MySQL": ["mysql", "cves"],
"OpenSSL": ["openssl", "cves"],
"OpenSSH": ["openssh", "cves"],
"phpMyAdmin": ["phpmyadmin", "cves"],
"Tomcat": ["tomcat", "cves"],
"Drupal": ["drupal", "cves"],
"Joomla": ["joomla", "cves"],
"GitLab": ["gitlab", "cves"],
"Jenkins": ["jenkins", "cves"],
}
all_findings = []
for tech, urls in tech_targets.items():
# Check if this tech has known CVE templates
matched_tech = None
for known_tech, tags in tech_cve_map.items():
if known_tech.lower() in tech.lower() or tech.lower() in known_tech.lower():
matched_tech = known_tech
break
if not matched_tech:
continue
# Write targets for this tech
tech_file = f"{WORK_DIR}/tech_{tech.lower().replace(' ', '_')}.txt"
with open(tech_file, "w") as f:
f.write("\n".join(urls[:20]))
# Run focused scan
tech_output = f"{WORK_DIR}/scan_{tech.lower().replace(' ', '_')}.json"
stdout, stderr, rc = run(
f"nuclei -l {tech_file} -j -rl 10 -c 5 "
f"-t {NUCLEI_TEMPLATES}/http/cves/ "
f"-severity critical,high,medium "
f"-o {tech_output} -silent 2>/dev/null",
timeout=120
)
if os.path.exists(tech_output):
with open(tech_output) as f:
findings = [l for l in f if l.strip()]
if findings:
all_findings.extend(findings)
ok(f"{tech}: {len(findings)} findings")
# Merge all findings
merged_file = f"{REPORTS_DIR}/tech_targeted_{int(time.time())}.json"
with open(merged_file, "w") as f:
f.write("\n".join(all_findings))
return merged_file, len(all_findings)
# ============================================================
# PHASE 5: REPORT
# ============================================================
def generate_report(findings_file, tech_summary_data, targets_count):
"""Generate a comprehensive report"""
report_file = f"{REPORTS_DIR}/hunter_report_{int(time.time())}.md"
findings = []
cves = Counter()
severities = Counter()
target_urls = set()
if os.path.exists(findings_file):
with open(findings_file) as f:
for line in f:
if not line.strip(): continue
try:
d = json.loads(line)
sev = d.get("info", {}).get("severity", "unknown")
severities[sev] += 1
# Extract CVE
cve_list = []
for ref in d.get("info", {}).get("classification", {}).get("cve", []):
cve_list.append(ref.get("id", ""))
cve_id = cve_list[0] if cve_list else "N/A"
for c in cve_list:
cves[c] += 1
findings.append({
"url": d.get("matched-at", d.get("host", "?")),
"cve": cve_id,
"severity": sev,
"name": d.get("info", {}).get("name", "?"),
"extracted": d.get("extracted-results", []),
})
target_urls.add(d.get("matched-at", d.get("host", "?")))
except: pass
# Build report
icons = {"critical": "🔴", "high": "🟠", "medium": "🟡", "low": "🔵", "unknown": ""}
lines = []
lines.append(f"# Mass Vulnerability Hunter Report")
lines.append(f"Generated: {time.strftime('%Y-%m-%d %H:%M')}")
lines.append(f"")
lines.append(f"## Summary")
lines.append(f"| Metric | Value |")
lines.append(f"|--------|-------|")
lines.append(f"| Targets Probed | {targets_count} |")
if tech_summary_data:
_, techs = tech_summary_data
lines.append(f"| Live Hosts | {len(tech_summary_data[0])} |")
lines.append(f"| Technologies Detected | {len(techs)} |")
lines.append(f"| Total Findings | {len(findings)} |")
lines.append(f"| Unique Vulnerable Hosts | {len(target_urls)} |")
for sev in ["critical", "high", "medium", "low"]:
if severities[sev]:
lines.append(f"| {icons.get(sev, '?')} {sev.capitalize()} | {severities[sev]} |")
if cves:
lines.append(f"")
lines.append(f"## CVEs Detected")
for cve, cnt in cves.most_common(30):
lines.append(f"- [{cve}](https://nvd.nist.gov/vuln/detail/{cve}): {cnt} occurrences")
if findings:
lines.append(f"")
lines.append(f"## All Findings")
for f_data in findings:
icon = icons.get(f_data["severity"], "?")
lines.append(f"- {icon} [{f_data['cve']}] {f_data['name']} @ {f_data['url']}")
if f_data["extracted"]:
for ex in f_data["extracted"][:3]:
lines.append(f" - `{ex}`")
if tech_summary_data:
_, techs = tech_summary_data
if techs:
lines.append(f"")
lines.append(f"## Detected Technologies")
for tech, cnt in techs.most_common(20):
lines.append(f"- {tech}: {cnt} targets")
with open(report_file, "w") as f:
f.write("\n".join(lines))
return report_file, findings
# ============================================================
# MAIN
# ============================================================
def main():
mode = sys.argv[1] if len(sys.argv) > 1 else "auto"
print()
print("╔═══════════════════════════════════════════╗")
print("║ NO-API VULNERABILITY HUNTER ║")
print("╚═══════════════════════════════════════════╝")
print()
merged_targets = f"{WORK_DIR}/merged_targets.txt"
if mode == "target" and len(sys.argv) >= 3:
# Hunt a specific target domain
domain = sys.argv[2]
log(f"Hunting target domain: {domain}")
# Phase 1: Subdomain enumeration
log("[1/4] Subdomain enumeration...")
subdomains = enumerate_subdomains_shodan(domain)
if subdomains:
ok(f"Discovered {len(subdomains)} subdomains for {domain}")
with open(merged_targets, "w") as f:
f.write("\n".join(subdomains))
else:
warn(f"No subdomains found via Shodan. Using root domain.")
with open(merged_targets, "w") as f:
f.write(domain)
elif mode == "deep":
# Deep scan - target mid-tier Tranco sites
log("[1/4] Target discovery (Tranco deep)...")
targets_file = discover_tranco_deep(count=2000, offset=50000)
if not targets_file:
bad("Failed to get target list")
return
# Also try CommonCrawl
cc_file = discover_commoncrawl_vuln_patterns()
# Merge targets
all_targets = []
with open(targets_file) as f:
all_targets.extend([l.strip() for l in f if l.strip()])
if cc_file and os.path.exists(cc_file):
with open(cc_file) as f:
all_targets.extend([l.strip() for l in f if l.strip()])
with open(merged_targets, "w") as f:
f.write("\n".join(sorted(set(all_targets))))
ok(f"{len(set(all_targets))} unique targets")
else:
# Auto mode - balanced approach
log("[1/4] Target discovery...")
# Get targets from multiple sources
tranco_file = discover_tranco_deep(count=500, offset=50000)
# Merge
all_targets = []
if tranco_file and os.path.exists(tranco_file):
with open(tranco_file) as f:
all_targets.extend([l.strip() for l in f if l.strip()])
with open(merged_targets, "w") as f:
f.write("\n".join(sorted(set(all_targets))))
ok(f"{len(set(all_targets))} unique targets")
# Phase 2: Tech Detection
targets_count = 0
if os.path.exists(merged_targets):
with open(merged_targets) as f:
targets_count = sum(1 for _ in f)
if targets_count == 0:
bad("No targets to scan")
return
print()
log(f"[2/4] Tech detection on {targets_count} targets...")
tech_file, live_count = tech_detect(merged_targets)
if live_count == 0:
warn(f"No live hosts found. Try different target range.")
return
ok(f"{live_count} live hosts detected")
# Show tech summary
targets, techs = tech_summary(tech_file)
print(f"\nTop technologies:")
for tech, cnt in techs.most_common(15):
print(f" {tech:35} {cnt} targets")
# Phase 3: CVE Scanning
print()
log("[3/4] CVE scanning...")
# Run mass CVE scan (critical/high)
mass_output, mass_count = scan_with_nuclei(merged_targets, "critical,high")
ok(f"Mass CVE scan: {mass_count} findings")
# Run tech-targeted scans (medium too, since we know the tech)
tech_output, tech_count = tech_targeted_scan(tech_file)
ok(f"Tech-targeted scan: {tech_count} findings")
# Merge findings
merged_findings = f"{REPORTS_DIR}/hunt_all_findings.json"
all_findings = []
for f in [mass_output, tech_output]:
if os.path.exists(f):
with open(f) as fh:
all_findings.extend([l for l in fh if l.strip()])
with open(merged_findings, "w") as f:
f.write("\n".join(all_findings))
# Phase 4: Report
print()
log("[4/4] Generating report...")
report_file, findings = generate_report(merged_findings, (targets, techs), targets_count)
print()
print("=" * 60)
print(f" ✅ HUNT COMPLETE")
print(f" Targets scanned: {targets_count}")
print(f" Live hosts: {live_count}")
print(f" Total findings: {len(findings)}")
print(f" Report: {report_file}")
print("=" * 60)
# Output findings summary
if findings:
print("\nTop CVEs found:")
cves = Counter(f["cve"] for f in findings)
for cve, cnt in cves.most_common(10):
print(f" {cve}: {cnt} occurrences")
return report_file
if __name__ == "__main__":
main()

317
engine/hunter.sh Executable file
View File

@@ -0,0 +1,317 @@
#!/usr/bin/env bash
# ============================================================
# HUNTER — Mass Vulnerability Discovery Engine
# Part of The Analyzer
# Finds vulnerable websites at scale using OSINT + nuclei
# ============================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ANALYZER_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
REPORTS_DIR="$ANALYZER_DIR/reports"
TARGETS_DIR="$ANALYZER_DIR/targets"
WORK_DIR="/tmp/analyzer-hunter"
NUCLEI_TEMPLATES="${NUCLEI_TEMPLATES:-$HOME/nuclei-templates}"
HTTPS="$HOME/go/bin/httpx"
mkdir -p "$WORK_DIR" "$REPORTS_DIR" "$TARGETS_DIR"
# Colors
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
BLUE='\033[0;34m'; NC='\033[0m'
log() { echo -e "${BLUE}[*]${NC} $1"; }
ok() { echo -e "${GREEN}[✓]${NC} $1"; }
warn(){ echo -e "${YELLOW}[!]${NC} $1"; }
err() { echo -e "${RED}[✗]${NC} $1"; }
# ============================================================
# PHASE 1: TARGET DISCOVERY
# ============================================================
discover_from_tranco() {
local count="${1:-500}"
local output="$TARGETS_DIR/hunt_tranco.txt"
log "Fetching top $count sites from Tranco..."
curl -skL "https://tranco-list.eu/top-1m.csv.zip" -o "$WORK_DIR/top1m.zip" 2>/dev/null
if unzip -o "$WORK_DIR/top1m.zip" -d "$WORK_DIR" 2>/dev/null; then
head -"$count" "$WORK_DIR"/top-1m.csv 2>/dev/null | cut -d, -f2 > "$output"
ok "$(wc -l < "$output") domains from Tranco"
return 0
fi
return 1
}
discover_from_analyzer() {
local output="$TARGETS_DIR/hunt_analyzer.txt"
if [ -f "$TARGETS_DIR/top50.txt" ]; then
cp "$TARGETS_DIR/top50.txt" "$output"
ok "$(wc -l < "$output") from Analyzer target list"
return 0
fi
return 1
}
discover_vulnerable_software() {
local output="$WORK_DIR/vuln_software_targets.txt"
log "Building vulnerable software target list..."
# Sites running known-vulnerable software
cat > "$WORK_DIR/vuln_sites.txt" << 'VULNSITES'
# Known software vendors/instances that may have vulnerable versions
wordpress.org
joomla.org
drupal.org
magento.com
prestashop.com
opencart.com
phpmyadmin.net
roundcube.net
cpanel.net
php.net
apache.org
nginx.org
mysql.com
postgresql.org
mongodb.com
nodejs.org
laravel.com
symfony.com
rails.org
docker.com
kubernetes.io
jenkins.io
gitlab.com
sonarqube.org
grafana.com
prometheus.io
elastic.co
redis.io
tomcat.apache.org
jira.atlassian.com
confluence.atlassian.com
vbforum.com
simplemachines.org
phpbb.com
mediawiki.org
VULNSITES
# Also add common CMS plugin repositories
echo "woocommerce.com" >> "$WORK_DIR/vuln_sites.txt"
echo "easy-digital-downloads.com" >> "$WORK_DIR/vuln_sites.txt"
httpx -l "$WORK_DIR/vuln_sites.txt" -rl 20 -silent -timeout 5 \
-o "$output" 2>/dev/null
if [ -s "$output" ]; then
ok "$(wc -l < "$output") live software targets"
fi
}
# ============================================================
# PHASE 2: TECH DETECTION & TARGETED CVE SCANNING
# ============================================================
detect_technologies() {
local targets_file="$1"
local output="$WORK_DIR/tech_detected.json"
log "Detecting technologies on $(wc -l < "$targets_file") targets..."
httpx -l "$targets_file" -tech-detect -j -rl 20 -silent -timeout 5 \
-o "$output" 2>/dev/null
local count=$(wc -l < "$output" 2>/dev/null || echo 0)
ok "Tech detected on $count hosts"
# Summary
python3 -c "
import json, sys
from collections import Counter
techs = Counter()
with open('$output') as f:
for line in f:
try:
d = json.loads(line)
for t in d.get('tech', []):
techs[t] += 1
except: pass
print('Top technologies detected:')
for tech, cnt in techs.most_common(20):
print(f' {tech}: {cnt}')
" 2>/dev/null
echo "$output"
}
run_focused_cve_scan() {
local targets_file="$1"
local tech_file="$2"
local output="$REPORTS_DIR/hunter_cve_$(date +%Y%m%d_%H%M%S).json"
# Map technologies to specific CVE template categories
log "Running focused CVE scan..."
# Scan ALL targets with general CVE templates (faster than all 4k)
nuclei -l "$targets_file" \
-j \
-rl 30 \
-c 15 \
-t "$NUCLEI_TEMPLATES/http/cves/" \
-o "$output" \
-severity critical,high \
-silent \
-stats \
2>/dev/null
if [ -s "$output" ]; then
ok "$(wc -l < "$output") critical/high findings"
else
warn "No critical/high findings in mass scan"
fi
# Also run medium + exploitation templates for more depth
local output2="$REPORTS_DIR/hunter_cve_medium_$(date +%s).json"
nuclei -l "$targets_file" \
-j \
-rl 20 \
-c 10 \
-t "$NUCLEI_TEMPLATES/http/cves/" \
-o "$output2" \
-severity medium \
-silent \
2>/dev/null
echo "$output"
}
# ============================================================
# PHASE 3: THE ANALYZER INTEGRATION
# ============================================================
analyze_findings() {
local findings_file="$1"
local output="$REPORTS_DIR/hunter_report_$(date +%Y%m%d_%H%M).md"
log "Generating report..."
python3 -c "
import json, sys
from collections import Counter
from datetime import datetime
findings = []
cves = Counter()
severities = Counter()
with open('$findings_file') as f:
for line in f:
try:
d = json.loads(line)
sev = d.get('info',{}).get('severity','unknown')
severities[sev] += 1
# Extract CVE IDs
cve_list = []
for ref in d.get('info',{}).get('classification',{}).get('cve',[]):
cve_list.append(ref.get('id',''))
if not cve_list:
# Try alternative CVE sources
for ref in d.get('info',{}).get('reference',[]):
if 'cve' in ref.lower() or 'CVE' in ref:
cve_list.append(ref.split('/')[-1])
cve_id = cve_list[0] if cve_list else 'N/A'
for c in cve_list:
cves[c] += 1
findings.append({
'url': d.get('matched-at', d.get('host', '?')),
'cve': cve_id,
'severity': sev,
'name': d.get('info',{}).get('name', '?'),
'template': d.get('template-id', ''),
'extracted': d.get('extracted-results', []),
})
except: pass
# Summary
icons = {'critical':'🔴','high':'🟠','medium':'🟡','low':'🔵','unknown':'⚪'}
print('# Mass Vulnerability Hunter Report')
print(f'Generated: {datetime.now().strftime(\"%Y-%m-%d %H:%M\")}')
print()
print('## Summary')
print('| Metric | Value |')
print('|--------|-------|')
print(f'| Total Findings | {len(findings)} |')
for sev in ['critical','high','medium','low']:
if severities[sev]:
print(f'| {icons.get(sev,\"?\")} {sev.capitalize()} | {severities[sev]} |')
if cves:
print()
print('## CVEs Detected')
for cve, cnt in cves.most_common(30):
print(f'- [{cve}](https://nvd.nist.gov/vuln/detail/{cve}): {cnt} occurrences')
print()
print('## All Findings')
for f in findings:
icon = icons.get(f['severity'], '?')
print(f'- {icon} [{f[\"cve\"]}] {f[\"name\"]} @ {f[\"url\"]}')
" > "$output" 2>/dev/null
ok "Report: $output"
cat "$output"
}
# ============================================================
# MAIN ENTRY POINT
# ============================================================
hunter_main() {
local target_count="${1:-500}"
local mode="${2:-auto}" # auto|quick|deep
echo ""
echo "╔═══════════════════════════════════════════╗"
echo "║ MASS VULNERABILITY HUNTER ║"
echo "╚═══════════════════════════════════════════╝"
echo ""
# Phase 1: Build target list
log "PHASE 1: Target Discovery"
discover_from_tranco "$target_count"
discover_vulnerable_software
discover_from_analyzer
# Merge targets
cat "$TARGETS_DIR"/hunt_*.txt "$WORK_DIR"/vuln_software_targets.txt 2>/dev/null | \
sort -u > "$WORK_DIR/all_targets.txt"
ok "Total unique targets: $(wc -l < "$WORK_DIR/all_targets.txt")"
# Phase 2: Tech Detection + CVE Scan
echo ""
log "PHASE 2: Scanning"
local tech_file="$WORK_DIR/tech_detected.json"
detect_technologies "$WORK_DIR/all_targets.txt" "$tech_file"
echo ""
local findings_file=$(run_focused_cve_scan "$WORK_DIR/all_targets.txt" "$tech_file")
# Phase 3: Analyze + Report
echo ""
log "PHASE 3: Analysis"
analyze_findings "$findings_file"
echo ""
ok "Hunt complete!"
echo " Targets scanned: $(wc -l < "$WORK_DIR/all_targets.txt")"
echo " Findings: $(wc -l < "$findings_file" 2>/dev/null || echo 0)"
echo " Report: $REPORTS_DIR/hunter_report_*.md"
}
# Run if executed directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
hunter_main "$@"
fi