selfmade_scripts/homelab_scanner.py

112 lines
4.3 KiB
Python
Raw Permalink Normal View History

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)