Add DeadHydra Recon Scanner - Advanced Penetration Testing Tool
This commit adds a comprehensive reconnaissance scanner for security testing: Features: - Multi-threaded port scanning with customizable ranges - DNS enumeration (A, AAAA, MX, NS, TXT, SOA, CNAME records) - Subdomain brute-force discovery with wordlists - Service banner grabbing and version detection - Web technology detection (CMS, frameworks, libraries) - WHOIS domain information lookup - JSON export for structured results Files: - recon_scanner.py: Main scanner implementation - recon.sh: Convenience wrapper script - subdomains.txt: Default wordlist with 100+ common subdomains - README.md: Comprehensive documentation with usage examples - .gitignore: Python and scan result exclusions Usage: ./recon.sh -t example.com --quick ./recon.sh -t 192.168.1.1 -p 1-1000 ./recon.sh -t domain.com --subdomains subdomains.txt -o results.json
This commit is contained in:
commit
a8f47dd8b1
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.so
|
||||||
|
.Python
|
||||||
|
venv/
|
||||||
|
env/
|
||||||
|
*.egg-info/
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
|
||||||
|
# Scan results
|
||||||
|
*.json
|
||||||
|
results/
|
||||||
|
output/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
@ -0,0 +1,153 @@
|
||||||
|
# DeadHydra Scripts Collection
|
||||||
|
|
||||||
|
Elite hacker tools and penetration testing scripts.
|
||||||
|
|
||||||
|
## 🎯 Recon Scanner
|
||||||
|
|
||||||
|
Advanced reconnaissance tool for penetration testing and security research.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- **DNS Resolution** - Resolve hostnames to IP addresses
|
||||||
|
- **Port Scanning** - Multi-threaded TCP port scanning
|
||||||
|
- **Banner Grabbing** - Service version detection
|
||||||
|
- **DNS Enumeration** - Query all DNS record types
|
||||||
|
- **Subdomain Discovery** - Brute-force subdomain enumeration
|
||||||
|
- **Web Technology Detection** - Identify CMS, frameworks, libraries
|
||||||
|
- **WHOIS Lookup** - Domain registration information
|
||||||
|
- **JSON Export** - Structured output format
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies
|
||||||
|
pip3 install dnspython requests urllib3
|
||||||
|
|
||||||
|
# Make script executable
|
||||||
|
chmod +x recon_scanner.py recon.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
#### Quick Start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Basic scan
|
||||||
|
./recon.sh -t example.com
|
||||||
|
|
||||||
|
# Quick scan (common ports only)
|
||||||
|
./recon.sh -t example.com --quick
|
||||||
|
|
||||||
|
# With output file
|
||||||
|
./recon.sh -t example.com -o results.json
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Advanced Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Full port scan (1-65535)
|
||||||
|
./recon.sh -t example.com --full
|
||||||
|
|
||||||
|
# Custom port range
|
||||||
|
./recon.sh -t 192.168.1.1 -p 1-1000
|
||||||
|
|
||||||
|
# Specific ports
|
||||||
|
./recon.sh -t example.com -p 22,80,443,8080
|
||||||
|
|
||||||
|
# Subdomain enumeration with custom wordlist
|
||||||
|
./recon.sh -t example.com --subdomains subdomains.txt
|
||||||
|
|
||||||
|
# Scan IP address
|
||||||
|
./recon.sh -t 192.168.1.1 --quick
|
||||||
|
```
|
||||||
|
|
||||||
|
### Command Line Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-t, --target TARGET Target domain or IP address (required)
|
||||||
|
-p, --ports PORTS Port range (e.g., 1-1000) or comma-separated
|
||||||
|
-o, --output OUTPUT Output file for results (JSON format)
|
||||||
|
--subdomains WORDLIST Subdomain wordlist file
|
||||||
|
--quick Quick scan (common ports only)
|
||||||
|
--full Full scan (all 65535 ports)
|
||||||
|
```
|
||||||
|
|
||||||
|
### What It Scans
|
||||||
|
|
||||||
|
1. **Network Layer**: IP resolution, reverse DNS
|
||||||
|
2. **Transport Layer**: TCP port scanning (multi-threaded)
|
||||||
|
3. **Application Layer**: HTTP/HTTPS, FTP, SSH, SMTP, MySQL, RDP, etc.
|
||||||
|
4. **DNS Infrastructure**: A, AAAA, MX, NS, TXT, SOA, CNAME records
|
||||||
|
5. **Subdomain Discovery**: Brute-force with customizable wordlists
|
||||||
|
6. **Web Stack**: Server headers, CMS detection, framework identification
|
||||||
|
7. **Registration Data**: WHOIS domain information
|
||||||
|
|
||||||
|
### Output Format
|
||||||
|
|
||||||
|
Results are saved in JSON format with the following structure:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"target": "example.com",
|
||||||
|
"scan_time": "2025-11-07T00:00:00",
|
||||||
|
"ip_addresses": ["93.184.216.34"],
|
||||||
|
"open_ports": [80, 443],
|
||||||
|
"services": [...],
|
||||||
|
"subdomains": [...],
|
||||||
|
"dns_records": {...},
|
||||||
|
"web_technologies": {...}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Files
|
||||||
|
|
||||||
|
- `recon_scanner.py` - Main scanner script
|
||||||
|
- `recon.sh` - Convenience wrapper script
|
||||||
|
- `subdomains.txt` - Default subdomain wordlist (100+ entries)
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
#### Scan a website
|
||||||
|
```bash
|
||||||
|
./recon.sh -t example.com -o example_scan.json
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Quick security assessment
|
||||||
|
```bash
|
||||||
|
./recon.sh -t target.com --quick --subdomains subdomains.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Full infrastructure scan
|
||||||
|
```bash
|
||||||
|
./recon.sh -t target.com --full -o full_scan.json
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Network range scan
|
||||||
|
```bash
|
||||||
|
./recon.sh -t 192.168.1.1 -p 1-1000
|
||||||
|
```
|
||||||
|
|
||||||
|
### Security Notes
|
||||||
|
|
||||||
|
⚠️ **Authorization Required**: Only use this tool on systems you own or have explicit permission to test.
|
||||||
|
|
||||||
|
⚠️ **Legal Compliance**: Unauthorized port scanning and reconnaissance may be illegal in your jurisdiction.
|
||||||
|
|
||||||
|
⚠️ **Ethical Usage**: This tool is intended for:
|
||||||
|
- Authorized penetration testing
|
||||||
|
- Security research with permission
|
||||||
|
- CTF competitions
|
||||||
|
- Educational purposes
|
||||||
|
- Testing your own infrastructure
|
||||||
|
|
||||||
|
### Contributing
|
||||||
|
|
||||||
|
This is part of the DeadHydra Collective security toolkit. Contributions welcome!
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT License - Use responsibly and ethically.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**HACK THE PLANET** // DeadHydra Collective
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# DeadHydra Recon Scanner Wrapper
|
||||||
|
# Quick access script for penetration testing reconnaissance
|
||||||
|
#
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PYTHON="${SCRIPT_DIR}/venv/bin/python3"
|
||||||
|
SCANNER="${SCRIPT_DIR}/recon_scanner.py"
|
||||||
|
|
||||||
|
# Check if Python script exists
|
||||||
|
if [ ! -f "$SCANNER" ]; then
|
||||||
|
echo "Error: recon_scanner.py not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run the scanner with all arguments
|
||||||
|
"$PYTHON" "$SCANNER" "$@"
|
||||||
|
|
@ -0,0 +1,432 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
DeadHydra Recon Scanner
|
||||||
|
Advanced Penetration Testing Reconnaissance Tool
|
||||||
|
Author: DeadHydra Collective
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import socket
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import dns.resolver
|
||||||
|
import requests
|
||||||
|
from datetime import datetime
|
||||||
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||||
|
import ipaddress
|
||||||
|
import re
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
class Colors:
|
||||||
|
"""Terminal colors for output"""
|
||||||
|
HEADER = '\033[95m'
|
||||||
|
OKBLUE = '\033[94m'
|
||||||
|
OKCYAN = '\033[96m'
|
||||||
|
OKGREEN = '\033[92m'
|
||||||
|
WARNING = '\033[93m'
|
||||||
|
FAIL = '\033[91m'
|
||||||
|
ENDC = '\033[0m'
|
||||||
|
BOLD = '\033[1m'
|
||||||
|
UNDERLINE = '\033[4m'
|
||||||
|
|
||||||
|
class ReconScanner:
|
||||||
|
def __init__(self, target, output_file=None):
|
||||||
|
self.target = target
|
||||||
|
self.output_file = output_file
|
||||||
|
self.results = {
|
||||||
|
'target': target,
|
||||||
|
'scan_time': datetime.now().isoformat(),
|
||||||
|
'ip_addresses': [],
|
||||||
|
'open_ports': [],
|
||||||
|
'services': [],
|
||||||
|
'subdomains': [],
|
||||||
|
'dns_records': {},
|
||||||
|
'web_technologies': {},
|
||||||
|
'ssl_info': {}
|
||||||
|
}
|
||||||
|
|
||||||
|
def banner(self):
|
||||||
|
"""Display scanner banner"""
|
||||||
|
banner = f"""
|
||||||
|
{Colors.OKGREEN}
|
||||||
|
╔═══════════════════════════════════════════════════════════╗
|
||||||
|
║ ║
|
||||||
|
║ ██████╗ ███████╗ █████╗ ██████╗ ██╗ ██╗ ║
|
||||||
|
║ ██╔══██╗██╔════╝██╔══██╗██╔══██╗██║ ██║ ║
|
||||||
|
║ ██║ ██║█████╗ ███████║██║ ██║███████║ ║
|
||||||
|
║ ██║ ██║██╔══╝ ██╔══██║██║ ██║██╔══██║ ║
|
||||||
|
║ ██████╔╝███████╗██║ ██║██████╔╝██║ ██║ ║
|
||||||
|
║ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝ ║
|
||||||
|
║ ║
|
||||||
|
║ DeadHydra Recon Scanner v1.0 ║
|
||||||
|
║ Advanced Penetration Testing Tool ║
|
||||||
|
║ ║
|
||||||
|
╚═══════════════════════════════════════════════════════════╝
|
||||||
|
{Colors.ENDC}
|
||||||
|
{Colors.OKCYAN}[*] Target: {self.target}
|
||||||
|
[*] Scan Started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
||||||
|
{Colors.ENDC}
|
||||||
|
"""
|
||||||
|
print(banner)
|
||||||
|
|
||||||
|
def resolve_target(self):
|
||||||
|
"""Resolve target to IP addresses"""
|
||||||
|
print(f"\n{Colors.BOLD}[+] Resolving Target...{Colors.ENDC}")
|
||||||
|
try:
|
||||||
|
# Try to parse as IP address first
|
||||||
|
try:
|
||||||
|
ip = ipaddress.ip_address(self.target)
|
||||||
|
self.results['ip_addresses'].append(str(ip))
|
||||||
|
print(f"{Colors.OKGREEN} [✓] IP Address: {ip}{Colors.ENDC}")
|
||||||
|
return
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Resolve hostname
|
||||||
|
ip_addresses = socket.gethostbyname_ex(self.target)[2]
|
||||||
|
for ip in ip_addresses:
|
||||||
|
self.results['ip_addresses'].append(ip)
|
||||||
|
print(f"{Colors.OKGREEN} [✓] Resolved: {ip}{Colors.ENDC}")
|
||||||
|
|
||||||
|
except socket.gaierror:
|
||||||
|
print(f"{Colors.FAIL} [✗] Failed to resolve target{Colors.ENDC}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def port_scan(self, ports=None, threads=100):
|
||||||
|
"""Scan for open ports"""
|
||||||
|
print(f"\n{Colors.BOLD}[+] Port Scanning...{Colors.ENDC}")
|
||||||
|
|
||||||
|
if ports is None:
|
||||||
|
# Common ports
|
||||||
|
ports = [21, 22, 23, 25, 53, 80, 110, 111, 135, 139, 143, 443, 445,
|
||||||
|
993, 995, 1723, 3306, 3389, 5900, 8080, 8443, 8888]
|
||||||
|
|
||||||
|
def scan_port(port):
|
||||||
|
try:
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
sock.settimeout(1)
|
||||||
|
result = sock.connect_ex((self.results['ip_addresses'][0], port))
|
||||||
|
sock.close()
|
||||||
|
if result == 0:
|
||||||
|
return port
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
with ThreadPoolExecutor(max_workers=threads) as executor:
|
||||||
|
future_to_port = {executor.submit(scan_port, port): port for port in ports}
|
||||||
|
for future in as_completed(future_to_port):
|
||||||
|
port = future.result()
|
||||||
|
if port:
|
||||||
|
self.results['open_ports'].append(port)
|
||||||
|
service = self.identify_service(port)
|
||||||
|
print(f"{Colors.OKGREEN} [✓] Port {port}/tcp open - {service}{Colors.ENDC}")
|
||||||
|
|
||||||
|
def identify_service(self, port):
|
||||||
|
"""Identify common services by port"""
|
||||||
|
services = {
|
||||||
|
21: 'FTP', 22: 'SSH', 23: 'Telnet', 25: 'SMTP', 53: 'DNS',
|
||||||
|
80: 'HTTP', 110: 'POP3', 111: 'RPCBind', 135: 'MSRPC', 139: 'NetBIOS',
|
||||||
|
143: 'IMAP', 443: 'HTTPS', 445: 'SMB', 993: 'IMAPS', 995: 'POP3S',
|
||||||
|
1723: 'PPTP', 3306: 'MySQL', 3389: 'RDP', 5900: 'VNC',
|
||||||
|
8080: 'HTTP-Proxy', 8443: 'HTTPS-Alt', 8888: 'HTTP-Alt'
|
||||||
|
}
|
||||||
|
return services.get(port, 'Unknown')
|
||||||
|
|
||||||
|
def banner_grab(self):
|
||||||
|
"""Grab service banners from open ports"""
|
||||||
|
print(f"\n{Colors.BOLD}[+] Banner Grabbing...{Colors.ENDC}")
|
||||||
|
|
||||||
|
for port in self.results['open_ports']:
|
||||||
|
try:
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
sock.settimeout(2)
|
||||||
|
sock.connect((self.results['ip_addresses'][0], port))
|
||||||
|
|
||||||
|
# Send HTTP request for web services
|
||||||
|
if port in [80, 443, 8080, 8443, 8888]:
|
||||||
|
sock.send(b'GET / HTTP/1.1\r\nHost: ' + self.target.encode() + b'\r\n\r\n')
|
||||||
|
|
||||||
|
banner = sock.recv(1024).decode('utf-8', errors='ignore').strip()
|
||||||
|
sock.close()
|
||||||
|
|
||||||
|
if banner:
|
||||||
|
service_info = {
|
||||||
|
'port': port,
|
||||||
|
'service': self.identify_service(port),
|
||||||
|
'banner': banner[:200] # Limit banner length
|
||||||
|
}
|
||||||
|
self.results['services'].append(service_info)
|
||||||
|
print(f"{Colors.OKGREEN} [✓] Port {port}: {banner[:100]}...{Colors.ENDC}")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def dns_enumeration(self):
|
||||||
|
"""Enumerate DNS records"""
|
||||||
|
print(f"\n{Colors.BOLD}[+] DNS Enumeration...{Colors.ENDC}")
|
||||||
|
|
||||||
|
# Remove IP prefix if present
|
||||||
|
domain = self.target
|
||||||
|
try:
|
||||||
|
ipaddress.ip_address(domain)
|
||||||
|
print(f"{Colors.WARNING} [!] Target is an IP address, skipping DNS enumeration{Colors.ENDC}")
|
||||||
|
return
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
record_types = ['A', 'AAAA', 'MX', 'NS', 'TXT', 'SOA', 'CNAME']
|
||||||
|
|
||||||
|
for record_type in record_types:
|
||||||
|
try:
|
||||||
|
answers = dns.resolver.resolve(domain, record_type)
|
||||||
|
records = [str(rdata) for rdata in answers]
|
||||||
|
self.results['dns_records'][record_type] = records
|
||||||
|
print(f"{Colors.OKGREEN} [✓] {record_type} Records:{Colors.ENDC}")
|
||||||
|
for record in records:
|
||||||
|
print(f" → {record}")
|
||||||
|
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer, dns.resolver.NoNameservers):
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def subdomain_enumeration(self, wordlist=None):
|
||||||
|
"""Enumerate subdomains"""
|
||||||
|
print(f"\n{Colors.BOLD}[+] Subdomain Enumeration...{Colors.ENDC}")
|
||||||
|
|
||||||
|
# Check if target is a domain
|
||||||
|
try:
|
||||||
|
ipaddress.ip_address(self.target)
|
||||||
|
print(f"{Colors.WARNING} [!] Target is an IP address, skipping subdomain enumeration{Colors.ENDC}")
|
||||||
|
return
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Common subdomains
|
||||||
|
if wordlist is None:
|
||||||
|
subdomains = [
|
||||||
|
'www', 'mail', 'ftp', 'localhost', 'webmail', 'smtp', 'pop', 'ns1',
|
||||||
|
'webdisk', 'ns2', 'cpanel', 'whm', 'autodiscover', 'autoconfig',
|
||||||
|
'dev', 'staging', 'test', 'api', 'admin', 'portal', 'vpn',
|
||||||
|
'blog', 'shop', 'store', 'app', 'mobile', 'cdn', 'static'
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
with open(wordlist, 'r') as f:
|
||||||
|
subdomains = [line.strip() for line in f]
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f"{Colors.FAIL} [✗] Wordlist not found{Colors.ENDC}")
|
||||||
|
return
|
||||||
|
|
||||||
|
def check_subdomain(subdomain):
|
||||||
|
target_domain = f"{subdomain}.{self.target}"
|
||||||
|
try:
|
||||||
|
ip = socket.gethostbyname(target_domain)
|
||||||
|
return (target_domain, ip)
|
||||||
|
except socket.gaierror:
|
||||||
|
return None
|
||||||
|
|
||||||
|
print(f"{Colors.OKCYAN} [*] Testing {len(subdomains)} subdomains...{Colors.ENDC}")
|
||||||
|
|
||||||
|
with ThreadPoolExecutor(max_workers=50) as executor:
|
||||||
|
future_to_sub = {executor.submit(check_subdomain, sub): sub for sub in subdomains}
|
||||||
|
for future in as_completed(future_to_sub):
|
||||||
|
result = future.result()
|
||||||
|
if result:
|
||||||
|
subdomain, ip = result
|
||||||
|
self.results['subdomains'].append({'subdomain': subdomain, 'ip': ip})
|
||||||
|
print(f"{Colors.OKGREEN} [✓] Found: {subdomain} → {ip}{Colors.ENDC}")
|
||||||
|
|
||||||
|
def web_technology_detection(self):
|
||||||
|
"""Detect web technologies"""
|
||||||
|
print(f"\n{Colors.BOLD}[+] Web Technology Detection...{Colors.ENDC}")
|
||||||
|
|
||||||
|
# Check if HTTP/HTTPS ports are open
|
||||||
|
web_ports = [port for port in self.results['open_ports'] if port in [80, 443, 8080, 8443, 8888]]
|
||||||
|
|
||||||
|
if not web_ports:
|
||||||
|
print(f"{Colors.WARNING} [!] No web services detected{Colors.ENDC}")
|
||||||
|
return
|
||||||
|
|
||||||
|
for port in web_ports:
|
||||||
|
protocol = 'https' if port in [443, 8443] else 'http'
|
||||||
|
url = f"{protocol}://{self.target}:{port}" if port not in [80, 443] else f"{protocol}://{self.target}"
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.get(url, timeout=5, verify=False, allow_redirects=True)
|
||||||
|
|
||||||
|
tech_info = {
|
||||||
|
'url': url,
|
||||||
|
'status_code': response.status_code,
|
||||||
|
'server': response.headers.get('Server', 'Unknown'),
|
||||||
|
'powered_by': response.headers.get('X-Powered-By', 'Unknown'),
|
||||||
|
'headers': dict(response.headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Detect common technologies from headers and content
|
||||||
|
content = response.text.lower()
|
||||||
|
technologies = []
|
||||||
|
|
||||||
|
if 'wordpress' in content:
|
||||||
|
technologies.append('WordPress')
|
||||||
|
if 'joomla' in content:
|
||||||
|
technologies.append('Joomla')
|
||||||
|
if 'drupal' in content:
|
||||||
|
technologies.append('Drupal')
|
||||||
|
if 'react' in content or 'reactjs' in content:
|
||||||
|
technologies.append('React')
|
||||||
|
if 'angular' in content:
|
||||||
|
technologies.append('Angular')
|
||||||
|
if 'vue' in content or 'vuejs' in content:
|
||||||
|
technologies.append('Vue.js')
|
||||||
|
if 'jquery' in content:
|
||||||
|
technologies.append('jQuery')
|
||||||
|
if 'bootstrap' in content:
|
||||||
|
technologies.append('Bootstrap')
|
||||||
|
|
||||||
|
tech_info['detected_technologies'] = technologies
|
||||||
|
self.results['web_technologies'][url] = tech_info
|
||||||
|
|
||||||
|
print(f"{Colors.OKGREEN} [✓] {url}{Colors.ENDC}")
|
||||||
|
print(f" Status: {response.status_code}")
|
||||||
|
print(f" Server: {tech_info['server']}")
|
||||||
|
if technologies:
|
||||||
|
print(f" Technologies: {', '.join(technologies)}")
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"{Colors.WARNING} [!] Failed to connect to {url}{Colors.ENDC}")
|
||||||
|
|
||||||
|
def whois_lookup(self):
|
||||||
|
"""Perform WHOIS lookup"""
|
||||||
|
print(f"\n{Colors.BOLD}[+] WHOIS Lookup...{Colors.ENDC}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Check if target is IP
|
||||||
|
try:
|
||||||
|
ipaddress.ip_address(self.target)
|
||||||
|
print(f"{Colors.WARNING} [!] WHOIS for IP addresses not implemented{Colors.ENDC}")
|
||||||
|
return
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
result = subprocess.run(['whois', self.target],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=10)
|
||||||
|
|
||||||
|
if result.returncode == 0:
|
||||||
|
whois_data = result.stdout
|
||||||
|
self.results['whois'] = whois_data
|
||||||
|
|
||||||
|
# Extract important info
|
||||||
|
registrar = re.search(r'Registrar: (.+)', whois_data)
|
||||||
|
creation_date = re.search(r'Creation Date: (.+)', whois_data)
|
||||||
|
expiration_date = re.search(r'Expir(?:y|ation) Date: (.+)', whois_data)
|
||||||
|
|
||||||
|
if registrar:
|
||||||
|
print(f"{Colors.OKGREEN} [✓] Registrar: {registrar.group(1)}{Colors.ENDC}")
|
||||||
|
if creation_date:
|
||||||
|
print(f"{Colors.OKGREEN} [✓] Created: {creation_date.group(1)}{Colors.ENDC}")
|
||||||
|
if expiration_date:
|
||||||
|
print(f"{Colors.OKGREEN} [✓] Expires: {expiration_date.group(1)}{Colors.ENDC}")
|
||||||
|
else:
|
||||||
|
print(f"{Colors.WARNING} [!] WHOIS lookup failed{Colors.ENDC}")
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f"{Colors.WARNING} [!] whois command not found{Colors.ENDC}")
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
print(f"{Colors.WARNING} [!] WHOIS lookup timed out{Colors.ENDC}")
|
||||||
|
|
||||||
|
def save_results(self):
|
||||||
|
"""Save results to file"""
|
||||||
|
if self.output_file:
|
||||||
|
try:
|
||||||
|
with open(self.output_file, 'w') as f:
|
||||||
|
json.dump(self.results, f, indent=4)
|
||||||
|
print(f"\n{Colors.OKGREEN}[✓] Results saved to: {self.output_file}{Colors.ENDC}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n{Colors.FAIL}[✗] Failed to save results: {e}{Colors.ENDC}")
|
||||||
|
|
||||||
|
def print_summary(self):
|
||||||
|
"""Print scan summary"""
|
||||||
|
print(f"\n{Colors.BOLD}{'='*60}")
|
||||||
|
print(f"SCAN SUMMARY")
|
||||||
|
print(f"{'='*60}{Colors.ENDC}")
|
||||||
|
print(f"{Colors.OKCYAN}Target: {self.target}")
|
||||||
|
print(f"IP Addresses: {', '.join(self.results['ip_addresses'])}")
|
||||||
|
print(f"Open Ports: {len(self.results['open_ports'])}")
|
||||||
|
print(f"Services Detected: {len(self.results['services'])}")
|
||||||
|
print(f"Subdomains Found: {len(self.results['subdomains'])}")
|
||||||
|
print(f"Scan Completed: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}{Colors.ENDC}")
|
||||||
|
print(f"{Colors.BOLD}{'='*60}{Colors.ENDC}\n")
|
||||||
|
|
||||||
|
def run_full_scan(self, ports=None, subdomain_wordlist=None):
|
||||||
|
"""Run complete reconnaissance scan"""
|
||||||
|
self.banner()
|
||||||
|
self.resolve_target()
|
||||||
|
self.port_scan(ports=ports)
|
||||||
|
self.banner_grab()
|
||||||
|
self.dns_enumeration()
|
||||||
|
self.subdomain_enumeration(wordlist=subdomain_wordlist)
|
||||||
|
self.web_technology_detection()
|
||||||
|
self.whois_lookup()
|
||||||
|
self.print_summary()
|
||||||
|
self.save_results()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description='DeadHydra Recon Scanner - Advanced Penetration Testing Reconnaissance Tool',
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
epilog="""
|
||||||
|
Examples:
|
||||||
|
%(prog)s -t example.com
|
||||||
|
%(prog)s -t 192.168.1.1 -p 1-1000
|
||||||
|
%(prog)s -t example.com -o results.json
|
||||||
|
%(prog)s -t example.com --subdomains wordlist.txt
|
||||||
|
%(prog)s -t example.com --quick
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument('-t', '--target', required=True,
|
||||||
|
help='Target domain or IP address')
|
||||||
|
parser.add_argument('-p', '--ports',
|
||||||
|
help='Port range (e.g., 1-1000) or comma-separated ports')
|
||||||
|
parser.add_argument('-o', '--output',
|
||||||
|
help='Output file for results (JSON format)')
|
||||||
|
parser.add_argument('--subdomains',
|
||||||
|
help='Subdomain wordlist file')
|
||||||
|
parser.add_argument('--quick', action='store_true',
|
||||||
|
help='Quick scan (common ports only)')
|
||||||
|
parser.add_argument('--full', action='store_true',
|
||||||
|
help='Full scan (all 65535 ports)')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Parse ports
|
||||||
|
ports = None
|
||||||
|
if args.ports:
|
||||||
|
if '-' in args.ports:
|
||||||
|
start, end = map(int, args.ports.split('-'))
|
||||||
|
ports = list(range(start, end + 1))
|
||||||
|
else:
|
||||||
|
ports = [int(p) for p in args.ports.split(',')]
|
||||||
|
elif args.full:
|
||||||
|
ports = list(range(1, 65536))
|
||||||
|
elif args.quick:
|
||||||
|
ports = [21, 22, 80, 443, 3306, 3389, 8080, 8443]
|
||||||
|
|
||||||
|
# Initialize scanner
|
||||||
|
scanner = ReconScanner(args.target, args.output)
|
||||||
|
|
||||||
|
# Run scan
|
||||||
|
try:
|
||||||
|
scanner.run_full_scan(ports=ports, subdomain_wordlist=args.subdomains)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print(f"\n{Colors.WARNING}[!] Scan interrupted by user{Colors.ENDC}")
|
||||||
|
scanner.save_results()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
www
|
||||||
|
mail
|
||||||
|
ftp
|
||||||
|
webmail
|
||||||
|
smtp
|
||||||
|
pop
|
||||||
|
imap
|
||||||
|
admin
|
||||||
|
portal
|
||||||
|
api
|
||||||
|
dev
|
||||||
|
staging
|
||||||
|
test
|
||||||
|
prod
|
||||||
|
production
|
||||||
|
demo
|
||||||
|
beta
|
||||||
|
alpha
|
||||||
|
login
|
||||||
|
auth
|
||||||
|
secure
|
||||||
|
vpn
|
||||||
|
remote
|
||||||
|
cloud
|
||||||
|
cdn
|
||||||
|
static
|
||||||
|
assets
|
||||||
|
images
|
||||||
|
img
|
||||||
|
media
|
||||||
|
files
|
||||||
|
docs
|
||||||
|
blog
|
||||||
|
forum
|
||||||
|
community
|
||||||
|
shop
|
||||||
|
store
|
||||||
|
cart
|
||||||
|
checkout
|
||||||
|
payment
|
||||||
|
pay
|
||||||
|
support
|
||||||
|
help
|
||||||
|
ticket
|
||||||
|
status
|
||||||
|
monitor
|
||||||
|
dashboard
|
||||||
|
panel
|
||||||
|
cpanel
|
||||||
|
whm
|
||||||
|
phpmyadmin
|
||||||
|
mysql
|
||||||
|
db
|
||||||
|
database
|
||||||
|
ns1
|
||||||
|
ns2
|
||||||
|
ns3
|
||||||
|
dns
|
||||||
|
mail1
|
||||||
|
mail2
|
||||||
|
smtp1
|
||||||
|
smtp2
|
||||||
|
pop3
|
||||||
|
imap1
|
||||||
|
exchange
|
||||||
|
webdisk
|
||||||
|
autodiscover
|
||||||
|
autoconfig
|
||||||
|
calendar
|
||||||
|
contacts
|
||||||
|
drive
|
||||||
|
backup
|
||||||
|
archive
|
||||||
|
download
|
||||||
|
upload
|
||||||
|
git
|
||||||
|
svn
|
||||||
|
repo
|
||||||
|
code
|
||||||
|
jenkins
|
||||||
|
gitlab
|
||||||
|
github
|
||||||
|
bitbucket
|
||||||
|
jira
|
||||||
|
confluence
|
||||||
|
wiki
|
||||||
|
kb
|
||||||
|
internal
|
||||||
|
intranet
|
||||||
|
extranet
|
||||||
|
partner
|
||||||
|
vendor
|
||||||
|
client
|
||||||
|
customer
|
||||||
|
mobile
|
||||||
|
app
|
||||||
|
apps
|
||||||
|
m
|
||||||
|
wap
|
||||||
|
old
|
||||||
|
new
|
||||||
|
legacy
|
||||||
|
v2
|
||||||
|
v3
|
||||||
|
staging2
|
||||||
|
dev2
|
||||||
|
test2
|
||||||
|
uat
|
||||||
|
qa
|
||||||
|
preprod
|
||||||
|
preview
|
||||||
|
sandbox
|
||||||
Loading…
Reference in New Issue