Files
dashboard/RAPPORT_FINAL.md

7.3 KiB
Raw Blame History

Rapport Final — SOC Bot Detector Dashboard

Date : 2026-03-16
Commits : 8032eba (corrections bugs), d4c3512 (améliorations)


1. Corrections de bugs (commit 8032eba)

Bug Cause Correction
Brute Force > Attaquants : IPs affichées en ::ffff:x.x.x.x Pas de normalisation IPv6 dans la requête SQL replaceRegexpAll(toString(src_ip), '^::ffff:', '') ajouté
Brute Force > Cibles : lien "Voir détails" → page inexistante Navigation vers /investigation/{host} (hostname) au lieu d'une IP Remplacement par composant TargetRow avec expansion inline des attaquants par host
Header Fingerprint : tableau de détail toujours vide Frontend lisait data.ips au lieu de data.items Correction de la clé
Heatmap Temporelle : "Top hosts ciblés" vide Frontend lisait data.hosts + erreur de type TypeScript { hosts: TopHost[] } Correction clé data.items + type annotation
Botnets Distribués : clic sur ligne n'affiche rien Frontend lisait data.countries au lieu de data.items Correction de la clé
Rotation & Persistance : IPs en ::ffff: + historique toujours vide Pas de normalisation + frontend lisait data.history au lieu de data.ja4_history Normalisation SQL + correction de la clé
TCP Spoofing : spoofings détectés sans corrélation TTL Filtre Python-side sur données déjà filtrées TTL=3031 Filtre SQL spoof_only déplacé côté ClickHouse

2. Améliorations implémentées (commit d4c3512)

J — Synthèse IP multi-sources

  • Endpoint : GET /api/investigation/{ip}/summary
  • Widget : IPActivitySummary en haut de toute page d'investigation IP
  • Données : ML + bruteforce + TCP spoofing + JA4 rotation + persistance + timeline 24h
  • Score de risque : 0100 (jauge SVG colorée)
  • Résultat : Contexte immédiat en un coup d'œil, sans naviguer entre 6 pages

I — Comparaison baseline 24h/hier

  • Endpoint : GET /api/metrics/baseline
  • Widget : 3 cartes (Détections 24h, IPs uniques, CRITICAL) avec variation ▲▼ en %
  • Impact : Détecte immédiatement les pics anormaux (ex: +246% détections observé)

M-4 — Score de sophistication adversaire

  • Endpoint : GET /api/rotation/sophistication
  • Calcul : JOIN 3 tables (rotation JA4 × 10 + récurrence × 20 + log(bruteforce+1) × 5)
  • Tiers : APT-like / Advanced / Automated / Basic
  • Résultat : Prioritisation des enquêtes les plus urgentes

M-7 — Chasse proactive (low-and-slow)

  • Endpoint : GET /api/rotation/proactive-hunt
  • Logique : IPs récurrentes avec abs(anomaly_score) < 0.5 — volent sous le radar ML
  • Évaluation : "Évadeur potentiel" (ratio récurrence/score > 10) ou "Persistant modéré"
  • Impact : Détecte les botnets slow-and-low que le modèle ML sous-score

M-2 — Badge réputation ASN inline

  • Modification : LEFT JOIN asn_reputation dans la requête des détections
  • Badge : Rouge (malicious/bot/scanner), orange (proxy/vpn), vert (human)
  • Limitation : La table asn_reputation contient 36 ASN français (ISPs légitimes) — les ASNs malveillants connus ne sont pas encore catalogués

3. Tests exhaustifs Playwright

Page Résultat Notes
Dashboard principal Baseline ▲ +246.5% détections, ▲ +11.6% IPs, = CRITICAL
Détections Badge ASN affiché (null pour ASNs hors table reputation)
Investigation IP (162.55.94.175) Score 38, TCP Spoof TTL 59, JA4 Rotation 9 sig
Rotation > Sophistication APT-like: 162.55.94.175 (score 100), 46.4.81.149 (score 100)
Rotation > Chasse proactive IPs avec scores négatifs sous le radar ML
Brute Force > Attaquants IPs propres (sans ::ffff:)
Brute Force > Cibles Expansion inline des attaquants par host
Header Fingerprint Tableau détail rempli au clic
Heatmap Temporelle Top hosts ciblés affiché
Botnets Distribués Détail pays au clic
TCP Spoofing Filtre spoof_only fonctionnel

4. Points problématiques et axes d'amélioration

🔴 Critiques

  1. Table asn_reputation incomplète — 36 entrées uniquement (ISPs français). Pour être utile, elle devrait contenir les ASNs des datacenters, VPS, proxies connus (OVH, DigitalOcean, AWS, Linode, etc.). Source suggérée : AbuseIPDB ASN database, IPInfo, Maxmind.

  2. Chasse proactive — scores négatifsview_ip_recurrence.worst_score stocke le score brut (peut être négatif). La condition abs(score) < 0.5 capture des IPs HIGH avec score -0.18 qui sont déjà détectées par ML. Il faudrait filtrer par niveau de menace (worst_threat_level NOT IN ('HIGH', 'CRITICAL')) pour vraiment identifier les cas sous le radar.

  3. Pas de persistance des classifications SOC — Les classifications manuelles (/api/analysis/classify) ne persistent que pendant la session si la table classifications n'est pas créée. Un script d'init DB serait utile.

🟡 Moyens

  1. Score de sophistication biaised — Les IPs avec forte rotation JA4 mais recurrence=0 dans view_ip_recurrence (non présentes) atteignent quand même score 100. Les données des deux vues ne sont pas toujours cohérentes sur la même période temporelle.

  2. Timeline 24h dans la synthèse IP — Utilise window_start >= now() - INTERVAL 24 HOUR sur agg_host_ip_ja4_1h. Si les données ont moins de 24h d'historique, le graphique sera partiel/vide. Adapter la fenêtre dynamiquement selon les données disponibles.

  3. Heatmap Temporelle — Les données de agg_host_ip_ja4_1h ne sont agrégées que pour les dernières 24h dans l'endpoint. Un sélecteur de plage temporelle (7j, 30j) permettrait de détecter les patterns de vagues cycliques (botnets hebdomadaires).

  4. Pas d'export des résultats — Les analystes SOC ne peuvent pas exporter les listes d'IPs malveillantes (CSV, STIX). Un endpoint GET /api/rotation/sophistication?format=csv serait utile pour l'IOC sharing.

🟢 Mineurs

  1. "Investiguer" dans le RotationView ne transmet pas le contexte — Un clic sur "Investiguer" depuis l'onglet Sophistication navigue vers /investigation/{ip} sans pré-charger le contexte de l'onglet source. Un ?source=sophistication&score=100 dans l'URL permettrait d'afficher un bandeau contextuel.

  2. Onglets non présents dans la sidebar — Les 7 dashboards d'analyse avancée ne sont pas organisés en sous-menus. Avec l'ajout des onglets Sophistication et Chasse proactive dans Rotation, la sidebar commence à être longue.

  3. Badge ASN ne trie pas les détections — Il n'y a pas encore de filtre "Afficher seulement les ASNs malveillants" dans les détections.


5. Architecture — points de vigilance

  • Le SPA catch-all (/{full_path:path}) doit rester le dernier router dans main.py
  • L'endpoint /api/investigation/{ip}/summary utilise le préfixe /api/investigation — compatible avec la route SPA /investigation/:ip (distinct)
  • Les scores négatifs dans anomaly_score et worst_score sont normaux — toujours utiliser abs() pour l'affichage
  • Les IPv6-mapped (::ffff:x.x.x.x) sont présentes dans toutes les vues agrégées — systématiquement utiliser replaceRegexpAll(toString(src_ip), '^::ffff:', '')