Create live.py
This commit is contained in:
parent
733e8dd39a
commit
05ab553477
|
@ -0,0 +1,155 @@
|
|||
#!/usr/bin/env python3
|
||||
# Nmap Integrator for Subdomains - v1.0
|
||||
# Integrates Nmap port scanning with subdomain lists (e.g., from Sublist3r).
|
||||
# Filters live subdomains (DNS + HTTP check), then scans for open ports.
|
||||
# Usage: python nmap_integrator.py -i subdomains.txt -o nmap_results.xml
|
||||
# Requires: pip install requests dnspython; nmap installed on system
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import subprocess
|
||||
import xml.etree.ElementTree as ET
|
||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||
import requests
|
||||
import dns.resolver
|
||||
import dns.exception
|
||||
import tempfile
|
||||
import os
|
||||
|
||||
def is_dns_live(subdomain):
|
||||
"""Check if subdomain resolves to an IP."""
|
||||
try:
|
||||
dns.resolver.resolve(subdomain, 'A')
|
||||
return True
|
||||
except (dns.exception.DNSException, Exception):
|
||||
return False
|
||||
|
||||
def is_http_live(subdomain, timeout=5):
|
||||
"""Check if subdomain responds to HTTP/HTTPS."""
|
||||
for protocol in ['http', 'https']:
|
||||
url = f"{protocol}://{subdomain}"
|
||||
try:
|
||||
resp = requests.get(url, timeout=timeout, verify=False, allow_redirects=True)
|
||||
if resp.status_code > 0:
|
||||
return True
|
||||
except requests.RequestException:
|
||||
continue
|
||||
return False
|
||||
|
||||
def check_live(subdomain, dns_only=False, timeout=5):
|
||||
"""Full live check: DNS + optional HTTP."""
|
||||
if not is_dns_live(subdomain):
|
||||
return False
|
||||
if dns_only:
|
||||
return True
|
||||
return is_http_live(subdomain, timeout)
|
||||
|
||||
def run_nmap_scan(subdomain, ports='top-1000', output_dir=None, output_format='xml'):
|
||||
"""Run Nmap scan on a subdomain and return results."""
|
||||
if output_dir:
|
||||
output_file = os.path.join(output_dir, f"{subdomain}_nmap.{output_format}")
|
||||
else:
|
||||
output_file = f"{subdomain}_nmap.{output_format}"
|
||||
|
||||
cmd = [
|
||||
'nmap', '-sV', '-sC', # Service version + script scan
|
||||
f'-p{ports}', # Ports to scan
|
||||
f'--open', # Only show open ports
|
||||
f'-o{output_format}', output_file, # Output format
|
||||
subdomain
|
||||
]
|
||||
|
||||
try:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300) # 5-min timeout per host
|
||||
if result.returncode == 0:
|
||||
print(f"[SCAN] {subdomain}: Scan complete. Output: {output_file}")
|
||||
return output_file
|
||||
else:
|
||||
print(f"[ERROR] {subdomain}: Nmap failed - {result.stderr}")
|
||||
return None
|
||||
except subprocess.TimeoutExpired:
|
||||
print(f"[TIMEOUT] {subdomain}: Scan timed out")
|
||||
return None
|
||||
except FileNotFoundError:
|
||||
print("[ERROR] Nmap not found. Install Nmap and ensure it's in PATH.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
def parse_nmap_xml(xml_file):
|
||||
"""Parse Nmap XML for summary (open ports)."""
|
||||
try:
|
||||
tree = ET.parse(xml_file)
|
||||
root = tree.getroot()
|
||||
host = root.find('host')
|
||||
if host is None:
|
||||
return []
|
||||
ports = []
|
||||
for port in host.findall('.//port[@state="open"]'):
|
||||
port_id = port.get('portid')
|
||||
service = port.find('service')
|
||||
service_name = service.get('name') if service is not None else 'unknown'
|
||||
ports.append(f"{port_id}/{service_name}")
|
||||
return ports
|
||||
except ET.ParseError:
|
||||
return []
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Integrate Nmap port scanning with subdomain lists.")
|
||||
parser.add_argument('-i', '--input', required=True, help="Input file with subdomains (one per line)")
|
||||
parser.add_argument('-o', '--output-dir', help="Directory for Nmap output files (default: current dir)")
|
||||
parser.add_argument('-t', '--threads', type=int, default=10, help="Threads for live check (default: 10); Nmap is sequential")
|
||||
parser.add_argument('--dns-only', action='store_true', help="Only check DNS (faster, skip HTTP)")
|
||||
parser.add_argument('--ports', default='top-1000', help="Nmap ports (default: top-1000)")
|
||||
parser.add_argument('--timeout', type=int, default=5, help="HTTP timeout in seconds (default: 5)")
|
||||
parser.add_argument('--summary', action='store_true', help="Print summary of open ports after scanning")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Read subdomains
|
||||
try:
|
||||
with open(args.input, 'r') as f:
|
||||
subdomains = [line.strip() for line in f if line.strip()]
|
||||
except FileNotFoundError:
|
||||
print(f"Error: Input file '{args.input}' not found.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
print(f"[INFO] Filtering {len(subdomains)} subdomains for live hosts...")
|
||||
|
||||
# Filter live subdomains
|
||||
live_subdomains = []
|
||||
with ThreadPoolExecutor(max_workers=args.threads) as executor:
|
||||
futures = {executor.submit(check_live, sub, args.dns_only, args.timeout): sub for sub in subdomains}
|
||||
for future in as_completed(futures):
|
||||
sub = futures[future]
|
||||
try:
|
||||
if future.result():
|
||||
live_subdomains.append(sub)
|
||||
print(f"[LIVE] {sub}")
|
||||
else:
|
||||
print(f"[DEAD] {sub}")
|
||||
except Exception as e:
|
||||
print(f"[ERROR] {sub}: {e}", file=sys.stderr)
|
||||
|
||||
print(f"[INFO] Found {len(live_subdomains)} live subdomains. Starting Nmap scans...")
|
||||
|
||||
# Create output dir if specified
|
||||
if args.output_dir:
|
||||
os.makedirs(args.output_dir, exist_ok=True)
|
||||
|
||||
# Run Nmap sequentially (to avoid overwhelming the network; parallelize if needed)
|
||||
scan_results = {}
|
||||
for subdomain in live_subdomains:
|
||||
output_file = run_nmap_scan(subdomain, args.ports, args.output_dir)
|
||||
if output_file and args.summary:
|
||||
open_ports = parse_nmap_xml(output_file)
|
||||
if open_ports:
|
||||
scan_results[subdomain] = open_ports
|
||||
print(f"[PORTS] {subdomain}: {', '.join(open_ports)}")
|
||||
|
||||
if args.summary and scan_results:
|
||||
print("\n[SUMMARY] Open Ports by Host:")
|
||||
for host, ports in scan_results.items():
|
||||
print(f"{host}: {', '.join(ports)}")
|
||||
|
||||
print(f"[COMPLETE] Scanned {len(live_subdomains)} hosts. Check output files for details.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue