112 lines
No EOL
4.3 KiB
Python
112 lines
No EOL
4.3 KiB
Python
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) |