import nmap import pandas as pd import os import sys import requests from bs4 import BeautifulSoup import urllib3 from datetime import datetime # Suppress SSL warnings for self-signed certificates urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def probe_for_web_interface(host, port): """ Zero-trust probe: Manually tries HTTPS and HTTP on EVERY open port. Captures webpage title and software version banners. """ for protocol in ["https", "http"]: url = f"{protocol}://{host}:{port}" try: headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'} response = requests.get(url, timeout=3, verify=False, allow_redirects=True, headers=headers) # We accept any response < 500 (200, 302, 401, 403) if response.status_code < 500: soup = BeautifulSoup(response.text, 'html.parser') title = soup.title.string.strip() if soup.title else "Web Page (No Title)" # Grab the 'Server' header to identify the software stack server_banner = response.headers.get('Server', 'Hidden/Unknown') return True, url, title, server_banner except: continue return False, None, None, None def run_exhaustive_scan(target_range): nm = nmap.PortScanner() # PHASE 1: Rapid Discovery print(f"[*] PHASE 1: Discovering live hosts on {target_range}...") nm.scan(hosts=target_range, arguments='-sn') live_hosts = nm.all_hosts() if not live_hosts: print("[!] No devices found. Check your connection to the 192.168.12.x VLAN.") return [] print(f"[+] Found {len(live_hosts)} active devices.") print("[*] PHASE 2: Deep Scanning top 10,000 ports (this will take a few minutes)...") # Using synchronous scan for Windows stability target_list = " ".join(live_hosts) # -sV: Service version detection for hostnames and initial banners nm_args = '-sV --open -T4 --top-ports 10000' nm.scan(hosts=target_list, arguments=nm_args) # PHASE 3: Zero-Trust Web Verification & Banner Grabbing scan_results = [] print("\n[*] PHASE 3: Verifying web interfaces and grabbing software banners...") for host in nm.all_hosts(): hostname = nm[host].hostname() print(f"\n[+] Analyzing host: {host} ({hostname if hostname else 'No DNS Name'})") for proto in nm[host].all_protocols(): lport = nm[host][proto].keys() for port in lport: print(f" - Probing port {port}...") is_web, verified_url, web_title, banner = probe_for_web_interface(host, port) if is_web: scan_results.append({ 'IP Address': host, 'Hostname': hostname, 'Port': port, 'Service Identity': web_title, 'Software Banner': banner, 'Verified Login URL': verified_url, 'Discovery Date': datetime.now().strftime("%Y-%m-%d %H:%M") }) return scan_results def save_to_excel(data, output_path): if not data: print("\n[!] No web services detected on the identified hosts.") return df = pd.DataFrame(data) # XlsxWriter is used to ensure URLs are formatted as clickable blue links writer = pd.ExcelWriter(output_path, engine='xlsxwriter') df.to_excel(writer, index=False, sheet_name='Homelab_Inventory') workbook = writer.book worksheet = writer.sheets['Homelab_Inventory'] # Formatting for better readability for i, col in enumerate(df.columns): width = max(df[col].astype(str).map(len).max(), len(col)) + 2 worksheet.set_column(i, i, width) writer.close() print(f"\n[SUCCESS] Discovery Finished! Your documentation is at: {output_path}") if __name__ == "__main__": # Settings TARGET_VLAN = "192.168.12.0/24" # Storing in your requested directory OUTPUT_FILE = r"D:\hackerstuff\scripts\my_scripts\ai-code\Full_Homelab_Recovery.xlsx" os.makedirs(os.path.dirname(OUTPUT_FILE), exist_ok=True) results = run_exhaustive_scan(TARGET_VLAN) save_to_excel(results, OUTPUT_FILE)