#!/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 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 # Hunt a specific target") print(" python3 autobounty.py all # Scan all known targets") print(" python3 autobounty.py watch # 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)