🚀 Enterprise-Grade Subdomain Reconnaissance & Intelligence Suite 🚀
Advanced subdomain enumeration tool with 20+ passive sources, intelligent brute force, AI-powered mutations, real-time dashboard, REST API, and vulnerability assessment.
Features • Installation • Usage • Configuration • API Documentation • Tutorials
- 🎯 Overview
- ✨ Features
- 🔧 Installation
- 🚀 Quick Start
- 💻 Usage
- ⚙️ Configuration
- 🌐 API Documentation
- 📚 Tutorials
- 🎨 Dashboard
- 🔌 Plugin System
- 📊 Output Formats
- 🛡️ Security & Best Practices
- 🤝 Contributing
- 📄 License
SubCandalena (SubHunterX Pro) adalah tool reconnaissance subdomain tingkat enterprise yang dirancang untuk penetration tester, bug bounty hunter, dan security researcher. Tool ini mengkombinasikan 20+ sumber passive reconnaissance, brute force cerdas, AI-powered mutations, dan analisis vulnerability real-time.
- 🔍 Comprehensive Discovery: 20+ sumber passive + brute force intelligence
- ⚡ Lightning Fast: Multi-threaded dengan asyncio untuk performa maksimal
- 🎨 Beautiful Dashboard: Web dashboard interaktif dengan visualisasi real-time
- 🤖 AI-Powered: Mutasi subdomain cerdas dengan pattern learning
- 📊 Rich Reporting: Export ke JSON, CSV, HTML dengan screenshot
- 🔌 Extensible: Plugin system untuk custom analyzer
- 🌐 REST API: Integrasi mudah dengan tool lain
- 💾 Database: Persistent storage dengan SQLite untuk tracking historical
- Certificate Transparency: crt.sh, Censys
- DNS Services: DNSDumpster, HackerTarget, ThreatCrowd
- Search Engines: Google, Bing, Yahoo dorking
- Archives: Wayback Machine, Common Crawl
- Security Platforms: VirusTotal, AlienVault OTX, URLScan
- Code Repositories: GitHub, GitLab API search
- Social Media: Twitter mentions, Pastebin leaks
- Custom Sources: 10+ additional proprietary sources
-
Intelligent Brute Force
- Smart wordlist generation (1k-100k entries)
- AI-powered permutations & mutations
- Pattern recognition dari existing subdomains
- DNS wildcard detection & filtering
-
Permutation Engine
- Prefix/suffix generation (dev-, staging-, prod-)
- Number mutations (api1, api2, api-v2)
- Common patterns (admin, portal, vpn, mail)
- Custom mutation rules
- HTTP/HTTPS Probe: Smart port detection (80, 443, 8080, 8443)
- Technology Detection: Framework, CMS, Server identification
- Screenshot Capture: Automated visual reconnaissance
- Response Analysis: Status codes, redirects, headers
- SSL/TLS Analysis: Certificate validation, expiry, issuer
- Vulnerability Indicators: Open ports, misconfigurations
- Rich terminal output dengan color coding
- Real-time progress bars
- Live statistics updates
- ASCII art banner
- Interactive menus
- Real-time Monitoring: Live scan progress
- Interactive Visualizations: Charts, graphs, maps
- Subdomain Explorer: Filter, search, sort results
- Screenshot Gallery: Visual subdomain preview
- Export Manager: Download results in multiple formats
- Scan History: Track previous scans & compare
- Scan Management: Start/stop/status endpoints
- Results Query: Filter by domain, status, date
- Export API: Programmatic data access
- Webhook Support: Real-time notifications
- Authentication: API key management
- SQLite Storage: Lightweight persistent database
- Scan History: Track all reconnaissance activities
- Subdomain Tracking: Monitor changes over time
- Relationship Mapping: Parent-child subdomain relations
- Meta Storage: Custom fields, tags, notes
- JSON: Structured data for automation
- CSV: Excel-compatible spreadsheet
- HTML: Beautiful web reports with embedded screenshots
- Markdown: Documentation-friendly format
- TXT: Simple list for piping to other tools
- Python: 3.8 or higher
- Operating System: Windows, Linux, macOS
- Memory: 2GB RAM minimum (4GB recommended)
- Storage: 500MB free space
# Clone repository
git clone https://github.com/yourusername/SubCandalena.git
cd SubCandalena
# Install dependencies
pip3 install -r requirements.txt
# Verify installation
python3 main.py --help# Create virtual environment
python3 -m venv venv
# Activate virtual environment
# Windows:
venv\Scripts\activate
# Linux/Mac:
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Run tool
python main.py example.comdocker pull subcandalena/subhunterx:latest
docker run -it subcandalena/subhunterx example.comrich==13.7.1 # Beautiful CLI output
aiohttp==3.9.1 # Async HTTP requests
requests==2.31.0 # HTTP library
fastapi==0.104.1 # REST API framework
uvicorn==0.24.0 # ASGI server
sqlalchemy==2.0.23 # Database ORM
pillow==10.1.0 # Screenshot processing
beautifulsoup4==4.12.2 # HTML parsing
selenium==4.15.2 # Browser automation
plotly==5.17.0 # Data visualization
pyyaml==6.0.1 # Configuration parser
# Simple scan
python main.py example.com
# Quick scan (fast mode)
python main.py example.com --quick
# With dashboard
python main.py example.com --dashboard
# Custom threads
python main.py example.com --threads 100🚀 Starting FULL reconnaissance on example.com
📡 PHASE 1: Passive Reconnaissance
✅ Found 127 passive subdomains
⚡ PHASE 2: Intelligent Brute Force
✅ Found 43 live subdomains
🔬 PHASE 3: Deep Analysis & Vulnerability Assessment
✅ Analyzed 170 subdomains
✅ Scan completed! Found 170 live subdomains
📁 Results saved to: reports/SubCandalena_example_com_20260115_072031.json
python main.py <domain> [options]| Option | Short | Description | Default |
|---|---|---|---|
--dashboard |
-d |
Open web dashboard after scan | False |
--threads |
-t |
Number of concurrent threads | 50 |
--quick |
-q |
Quick scan mode (100 words, no screenshots) | False |
# Standard reconnaissance
python main.py target.com
# High-speed scan with 100 threads
python main.py target.com --threads 100
# Quick scan for CI/CD integration
python main.py target.com --quick
# Full scan with dashboard
python main.py target.com --dashboard
# Combine multiple options
python main.py target.com --threads 80 --dashboardStart the web dashboard:
# Start dashboard server
python dashboard.py
# Access at: http://localhost:5000Dashboard Features:
- 📊 Real-time scan statistics
- 🔍 Interactive subdomain explorer
- 📸 Screenshot gallery
- 📈 Historical scan comparison
- 💾 Export management
Start the REST API server:
# Start API server
python api_server.py
# API available at: http://localhost:8000Edit config/config.yaml to customize behavior:
# SubHunterX Pro Configuration
# API Settings
api:
host: 127.0.0.1
port: 8000
# Database Settings
database:
path: ./subhunterx_pro.db
# Scanning Settings
subhunterx:
threads: 50 # Concurrent threads (10-200)
timeout: 8 # Request timeout in seconds
rate_limit: 0.1 # Delay between requests
screenshot: false # Enable screenshot capture
max_screenshots: 20 # Maximum screenshots to capture
# Wordlist Settings
wordlists:
brute_size: 1000 # Wordlist size (100-100000)- Range: 10-200
- Recommended: 50-100
- Low (10-30): Stealthy, slower
- Medium (50-80): Balanced
- High (100-200): Fast, aggressive
- Range: 3-15 seconds
- Recommended: 8
- Low (3-5): Fast but may miss slow servers
- High (10-15): Thorough but slower
- 100: Quick scan (~1 minute)
- 1000: Standard scan (~5-10 minutes)
- 10000: Deep scan (~30-60 minutes)
- 100000: Extreme scan (~2-4 hours)
- false: Fast, no visual recon
- true: Capture webpage screenshots (slower)
Base URL: http://localhost:8000
GET /api/results?domain=example.comResponse:
{
"status": "success",
"data": [
{
"subdomain": "api.example.com",
"status_code": 200,
"ip_address": "1.2.3.4",
"source": "passive",
"timestamp": "2026-01-15T07:20:31"
}
],
"count": 127
}POST /api/scan
Content-Type: application/json
{
"domain": "example.com"
}Response:
{
"status": "scan_started",
"domain": "example.com",
"scan_id": "abc123"
}GET /api/status/{scan_id}Response:
{
"scan_id": "abc123",
"status": "running",
"progress": 45,
"subdomains_found": 78,
"elapsed_time": "00:05:32"
}import requests
# Start a scan
response = requests.post('http://localhost:8000/api/scan',
json={'domain': 'example.com'})
scan_id = response.json()['scan_id']
# Check status
status = requests.get(f'http://localhost:8000/api/status/{scan_id}')
print(status.json())
# Get results
results = requests.get('http://localhost:8000/api/results?domain=example.com')
for subdomain in results.json()['data']:
print(f"{subdomain['subdomain']} - {subdomain['status_code']}")Goal: Find all subdomains for a target domain
# Step 1: Run basic scan
python main.py target.com
# Step 2: View results
cat reports/SubCandalena_target_com_*.json
# Step 3: Extract live subdomains
python -c "import json; data=json.load(open('reports/SubCandalena_target_com_*.json')); print('\n'.join([s['subdomain'] for s in data if s['status_code']==200]))"Expected Output: List of all discovered subdomains with status codes
Goal: Scan target as fast as possible
# Step 1: Configure for speed
python main.py target.com --threads 150 --quick
# Step 2: Results in under 5 minutes
# Quick mode uses:
# - 20 threads only
# - 100 word wordlist
# - No screenshots
# - Basic analysisUse Cases:
- CI/CD pipeline integration
- Quick subdomain validation
- Bug bounty recon phase
Goal: Visual reconnaissance with web interface
# Step 1: Run scan with dashboard flag
python main.py target.com --dashboard
# Step 2: Dashboard auto-opens at http://localhost:5000
# Step 3: Explore features
# - View real-time progress
# - Filter subdomains by status
# - View screenshots
# - Export custom reports
# - Compare with previous scansDashboard Features:
- 📊 Interactive charts (subdomain distribution, status codes)
- 🔍 Search & filter functionality
- 📸 Screenshot carousel
- 💾 One-click export (JSON/CSV/HTML)
- 📈 Historical trend analysis
Goal: Integrate SubCandalena into your workflow
# Step 1: Start API server
python api_server.py &
# Step 2: Create automation scriptautomation.py:
#!/usr/bin/env python3
import requests
import time
API_BASE = "http://localhost:8000"
def scan_domain(domain):
# Start scan
response = requests.post(f"{API_BASE}/api/scan",
json={"domain": domain})
scan_id = response.json()['scan_id']
# Wait for completion
while True:
status = requests.get(f"{API_BASE}/api/status/{scan_id}")
data = status.json()
if data['status'] == 'completed':
break
print(f"Progress: {data['progress']}% - Found: {data['subdomains_found']}")
time.sleep(5)
# Get results
results = requests.get(f"{API_BASE}/api/results?domain={domain}")
return results.json()['data']
# Usage
targets = ['example.com', 'target.com', 'test.com']
for target in targets:
print(f"\n🎯 Scanning {target}...")
subdomains = scan_domain(target)
print(f"✅ Found {len(subdomains)} subdomains")# Step 3: Run automation
python automation.pyGoal: Optimize for specific scenarios
# config/config.yaml
subhunterx:
threads: 10 # Low thread count
timeout: 12 # Higher timeout
rate_limit: 1.0 # 1 second delay between requests
screenshot: false
wordlists:
brute_size: 500 # Smaller wordlistpython main.py target.com
# Slow but stealthy, minimal footprint# config/config.yaml
subhunterx:
threads: 150 # High concurrency
timeout: 6 # Lower timeout
rate_limit: 0.05 # Minimal delay
screenshot: true # Capture screenshots
max_screenshots: 50
wordlists:
brute_size: 50000 # Large wordlistpython main.py target.com --threads 200
# Aggressive, maximum discovery# config/config.yaml
subhunterx:
threads: 80
timeout: 8
rate_limit: 0.1
screenshot: true # Visual evidence
max_screenshots: 30
wordlists:
brute_size: 10000 # Comprehensive wordlistpython main.py target.com --dashboard
# Balanced approach with visual reconGoal: Track subdomain changes over time
monitor.sh:
#!/bin/bash
DOMAIN="target.com"
INTERVAL=3600 # 1 hour
while true; do
echo "[$(date)] Starting scan for $DOMAIN"
# Run scan
python main.py $DOMAIN --quick
# Compare with previous results
python scripts/compare_scans.py $DOMAIN
# Alert on new subdomains
python scripts/alert_new.py $DOMAIN
echo "[$(date)] Sleeping for $INTERVAL seconds"
sleep $INTERVAL
donecompare_scans.py:
import json
from pathlib import Path
import sys
domain = sys.argv[1]
reports = sorted(Path('reports').glob(f'SubCandalena_{domain.replace(".", "_")}_*.json'))
if len(reports) < 2:
print("Need at least 2 scans to compare")
sys.exit(1)
# Load last two scans
with open(reports[-2]) as f:
old_data = json.load(f)
with open(reports[-1]) as f:
new_data = json.load(f)
old_subs = {s['subdomain'] for s in old_data}
new_subs = {s['subdomain'] for s in new_data}
# Find differences
added = new_subs - old_subs
removed = old_subs - new_subs
print(f"\n📊 Scan Comparison for {domain}")
print(f"📈 New subdomains: {len(added)}")
for sub in added:
print(f" + {sub}")
print(f"\n📉 Removed subdomains: {len(removed)}")
for sub in removed:
print(f" - {sub}")Goal: Extend SubCandalena with custom analyzers
plugins/custom_analyzer.py:
"""
Custom Analyzer Plugin Example
Checks for common vulnerabilities in subdomains
"""
class CustomAnalyzer:
def __init__(self, config):
self.config = config
self.vulnerabilities = []
def analyze(self, subdomain, response):
"""
Analyze subdomain for vulnerabilities
Args:
subdomain: Subdomain URL
response: HTTP response object
Returns:
dict: Analysis results
"""
results = {
'subdomain': subdomain,
'vulnerabilities': []
}
# Check for sensitive paths
sensitive_paths = [
'/.git/config',
'/.env',
'/admin',
'/phpmyadmin',
'/.aws/credentials'
]
for path in sensitive_paths:
if self.check_path(subdomain + path):
results['vulnerabilities'].append({
'type': 'Exposed Sensitive Path',
'path': path,
'severity': 'HIGH'
})
# Check for common misconfigurations
headers = response.headers
if 'Server' in headers:
results['server'] = headers['Server']
if 'X-Powered-By' in headers:
results['vulnerabilities'].append({
'type': 'Information Disclosure',
'detail': f"X-Powered-By: {headers['X-Powered-By']}",
'severity': 'LOW'
})
return results
def check_path(self, url):
"""Check if path exists"""
import requests
try:
r = requests.get(url, timeout=3, verify=False)
return r.status_code == 200
except:
return False
# Register plugin
def register():
return CustomAnalyzerUsage:
# In main.py or engine.py
from plugins.custom_analyzer import CustomAnalyzer
# Initialize plugin
analyzer = CustomAnalyzer(config)
# Use in scan
for subdomain in subdomains:
results = analyzer.analyze(subdomain, response)
if results['vulnerabilities']:
print(f"🚨 Vulnerabilities found in {subdomain}")
for vuln in results['vulnerabilities']:
print(f" - {vuln['type']}: {vuln.get('detail', 'N/A')}")-
Real-Time Monitoring
- Live scan progress
- Subdomains discovered counter
- Current phase indicator
- Elapsed time tracker
-
Subdomain Explorer
- Searchable table
- Filter by status code
- Sort by various fields
- Pagination
-
Visualizations
- Status code distribution (pie chart)
- Subdomain timeline (line graph)
- Source breakdown (bar chart)
- Geolocation map
-
Screenshot Gallery
- Thumbnail grid view
- Full-size lightbox
- Download individual screenshots
- Bulk export
-
Export Manager
- Export to JSON, CSV, HTML
- Custom field selection
- Filtered exports
- Scheduled exports
Dashboard Preview:
┌─────────────────────────────────────────────────┐
│ SubCandalena Dashboard │
├─────────────────────────────────────────────────┤
│ 📊 Statistics │
│ Total Subdomains: 237 │
│ Live: 189 | Down: 48 │
│ Sources: Passive (145) | Brute (92) │
├─────────────────────────────────────────────────┤
│ 🔍 Search: [_____] 🔽 Filter: All Status │
├─────────────────────────────────────────────────┤
│ Subdomain Status IP │
│ api.example.com 200 1.2.3.4 │
│ dev.example.com 200 1.2.3.5 │
│ staging.example.com 403 1.2.3.6 │
│ ... │
└─────────────────────────────────────────────────┘
-
Custom Analyzer (
plugins/custom_analyzer.py)- Vulnerability detection
- Technology fingerprinting
- Custom checks
-
Parameter Scanner (Coming Soon)
- URL parameter discovery
- Injection point identification
-
API Fuzzer (Coming Soon)
- API endpoint discovery
- Parameter fuzzing
See Tutorial 7: Custom Plugin Development for detailed guide.
{
"scan_info": {
"domain": "example.com",
"timestamp": "2026-01-15T07:20:31",
"duration": "00:15:43",
"total_found": 237
},
"subdomains": [
{
"subdomain": "api.example.com",
"ip_address": "1.2.3.4",
"status_code": 200,
"title": "API Gateway",
"server": "nginx",
"source": "passive",
"screenshot": "screenshots/api_example_com.png"
}
]
}Subdomain,IP Address,Status Code,Title,Server,Source,Timestamp
api.example.com,1.2.3.4,200,API Gateway,nginx,passive,2026-01-15 07:20:31
dev.example.com,1.2.3.5,200,Dev Environment,Apache,brute,2026-01-15 07:25:18Professional HTML report with:
- Executive summary
- Statistics dashboard
- Subdomain table
- Embedded screenshots
- Export functionality
- Print-friendly layout
api.example.com
dev.example.com
staging.example.com
IMPORTANT: Only use SubCandalena on domains you own or have explicit permission to test. Unauthorized scanning may be illegal in your jurisdiction.
- Rate Limiting: Use appropriate rate limits to avoid overwhelming target servers
- Threads: Don't use excessive threads (>200) unless necessary
- Scope: Define clear scope before scanning
- Authorization: Always get written permission
- Data Privacy: Handle discovered data responsibly
- Logging: Keep audit logs of your activities
- ✅ Use for authorized penetration testing
- ✅ Use for bug bounty programs (within scope)
- ✅ Use for your own domains
- ❌ Don't scan without permission
- ❌ Don't exploit discovered vulnerabilities
- ❌ Don't share sensitive data publicly
We welcome contributions! Here's how:
- Check existing issues
- Create detailed bug report
- Include steps to reproduce
- Attach relevant logs/screenshots
- Check roadmap & existing requests
- Describe use case clearly
- Explain expected behavior
- Consider implementation complexity
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open Pull Request
- Follow PEP 8 for Python code
- Use type hints
- Add docstrings
- Write unit tests
- Update documentation
This project is licensed under the MIT License - see the LICENSE file for details.
MIT License
Copyright (c) 2026 SubCandalena Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
[Full MIT License Text]
- Thanks to all contributors
- Inspired by tools like Sublist3r, Amass, Subfinder
- Built with amazing open-source libraries
- GitHub: https://github.com/yourusername/SubCandalena
- Issues: Report a bug
- Email: support@subcandalena.com
- Twitter: @SubCandalena
- Docker support
- Kubernetes scanning
- Cloud provider integration (AWS, Azure, GCP)
- Advanced reporting templates
- Machine learning for subdomain prediction
- Automated vulnerability exploitation
- Integration with popular security tools
- Mobile app (iOS/Android)
- Distributed scanning cluster
- Real-time collaboration
- Enterprise SaaS platform
- Advanced AI-powered reconnaissance
- Sublist3r: Fast subdomain enumeration
- Amass: Network mapping & attack surface discovery
- Subfinder: Fast passive subdomain discovery
- DNSRecon: DNS enumeration script
- Knockpy: Subdomain scanner
- OWASP Testing Guide
- Bug Bounty Methodology
- DNS RFC Documentation
- Penetration Testing Framework
# Create custom wordlist from discovered subdomains
cat reports/*.json | jq -r '.subdomains[].subdomain' | cut -d'.' -f1 | sort -u > custom_words.txt
# Use custom wordlist
# Edit config.yaml to point to custom_words.txt# Pipe to nmap for port scanning
python main.py target.com | grep "^[a-z]" | nmap -iL - -oA scan_results
# Pipe to httpx for HTTP probing
python main.py target.com | grep "^[a-z]" | httpx -o live_hosts.txt
# Pipe to nuclei for vulnerability scanning
python main.py target.com | grep "^[a-z]" | nuclei -t cves/ -o vulns.txt# Add to crontab for daily scans
0 2 * * * cd /path/to/SubCandalena && python main.py target.com --quick 2>&1 | tee -a logs/daily_scan.log# For VPS with limited resources
python main.py target.com --threads 30
# For powerful servers
python main.py target.com --threads 200
# For stealth operations
python main.py target.com --threads 10import json
# Load results
with open('reports/scan.json') as f:
data = json.load(f)
# Filter only 200 OK
live = [s for s in data['subdomains'] if s['status_code'] == 200]
# Filter by keyword
admin_panels = [s for s in data['subdomains'] if 'admin' in s['subdomain']]
# Export filtered results
with open('filtered.json', 'w') as f:
json.dump(admin_panels, f, indent=2)🎯 Happy Hunting! 🎯
If you found this tool useful, please consider giving it a ⭐ on GitHub!