This commit is contained in:
pika 2025-03-30 19:57:41 +02:00
parent 6dd38036e7
commit 097b3dbf09
34 changed files with 1719 additions and 520 deletions

View file

@ -1,23 +1,49 @@
from app.core.extensions import db
from app.core.models import Subnet, Server, App
from app.core.auth import User
from app.core.models import Subnet, Server, App, Port
from app.core.auth import User # Import User from auth module
import json
def seed_database():
# Example seed data for network objects
subnet = Subnet(cidr='192.168.1.0/24', location='Office', auto_scan=True)
server = Server(hostname='server1', ip_address='192.168.1.10', subnet=subnet)
app = App(name='Web App', server=server, documentation='# Welcome to Web App',
_ports='[{"port": 80, "type": "tcp", "desc": "Web"}]')
"""Add sample data to the database"""
# Create a default subnet if none exists
if Subnet.query.count() == 0:
subnet = Subnet(
cidr='192.168.1.0/24',
location='Office',
auto_scan=True,
active_hosts=json.dumps([])
)
db.session.add(subnet)
# Create a sample server
server = Server(
hostname='server1',
ip_address='192.168.1.10',
subnet=subnet,
documentation='# Server 1\n\nThis is a sample server.'
)
db.session.add(server)
# Create a sample app
app = App(
name='Web App',
server=server,
documentation='# Welcome to Web App\n\nThis is a sample application.'
)
db.session.add(app)
# Add some ports
ports = [
Port(app=app, port_number=80, protocol='TCP', description='HTTP'),
Port(app=app, port_number=443, protocol='TCP', description='HTTPS')
]
db.session.add_all(ports)
# Create a default user if none exists
if User.query.count() == 0:
admin = User(email="admin@example.com", is_admin=True)
admin.set_password("admin")
admin = User(username='admin', email='admin@example.com', is_admin=True)
admin.set_password('admin')
db.session.add(admin)
db.session.add(subnet)
db.session.add(server)
db.session.add(app)
try:
db.session.commit()

View file

@ -7,63 +7,41 @@ from app.core.extensions import db
from app.core.models import Subnet, Server
import json
import subprocess
import concurrent.futures
from datetime import datetime
import platform
def scan(cidr, max_threads=10, save_results=False):
def scan(subnet, manual_trigger=False):
"""
Scan a subnet for active hosts
Args:
cidr: The subnet in CIDR notation (e.g. "192.168.1.0/24")
max_threads: Maximum number of threads to use
save_results: Whether to save results to the database
Returns:
A list of dictionaries with IP, hostname, and status
subnet: The subnet object to scan
manual_trigger: If False, only scan if the subnet hasn't been scanned recently
"""
print(f"Starting scan of {cidr}")
network = ipaddress.ip_network(cidr)
# Skip if not auto scan and not manually triggered
if not subnet.auto_scan and not manual_trigger:
return False
# Skip network and broadcast addresses for IPv4
if network.version == 4:
hosts = list(network.hosts())
else:
# For IPv6, just take the first 100 addresses to avoid scanning too many
hosts = list(network.hosts())[:100]
active_hosts = []
# Split the hosts into chunks for multithreading
chunks = [[] for _ in range(max_threads)]
for i, host in enumerate(hosts):
chunks[i % max_threads].append(host)
# Initialize results
results = [[] for _ in range(max_threads)]
# Create and start threads
threads = []
for i in range(max_threads):
if chunks[i]: # Only start a thread if there are IPs to scan
t = threading.Thread(target=scan_worker, args=(chunks[i], results, i))
threads.append(t)
t.start()
# Wait for all threads to complete
for t in threads:
t.join()
# Combine results
all_results = []
for r in results:
all_results.extend(r)
# Save results to database if requested
if save_results:
try:
save_scan_results(cidr, all_results)
except Exception as e:
print(f"Error saving scan results: {e}")
print(f"Scan completed. Found {len(all_results)} active hosts.")
return all_results
try:
# Parse the CIDR notation
network = ipaddress.ip_network(subnet.cidr, strict=False)
# For each address in this network, ping it
for ip in network.hosts():
if ping(str(ip)):
active_hosts.append(str(ip))
# Update subnet with scan results
subnet.active_hosts = json.dumps(active_hosts)
subnet.last_scanned = datetime.utcnow()
return True
except Exception as e:
print(f"Error scanning subnet {subnet.cidr}: {str(e)}")
return False
def scan_worker(ip_list, results, index):
"""Worker function for threading"""
@ -76,13 +54,23 @@ def scan_worker(ip_list, results, index):
'status': 'up'
})
def ping(ip):
"""Ping an IP address and return True if it responds"""
def ping(host):
"""
Returns True if host responds to a ping request
"""
# Ping parameters based on OS
param = '-n' if platform.system().lower() == 'windows' else '-c'
# Build the command
command = ['ping', param, '1', '-w', '1', host]
try:
# Faster timeout (1 second)
subprocess.check_output(['ping', '-c', '1', '-W', '1', str(ip)], stderr=subprocess.STDOUT)
return True
except subprocess.CalledProcessError:
# Run the command and capture output
output = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=2)
# Return True if ping was successful
return output.returncode == 0
except subprocess.TimeoutExpired:
return False
except Exception:
return False
def get_hostname(ip):
@ -166,7 +154,7 @@ def schedule_subnet_scans():
# Start a thread for each subnet
thread = threading.Thread(
target=scan,
args=(subnet.cidr,),
args=(subnet,),
daemon=True
)
thread.start()