diff --git a/services/dashboard/app/main.py b/services/dashboard/app/main.py index 7303038..eb96962 100644 --- a/services/dashboard/app/main.py +++ b/services/dashboard/app/main.py @@ -464,11 +464,13 @@ async def start_network_scan(request: NetworkScanRequest): # Build nmap command based on scan type # Use -T4 for faster timing, --stats-every for progress, --min-hostgroup for parallel scanning + # --disable-arp-ping prevents false positives from routers with proxy ARP + # MAC addresses are collected automatically in XML output for local network scans scan_commands = { - "ping": f"nmap -sn -T4 --min-hostgroup 64 {request.target} -oX - --stats-every 1s", - "quick": f"nmap -T4 -F --top-ports 100 --min-hostgroup 32 {request.target} -oX - --stats-every 1s", - "os": f"nmap -T4 -O --osscan-guess --max-os-tries 1 --min-hostgroup 16 {request.target} -oX - --stats-every 2s", - "full": f"nmap -T4 -sS -sV -O --version-light -p- --min-hostgroup 8 {request.target} -oX - --stats-every 2s" + "ping": f"nmap -sn -T4 --disable-arp-ping --min-hostgroup 64 {request.target} -oX - --stats-every 1s", + "quick": f"nmap -T4 -sS -Pn --disable-arp-ping -F --top-ports 100 --min-hostgroup 32 {request.target} -oX - --stats-every 1s", + "os": f"nmap -T4 -sS -Pn --disable-arp-ping -O --osscan-guess --max-os-tries 1 --min-hostgroup 16 {request.target} -oX - --stats-every 2s", + "full": f"nmap -T4 -sS -Pn --disable-arp-ping -sV -O --version-light -p- --min-hostgroup 8 {request.target} -oX - --stats-every 2s" } command = scan_commands.get(request.scan_type, scan_commands["quick"]) diff --git a/services/kali-executor/app/main.py b/services/kali-executor/app/main.py index 401c41a..2736298 100644 --- a/services/kali-executor/app/main.py +++ b/services/kali-executor/app/main.py @@ -150,20 +150,48 @@ def detect_os_type(os_string: str) -> str: def infer_os_from_ports(ports: List[Dict]) -> str: - """Infer OS type from open ports.""" + """Infer OS type from open ports. + + Uses a scoring system to handle hosts running multiple services + (e.g., Linux with Samba looks like Windows on port 445). + """ port_nums = {p["port"] for p in ports} + services = {p.get("service", "").lower() for p in ports} products = [p.get("product", "").lower() for p in ports] - # Windows indicators - windows_ports = {135, 139, 445, 3389, 5985, 5986} - if windows_ports & port_nums: - return "Windows" - if any("microsoft" in p or "windows" in p for p in products): - return "Windows" + # Score-based detection to handle mixed indicators + linux_score = 0 + windows_score = 0 - # Linux indicators - if 22 in port_nums: + # Strong Linux indicators + if 22 in port_nums: # SSH is strongly Linux/Unix + linux_score += 3 + if any("openssh" in p or "linux" in p for p in products): + linux_score += 5 + if any("apache" in p or "nginx" in p for p in products): + linux_score += 2 + + # Strong Windows indicators + if 135 in port_nums: # MSRPC is Windows-only + windows_score += 5 + if 3389 in port_nums: # RDP is Windows + windows_score += 3 + if 5985 in port_nums or 5986 in port_nums: # WinRM is Windows-only + windows_score += 5 + if any("microsoft" in p or "windows" in p for p in products): + windows_score += 5 + + # Weak indicators (could be either) + if 445 in port_nums: # SMB - could be Samba on Linux or Windows + windows_score += 1 # Slight Windows bias but not definitive + if 139 in port_nums: # NetBIOS - same as above + windows_score += 1 + + # Decide based on score + if linux_score > windows_score: return "Linux" + if windows_score > linux_score: + return "Windows" # Network device indicators if 161 in port_nums or 162 in port_nums: @@ -265,7 +293,11 @@ def parse_nmap_xml(xml_output: str) -> List[Dict[str, Any]]: if not host["os_type"] and host["ports"]: host["os_type"] = infer_os_from_ports(host["ports"]) - if host["ip"]: + # Only include hosts that have either: + # 1. At least one open port (proves real service) + # 2. A valid MAC address (proves real local device) + # This filters out false positives from router proxy ARP + if host["ip"] and (host["ports"] or host["mac"]): hosts.append(host) except ET.ParseError as e: diff --git a/services/kali/Dockerfile b/services/kali/Dockerfile index 3861103..8701b3a 100644 --- a/services/kali/Dockerfile +++ b/services/kali/Dockerfile @@ -8,29 +8,14 @@ RUN echo 'Acquire::Retries "3";' > /etc/apt/apt.conf.d/80-retries && \ echo 'Acquire::http::Timeout "30";' >> /etc/apt/apt.conf.d/80-retries && \ echo 'deb http://kali.download/kali kali-rolling main non-free non-free-firmware contrib' > /etc/apt/sources.list -# Update and install core Kali tools (smaller, faster, more reliable) -RUN apt-get update && apt-get install -y --no-install-recommends \ - nmap \ - sqlmap \ - hydra \ - john \ - tcpdump \ - netcat-openbsd \ - curl \ - wget \ - git \ - python3 \ - python3-pip \ - whois \ - dnsutils \ - dirb \ - gobuster \ - ffuf \ - seclists \ - smbclient \ - impacket-scripts \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* +# Install kali-linux-everything metapackage (600+ tools, ~15GB) +# This includes: nmap, metasploit, burpsuite, wireshark, aircrack-ng, +# hashcat, john, hydra, sqlmap, nikto, wpscan, responder, crackmapexec, +# enum4linux, gobuster, dirb, wfuzz, masscan, and hundreds more +RUN apt-get update && \ + apt-get install -y kali-linux-everything && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* # Install additional Python tools and utilities for command logging # Install setuptools first to fix compatibility issues with Python 3.13