mirror of
https://github.com/Gowtham-Darkseid/AutoPentestX.git
synced 2026-03-31 08:39:05 +02:00
222 lines
8.6 KiB
Python
222 lines
8.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
AutoPentestX - Network Scanner Module
|
|
Handles port scanning, OS detection, and service enumeration using Nmap
|
|
"""
|
|
|
|
import nmap
|
|
import subprocess
|
|
import json
|
|
import re
|
|
from datetime import datetime
|
|
|
|
class Scanner:
|
|
def __init__(self, target):
|
|
"""Initialize scanner with target"""
|
|
self.target = target
|
|
self.nm = nmap.PortScanner()
|
|
self.scan_results = {
|
|
'target': target,
|
|
'os_detection': 'Unknown',
|
|
'ports': [],
|
|
'services': [],
|
|
'scan_time': None
|
|
}
|
|
|
|
def validate_target(self):
|
|
"""Validate target IP or domain"""
|
|
try:
|
|
# Try to resolve the target
|
|
import socket
|
|
socket.gethostbyname(self.target)
|
|
return True
|
|
except socket.gaierror:
|
|
print(f"[✗] Invalid target: {self.target}")
|
|
return False
|
|
|
|
def detect_os(self):
|
|
"""Detect operating system using Nmap"""
|
|
print(f"[*] Detecting operating system for {self.target}...")
|
|
try:
|
|
# Run OS detection with Nmap (requires root/sudo)
|
|
self.nm.scan(self.target, arguments='-O -Pn')
|
|
|
|
if self.target in self.nm.all_hosts():
|
|
if 'osmatch' in self.nm[self.target]:
|
|
os_matches = self.nm[self.target]['osmatch']
|
|
if os_matches:
|
|
os_name = os_matches[0]['name']
|
|
accuracy = os_matches[0]['accuracy']
|
|
self.scan_results['os_detection'] = f"{os_name} (Accuracy: {accuracy}%)"
|
|
print(f"[✓] OS Detected: {os_name} ({accuracy}% accuracy)")
|
|
return self.scan_results['os_detection']
|
|
|
|
# Fallback: Try using TTL values
|
|
result = subprocess.run(['ping', '-c', '1', self.target],
|
|
capture_output=True, text=True, timeout=5)
|
|
|
|
if result.returncode == 0:
|
|
ttl_match = re.search(r'ttl=(\d+)', result.stdout.lower())
|
|
if ttl_match:
|
|
ttl = int(ttl_match.group(1))
|
|
if ttl <= 64:
|
|
self.scan_results['os_detection'] = "Linux/Unix (TTL <= 64)"
|
|
elif ttl <= 128:
|
|
self.scan_results['os_detection'] = "Windows (TTL <= 128)"
|
|
else:
|
|
self.scan_results['os_detection'] = "Unknown (TTL > 128)"
|
|
|
|
print(f"[✓] OS Detected (TTL-based): {self.scan_results['os_detection']}")
|
|
return self.scan_results['os_detection']
|
|
|
|
self.scan_results['os_detection'] = "Unknown"
|
|
print("[!] Could not detect OS reliably")
|
|
return "Unknown"
|
|
|
|
except Exception as e:
|
|
print(f"[!] OS Detection failed: {e}")
|
|
self.scan_results['os_detection'] = "Unknown"
|
|
return "Unknown"
|
|
|
|
def scan_all_ports(self):
|
|
"""Perform comprehensive port scan"""
|
|
print(f"[*] Scanning all TCP ports on {self.target}...")
|
|
try:
|
|
start_time = datetime.now()
|
|
|
|
# Scan top 1000 ports first (faster)
|
|
print("[*] Phase 1: Scanning top 1000 ports...")
|
|
self.nm.scan(self.target, arguments='-sS -sV -T4 -Pn --top-ports 1000')
|
|
|
|
if self.target in self.nm.all_hosts():
|
|
host = self.nm[self.target]
|
|
|
|
# Process TCP ports
|
|
if 'tcp' in host:
|
|
for port in host['tcp'].keys():
|
|
port_info = host['tcp'][port]
|
|
if port_info['state'] == 'open':
|
|
port_data = {
|
|
'port': port,
|
|
'protocol': 'tcp',
|
|
'state': port_info['state'],
|
|
'service': port_info.get('name', 'unknown'),
|
|
'version': port_info.get('product', '') + ' ' + port_info.get('version', ''),
|
|
'extrainfo': port_info.get('extrainfo', '')
|
|
}
|
|
self.scan_results['ports'].append(port_data)
|
|
print(f"[✓] Port {port}/tcp open - {port_data['service']} {port_data['version']}")
|
|
|
|
# Process UDP ports (limited scan for speed)
|
|
print("[*] Phase 2: Scanning common UDP ports...")
|
|
self.nm.scan(self.target, arguments='-sU -Pn --top-ports 20')
|
|
|
|
if 'udp' in self.nm[self.target]:
|
|
for port in self.nm[self.target]['udp'].keys():
|
|
port_info = self.nm[self.target]['udp'][port]
|
|
if port_info['state'] in ['open', 'open|filtered']:
|
|
port_data = {
|
|
'port': port,
|
|
'protocol': 'udp',
|
|
'state': port_info['state'],
|
|
'service': port_info.get('name', 'unknown'),
|
|
'version': port_info.get('product', '') + ' ' + port_info.get('version', ''),
|
|
'extrainfo': port_info.get('extrainfo', '')
|
|
}
|
|
self.scan_results['ports'].append(port_data)
|
|
print(f"[✓] Port {port}/udp {port_info['state']} - {port_data['service']}")
|
|
|
|
end_time = datetime.now()
|
|
scan_duration = (end_time - start_time).total_seconds()
|
|
self.scan_results['scan_time'] = scan_duration
|
|
|
|
print(f"[✓] Port scan completed in {scan_duration:.2f} seconds")
|
|
print(f"[✓] Total open ports found: {len(self.scan_results['ports'])}")
|
|
|
|
return self.scan_results['ports']
|
|
|
|
except Exception as e:
|
|
print(f"[✗] Port scanning failed: {e}")
|
|
return []
|
|
|
|
def enumerate_services(self):
|
|
"""Extract detailed service information"""
|
|
print(f"[*] Enumerating services on {self.target}...")
|
|
|
|
services = []
|
|
for port_data in self.scan_results['ports']:
|
|
service_info = {
|
|
'port': port_data['port'],
|
|
'protocol': port_data['protocol'],
|
|
'service': port_data['service'],
|
|
'version': port_data['version'].strip(),
|
|
'banner': port_data.get('extrainfo', ''),
|
|
'vulnerabilities': []
|
|
}
|
|
services.append(service_info)
|
|
|
|
self.scan_results['services'] = services
|
|
print(f"[✓] Enumerated {len(services)} services")
|
|
return services
|
|
|
|
def run_full_scan(self):
|
|
"""Execute complete scan workflow"""
|
|
print("\n" + "="*60)
|
|
print("AutoPentestX - Network Scanner")
|
|
print("="*60)
|
|
print(f"Target: {self.target}")
|
|
print(f"Scan started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
print("="*60 + "\n")
|
|
|
|
# Validate target
|
|
if not self.validate_target():
|
|
return None
|
|
|
|
# Step 1: OS Detection
|
|
self.detect_os()
|
|
|
|
# Step 2: Port Scanning
|
|
self.scan_all_ports()
|
|
|
|
# Step 3: Service Enumeration
|
|
self.enumerate_services()
|
|
|
|
print("\n" + "="*60)
|
|
print("SCAN SUMMARY")
|
|
print("="*60)
|
|
print(f"Target: {self.target}")
|
|
print(f"OS: {self.scan_results['os_detection']}")
|
|
print(f"Open Ports: {len(self.scan_results['ports'])}")
|
|
print(f"Services Detected: {len(self.scan_results['services'])}")
|
|
print("="*60 + "\n")
|
|
|
|
return self.scan_results
|
|
|
|
def get_results(self):
|
|
"""Return scan results"""
|
|
return self.scan_results
|
|
|
|
def save_results(self, filename):
|
|
"""Save scan results to JSON file"""
|
|
try:
|
|
with open(filename, 'w') as f:
|
|
json.dump(self.scan_results, f, indent=4)
|
|
print(f"[✓] Scan results saved to {filename}")
|
|
except Exception as e:
|
|
print(f"[✗] Failed to save results: {e}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
|
|
if len(sys.argv) < 2:
|
|
print("Usage: python scanner.py <target>")
|
|
sys.exit(1)
|
|
|
|
target = sys.argv[1]
|
|
scanner = Scanner(target)
|
|
results = scanner.run_full_scan()
|
|
|
|
if results:
|
|
scanner.save_results(f"scan_{target.replace('.', '_')}.json")
|