Visualize observed access paths
All checks were successful
OfficeCom Sentinel Client / validate-client (push) Successful in 23s
OfficeCom Sentinel Client / build-client-windows (push) Successful in 48s

This commit is contained in:
OfficeCom Codex
2026-07-30 01:16:20 +02:00
parent 42b387f3ef
commit c65001aa17
4 changed files with 60 additions and 1 deletions

View File

@@ -245,6 +245,57 @@ def organization(organization_id):
)
@app.get("/network")
def network():
with db_connection() as connection, connection.cursor() as cursor:
cursor.execute(
"""
SELECT machine_name, received_at, payload
FROM ocsentinel.current_device_status
WHERE received_at >= now() - interval '14 days'
"""
)
reports = cursor.fetchall()
flows = {}
for machine_name, received_at, payload in reports:
for event in (payload or {}).get("Events", []):
source_ip = event.get("SourceIp") or ""
if not source_ip or source_ip in {"-", "127.0.0.1", "::1"}:
continue
account = event.get("Username") or "[unbekannt]"
target = event.get("Target") or "Anmeldung"
key = (source_ip, machine_name, account, target)
entry = flows.setdefault(
key,
{
"source_ip": source_ip,
"machine_name": machine_name,
"account": account,
"target": target,
"count": 0,
"last_seen": received_at,
},
)
entry["count"] += 1
timestamp = event.get("Timestamp")
if timestamp and (entry["last_seen"] is None or str(timestamp) > str(entry["last_seen"])):
entry["last_seen"] = timestamp
flow_rows = sorted(flows.values(), key=lambda entry: (entry["count"], str(entry["last_seen"])), reverse=True)[:60]
max_count = max([entry["count"] for entry in flow_rows] or [1])
source_count = len({entry["source_ip"] for entry in flow_rows})
target_count = len({entry["machine_name"] for entry in flow_rows})
return render_template(
"network.html",
flows=flow_rows,
max_count=max_count,
source_count=source_count,
target_count=target_count,
total_events=sum(entry["count"] for entry in flow_rows),
)
@app.get("/device/<machine_name>")
def device(machine_name):
with db_connection() as connection, connection.cursor() as cursor: