Introduction to Network Mapping and Port Scanning
Network mapping and port scanning are fundamental reconnaissance techniques in cybersecurity. They allow security professionals to discover devices on a network, identify open ports, detect running services, and understand the attack surface of an organization. These techniques are used both by security teams to assess vulnerabilities and by attackers to identify potential entry points.
Key Concepts
- Network Discovery: Identifying live hosts on a network
- Port Scanning: Determining which ports are open on a target
- Service Detection: Identifying running services and their versions
- OS Fingerprinting: Determining the operating system of target hosts
- Network Topology: Mapping the structure and relationships between network devices
1. Network Discovery Fundamentals
Understanding Network Topology
import ipaddress import subprocess import socket import threading import queue import time from dataclasses import dataclass from typing import List, Dict, Optional import concurrent.futures @dataclass class NetworkHost: """Represents a discovered network host""" ip: str hostname: Optional[str] = None status: str = "unknown" open_ports: List[int] = None services: Dict[int, str] = None os: Optional[str] = None def __post_init__(self): if self.open_ports is None: self.open_ports = [] if self.services is None: self.services = {} class NetworkDiscovery: """Network discovery and host enumeration""" def __init__(self): self.hosts = [] self.network = None def parse_network(self, network_cidr): """Parse network CIDR notation""" try: self.network = ipaddress.ip_network(network_cidr, strict=False) print(f"Target network: {self.network}") return True except ValueError as e: print(f"Invalid network: {e}") return False def ping_host(self, ip): """Ping a single host to check if it's alive""" # Different ping commands for different OS param = '-n' if 'win' in subprocess.getoutput('uname -s').lower() else '-c' command = ['ping', param, '1', '-W', '1', str(ip)] try: result = subprocess.run(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=2) return result.returncode == 0 except subprocess.TimeoutExpired: return False except Exception: return False def discover_hosts(self, timeout=2, max_workers=100): """Discover live hosts using ping sweep""" if not self.network: print("No network specified") return print(f"\nDiscovering live hosts on {self.network}...") print("=" * 50) live_hosts = [] hosts = list(self.network.hosts()) def check_host(ip): if self.ping_host(ip): return ip with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: futures = [executor.submit(check_host, ip) for ip in hosts] for future in concurrent.futures.as_completed(futures): result = future.result() if result: live_hosts.append(result) print(f" ✓ Host: {result}") print(f"\nFound {len(live_hosts)} live hosts") # Create host objects for ip in live_hosts: host = NetworkHost(ip=str(ip), status="up") self.hosts.append(host) return self.hosts def reverse_dns_lookup(self, host): """Perform reverse DNS lookup""" try: hostname = socket.gethostbyaddr(host.ip) host.hostname = hostname[0] return True except socket.herror: return False def resolve_all_hostnames(self): """Resolve hostnames for all discovered hosts""" print("\nResolving hostnames...") for host in self.hosts: if self.reverse_dns_lookup(host): print(f" {host.ip} → {host.hostname}") else: print(f" {host.ip} → (no PTR record)") # Example usage discovery = NetworkDiscovery() discovery.parse_network("192.168.1.0/24") discovery.discover_hosts() discovery.resolve_all_hostnames() ICMP Techniques
class ICMPTechniques: """Advanced ICMP discovery techniques""" @staticmethod def explain_icmp_types(): """Explain different ICMP types used in network discovery""" icmp_types = { "Echo Request (Type 8)": "Standard ping - most common but often blocked", "Echo Reply (Type 0)": "Response to ping, indicates host is up", "Timestamp Request (Type 13)": "Alternative ICMP probe, sometimes allowed", "Address Mask Request (Type 17)": "Less commonly filtered", "Information Request (Type 15)": "Legacy, sometimes allowed through firewalls" } print("ICMP Discovery Techniques") print("=" * 50) for probe, description in icmp_types.items(): print(f" • {probe}: {description}") print("\nICMP Bypass Techniques:") print(" • Use alternative ICMP types that firewalls may allow") print(" • Combine with TCP/UDP probes for more reliable detection") print(" • Use ICMP echo with large packet sizes for MTU discovery") @staticmethod def icmp_timestamp_scan(): """Conceptual ICMP timestamp scan""" print("\nICMP Timestamp Scan Concept:") print(" • Sends ICMP Timestamp Request (type 13)") print(" • Some networks allow this when standard ICMP is blocked") print(" • Can reveal host time and sometimes OS information") @staticmethod def icmp_address_mask_scan(): """Conceptual ICMP address mask scan""" print("\nICMP Address Mask Scan Concept:") print(" • Sends ICMP Address Mask Request (type 17)") print(" • Often allowed through firewalls") print(" • Can reveal subnet mask information") ICMPTechniques.explain_icmp_types() 2. Port Scanning Techniques
TCP Connect Scan
class TCPScanner: """TCP port scanning implementation""" def __init__(self): self.common_ports = { 20: "FTP-data", 21: "FTP", 22: "SSH", 23: "Telnet", 25: "SMTP", 53: "DNS", 80: "HTTP", 110: "POP3", 111: "RPC", 135: "MSRPC", 139: "NetBIOS", 143: "IMAP", 443: "HTTPS", 445: "SMB", 993: "IMAPS", 995: "POP3S", 1433: "MSSQL", 3306: "MySQL", 3389: "RDP", 5432: "PostgreSQL", 5900: "VNC", 8080: "HTTP-Alt", 8443: "HTTPS-Alt" } def tcp_connect_scan(self, host, ports, timeout=2): """Perform TCP connect scan (full handshake)""" print(f"\nTCP Connect Scan on {host}") print("=" * 50) print("Port\tState\tService") print("-" * 40) open_ports = [] for port in ports: try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(timeout) result = sock.connect_ex((host, port)) if result == 0: service = self.common_ports.get(port, "unknown") print(f"{port}\topen\t{service}") open_ports.append(port) sock.close() except Exception as e: continue return open_ports def tcp_syn_scan_concept(self): """Explain SYN scan (half-open)""" print("\nSYN Scan (Half-Open) Technique") print("=" * 40) print(""" Normal TCP handshake: Client → SYN → Server Server → SYN-ACK → Client Client → ACK → Server [Connection established] SYN Scan: Client → SYN → Server Server → SYN-ACK → Client Client → RST → Server [Connection never fully established] Advantages: • Faster (no full handshake) • Stealthier (no application layer logs) • Can bypass some firewalls Disadvantages: • Requires raw packet privileges (root) • May be detected by IDS """) def udp_scan(self, host, ports, timeout=2): """Perform UDP port scan""" print(f"\nUDP Scan on {host}") print("=" * 50) print("Port\tState\tService") print("-" * 40) open_ports = [] for port in ports: try: sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(timeout) # Send empty UDP packet sock.sendto(b'', (host, port)) # Try to receive response try: data, addr = sock.recvfrom(1024) service = self.common_ports.get(port, "unknown") print(f"{port}\topen\t{service}") open_ports.append(port) except socket.timeout: # No response doesn't necessarily mean closed # Could be open but not responding pass except ConnectionRefusedError: # ICMP port unreachable - port is closed pass sock.close() except Exception as e: continue print("\nNote: UDP scan is less reliable than TCP scan") print(" • Many services don't respond to empty UDP packets") print(" • Rate limiting may affect results") return open_ports # Example usage scanner = TCPScanner() scanner.tcp_syn_scan_concept() # Scan common ports common_ports = [21, 22, 23, 25, 80, 443, 3306, 3389, 8080] # scanner.tcp_connect_scan("192.168.1.1", common_ports) Port Scanning Techniques Comparison
class ScanningTechniques: """Comparison of different port scanning techniques""" techniques = { "TCP Connect": { "description": "Complete TCP handshake", "stealth": "Low - full connection logged", "speed": "Medium", "privileges": "User", "detection": "Easy to detect", "reliability": "High" }, "SYN Scan": { "description": "Half-open, no final ACK", "stealth": "Medium - connection not completed", "speed": "Fast", "privileges": "Root", "detection": "Moderate", "reliability": "High" }, "FIN Scan": { "description": "Send FIN packet", "stealth": "High - may bypass firewalls", "speed": "Fast", "privileges": "Root", "detection": "Low", "reliability": "Medium (OS dependent)" }, "NULL Scan": { "description": "No flags set", "stealth": "High", "speed": "Fast", "privileges": "Root", "detection": "Low", "reliability": "Medium" }, "XMAS Scan": { "description": "FIN, URG, PUSH flags set", "stealth": "High", "speed": "Fast", "privileges": "Root", "detection": "Low", "reliability": "Medium" }, "UDP Scan": { "description": "Send UDP packets", "stealth": "Medium", "speed": "Slow", "privileges": "User", "detection": "Moderate", "reliability": "Low (many false positives)" }, "ACK Scan": { "description": "Send ACK packet", "stealth": "Medium", "speed": "Fast", "privileges": "Root", "detection": "Moderate", "reliability": "High for firewall detection" } } @classmethod def compare_techniques(cls): """Display comparison of scanning techniques""" print("Port Scanning Techniques Comparison") print("=" * 80) print(f"{'Technique':<12} {'Description':<20} {'Stealth':<8} {'Speed':<8} {'Privileges':<10} {'Reliability':<10}") print("-" * 80) for name, details in cls.techniques.items(): print(f"{name:<12} {details['description'][:18]:<20} " f"{details['stealth']:<8} {details['speed']:<8} " f"{details['privileges']:<10} {details['reliability']:<10}") @classmethod def scan_type_recommendations(cls): """Provide recommendations for different scenarios""" print("\n" + "="*80) print("Recommended Scan Types by Scenario") print("="*80) scenarios = { "Standard Penetration Test": "SYN scan (fast, reliable)", "Firewall Testing": "ACK scan, FIN scan, NULL scan", "UDP Service Discovery": "UDP scan combined with service-specific probes", "Stealth Assessment": "FIN/NULL/XMAS scans", "Internal Network Audit": "TCP Connect (full logging for audit)", "Quick Discovery": "SYN scan on common ports", "Comprehensive Audit": "Full port scan with service version detection" } for scenario, recommendation in scenarios.items(): print(f" • {scenario}: {recommendation}") ScanningTechniques.compare_techniques() ScanningTechniques.scan_type_recommendations() 3. Service and Version Detection
class ServiceDetection: """Service and version fingerprinting""" def __init__(self): self.service_signatures = { # Web servers "HTTP": [ (b"Server: Apache", "Apache HTTP Server"), (b"Server: nginx", "nginx"), (b"Server: Microsoft-IIS", "Microsoft IIS"), (b"Server: lighttpd", "lighttpd"), (b"Server: Caddy", "Caddy"), ], # SSH "SSH": [ (b"SSH-2.0-OpenSSH", "OpenSSH"), (b"SSH-2.0-OpenSSH_", "OpenSSH (with version)"), (b"SSH-2.0-dropbear", "Dropbear SSH"), ], # FTP "FTP": [ (b"220 ", "FTP Service Ready"), (b"vsFTPd", "vsFTPd"), (b"ProFTPD", "ProFTPD"), (b"Microsoft FTP", "Microsoft FTP Service"), ], # SMTP "SMTP": [ (b"220 ", "SMTP Ready"), (b"ESMTP Postfix", "Postfix"), (b"ESMTP Sendmail", "Sendmail"), (b"Exchange", "Microsoft Exchange"), ] } def banner_grab(self, host, port, timeout=3): """Attempt to grab service banner""" try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(timeout) sock.connect((host, port)) # Send common probes probes = [ b"\r\n", # CRLF b"HEAD / HTTP/1.0\r\n\r\n", # HTTP probe b"QUIT\r\n", # FTP/SMTP probe b"\n", # Simple newline ] for probe in probes: try: sock.send(probe) data = sock.recv(1024) if data: return self.identify_service(port, data) except: continue sock.close() return None except Exception as e: return None def identify_service(self, port, banner): """Identify service from banner""" service_name = None # Determine likely service based on port service_by_port = { 80: "HTTP", 443: "HTTPS", 22: "SSH", 21: "FTP", 25: "SMTP", 53: "DNS", 3306: "MySQL", 5432: "PostgreSQL" } service_type = service_by_port.get(port, "Unknown") # Check signatures for this service type if service_type in self.service_signatures: for signature, name in self.service_signatures[service_type]: if signature in banner: service_name = name break if not service_name: # Try to identify from banner content if b"SSH" in banner: service_name = "SSH" elif b"HTTP" in banner or b"Server:" in banner: service_name = "HTTP" elif b"220" in banner and b"FTP" in banner: service_name = "FTP" else: service_name = service_type return { 'port': port, 'service': service_name, 'banner': banner[:200].decode('utf-8', errors='ignore'), 'version': self.extract_version(banner) } def extract_version(self, banner): """Extract version information from banner""" import re # Common version patterns patterns = [ r'(\d+\.\d+\.\d+)', r'(\d+\.\d+)', r'version[^\d]*(\d+\.\d+\.?\d*)', ] banner_str = banner.decode('utf-8', errors='ignore') for pattern in patterns: match = re.search(pattern, banner_str, re.IGNORECASE) if match: return match.group(1) return "unknown" def scan_services(self, host, ports): """Scan multiple ports for service identification""" results = [] print(f"\nService Detection on {host}") print("=" * 60) print("Port\tService\t\tVersion\t\tBanner Preview") print("-" * 60) for port in ports: banner = self.banner_grab(host, port) if banner: results.append(banner) print(f"{port}\t{banner['service']:<15} {banner['version']:<12} " f"{banner['banner'][:40]}...") else: print(f"{port}\t(no response)") return results # Example usage detector = ServiceDetection() # results = detector.scan_services("192.168.1.1", [80, 22, 443, 3306]) 4. OS Fingerprinting
class OSFingerprinting: """Operating system detection techniques""" def __init__(self): self.os_signatures = { "Linux": { "ttl": [64, 255], "window_size": [5840, 5792], "tcp_options": ["mss", "nop", "wscale", "sackOK"], "fingerprints": [ b"Linux", b"Ubuntu", b"Debian", b"Red Hat", b"CentOS" ] }, "Windows": { "ttl": [128], "window_size": [8192, 16384, 64240], "tcp_options": ["mss", "nop", "nop", "sackOK"], "fingerprints": [ b"Windows", b"Microsoft", b"Windows NT", b"Server" ] }, "MacOS": { "ttl": [64], "window_size": [65535], "tcp_options": ["mss", "nop", "wscale", "sackOK"], "fingerprints": [b"Darwin", b"Mac OS", b"macOS"] }, "FreeBSD": { "ttl": [64], "window_size": [65535], "tcp_options": ["mss", "nop", "sackOK"], "fingerprints": [b"FreeBSD", b"BSD"] } } def tcp_os_fingerprint(self, host, port=80): """Perform TCP OS fingerprinting""" try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(3) sock.connect((host, port)) # Get socket options to infer OS # This is simplified - real OS fingerprinting uses more sophisticated techniques ttl = self._get_ttl(host) window_size = self._get_tcp_window(host, port) # Attempt banner grab for OS identification banner = self._get_banner(host, port) sock.close() return self._match_os(ttl, window_size, banner) except Exception as e: return {"os": "Unknown", "confidence": "low", "error": str(e)} def _get_ttl(self, host): """Get TTL value using ping""" param = '-n' if 'win' in subprocess.getoutput('uname -s').lower() else '-c' try: result = subprocess.run(['ping', param, '1', host], capture_output=True, text=True, timeout=2) # Parse TTL from output import re match = re.search(r'ttl[= ](\d+)', result.stdout.lower()) if match: return int(match.group(1)) except: pass return None def _get_tcp_window(self, host, port): """Get TCP window size""" try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) window = sock.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF) sock.close() return window except: return None def _get_banner(self, host, port): """Get service banner""" try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(2) sock.connect((host, port)) sock.send(b"\r\n") banner = sock.recv(1024) sock.close() return banner except: return b"" def _match_os(self, ttl, window, banner): """Match collected data to OS signatures""" matches = [] for os_name, signature in self.os_signatures.items(): score = 0 if ttl in signature.get('ttl', []): score += 30 if window in signature.get('window_size', []): score += 30 if any(fingerprint in banner for fingerprint in signature.get('fingerprints', [])): score += 40 if score > 0: matches.append((os_name, score)) if matches: matches.sort(key=lambda x: x[1], reverse=True) best_match = matches[0] return { "os": best_match[0], "confidence": "high" if best_match[1] > 70 else "medium", "score": best_match[1] } return {"os": "Unknown", "confidence": "low", "score": 0} def passive_os_fingerprint(self, capture_data): """Passive OS fingerprinting from captured traffic""" # Analyze packet characteristics # This is a simplified version print("\nPassive OS Fingerprinting Analysis:") indicators = { "Initial TTL": "64 = Linux/Unix, 128 = Windows", "TCP Window Size": "5840 = Linux, 8192/16384 = Windows", "TCP Options": "Order and values indicate OS", "DF Flag": "Don't Fragment flag behavior", "IP ID": "Increment patterns" } for indicator, description in indicators.items(): print(f" • {indicator}: {description}") # Example usage fingerprinter = OSFingerprinting() result = fingerprinter.tcp_os_fingerprint("scanme.nmap.org", 80) print(f"\nOS Fingerprint Result: {result}") 5. Advanced Scanning Techniques
Stealth Scanning
class StealthScanning: """Advanced stealth scanning techniques""" @staticmethod def explain_stealth_techniques(): """Explain stealth scanning methods""" print("Stealth Scanning Techniques") print("=" * 50) techniques = { "Decoy Scanning": { "description": "Use multiple decoy IPs to hide real source", "command": "nmap -D RND:10,ME target", "effect": "Makes attribution difficult" }, "Idle Scan": { "description": "Use a zombie host to bounce scan", "command": "nmap -sI zombie target", "effect": "Extremely stealthy, no packets from attacker" }, "Fragmentation": { "description": "Split packets into fragments", "command": "nmap -f target", "effect": "Bypass simple packet filters" }, "Source Port Manipulation": { "description": "Spoof source port", "command": "nmap -g 53 target", "effect": "Bypass port-based filtering" }, "Timing Manipulation": { "description": "Slow down scan rate", "command": "nmap -T0 (Paranoid), -T1 (Sneaky)", "effect": "Avoid IDS detection" } } for name, details in techniques.items(): print(f"\n• {name}:") print(f" {details['description']}") print(f" Command: {details['command']}") print(f" Effect: {details['effect']}") @staticmethod def timing_templates(): """Explain Nmap timing templates""" print("\nNmap Timing Templates") print("-" * 40) templates = { "T0 (Paranoid)": "0.33 seconds between probes, very slow", "T1 (Sneaky)": "1.5 seconds between probes, stealthy", "T2 (Polite)": "0.4 seconds between probes, polite scanning", "T3 (Normal)": "Default timing, normal speed", "T4 (Aggressive)": "Faster, assumes good network", "T5 (Insane)": "Very fast, may drop packets" } for name, description in templates.items(): print(f" {name:<15}: {description}") StealthScanning.explain_stealth_techniques() StealthScanning.timing_templates() Firewall Evasion
class FirewallEvasion: """Firewall evasion techniques""" @staticmethod def explain_evasion(): """Explain firewall evasion techniques""" print("Firewall Evasion Techniques") print("=" * 50) techniques = { "ACK Scan": { "method": "Send ACK packets to probe firewall rules", "purpose": "Determine which ports are filtered", "response": "RST for unfiltered, no response for filtered" }, "Window Scan": { "method": "Examine TCP window field in RST packets", "purpose": "Determine open vs closed ports", "response": "Non-zero window = open, zero = closed" }, "Maimon Scan": { "method": "Send FIN/ACK packet", "purpose": "Some systems respond differently", "response": "RST for open ports (non-standard)" }, "Idle Scan": { "method": "Use zombie host to bounce scan", "purpose": "Complete stealth, no packets from attacker", "response": "Analyze IP ID changes on zombie" }, "FTP Bounce": { "method": "Use FTP server as proxy", "purpose": "Obscure source, bypass firewalls", "response": "Limited to FTP port" } } for name, details in techniques.items(): print(f"\n• {name}:") print(f" Method: {details['method']}") print(f" Purpose: {details['purpose']}") print(f" Response: {details['response']}") FirewallEvasion.explain_evasion() 6. Network Mapping Visualization
class NetworkMapper: """Network topology mapping and visualization""" def __init__(self): self.nodes = {} self.edges = [] def add_host(self, ip, hostname=None, os=None, services=None): """Add host to network map""" self.nodes[ip] = { 'ip': ip, 'hostname': hostname, 'os': os, 'services': services or [], 'type': self._classify_host(ip, services) } def _classify_host(self, ip, services): """Classify host type based on IP and services""" # Check for common service patterns if not services: return "unknown" service_ports = [s.get('port', 0) for s in services] if 80 in service_ports or 443 in service_ports: return "web_server" if 3306 in service_ports or 5432 in service_ports: return "database" if 22 in service_ports: return "ssh_server" if 445 in service_ports or 139 in service_ports: return "file_server" if 53 in service_ports: return "dns_server" return "workstation" def add_connection(self, source, destination, protocol="unknown"): """Add network connection between hosts""" self.edges.append({ 'source': source, 'destination': destination, 'protocol': protocol }) def generate_graphviz(self, filename="network_map.dot"): """Generate Graphviz DOT file for visualization""" with open(filename, 'w') as f: f.write('graph NetworkMap {\n') f.write(' rankdir=TB;\n') f.write(' node [shape=box];\n\n') # Add nodes for ip, data in self.nodes.items(): label = f"{ip}" if data['hostname']: label = f"{data['hostname']}\\n{ip}" if data['os']: label += f"\\n{data['os']}" # Node styling based on type node_type = data['type'] if node_type == 'web_server': f.write(f' "{ip}" [shape=ellipse, fillcolor=lightblue, style=filled, label="{label}"];\n') elif node_type == 'database': f.write(f' "{ip}" [shape=cylinder, fillcolor=lightgreen, style=filled, label="{label}"];\n') elif node_type == 'file_server': f.write(f' "{ip}" [shape=folder, fillcolor=yellow, style=filled, label="{label}"];\n') else: f.write(f' "{ip}" [label="{label}"];\n') # Add edges for edge in self.edges: f.write(f' "{edge["source"]}" -- "{edge["destination"]}" [label="{edge["protocol"]}"];\n') f.write('}\n') print(f"Graphviz file generated: {filename}") print("To render: dot -Tpng network_map.dot -o network_map.png") def generate_ascii_map(self): """Generate simple ASCII representation of network""" print("\nNetwork Map (ASCII)") print("=" * 50) # Group by IP class by_class = {} for ip in self.nodes: first_octet = ip.split('.')[0] if first_octet not in by_class: by_class[first_octet] = [] by_class[first_octet].append(ip) for net_class, ips in sorted(by_class.items()): print(f"\nNetwork {net_class}.0.0.0/8:") for ip in sorted(ips): data = self.nodes[ip] host_str = f" ├─ {ip}" if data['hostname']: host_str += f" ({data['hostname']})" if data['services']: services_str = ", ".join([s.get('service', 'unknown') for s in data['services']]) host_str += f" [{services_str}]" print(host_str) # Show connections connections = [e for e in self.edges if e['source'] == ip or e['destination'] == ip] for conn in connections: other = conn['destination'] if conn['source'] == ip else conn['source'] print(f" └─ connects to {other} ({conn['protocol']})") # Example network mapping mapper = NetworkMapper() # Add hosts mapper.add_host("192.168.1.1", "router.local", "Linux", [{"port": 80, "service": "http"}]) mapper.add_host("192.168.1.10", "web01.local", "Ubuntu", [{"port": 80, "service": "nginx"}, {"port": 22, "service": "ssh"}]) mapper.add_host("192.168.1.20", "db01.local", "CentOS", [{"port": 3306, "service": "mysql"}]) mapper.add_host("192.168.1.100", "workstation", "Windows", [{"port": 3389, "service": "rdp"}]) # Add connections mapper.add_connection("192.168.1.1", "192.168.1.10", "gateway") mapper.add_connection("192.168.1.10", "192.168.1.20", "database") mapper.add_connection("192.168.1.100", "192.168.1.10", "http") # Generate maps mapper.generate_ascii_map() # mapper.generate_graphviz() 7. Practical Scanning with Nmap
class NmapWrapper: """Python wrapper for Nmap scanning""" def __init__(self): self.scan_results = {} def run_nmap_scan(self, target, options): """Execute Nmap scan (conceptual - requires nmap installed)""" print(f"\nRunning Nmap scan: nmap {options} {target}") print("=" * 60) # This is a conceptual implementation - actual execution requires nmap installed # In practice, you'd use subprocess to call nmap or python-nmap library scan_templates = { "quick": "-T4 -F", "intensive": "-T4 -A -p-", "stealth": "-T2 -sS -f", "service": "-sV --version-intensity 5", "os": "-O --osscan-guess", "script": "-sC --script default" } scan_type = options if options in scan_templates: actual_options = scan_templates[options] else: actual_options = options print(f"Command: nmap {actual_options} {target}") print("\nCommon Nmap Commands:") print(" • Quick scan: nmap -T4 -F 192.168.1.0/24") print(" • Service detection: nmap -sV 192.168.1.1") print(" • OS detection: nmap -O 192.168.1.1") print(" • Aggressive scan: nmap -A 192.168.1.1") print(" • Full port scan: nmap -p- 192.168.1.1") print(" • Script scan: nmap -sC 192.168.1.1") print(" • UDP scan: nmap -sU 192.168.1.1") @staticmethod def nmap_script_categories(): """Explain Nmap script categories""" print("\nNmap Script Categories") print("=" * 50) categories = { "auth": "Authentication credentials", "broadcast": "Network broadcast discovery", "brute": "Brute force attacks", "default": "Default scripts (safe)", "discovery": "Host/service discovery", "dos": "Denial of service", "exploit": "Exploitation", "external": "External services (whois, etc.)", "fuzzer": "Fuzzing", "intrusive": "Potentially intrusive scripts", "malware": "Malware detection", "safe": "Safe scripts (no impact)", "version": "Version detection", "vuln": "Vulnerability detection" } for category, description in categories.items(): print(f" • {category:<12}: {description}") @staticmethod def useful_nmap_scripts(): """List useful Nmap scripts""" print("\nUseful Nmap Scripts") print("=" * 50) scripts = { "http-enum": "Enumerate web directories", "http-headers": "Retrieve HTTP headers", "http-title": "Get web page titles", "smb-os-discovery": "Discover SMB OS", "smb-enum-shares": "Enumerate SMB shares", "ssl-cert": "Get SSL certificate details", "ssl-enum-ciphers": "Enumerate SSL ciphers", "dns-brute": "Brute force DNS subdomains", "whois": "WHOIS lookup", "vulners": "Check vulnerabilities" } for script, description in scripts.items(): print(f" • {script:<20}: {description}") # Example usage nmap = NmapWrapper() nmap.run_nmap_scan("192.168.1.0/24", "quick") NmapWrapper.nmap_script_categories() 8. Network Mapping Tools Comparison
class ToolComparison: """Comparison of network mapping tools""" tools = { "Nmap": { "type": "Command-line", "features": ["Port scanning", "OS detection", "Service version", "Script engine"], "best_for": "Comprehensive scanning, scripting", "pros": "Powerful, flexible, extensive features", "cons": "Steep learning curve" }, "Masscan": { "type": "Command-line", "features": ["Very fast port scanning", "Internet-scale scanning"], "best_for": "Large-scale, fast scanning", "pros": "Extremely fast (millions packets/sec)", "cons": "Less feature-rich than Nmap" }, "Zmap": { "type": "Command-line", "features": ["Fast network scanning", "Protocol-specific modules"], "best_for": "Internet-wide scanning", "pros": "Very fast, efficient", "cons": "No service detection" }, "Zenmap": { "type": "GUI", "features": ["Nmap GUI", "Visualization", "Profiles"], "best_for": "Beginners, visualization", "pros": "User-friendly, graphical output", "cons": "Limited compared to command line" }, "Angry IP Scanner": { "type": "GUI (Java)", "features": ["IP scanning", "NetBIOS info", "Ping sweep"], "best_for": "Quick network discovery", "pros": "Cross-platform, simple interface", "cons": "Limited features" }, "Netcat": { "type": "Command-line", "features": ["Manual banner grabbing", "Port scanning"], "best_for": "Manual exploration, scripts", "pros": "Lightweight, versatile", "cons": "Manual, no automation" } } @classmethod def compare(cls): """Display tool comparison""" print("Network Mapping Tools Comparison") print("=" * 80) for name, details in cls.tools.items(): print(f"\n🔧 {name}") print(f" Type: {details['type']}") print(f" Features: {', '.join(details['features'])}") print(f" Best For: {details['best_for']}") print(f" Pros: {details['pros']}") print(f" Cons: {details['cons']}") ToolComparison.compare() 9. Legal and Ethical Considerations
class LegalEthicalConsiderations: """Legal and ethical guidelines for network scanning""" @staticmethod def legal_guidelines(): """Provide legal guidelines for network scanning""" print("Legal Guidelines for Network Scanning") print("=" * 60) guidelines = [ "1. Authorization: Always obtain written permission before scanning", "2. Scope: Only scan systems you own or have explicit permission for", "3. Laws: Be aware of local and international laws (CFAA, Computer Misuse Act)", "4. Data Protection: Handle discovered data responsibly", "5. Disclosure: Report findings responsibly to relevant parties", "6. Contract: Ensure scanning is within scope of agreements", "7. Impact: Consider potential impact on production systems" ] for guideline in guidelines: print(f" {guideline}") @staticmethod def ethical_principles(): """Outline ethical principles for security testing""" print("\nEthical Principles for Security Testing") print("=" * 60) principles = { "Do No Harm": "Avoid disrupting services or damaging systems", "Transparency": "Be open about your activities and findings", "Confidentiality": "Protect discovered vulnerabilities and data", "Integrity": "Do not modify or corrupt systems or data", "Competence": "Only perform tests you're qualified to conduct", "Responsibility": "Report findings appropriately and timely" } for principle, description in principles.items(): print(f" • {principle}: {description}") @staticmethod def scanning_permission_template(): """Provide template for scanning authorization""" print("\nScanning Authorization Template") print("=" * 60) print(""" Authorization for Network Security Testing I, [NAME], as [ROLE] of [ORGANIZATION], hereby authorize [TESTER_NAME] to perform network security testing including: - Network discovery and host enumeration - Port scanning (TCP and UDP) - Service version detection - OS fingerprinting - Vulnerability scanning Scope of testing: - IP Ranges: [LIST IP RANGES] - Time Window: [START DATE] to [END DATE] - Systems Excluded: [LIST EXCLUDED SYSTEMS] Authorized personnel: [NAMES] Rules of Engagement: - Testing will not intentionally disrupt services - Findings will be reported confidentially - Any critical findings will be reported immediately Signed: ______________________ Date: ______________________ """) LegalEthicalConsiderations.legal_guidelines() LegalEthicalConsiderations.ethical_principles() 10. Practical Exercise: Network Discovery Script
class NetworkDiscoveryExercise: """Complete network discovery and scanning exercise""" def __init__(self, target_network): self.target_network = target_network self.discovery_results = { 'live_hosts': [], 'open_ports': {}, 'services': {}, 'os_fingerprints': {}, 'summary': {} } def run_full_discovery(self): """Run complete network discovery workflow""" print("=" * 70) print("NETWORK DISCOVERY AND MAPPING EXERCISE") print("=" * 70) # Step 1: Network Discovery print("\n[1] NETWORK DISCOVERY") print("-" * 40) discovery = NetworkDiscovery() if discovery.parse_network(self.target_network): self.discovery_results['live_hosts'] = discovery.discover_hosts() discovery.resolve_all_hostnames() if not self.discovery_results['live_hosts']: print("No live hosts found. Exiting.") return # Step 2: Port Scanning print("\n[2] PORT SCANNING") print("-" * 40) scanner = TCPScanner() common_ports = [21, 22, 23, 25, 53, 80, 443, 3306, 3389, 8080] for host in self.discovery_results['live_hosts'][:3]: # Limit to first 3 hosts print(f"\nScanning {host.ip}:") open_ports = scanner.tcp_connect_scan(host.ip, common_ports) self.discovery_results['open_ports'][host.ip] = open_ports # Step 3: Service Detection print("\n[3] SERVICE DETECTION") print("-" * 40) detector = ServiceDetection() for host in self.discovery_results['live_hosts'][:3]: if host.ip in self.discovery_results['open_ports']: services = detector.scan_services(host.ip, self.discovery_results['open_ports'][host.ip]) self.discovery_results['services'][host.ip] = services # Step 4: OS Fingerprinting print("\n[4] OS FINGERPRINTING") print("-" * 40) fingerprinter = OSFingerprinting() for host in self.discovery_results['live_hosts'][:3]: result = fingerprinter.tcp_os_fingerprint(host.ip, 80) self.discovery_results['os_fingerprints'][host.ip] = result print(f"\n{host.ip}: {result['os']} (confidence: {result['confidence']})") # Step 5: Generate Report self.generate_report() return self.discovery_results def generate_report(self): """Generate discovery report""" print("\n" + "="*70) print("NETWORK DISCOVERY REPORT") print("="*70) print(f"\nTarget Network: {self.target_network}") print(f"Live Hosts Found: {len(self.discovery_results['live_hosts'])}") print("\nHost Details:") print("-" * 50) for host in self.discovery_results['live_hosts'][:3]: print(f"\n📡 {host.ip}") if host.hostname: print(f" Hostname: {host.hostname}") if host.ip in self.discovery_results['os_fingerprints']: os_info = self.discovery_results['os_fingerprints'][host.ip] print(f" OS: {os_info['os']} ({os_info['confidence']} confidence)") if host.ip in self.discovery_results['open_ports']: print(f" Open Ports: {', '.join(map(str, self.discovery_results['open_ports'][host.ip]))}") if host.ip in self.discovery_results['services']: print(" Services:") for service in self.discovery_results['services'][host.ip]: print(f" • {service['port']}: {service['service']} " f"(version: {service['version']})") print("\n" + "="*70) print("RECOMMENDATIONS") print("="*70) for host in self.discovery_results['live_hosts'][:3]: if host.ip in self.discovery_results['open_ports']: open_ports = self.discovery_results['open_ports'][host.ip] for port in open_ports: if port in [22, 23, 21]: print(f" • {host.ip} - Consider restricting access to port {port}") if port in [80, 443]: print(f" • {host.ip} - Ensure web applications are up to date") if port in [3306, 1433]: print(f" • {host.ip} - Database port exposed, consider firewall rules") # Run the exercise # exercise = NetworkDiscoveryExercise("192.168.1.0/24") # results = exercise.run_full_discovery() 11. Security Hardening Recommendations
class SecurityHardening: """Network security hardening recommendations""" @staticmethod def hardening_guidelines(): """Provide network hardening recommendations""" print("Network Security Hardening Guidelines") print("=" * 60) categories = { "Network Segmentation": [ "Implement VLANs to isolate different traffic types", "Use firewalls to control inter-VLAN traffic", "Create DMZ for public-facing services", "Implement micro-segmentation for critical assets" ], "Access Control": [ "Implement 802.1X for network authentication", "Use ACLs to restrict traffic", "Disable unused ports and services", "Implement least privilege access" ], "Monitoring": [ "Deploy IDS/IPS for threat detection", "Implement centralized logging (SIEM)", "Regular vulnerability scanning", "Monitor for port scans and anomalies" ], "Encryption": [ "Encrypt all sensitive traffic", "Use strong cipher suites (TLS 1.3)", "Implement VPN for remote access", "Enable WPA3 for wireless networks" ], "Configuration Management": [ "Harden network device configurations", "Change default credentials", "Regular security audits", "Patch management process" ] } for category, recommendations in categories.items(): print(f"\n📌 {category}:") for rec in recommendations: print(f" • {rec}") SecurityHardening.hardening_guidelines() Conclusion
Network mapping and port scanning are essential skills for cybersecurity professionals. This guide has covered:
Key Takeaways
- Discovery Techniques: ICMP, ARP, and TCP/UDP probes for host discovery
- Scanning Methods: Various port scanning techniques with different stealth levels
- Service Detection: Banner grabbing and fingerprinting for service identification
- OS Fingerprinting: TTL analysis, TCP stack behavior, and banner analysis
- Tools: Nmap, Masscan, and other network mapping utilities
- Legal/Ethical: Always obtain permission before scanning
- Hardening: Recommendations to protect against scanning
Common Ports to Know
| Port | Service | Security Concern |
|---|---|---|
| 21 | FTP | Plaintext authentication |
| 22 | SSH | Weak ciphers, brute force |
| 23 | Telnet | Plaintext communication |
| 25 | SMTP | Open relay, spam |
| 80 | HTTP | Lack of encryption |
| 443 | HTTPS | Weak SSL/TLS |
| 3306 | MySQL | Default credentials |
| 3389 | RDP | Brute force attacks |
| 445 | SMB | EternalBlue, ransomware |
Final Thoughts
Network mapping and port scanning are powerful reconnaissance techniques. Use them responsibly—only on systems you own or have explicit permission to test. The knowledge gained from these techniques helps organizations identify and fix vulnerabilities before attackers can exploit them.
Java Logistics, Shipping Integration & Enterprise Inventory Automation (Tracking, ERP, RFID & Billing Systems)
https://macronepal.com/blog/aftership-tracking-in-java-enterprise-package-visibility/
Explains how to integrate AfterShip tracking services into Java applications to provide real-time shipment visibility, delivery status updates, and centralized tracking across multiple courier services.
https://macronepal.com/blog/shipping-integration-using-fedex-api-with-java-for-logistics-automation/
Explains how to integrate the FedEx API into Java systems to automate shipping tasks such as creating shipments, calculating delivery costs, generating shipping labels, and tracking packages.
https://macronepal.com/blog/shipping-and-logistics-integrating-ups-apis-with-java-applications/
Explains UPS API integration in Java to enable automated shipping operations including rate calculation, shipment scheduling, tracking, and delivery confirmation management.
https://macronepal.com/blog/generating-and-reading-qr-codes-for-products-in-java/
Explains how Java applications generate and read QR codes for product identification, tracking, and authentication, supporting faster inventory handling and product verification processes.
https://macronepal.com/blog/designing-a-robust-pick-and-pack-workflow-in-java/
Explains how to design an efficient pick-and-pack workflow in Java warehouse systems, covering order processing, item selection, packaging steps, and logistics preparation to improve fulfillment efficiency.
https://macronepal.com/blog/rfid-inventory-management-system-in-java-a-complete-guide/
Explains how RFID technology integrates with Java applications to automate inventory tracking, reduce manual errors, and enable real-time stock monitoring in warehouses and retail environments.
https://macronepal.com/blog/erp-integration-with-odoo-in-java/
Explains how Java applications connect with Odoo ERP systems to synchronize inventory, orders, customer records, and financial data across enterprise systems.
https://macronepal.com/blog/automated-invoice-generation-creating-professional-excel-invoices-with-apache-poi-in-java/
Explains how to automatically generate professional Excel invoices in Java using Apache POI, enabling structured billing documents and automated financial record creation.
https://macronepal.com/blog/enterprise-financial-integration-using-quickbooks-api-in-java-applications/
Explains QuickBooks API integration in Java to automate financial workflows such as invoice management, payment tracking, accounting synchronization, and financial reporting.