mirror of
https://github.com/smittix/intercept.git
synced 2026-07-08 01:28:13 -07:00
Integrate device identity engine into TSCM sweep
- Import device identity functions (get_identity_engine, ingest_ble_dict, etc.) - Initialize and clear identity engine at sweep start - Feed BLE observations to identity engine during Bluetooth scan - Feed WiFi observations to identity engine during WiFi scan - Finalize sessions and emit identity_clusters event at sweep completion - Include identity cluster statistics in sweep results The device identity engine provides MAC-randomization resistant detection by clustering observations using fingerprinting, timing patterns, and RSSI trajectory analysis.
This commit is contained in:
@@ -43,6 +43,12 @@ from utils.tscm.correlation import (
|
|||||||
reset_correlation_engine,
|
reset_correlation_engine,
|
||||||
)
|
)
|
||||||
from utils.tscm.detector import ThreatDetector
|
from utils.tscm.detector import ThreatDetector
|
||||||
|
from utils.tscm.device_identity import (
|
||||||
|
get_identity_engine,
|
||||||
|
reset_identity_engine,
|
||||||
|
ingest_ble_dict,
|
||||||
|
ingest_wifi_dict,
|
||||||
|
)
|
||||||
|
|
||||||
logger = logging.getLogger('intercept.tscm')
|
logger = logging.getLogger('intercept.tscm')
|
||||||
|
|
||||||
@@ -1226,6 +1232,10 @@ def _run_sweep(
|
|||||||
# Clear old profiles from previous sweeps (keep 24h history)
|
# Clear old profiles from previous sweeps (keep 24h history)
|
||||||
correlation.clear_old_profiles(24)
|
correlation.clear_old_profiles(24)
|
||||||
|
|
||||||
|
# Initialize device identity engine for MAC-randomization resistant detection
|
||||||
|
identity_engine = get_identity_engine()
|
||||||
|
identity_engine.clear() # Start fresh for this sweep
|
||||||
|
|
||||||
# Collect and analyze data
|
# Collect and analyze data
|
||||||
threats_found = 0
|
threats_found = 0
|
||||||
severity_counts = {'critical': 0, 'high': 0, 'medium': 0, 'low': 0}
|
severity_counts = {'critical': 0, 'high': 0, 'medium': 0, 'low': 0}
|
||||||
@@ -1266,6 +1276,24 @@ def _run_sweep(
|
|||||||
# Classify device and get correlation profile
|
# Classify device and get correlation profile
|
||||||
classification = detector.classify_wifi_device(network)
|
classification = detector.classify_wifi_device(network)
|
||||||
profile = correlation.analyze_wifi_device(network)
|
profile = correlation.analyze_wifi_device(network)
|
||||||
|
|
||||||
|
# Feed to identity engine for MAC-randomization resistant clustering
|
||||||
|
# Note: WiFi APs don't typically use randomized MACs, but clients do
|
||||||
|
try:
|
||||||
|
wifi_obs = {
|
||||||
|
'timestamp': datetime.now().isoformat(),
|
||||||
|
'src_mac': bssid,
|
||||||
|
'bssid': bssid,
|
||||||
|
'ssid': network.get('essid'),
|
||||||
|
'rssi': network.get('power'),
|
||||||
|
'channel': network.get('channel'),
|
||||||
|
'encryption': network.get('privacy'),
|
||||||
|
'frame_type': 'beacon',
|
||||||
|
}
|
||||||
|
ingest_wifi_dict(wifi_obs)
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"Identity engine WiFi ingest error: {e}")
|
||||||
|
|
||||||
# Send device to frontend
|
# Send device to frontend
|
||||||
_emit_event('wifi_device', {
|
_emit_event('wifi_device', {
|
||||||
'bssid': bssid,
|
'bssid': bssid,
|
||||||
@@ -1306,6 +1334,22 @@ def _run_sweep(
|
|||||||
# Classify device and get correlation profile
|
# Classify device and get correlation profile
|
||||||
classification = detector.classify_bt_device(device)
|
classification = detector.classify_bt_device(device)
|
||||||
profile = correlation.analyze_bluetooth_device(device)
|
profile = correlation.analyze_bluetooth_device(device)
|
||||||
|
|
||||||
|
# Feed to identity engine for MAC-randomization resistant clustering
|
||||||
|
try:
|
||||||
|
ble_obs = {
|
||||||
|
'timestamp': datetime.now().isoformat(),
|
||||||
|
'addr': mac,
|
||||||
|
'rssi': device.get('rssi'),
|
||||||
|
'manufacturer_id': device.get('manufacturer_id') or device.get('company_id'),
|
||||||
|
'manufacturer_data': device.get('manufacturer_data'),
|
||||||
|
'service_uuids': device.get('services', []),
|
||||||
|
'local_name': device.get('name'),
|
||||||
|
}
|
||||||
|
ingest_ble_dict(ble_obs)
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"Identity engine BLE ingest error: {e}")
|
||||||
|
|
||||||
# Send device to frontend
|
# Send device to frontend
|
||||||
_emit_event('bt_device', {
|
_emit_event('bt_device', {
|
||||||
'mac': mac,
|
'mac': mac,
|
||||||
@@ -1403,6 +1447,11 @@ def _run_sweep(
|
|||||||
correlations = correlation.correlate_devices()
|
correlations = correlation.correlate_devices()
|
||||||
findings = correlation.get_all_findings()
|
findings = correlation.get_all_findings()
|
||||||
|
|
||||||
|
# Finalize identity engine and get MAC-randomization resistant clusters
|
||||||
|
identity_engine.finalize_all_sessions()
|
||||||
|
identity_summary = identity_engine.get_summary()
|
||||||
|
identity_clusters = [c.to_dict() for c in identity_engine.get_clusters()]
|
||||||
|
|
||||||
update_tscm_sweep(
|
update_tscm_sweep(
|
||||||
_current_sweep_id,
|
_current_sweep_id,
|
||||||
status='completed',
|
status='completed',
|
||||||
@@ -1412,6 +1461,7 @@ def _run_sweep(
|
|||||||
'rf_signals': len(all_rf),
|
'rf_signals': len(all_rf),
|
||||||
'severity_counts': severity_counts,
|
'severity_counts': severity_counts,
|
||||||
'correlation_summary': findings.get('summary', {}),
|
'correlation_summary': findings.get('summary', {}),
|
||||||
|
'identity_summary': identity_summary.get('statistics', {}),
|
||||||
},
|
},
|
||||||
threats_found=threats_found,
|
threats_found=threats_found,
|
||||||
completed=True
|
completed=True
|
||||||
@@ -1424,6 +1474,15 @@ def _run_sweep(
|
|||||||
'needs_review_count': findings['summary'].get('needs_review', 0),
|
'needs_review_count': findings['summary'].get('needs_review', 0),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# Emit device identity cluster findings (MAC-randomization resistant)
|
||||||
|
_emit_event('identity_clusters', {
|
||||||
|
'total_clusters': identity_summary['statistics'].get('total_clusters', 0),
|
||||||
|
'high_risk_count': identity_summary['statistics'].get('high_risk_count', 0),
|
||||||
|
'medium_risk_count': identity_summary['statistics'].get('medium_risk_count', 0),
|
||||||
|
'unique_fingerprints': identity_summary['statistics'].get('unique_fingerprints', 0),
|
||||||
|
'clusters': identity_clusters,
|
||||||
|
})
|
||||||
|
|
||||||
_emit_event('sweep_completed', {
|
_emit_event('sweep_completed', {
|
||||||
'sweep_id': _current_sweep_id,
|
'sweep_id': _current_sweep_id,
|
||||||
'threats_found': threats_found,
|
'threats_found': threats_found,
|
||||||
@@ -1434,6 +1493,7 @@ def _run_sweep(
|
|||||||
'high_interest_devices': findings['summary'].get('high_interest', 0),
|
'high_interest_devices': findings['summary'].get('high_interest', 0),
|
||||||
'needs_review_devices': findings['summary'].get('needs_review', 0),
|
'needs_review_devices': findings['summary'].get('needs_review', 0),
|
||||||
'correlations_found': len(correlations),
|
'correlations_found': len(correlations),
|
||||||
|
'identity_clusters': identity_summary['statistics'].get('total_clusters', 0),
|
||||||
})
|
})
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user