I used to spend 4β5 hours manually doing recon on every target.
Subdomain enumeration. Port scanning. Vulnerability checking. Directory bruteforcing. It was repetitive, slow, and exhausting.
Then I automated it.
Now I run one script before bed and wake up to a report of potential vulnerabilities. This article shows you exactly how I built that system β and how you can copy it for your own bug bounty workflow.
What Is Recon and Why Automate It?
Recon (reconnaissance) is the first step in bug bounty hunting. Before you can find vulnerabilities, you need to map the target:
- What subdomains exist?
- What ports are open?
- What technologies are running?
- What known vulnerabilities exist on those technologies?
Doing this manually for every target is a waste of your most valuable resource time.
Automation solves this. You define the logic once, and the machine runs it thousands of times faster than you ever could.
Tools We'll Use
Subfinder Subdomain discovery
go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
Httpx HTTP probing (live hosts)
go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest
Nuclei Vulnerability scanning
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
Nmap Port scanning
sudo apt install nmap
Python 3 Glue everything together
Pre-installed on Kali Linux

All tools are free and open source. Install Go first if you haven't:
sudo apt install golang-gThe Recon Automation Script
Here is the full Python script. Save it as recon.py:
import subprocess
import os
import sys
import datetime
def banner():
print("""
βββββββ ββββββββ βββββββ βββββββ ββββ βββ
ββββββββββββββββββββββββββββββββββββββ βββ
ββββββββββββββ βββ βββ βββββββββ βββ
ββββββββββββββ βββ βββ βββββββββββββ
βββ βββββββββββββββββββββββββββββββ ββββββ
βββ βββββββββββ βββββββ βββββββ βββ βββββ
Bug Bounty Recon Automation - by @HackerMD
""")
def create_output_dir(domain):
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
output_dir = f"recon_{domain}_{timestamp}"
os.makedirs(output_dir, exist_ok=True)
return output_dir
def run_subfinder(domain, output_dir):
print(f"\n[*] Running Subfinder on {domain}...")
output_file = f"{output_dir}/subdomains.txt"
cmd = f"subfinder -d {domain} -silent -o {output_file}"
subprocess.run(cmd, shell=True)
print(f"[+] Subdomains saved to {output_file}")
return output_file
def run_httpx(subdomains_file, output_dir):
print("\n[*] Probing for live hosts with Httpx...")
output_file = f"{output_dir}/live_hosts.txt"
cmd = f"httpx -l {subdomains_file} -silent -o {output_file} -status-code -title -tech-detect"
subprocess.run(cmd, shell=True)
print(f"[+] Live hosts saved to {output_file}")
return output_file
def run_nuclei(live_hosts_file, output_dir):
print("\n[*] Running Nuclei vulnerability scan...")
output_file = f"{output_dir}/nuclei_results.txt"
cmd = f"nuclei -l {live_hosts_file} -severity critical,high,medium -o {output_file} -silent"
subprocess.run(cmd, shell=True)
print(f"[+] Nuclei results saved to {output_file}")
return output_file
def run_nmap(domain, output_dir):
print(f"\n[*] Running Nmap port scan on {domain}...")
output_file = f"{output_dir}/nmap_results.txt"
cmd = f"nmap -sV --top-ports 1000 {domain} -oN {output_file}"
subprocess.run(cmd, shell=True)
print(f"[+] Nmap results saved to {output_file}")
def generate_report(domain, output_dir):
print("\n[*] Generating final report...")
report_file = f"{output_dir}/REPORT_{domain}.txt"
with open(report_file, "w") as report:
report.write(f"=== BUG BOUNTY RECON REPORT ===\n")
report.write(f"Target: {domain}\n")
report.write(f"Date: {datetime.datetime.now()}\n")
report.write(f"Tool: @HackerMD Recon Automation\n\n")
for filename in os.listdir(output_dir):
filepath = os.path.join(output_dir, filename)
if filename.endswith(".txt") and filename != f"REPORT_{domain}.txt":
report.write(f"\n{'='*50}\n")
report.write(f"[{filename}]\n")
report.write(f"{'='*50}\n")
with open(filepath, "r") as f:
report.write(f.read())
print(f"\n[β] Report generated: {report_file}")
print(f"[β] All files saved in: {output_dir}/\n")
def main():
banner()
if len(sys.argv) != 2:
print("Usage: python3 recon.py <target-domain>")
print("Example: python3 recon.py example.com")
sys.exit(1)
domain = sys.argv[1]
output_dir = create_output_dir(domain)
print(f"[+] Target: {domain}")
print(f"[+] Output Directory: {output_dir}")
subdomains_file = run_subfinder(domain, output_dir)
live_hosts_file = run_httpx(subdomains_file, output_dir)
run_nuclei(live_hosts_file, output_dir)
run_nmap(domain, output_dir)
generate_report(domain, output_dir)
if __name__ == "__main__":
main()How to Run It
# Save the script
nano recon.py
# Make it executable
chmod +x recon.py
# Run against a target (only on programs you have permission for!)
python3 recon.py targetdomain.comOutput you'll get:
recon_targetdomain.com_20260225_210000/
βββ subdomains.txt β All discovered subdomains
βββ live_hosts.txt β Only live/active hosts
βββ nuclei_results.txt β Vulnerability scan results
βββ nmap_results.txt β Open ports & services
βββ REPORT_targetdomain.txt β Full combined reportUnderstanding Each Step
Step 1 Subfinder
Subfinder queries over 50 passive DNS sources simultaneously β Shodan, VirusTotal, CertSpotter, and more. A target like example.com might have 500+ subdomains that are invisible to normal browsing. Many of these subdomains have older, forgotten, vulnerable services running on them β these are goldmines for bug hunters.
Step 2 Httpx
Out of 500 subdomains, maybe only 200 are actually live. Httpx filters these out quickly, shows you their HTTP status codes, page titles, and what technologies they're running (Apache, Nginx, WordPress, etc.). Tech detection alone can tell you which exploits to try.
Step 3 Nuclei
This is where the magic happens. Nuclei has 9,000+ vulnerability templates maintained by the ProjectDiscovery team. It checks for:
- Exposed admin panels
- Default credentials
- CVEs in detected technologies
- Misconfigurations
- Exposed sensitive files (.env, .git, backup files)
- SSRF, XSS, SQLi patterns
One Nuclei scan can surface findings that would take hours to find manually.
Step 4 Nmap
Port scanning reveals services running outside port 80/443. An FTP server on port 21, a Redis instance on 6379, or an exposed Elasticsearch on 9200 β these are all potential critical findings.
Advanced: Adding Waybackurls for Historical Recon
Want to find even more attack surface? Add historical URL discovery:
pip install waybackpyAdd this function to the script:
def run_wayback(domain, output_dir):
print(f"\n[*] Fetching historical URLs from Wayback Machine...")
output_file = f"{output_dir}/wayback_urls.txt"
cmd = f"echo {domain} | waybackurls > {output_file}"
subprocess.run(cmd, shell=True)
print(f"[+] Historical URLs saved to {output_file}")Historical URLs often reveal forgotten endpoints β old API versions, backup pages, internal paths β that developers forgot to secure.
Important Rules β Read This
Before you run this on any target:
- Only scan programs you are authorized to test β HackerOne, Bugcrowd, or explicit written permission
- Never scan government or critical infrastructure
- Rate limit your scans β Add
-rate-limit 100to Nuclei to avoid overwhelming servers - Check the program's scope β Some programs exclude specific subdomains
Running unauthorized scans is illegal. Stick to your authorized scope β always.
Real Results From My Workflow
Using this exact automation pipeline, I have found:
- Exposed .env files containing database credentials β High severity
- Default admin credentials on forgotten subdomains β Critical
- Outdated Apache versions with known CVEs β Medium/High
- Open redirect vulnerabilities via Nuclei templates β Low/Medium
Not every scan returns critical findings β but consistency pays off. Run this against 10 targets and you will find something reportable.
What to Do When Nuclei Finds Something
- Verify manually β Always confirm the finding is real, not a false positive
- Document everything β Screenshot, request/response, impact explanation
- Write a clear report β Title, severity, steps to reproduce, impact, remediation
- Submit to the program β Bugcrowd, HackerOne, or the program's VDP
The automation finds the lead. You close the deal with a good report.
Final Thoughts
Manual recon is dead for serious bug hunters. The hunters who are consistently earning are the ones who built systems that work while they sleep.
This script is your starting point. Customize it, add more tools, improve the report format, add Slack/email notifications for critical findings.
The best recon pipeline is the one you build yourself β because you understand every line of it.
Now go automate. π
I'm @HackerMD β a cybersecurity researcher and bug bounty hunter from India. Follow me for more practical security content, real writeups, and automation scripts.