Lucene search
+L

Linux Internal Network Scanner

🗓️ 24 Jan 2026 22:19:45Reported by KittySploitType 
kittysploit
 kittysploit
🔗 kittysploit.com👁 1 Views

Linux Internal Network Scanner scans internal networks for pivoting targets.

Refs
Code
from kittysploit import *
from lib.post.linux.system import System
from lib.post.linux.session import LinuxSessionMixin
import re

class Module(Post, System, LinuxSessionMixin):

    __info__ = {
        "name": "Linux Internal Network Scanner",
        "description": "Scan internal network from compromised Linux machine for pivoting targets",
        "platform": Platform.LINUX,
        "author": "KittySploit Team",
        "session_type": [SessionType.SHELL, 
                        SessionType.METERPRETER,
                        SessionType.SSH],
    'agent': {
        'risk': 'intrusive',
        'effects': ['active_exploitation'],
        'expected_requests': 2,
        'reversible': False,
        'approval_required': True,
        'produces': ['risk_signals'],
        'cost': 1.5,
        'noise': 0.5,
        'value': 1.0,
        'requires':         {'min_endpoints': 0,
         'min_params': 0,
         'tech_hints_any': [],
         'tech_hints_all': [],
         'specializations_any': [],
         'risk_signals_any': [],
         'auth_session': False,
         'capabilities_any': [],
         'capabilities_all': [],
         'confidence_min': {},
         'confidence_min_any': {},
         'endpoint_pattern_any': [],
         'param_any': [],
         'api_surface_ready': False},
        'chain':         {'produces_capabilities': [],
         'consumes_capabilities': ['shell'],
         'option_bindings': {},
         'suggested_followups': []},
    },
    }

    network_range = OptString("", "Network range to scan (e.g., 192.168.1.0/24 or 10.0.0.0/24)", required=True)
    scan_type = OptString("all", "Scan type: all, arp, ping, tcp, udp", required=False)
    ports = OptString("22,80,443,3389,8080", "TCP ports to scan (comma-separated)", required=False)
    timeout = OptInteger(1, "Timeout per host in seconds", required=False)

    IPV4_REGEX = re.compile(r"\b((?:25[0-5]|2[0-4]\d|1?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|1?\d?\d)){3})\b")

    def run(self):
        """Scan internal network from compromised machine"""
        
        if not self.linux_require_linux():
            return False

        print_status("Scanning internal network from compromised machine...")
        print_info(f"Network range: {self.network_range}")
        print_info(f"Scan type: {self.scan_type}")
        
        if not self.network_range:
            print_error("Network range is required")
            print_info("Example: 192.168.1.0/24 or 10.0.0.0/24")
            return False
        
        # Detect network if not provided
        if "/" not in self.network_range:
            print_status("Auto-detecting network range...")
            detected_network = self._detect_network()
            if detected_network:
                print_info(f"Detected network: {detected_network}")
                self.network_range = detected_network
            else:
                print_error("Could not auto-detect network. Please specify network range.")
                return False
        
        results = {}
        
        # Perform scans based on type
        if self.scan_type == "all" or self.scan_type == "arp":
            print_status("Performing ARP scan...")
            arp_results = self._arp_scan()
            results.update(arp_results)
        
        if self.scan_type == "all" or self.scan_type == "ping":
            print_status("Performing ICMP ping sweep...")
            ping_results = self._ping_sweep()
            results.update(ping_results)
        
        if self.scan_type == "all" or self.scan_type == "tcp":
            print_status("Performing TCP port scan...")
            tcp_results = self._tcp_scan()
            results.update(tcp_results)
        
        if self.scan_type == "all" or self.scan_type == "udp":
            print_status("Performing UDP scan...")
            udp_results = self._udp_scan()
            results.update(udp_results)
        
        # Display results
        self._display_results(results)
        
        return True
    
    def _detect_network(self):
        """Auto-detect network range from compromised machine"""
        try:
            # Get default route
            route_output = self.linux_execute("ip route | grep default 2>/dev/null || route -n | grep '^0.0.0.0' 2>/dev/null")
            if route_output:
                # Extract interface
                if "dev" in route_output:
                    parts = route_output.split()
                    if "dev" in parts:
                        idx = parts.index("dev")
                        if idx + 1 < len(parts):
                            interface = parts[idx + 1]
                            
                            # Get IP and netmask for this interface
                            ip_output = self.linux_execute(f"ip addr show {interface} 2>/dev/null | grep 'inet '")
                            if ip_output:
                                # Extract IP and CIDR
                                match = re.search(r'inet\s+(\d+\.\d+\.\d+\.\d+)/(\d+)', ip_output)
                                if match:
                                    ip = match.group(1)
                                    cidr = match.group(2)
                                    # Calculate network
                                    ip_parts = ip.split('.')
                                    if cidr == "24":
                                        network = f"{ip_parts[0]}.{ip_parts[1]}.{ip_parts[2]}.0/24"
                                        return network
                                    elif cidr == "16":
                                        network = f"{ip_parts[0]}.{ip_parts[1]}.0.0/16"
                                        return network
            
            # Fallback: try ifconfig
            ifconfig_output = self.linux_execute("ifconfig 2>/dev/null | grep -A 1 'inet '")
            if ifconfig_output:
                match = re.search(r'inet\s+(\d+\.\d+\.\d+\.\d+).*netmask\s+(\d+\.\d+\.\d+\.\d+)', ifconfig_output)
                if match:
                    ip = match.group(1)
                    netmask = match.group(2)
                    if netmask == "255.255.255.0":
                        ip_parts = ip.split('.')
                        return f"{ip_parts[0]}.{ip_parts[1]}.{ip_parts[2]}.0/24"
            
            return None
            
        except Exception as e:
            print_warning(f"Error detecting network: {e}")
            return None

    def _extract_ipv4(self, value):
        """Extract first valid IPv4 address from a string."""
        if not value:
            return None
        match = self.IPV4_REGEX.search(str(value))
        return match.group(1) if match else None
    
    def _arp_scan(self):
        """Perform ARP scan"""
        results = {}
        try:
            # Extract network base
            network_base = self.network_range.split('/')[0]
            base_parts = network_base.split('.')
            
            if len(base_parts) == 4:
                # Assume /24 for now
                base = f"{base_parts[0]}.{base_parts[1]}.{base_parts[2]}"
                
                print_info(f"Scanning {base}.0/24 with ARP...")
                
                # Use arp-scan if available
                if self.command_exists('arp-scan'):
                    arp_cmd = f"arp-scan --local --quiet 2>/dev/null | grep -E '^[0-9]'"
                    output = self.linux_execute(arp_cmd)
                    if output:
                        for line in output.strip().split('\n'):
                            if line.strip():
                                parts = line.split()
                                if len(parts) >= 2:
                                    ip = self._extract_ipv4(parts[0])
                                    if not ip:
                                        continue
                                    mac = parts[1]
                                    results[ip] = {
                                        'ip': ip,
                                        'mac': mac,
                                        'method': 'arp',
                                        'alive': True
                                    }
                else:
                    # Use arp table
                    arp_output = self.linux_execute("arp -a 2>/dev/null || ip neigh show 2>/dev/null")
                    if arp_output:
                        for line in arp_output.strip().split('\n'):
                            if line.strip():
                                # Parse ARP entry
                                ip = self._extract_ipv4(line)
                                if ip:
                                    mac_match = re.search(r'([0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}', line)
                                    mac = mac_match.group(0) if mac_match else "unknown"
                                    results[ip] = {
                                        'ip': ip,
                                        'mac': mac,
                                        'method': 'arp',
                                        'alive': True
                                    }
            
        except Exception as e:
            print_warning(f"ARP scan error: {e}")
        
        return results
    
    def _ping_sweep(self):
        """Perform ICMP ping sweep"""
        results = {}
        try:
            network_base = self.network_range.split('/')[0]
            base_parts = network_base.split('.')
            
            if len(base_parts) == 4:
                base = f"{base_parts[0]}.{base_parts[1]}.{base_parts[2]}"
                
                print_info(f"Ping sweeping {base}.0/24...")
                
                # Use fping if available (faster)
                if self.command_exists('fping'):
                    fping_cmd = f"fping -a -g {base}.0 {base}.255 -q 2>/dev/null"
                    output = self.linux_execute(fping_cmd)
                    if output:
                        for line in output.strip().split('\n'):
                            ip = self._extract_ipv4(line)
                            if ip:
                                results[ip] = {
                                    'ip': ip,
                                    'method': 'ping',
                                    'alive': True
                                }
                else:
                    # Use ping in loop (slower)
                    print_info("Using ping (this may take a while)...")
                    for i in range(1, 255):
                        ip = f"{base}.{i}"
                        ping_cmd = f"ping -c 1 -W {self.timeout} {ip} 2>/dev/null | grep '1 received'"
                        result = self.linux_execute(ping_cmd)
                        if result and result.strip():
                            results[ip] = {
                                'ip': ip,
                                'method': 'ping',
                                'alive': True
                            }
                            print_info(f"  Found: {ip}")
        
        except Exception as e:
            print_warning(f"Ping sweep error: {e}")
        
        return results
    
    def _tcp_scan(self):
        """Perform TCP port scan"""
        results = {}
        try:
            # Get alive hosts first
            alive_hosts = []
            
            # Quick ping to find alive hosts
            network_base = self.network_range.split('/')[0]
            base_parts = network_base.split('.')
            
            if len(base_parts) == 4:
                base = f"{base_parts[0]}.{base_parts[1]}.{base_parts[2]}"
                
                # Use nmap if available
                if self.command_exists('nmap'):
                    ports = self.ports.replace(' ', '')
                    nmap_cmd = f"nmap -sn {self.network_range} 2>/dev/null | grep -E '^Nmap scan report' | awk '{{print $5}}'"
                    hosts_output = self.linux_execute(nmap_cmd)
                    if hosts_output:
                        alive_hosts = []
                        for line in hosts_output.strip().split('\n'):
                            host_ip = self._extract_ipv4(line)
                            if host_ip:
                                alive_hosts.append(host_ip)
                else:
                    # Use fping or ping
                    if self.command_exists('fping'):
                        fping_output = self.linux_execute(f"fping -a -g {base}.0 {base}.255 -q 2>/dev/null")
                        if fping_output:
                            alive_hosts = []
                            for line in fping_output.strip().split('\n'):
                                host_ip = self._extract_ipv4(line)
                                if host_ip:
                                    alive_hosts.append(host_ip)

                # Deduplicate while keeping order
                alive_hosts = list(dict.fromkeys(alive_hosts))
                
                # Scan ports on alive hosts
                ports_list = [p.strip() for p in self.ports.split(',') if p.strip()]
                
                print_info(f"Scanning {len(ports_list)} port(s) on {len(alive_hosts)} host(s)...")
                
                for host in alive_hosts[:50]:  # Limit to 50 hosts
                    if host not in results:
                        results[host] = {
                            'ip': host,
                            'ports': {},
                            'method': 'tcp'
                        }
                    
                    for port in ports_list:
                        try:
                            port_num = int(port)
                            # Use nc or bash /dev/tcp
                            nc_cmd = f"timeout {self.timeout} bash -c '</dev/tcp/{host}/{port_num}' 2>/dev/null && echo 'open'"
                            result = self.linux_execute(nc_cmd)
                            if result and 'open' in result:
                                results[host]['ports'][port_num] = 'open'
                                print_info(f"  {host}:{port_num} - OPEN")
                        except:
                            pass
        
        except Exception as e:
            print_warning(f"TCP scan error: {e}")
        
        return results
    
    def _udp_scan(self):
        """Perform UDP scan"""
        results = {}
        try:
            print_warning("UDP scanning is slower and less reliable")
            print_info("Scanning common UDP ports...")
            
            # UDP scanning is complex and slow, so we'll do a basic check
            network_base = self.network_range.split('/')[0]
            base_parts = network_base.split('.')
            
            if len(base_parts) == 4:
                base = f"{base_parts[0]}.{base_parts[1]}.{base_parts[2]}"
                
                # Use nmap for UDP if available
                if self.command_exists('nmap'):
                    nmap_cmd = f"nmap -sU --top-ports 10 {self.network_range} 2>/dev/null"
                    output = self.linux_execute(nmap_cmd)
                    if output:
                        # Parse nmap output
                        current_host = None
                        for line in output.strip().split('\n'):
                            if 'Nmap scan report' in line:
                                match = re.search(r'(\d+\.\d+\.\d+\.\d+)', line)
                                if match:
                                    current_host = match.group(1)
                                    if current_host not in results:
                                        results[current_host] = {
                                            'ip': current_host,
                                            'ports': {},
                                            'method': 'udp'
                                        }
                            elif current_host and '/udp' in line and 'open' in line:
                                match = re.search(r'(\d+)/udp', line)
                                if match:
                                    port = match.group(1)
                                    results[current_host]['ports'][int(port)] = 'open'
        
        except Exception as e:
            print_warning(f"UDP scan error: {e}")
        
        return results
    
    def _display_results(self, results):
        """Display scan results"""
        print_status("="*60)
        print_status("Scan Results")
        print_status("="*60)
        
        if not results:
            print_warning("No hosts found")
            return
        
        # Group by IP
        hosts = {}
        for ip, data in results.items():
            if ip not in hosts:
                hosts[ip] = {
                    'ip': ip,
                    'methods': [],
                    'ports': {},
                    'mac': None
                }
            
            if 'method' in data:
                if data['method'] not in hosts[ip]['methods']:
                    hosts[ip]['methods'].append(data['method'])
            
            if 'mac' in data:
                hosts[ip]['mac'] = data['mac']
            
            if 'ports' in data:
                hosts[ip]['ports'].update(data['ports'])
        
        print_success(f"Found {len(hosts)} host(s)")
        print_info("")
        
        for ip, data in sorted(hosts.items()):
            print_info(f"Host: {ip}")
            if data['mac']:
                print_info(f"  MAC: {data['mac']}")
            if data['methods']:
                print_info(f"  Detected by: {', '.join(data['methods'])}")
            if data['ports']:
                open_ports = [str(p) for p, status in data['ports'].items() if status == 'open']
                if open_ports:
                    print_info(f"  Open ports: {', '.join(open_ports)}")
            print_info("")

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

02 Aug 2026 20:51Current
5.9Medium risk
Vulners AI Score5.9
1