""" Script to trigger anomaly detection on all existing events """ import sys import os import numpy as np sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from database import SessionLocal import models from ml.feature_engineering import calculate_behavioral_fingerprint from ml.anomaly_detector import AnomalyDetector from ml.explainability import ExplainabilityEngine from ml.mitre_mapper import MitreMapper from ml.mitigation_engine import MitigationEngine from datetime import datetime, timedelta, timezone def detect_anomalies(): """Run anomaly detection on all employees""" db = SessionLocal() try: print("šŸ” Starting anomaly detection...") # Initialize ML components detector = AnomalyDetector() explainer = ExplainabilityEngine(detector) mitre_mapper = MitreMapper() mitigation_engine = MitigationEngine() # Load the trained model try: detector.load_model() print("āœ“ Model loaded successfully") except Exception as e: print(f"āŒ Error loading model: {e}") print("Please train the model first: POST http://localhost:8000/api/ml/train") return # Get all employees employees = db.query(models.Employee).all() print(f"āœ“ Found {len(employees)} employees") total_anomalies = 0 for employee in employees: print(f"\nProcessing {employee.name} (ID: {employee.id})...") # Get recent events (last 24 hours) cutoff = datetime.now(timezone.utc) - timedelta(hours=24) recent_events = db.query(models.BehavioralEvent).filter( models.BehavioralEvent.employee_id == employee.id, models.BehavioralEvent.timestamp >= cutoff ).all() if not recent_events: print(f" No recent events for {employee.name}") continue print(f" Found {len(recent_events)} recent events") # Calculate behavioral features features = calculate_behavioral_fingerprint(db, employee.id, days_back=30) if not features: print(f" Insufficient data for {employee.name}") continue # Convert features dict to array from ml.feature_engineering import get_feature_names feature_names = get_feature_names() feature_array = np.array([[features.get(name, 0.0) for name in feature_names]]) # Predict anomaly result = detector.predict_single(feature_array) if result['is_anomaly']: print(f" 🚨 ANOMALY DETECTED! Risk: {result['risk_level']} ({result['risk_score']})") # Get SHAP explanation explanation = explainer.explain(feature_array) # Determine anomaly type based on top features top_feature = explanation['top_features'][0]['feature'] if explanation['top_features'] else 'unknown' anomaly_type_map = { 'avg_login_hour': 'unusual_login', 'login_hour_std': 'unusual_login', 'avg_location_distance': 'unusual_location', 'unique_ports_count': 'unusual_port', 'sensitive_file_access_rate': 'sensitive_files', 'privilege_escalation_rate': 'privilege_escalation', 'firewall_change_rate': 'firewall_change', 'failed_login_rate': 'failed_logins' } anomaly_type = anomaly_type_map.get(top_feature, 'behavioral_anomaly') # Create anomaly description description = f"Anomalous behavior detected for {employee.name}. " if explanation['top_features']: top_contrib = explanation['top_features'][0] description += top_contrib['description'] # Save anomaly to database anomaly = models.Anomaly( employee_id=employee.id, anomaly_score=result['anomaly_score'], risk_level=result['risk_level'], risk_score=result['risk_score'], description=description, anomaly_type=anomaly_type, shap_values=explanation['shap_values'], top_features=explanation['top_features'], status='open' ) db.add(anomaly) db.flush() # Generate MITRE mappings mappings = mitre_mapper.map_anomaly(anomaly_type, explanation['top_features'], result['risk_score']) for mapping in mappings: mitre_record = models.MitreMapping( anomaly_id=anomaly.id, technique_id=mapping['technique_id'], technique_name=mapping['technique_name'], tactic=mapping['tactic'], description=mapping['description'], confidence=mapping['confidence'] ) db.add(mitre_record) # Generate mitigation strategies strategies = mitigation_engine.generate_strategies( anomaly_type=anomaly_type, risk_level=result['risk_level'], mitre_techniques=mappings ) for strategy in strategies: mitigation = models.MitigationStrategy( anomaly_id=anomaly.id, priority=strategy['priority'], category=strategy['category'], action=strategy['action'], description=strategy['description'] ) db.add(mitigation) db.commit() total_anomalies += 1 print(f" āœ“ Anomaly saved with {len(mappings)} MITRE mappings and {len(strategies)} mitigations") else: print(f" āœ“ Normal behavior") print(f"\nāœ… Anomaly detection complete!") print(f" Total anomalies detected: {total_anomalies}") except Exception as e: print(f"āŒ Error: {e}") import traceback traceback.print_exc() db.rollback() finally: db.close() if __name__ == "__main__": detect_anomalies()