Skip to main content

A comprehensive Python wrapper for nmap with enhanced features

Project description

nust-nmap

PyPI version Python versions License: MIT Downloads

A robust, type-safe Python library providing an intuitive interface to the Nmap network scanning tool. Designed for security professionals, network administrators, and developers who need reliable network discovery and security auditing capabilities.

🚀 Key Features

  • 🛡️ Type Safety: Comprehensive type hints with enhanced error handling
  • ⚡ Performance: Asynchronous scanning with generator-based processing
  • 📊 Multiple Output Formats: CSV export and raw XML access
  • 🔍 Comprehensive Analysis: OS detection, service enumeration, and script execution
  • 🔄 Flexible Scanning: Synchronous, asynchronous, and yield-based scan modes
  • 📈 Production Ready: Robust error handling and logging for enterprise use

📦 Installation

Prerequisites

System Requirements:

  • Python 3.8 or higher
  • Nmap 7.0+ installed on your system

Install nust-nmap

pip install nust-nmap

Install Nmap

Ubuntu/Debian

sudo apt update && sudo apt install nmap

CentOS/RHEL/Fedora

sudo dnf install nmap  # Fedora
sudo yum install nmap  # CentOS/RHEL

macOS

brew install nmap

Windows

Download and install from nmap.org/download.html

🔧 Quick Start

Basic Network Scanning

import nmap

# Initialize scanner
scanner = nmap.PortScanner()

# Perform basic host discovery
result = scanner.scan('192.168.1.0/24', '22,80,443,8080')

# Analyze results
for host in scanner.all_hosts():
    if scanner[host].state() == 'up':
        print(f"🟢 {host} ({scanner[host].hostname()}) - {scanner[host].state()}")
        
        for protocol in scanner[host].all_protocols():
            ports = scanner[host][protocol].keys()
            for port in sorted(ports):
                state = scanner[host][protocol][port]['state']
                service = scanner[host][protocol][port]['name']
                print(f"   Port {port}/{protocol}: {state} ({service})")

Service Version Detection

# Comprehensive service and version detection
scanner.scan('target.example.com', '1-1000', '-sV -sC -O')

for host in scanner.all_hosts():
    print(f"\n=== {host} ===")
    for port in scanner[host]['tcp']:
        service_info = scanner[host]['tcp'][port]
        print(f"Port {port}: {service_info['state']} "
              f"({service_info['name']} {service_info.get('version', '')})")

📖 Comprehensive Usage Guide

Advanced Scanning Techniques

Stealth Scanning

# SYN stealth scan with timing optimization
scanner.scan('target-network.com', '1-65535', '-sS -T4 --min-rate 1000')

Service and OS Detection

# Comprehensive reconnaissance
scanner.scan('target.com', arguments='-sV -sC -O -A --script vuln')

Custom Nmap Scripts

# Execute specific NSE scripts
scanner.scan('web-server.com', '80,443', '--script http-title,http-headers,ssl-cert')

Asynchronous Scanning for Performance

import time
import threading

class NetworkScanner:
    def __init__(self):
        self.results = []
        self.scan_complete = threading.Event()
    
    def scan_callback(self, host, scan_result):
        """Callback function for async scan results"""
        if scan_result:
            self.results.append((host, scan_result))
            print(f"✅ Completed scan for {host}")
        else:
            print(f"❌ Failed to scan {host}")
    
    def scan_network_async(self, network, ports):
        """Perform asynchronous network scan"""
        scanner = nmap.PortScannerAsync()
        
        scanner.scan(
            hosts=network,
            ports=ports,
            arguments='-sS -sV',
            callback=self.scan_callback
        )
        
        # Monitor scan progress
        while scanner.still_scanning():
            print(f"⏳ Scanning in progress... ({len(self.results)} hosts completed)")
            time.sleep(2)
        
        print(f"🎉 Network scan completed! Found {len(self.results)} responsive hosts")
        return self.results

# Usage
network_scanner = NetworkScanner()
results = network_scanner.scan_network_async('192.168.1.0/24', '22,80,443,8080')

Generator-Based Processing

def process_large_network(network_range, ports):
    """Efficiently process large network ranges"""
    scanner = nmap.PortScannerYield()
    
    active_hosts = []
    
    for host, result in scanner.scan(network_range, ports=ports, arguments='-sS'):
        if result and result['nmap']['scanstats']['uphosts'] != '0':
            active_hosts.append(host)
            print(f"📡 Active host discovered: {host}")
            
            # Process immediately to save memory
            yield host, result
    
    print(f"🔍 Discovery complete: {len(active_hosts)} active hosts found")

# Process enterprise network efficiently
for host, data in process_large_network('10.0.0.0/16', '22,80,443'):
    # Handle each host as discovered
    pass

Data Export and Analysis

import csv
from datetime import datetime

def export_scan_results(scanner, filename=None):
    """Export scan results to multiple formats"""
    
    if not filename:
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"nmap_scan_{timestamp}"
    
    # Export to CSV
    csv_data = scanner.csv()
    with open(f"{filename}.csv", 'w', newline='') as f:
        f.write(csv_data)
    
    # Export raw XML
    xml_data = scanner.get_nmap_last_output()
    with open(f"{filename}.xml", 'w') as f:
        f.write(xml_data)
    
    print(f"📄 Results exported:")
    print(f"   CSV: {filename}.csv")
    print(f"   XML: {filename}.xml")
    
    return filename

# Usage
scanner.scan('192.168.1.0/24', '22,80,443,8080', '-sV')
export_scan_results(scanner, "network_audit_2024")

🔧 API Reference

Core Classes

PortScanner

Primary synchronous scanning interface.

scanner = nmap.PortScanner()

Key Methods:

  • scan(hosts, ports=None, arguments='-sV', sudo=False, timeout=0) - Execute scan
  • listscan(hosts) - Host discovery without port scanning
  • all_hosts() - Retrieve all discovered hosts
  • has_host(host) - Check if host exists in results
  • csv() - Export results as CSV
  • get_nmap_last_output() - Get raw XML output

PortScannerAsync

High-performance asynchronous scanning.

async_scanner = nmap.PortScannerAsync()
async_scanner.scan(hosts, ports, arguments, callback)

PortScannerYield

Memory-efficient generator-based scanning.

yield_scanner = nmap.PortScannerYield()
for host, result in yield_scanner.scan(hosts, ports):
    process_host(host, result)

Host Data Access

# Access host information
host = scanner['192.168.1.1']

# Host properties
host.hostname()              # DNS hostname
host.state()                # Host state (up/down)
host.all_protocols()        # Available protocols
host.all_tcp()              # TCP ports
host.all_udp()              # UDP ports

# Port-specific data
host.has_tcp(80)            # Check TCP port existence
port_info = host.tcp(80)    # Get port details

🛡️ Security Best Practices

Ethical Scanning Guidelines

import ipaddress

def validate_scan_target(target):
    """Validate scan targets against ethical guidelines"""
    
    # Define restricted networks
    restricted_networks = [
        ipaddress.ip_network('169.254.0.0/16'),  # Link-local
        ipaddress.ip_network('224.0.0.0/4'),    # Multicast
        ipaddress.ip_network('127.0.0.0/8'),    # Loopback (allow for testing)
    ]
    
    try:
        target_network = ipaddress.ip_network(target, strict=False)
        
        for restricted in restricted_networks:
            if target_network.overlaps(restricted) and not target.startswith('127.'):
                raise ValueError(f"Scanning {target} is not recommended")
                
    except ValueError as e:
        print(f"⚠️  Target validation warning: {e}")
        return False
    
    return True

# Always validate targets
if validate_scan_target('192.168.1.0/24'):
    scanner.scan('192.168.1.0/24', '22,80,443')

Error Handling and Resilience

import logging
from contextlib import contextmanager

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@contextmanager
def safe_scan_context():
    """Context manager for safe scanning with cleanup"""
    scanner = None
    try:
        scanner = nmap.PortScanner()
        yield scanner
    except nmap.PortScannerError as e:
        logger.error(f"Scan error: {e}")
        raise
    except nmap.PortScannerTimeout as e:
        logger.warning(f"Scan timeout: {e}")
        raise
    except Exception as e:
        logger.error(f"Unexpected error: {e}")
        raise
    finally:
        if scanner:
            logger.info("Scan context cleanup completed")

# Robust scanning implementation
def robust_network_scan(network, ports, max_retries=3):
    """Perform network scan with retry logic"""
    
    for attempt in range(max_retries):
        try:
            with safe_scan_context() as scanner:
                result = scanner.scan(network, ports, arguments='-sS -T3')
                return scanner, result
                
        except nmap.PortScannerTimeout:
            if attempt < max_retries - 1:
                logger.warning(f"Timeout on attempt {attempt + 1}, retrying...")
                continue
            raise
        except nmap.PortScannerError as e:
            logger.error(f"Scan failed: {e}")
            if "permission" in str(e).lower():
                logger.info("Try running with sudo for raw socket access")
            raise

# Usage
try:
    scanner, results = robust_network_scan('192.168.1.0/24', '22,80,443')
    logger.info(f"Successfully scanned {len(scanner.all_hosts())} hosts")
except Exception as e:
    logger.error(f"Network scan failed: {e}")

📊 Common Scan Patterns

Scan Type Command Use Case
Host Discovery -sn Network reconnaissance
Stealth Scan -sS Firewall evasion
Version Detection -sV Service enumeration
OS Detection -O Operating system fingerprinting
Aggressive Scan -A Comprehensive analysis
Script Scan --script <category> Vulnerability assessment
UDP Scan -sU UDP service discovery
Fast Scan -T4 --min-rate 1000 Time-sensitive scanning

🤝 Contributing

We welcome contributions! Please see our Contributing Guidelines for details.

Development Setup

# Clone repository
git clone https://github.com/codeNinja62/nust-nmap.git
cd nust-nmap

# Create virtual environment
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest tests/

📜 License

This project is licensed under the MIT License - see the LICENSE file for details.

👤 Author

Sameer Ahmed

🙏 Acknowledgments

  • Built upon the robust Nmap Security Scanner
  • Inspired by the original python-nmap library
  • Special thanks to the cybersecurity community for feedback and contributions

🔗 Links

⚠️ Legal Disclaimer

IMPORTANT: This tool is designed for authorized security testing and network administration only.

  • Authorized Use: Own networks, approved penetration testing, security research
  • Prohibited Use: Unauthorized scanning, malicious activities, illegal reconnaissance

Users are solely responsible for compliance with applicable laws and regulations. Always obtain explicit permission before scanning networks you do not own or administer.


"Know your network, secure your future." 🛡️

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nust_nmap-1.2.tar.gz (30.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nust_nmap-1.2-py3-none-any.whl (25.5 kB view details)

Uploaded Python 3

File details

Details for the file nust_nmap-1.2.tar.gz.

File metadata

  • Download URL: nust_nmap-1.2.tar.gz
  • Upload date:
  • Size: 30.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for nust_nmap-1.2.tar.gz
Algorithm Hash digest
SHA256 04ee7f51fa75e4a50550d3eabb7470d74bfea4848b0aab045f0f81e0a4ccb221
MD5 02187874195eaea502ceb570ea6fead0
BLAKE2b-256 6da8deec8eabc53f60f98a7697c5ccf334a8987a7996db240aac10bdf758af31

See more details on using hashes here.

Provenance

The following attestation bundles were made for nust_nmap-1.2.tar.gz:

Publisher: publish.yml on codeNinja62/nust-nmap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nust_nmap-1.2-py3-none-any.whl.

File metadata

  • Download URL: nust_nmap-1.2-py3-none-any.whl
  • Upload date:
  • Size: 25.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for nust_nmap-1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e2040b299b53c5cb57e37c801d264b01e335306d98e727e07b525aac8b4476e7
MD5 c93184a62545ebc3302b1396b1729dbf
BLAKE2b-256 48423ffbdbce509dbb34c804d181918e2484f276fac287957fe6096810246d56

See more details on using hashes here.

Provenance

The following attestation bundles were made for nust_nmap-1.2-py3-none-any.whl:

Publisher: publish.yml on codeNinja62/nust-nmap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page