Files
logcorrelator/idees/views.md
toto 20ebe7240e
Some checks failed
Build and Test / test (push) Has been cancelled
Build and Test / build (push) Has been cancelled
Build and Test / docker (push) Has been cancelled
Feat: Détection menaces HTTP via vues ClickHouse + simplification shutdown
Nouvelles vues de détection (sql/views.sql) :
- Identification hosts par IP/JA4 (view_host_identification, view_host_ja4_anomalies)
- Détection brute force POST et query params variables
- Header fingerprinting (ordre, headers modernes manquants, Sec-CH-UA)
- ALPN mismatch detection (h2 déclaré mais HTTP/1.1 parlé)
- Rate limiting & burst detection (50 req/min, 20 req/10s)
- Path enumeration/scanning (paths sensibles)
- Payload attacks (SQLi, XSS, path traversal)
- JA4 botnet detection (même fingerprint sur 20+ IPs)
- Correlation quality (orphan ratio >80%)

ClickHouse (sql/init.sql) :
- Compression ZSTD(3) sur champs texte (path, query, headers, ja3/ja4)
- TTL automatique : 1 jour (raw) + 7 jours (http_logs)
- Paramètre ttl_only_drop_parts = 1

Shutdown simplifié (internal/app/orchestrator.go) :
- Suppression ShutdownTimeout et logique de flush/attente
- Stop() = cancel() + Close() uniquement
- systemd TimeoutStopSec gère l'arrêt forcé si besoin

File output toggle (internal/config/*.go) :
- Ajout champ Enabled dans FileOutputConfig
- Le sink fichier n'est créé que si enabled && path != ''
- Tests : TestValidate_FileOutputDisabled, TestLoadConfig_FileOutputDisabled

RPM packaging (packaging/rpm/logcorrelator.spec) :
- Changelog 1.1.18 → 1.1.22
- Suppression logcorrelator-tmpfiles.conf (redondant RuntimeDirectory=)

Nettoyage :
- idees.txt → idees/ (dossier)
- Suppression 91.224.92.185.txt (logs exemple)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-11 18:28:07 +01:00

18 KiB

🛡️ Manuel de Référence Technique : Moteur de Détection Antispam & Bot

Ce document détaille les algorithmes de détection implémentés dans les vues ClickHouse pour la plateforme.


1. Analyse de la Couche Transport (L4) : La "Trace Physique"

Avant même d'analyser l'URL, le moteur inspecte la manière dont la connexion a été établie. C'est la couche la plus difficile à falsifier pour un attaquant.

A. Fingerprint de la Pile TCP (tcp_fingerprint)

  • Fonctionnement : Nous utilisons cityHash64 pour créer un identifiant unique basé sur trois paramètres immuables du handshake : le MSS (Maximum Segment Size), la Window Size et le Window Scale.
  • Ce que ça détecte : L'unicité logicielle. Un bot tournant sur une image Alpine Linux aura une signature TCP différente d'un utilisateur sur iOS 17 ou Windows 11.
  • Détection de botnet : Si 500 IPs différentes partagent exactement le même tcp_fingerprint ET le même ja4, il y a une probabilité de 99% qu'il s'agisse d'un cluster de bots clonés.

B. Analyse de la gigue (Jitter) et Handshake

  • Fonctionnement : On calcule la variance (varPop) du délai entre le SYN et le ClientHello TLS.
  • Ce que ça détecte : La stabilité robotique.
    • Humain : Latence variable (4G, Wi-Fi, mouvements). La variance est élevée.
    • Bot Datacenter : Latence ultra-stable (fibre optique dédiée). Une variance proche de 0 indique une connexion automatisée depuis une infrastructure cloud.

2. Analyse de la Session (L5) : Le "Passeport TLS"

Le handshake TLS est une mine d'or pour identifier la bibliothèque logicielle (OpenSSL, Go-TLS, etc.).

A. Incohérence UA vs JA4

  • Fonctionnement : Le moteur croise le header_user_agent (déclaratif) avec le ja4 (structurel).
  • Ce que ça détecte : Le Spoofing de Browser. Un script Python peut facilement écrire User-Agent: Mozilla/5.0...Chrome/120, mais il ne peut pas simuler l'ordre exact des extensions TLS et des algorithmes de chiffrement d'un vrai Chrome sans une ingénierie complexe (comme utls).
  • Logique de score : Si UA = Chrome mais JA4 != Signature_Chrome -> +50 points de risque.

B. Discordance Host vs SNI

  • Fonctionnement : Comparaison entre le champ tls_sni (négocié en clair lors du handshake) et le header Host (envoyé plus tard dans la requête chiffrée).
  • Ce que ça détecte : Le Domain Fronting ou les attaques par tunnel. Un bot peut demander un certificat pour domaine-innocent.com (SNI) mais tenter d'attaquer api-critique.com (Host).

3. Analyse Applicative (L7) : Le "Comportement HTTP"

Une fois le tunnel établi, on analyse la structure de la requête HTTP.

A. Empreinte d'ordre des Headers (http_fp)

  • Fonctionnement : Nous hashons la liste ordonnée des clés de headers (Accept, User-Agent, Connection, etc.).
  • Ce que ça détecte : La signature du moteur de rendu. Chaque navigateur (Firefox, Safari, Chromium) a un ordre immuable pour envoyer ses headers.
  • Détection : Si un client envoie les headers dans un ordre inhabituel ou minimaliste (pauvreté des headers < 6), il est marqué comme suspect.

B. Analyse des Payloads et Entropie

  • Fonctionnement : Recherche de patterns via regex dans query et path (détection SQLi, XSS, Path Traversal).
  • Complexité : Nous détectons les encodages multiples (ex: %2520) qui tentent de tromper les pare-feux simples.

4. Corrélation Temporelle & Baseline : Le "Voisinage Statistique"

Le score final dépend du passé de la signature TLS.

A. Le Malus de Nouveauté (agg_novelty)

  • Logique : Une signature (JA4 + FP) vue pour la première fois aujourd'hui est "froide".
  • Traitement : On applique un malus si first_seen date de moins de 2 heures. Un botnet qui vient de lancer une campagne de rotation de signatures sera immédiatement pénalisé par son manque d'historique.

B. Le Dépassement de Baseline (tbl_baseline_ja4_7d)

  • Fonctionnement : On compare les hits actuels au 99ème percentile (p99) historique de cette signature précise.
  • Exemple : Si le JA4 de "Chrome 122" fait habituellement 10 requêtes/min/IP sur votre site, et qu'une IP en fait soudainement 300, le score explose même si la requête est techniquement parfaite.

5. Synthèse du Scoring (Le Verdict)

Algorithme Signal Impact Score
Fingerprint Mismatch UA vs TLS (Spoofing) Haut (50)
L4 Anomaly Variance latence < 0.5ms Moyen (30)
Path Sensitivity Hit sur /admin ou /config Haut (40)
Payload Security Caractères d'injection (SQL/XSS) Critique (60)
Mass Distribution 1 JA4 sur > 50 IPs différentes Moyen (30)

6. Identification des Hosts par IP et JA4 (sql/hosts.sql)

Cette section détaille les vues d'agrégation et de détection pour identifier quels hosts sont associés à quelles signatures (IP + JA4).

A. Agrégats de Base

Table Granularité Description
agg_host_ip_ja4_1h heure Hits, paths uniques, query params, méthodes par (IP, JA4, host)
agg_host_ip_ja4_24h jour Rollup quotidien pour historique long terme

B. Vues d'Identification

view_host_identification - Top hosts par signature

-- Quel host est associé à cette IP/JA4 ?
SELECT src_ip, ja4, host, total_hits, unique_paths, user_agent
FROM mabase_prod.view_host_identification
WHERE src_ip = '1.2.3.4'
ORDER BY total_hits DESC;

view_host_ja4_anomalies - JA4 partagé par plusieurs hosts (botnet)

-- Ce JA4 est-il utilisé par plusieurs hosts différents ?
SELECT ja4, hosts, unique_hosts, unique_ips
FROM mabase_prod.view_host_ja4_anomalies
HAVING unique_hosts >= 3;
-- Interprétation : 1 JA4 sur 3+ hosts = botnet cloné probable

view_host_ip_ja4_rotation - IP avec rotation de fingerprints

-- Cette IP change-t-elle de JA4 fréquemment ?
SELECT src_ip, ja4s, unique_ja4s
FROM mabase_prod.view_host_ip_ja4_rotation
HAVING unique_ja4s >= 5;
-- Interprétation : 1 IP avec 5+ JA4 différents = fingerprint spoofing

7. Détection de Brute Force (sql/hosts.sql)

A. Brute Force sur POST (endpoints sensibles)

Table : agg_bruteforce_post_5m - Fenêtres de 5 minutes

Vue : view_bruteforce_post_detected

-- Détecter les tentatives de brute force sur les login
SELECT window, src_ip, ja4, host, path, attempts, attempts_per_minute
FROM mabase_prod.view_bruteforce_post_detected
WHERE host = 'api.example.com'
ORDER BY attempts DESC;

-- Threshold : ≥10 POST en 5 minutes sur endpoints sensibles
-- Endpoints ciblés : login, auth, signin, password, admin, wp-login, etc.

B. Brute Force sur Formulaire (Query params variables)

Table : agg_form_bruteforce_5m

Vue : view_form_bruteforce_detected

-- Détecter les requêtes avec query params hautement variables
SELECT window, src_ip, ja4, host, path, requests, unique_query_patterns
FROM mabase_prod.view_form_bruteforce_detected
HAVING requests >= 20 AND unique_query_patterns >= 10;

-- Interprétation : 20+ requêtes avec 10+ patterns query différents
-- = tentative de fuzzing ou brute force sur paramètres

8. Header Fingerprinting (sql/hosts.sql)

Le champ client_headers contient la liste comma-separated des headers présents. Exemple : "Accept,Accept-Encoding,Sec-CH-UA,Sec-Fetch-Dest,User-Agent"

A. Signature par Ordre de Headers

Table : agg_header_fingerprint_1h

Champ Description
header_count Nombre total de headers (virgules + 1)
has_* Flags pour chaque header moderne (Sec-CH-UA, Sec-Fetch-*, etc.)
header_order_hash MD5(client_headers) = signature unique de l'ordre
modern_browser_score Score 0-100 basé sur les headers modernes présents

B. Vues de Détection

view_header_missing_modern_headers - Headers modernes manquants

-- Navigateurs "modernes" avec headers manquants
SELECT src_ip, ja4, header_user_agent, modern_browser_score, header_count
FROM mabase_prod.view_header_missing_modern_headers
WHERE header_user_agent ILIKE '%Chrome%';

-- Threshold : score < 70 pour Chrome/Firefox = suspect
-- Un vrai Chrome envoie automatiquement Sec-CH-UA, Sec-Fetch-*, etc.

view_header_ua_order_mismatch - Spoofing détecté

-- Même User-Agent avec ordre de headers différent
SELECT header_user_agent, ja4, unique_hashes, unique_ips
FROM mabase_prod.view_header_ua_order_mismatch
HAVING unique_hashes > 1;

-- Interprétation : 1 UA avec 2+ ordres de headers = spoofing ou outil custom

view_header_minimalist_count - Bot minimaliste

-- Clients avec trop peu de headers
SELECT src_ip, ja4, header_count, header_user_agent
FROM mabase_prod.view_header_minimalist_count
WHERE header_count < 6;

-- Threshold : < 6 headers = bot scripté (curl, Python requests, etc.)

view_header_sec_ch_missing - Incohérence Chrome

-- Chrome sans Sec-CH-UA (impossible pour un vrai Chrome)
SELECT src_ip, ja4, header_user_agent
FROM mabase_prod.view_header_sec_ch_missing
WHERE header_user_agent ILIKE '%Chrome/%';

view_header_known_bot_signature - Signature botnet

-- Même ordre de headers sur 10+ IPs différentes
SELECT header_order_hash, header_user_agent, unique_ips, total_hits
FROM mabase_prod.view_header_known_bot_signature
HAVING unique_ips >= 10;

-- Interprétation : 1 signature sur 10+ IPs = cluster de bots clonés

9. ALPN Mismatch Detection (sql/hosts.sql)

Principe

ALPN (Application-Layer Protocol Negotiation) est une extension TLS qui négocie le protocole HTTP avant la requête.

ALPN déclaré HTTP réel Interprétation
h2 HTTP/2 Normal
h2 HTTP/1.1 Bot mal configuré
http/1.1 HTTP/1.1 Normal

Vue de Détection

view_alpn_mismatch_detected

-- Clients déclarant h2 mais parlant HTTP/1.1
SELECT src_ip, ja4, declared_alpn, actual_http_version, mismatches, mismatch_pct
FROM mabase_prod.view_alpn_mismatch_detected
HAVING mismatch_pct >= 80;

-- Threshold : ≥5 requêtes avec ≥80% d'incohérence
-- Cause : curl mal configuré, Python requests, bots spoofant ALPN

10. Rate Limiting & Burst Detection (sql/hosts.sql)

A. Rate Limiting (1 minute)

Table : agg_rate_limit_1m

Vue : view_rate_limit_exceeded

-- IPs dépassant 50 requêtes/minute
SELECT minute, src_ip, ja4, requests_per_min, unique_paths
FROM mabase_prod.view_rate_limit_exceeded
ORDER BY requests_per_min DESC;

-- Threshold : > 50 req/min = trafic automatisé
-- Un humain ne peut pas soutenir 50+ req/min de manière cohérente

B. Burst Detection (10 secondes)

Table : agg_burst_10s

Vue : view_burst_detected

-- Pics soudains de trafic
SELECT window, src_ip, ja4, burst_count
FROM mabase_prod.view_burst_detected
HAVING burst_count > 20;

-- Threshold : > 20 requêtes en 10 secondes = burst suspect
-- Utile pour détecter les attaques par vagues

11. Path Enumeration / Scanning (sql/hosts.sql)

Vue de Détection

view_path_scan_detected

-- Détection de scanning de paths sensibles
SELECT window, src_ip, ja4, host, sensitive_hits, sensitive_ratio
FROM mabase_prod.view_path_scan_detected
HAVING sensitive_hits >= 5;

-- Paths surveillés : admin, backup, config, .env, .git, wp-admin,
-- phpinfo, test, debug, log, sql, dump, passwd, shadow, htaccess, etc.

-- Threshold : ≥5 paths sensibles en 5 minutes = scanning

Exemple de Résultat

src_ip ja4 host sensitive_hits sensitive_ratio
1.2.3.4 t13d... api.example.com 47 94.00
5.6.7.8 t13d... www.example.com 12 80.00

Interprétation : Ces IPs testent systématiquement les paths sensibles = outils comme Nikto, Dirb, Gobuster.


12. Payload Attack Detection (sql/hosts.sql)

A. Types d'Attaques Détectées

Type Patterns Détectés
SQL Injection UNION SELECT, OR 1=1, DROP TABLE, ; --, /* */, WAITFOR DELAY, SLEEP()
XSS <script>, javascript:, onerror=, onload=, <img src=data:, <svg onload>
Path Traversal ../, ..\\, %2e%2e%2f, %252e%252e, %%32%65%%32%65

Vue de Détection

view_payload_attacks_detected

-- Toutes les tentatives d'injection
SELECT window, src_ip, ja4, host, path, 
       sqli_attempts, xss_attempts, traversal_attempts
FROM mabase_prod.view_payload_attacks_detected
ORDER BY sqli_attempts DESC, xss_attempts DESC, traversal_attempts DESC;

-- Threshold : ≥1 tentative = alerte (zero tolerance)

13. JA4 Botnet Detection (sql/hosts.sql)

Principe

Un vrai navigateur a un fingerprint TLS unique. Un bot déployé sur 100 machines aura le même JA4.

Vue de Détection

view_ja4_botnet_suspected

-- JA4 partagé par 20+ IPs différentes
SELECT ja4, ja3_hash, unique_ips, unique_asns, unique_countries, total_hits
FROM mabase_prod.view_ja4_botnet_suspected
HAVING unique_ips >= 20;

-- Threshold : ≥20 IPs avec le même JA4 = botnet cloné

Exemple de Résultat

ja4 ja3_hash unique_ips unique_asns unique_countries
t13d1512... a3b5c7... 147 12 8
t13d0918... f1e2d3... 52 3 2

Interprétation : 147 IPs différentes avec le même fingerprint = cluster de bots clonés.


14. Correlation Quality (sql/hosts.sql)

Principe

Mesure le ratio d'événements non-corrélés (orphelins). Un trafic légitime a une bonne corrélation HTTP/TCP.

Vue de Détection

view_high_orphan_ratio

-- Trafic avec >80% d'événements non-corrélés
SELECT hour, src_ip, ja4, host, correlated, orphans, orphan_pct
FROM mabase_prod.view_high_orphan_ratio
ORDER BY orphan_pct DESC;

-- Threshold : orphan_pct > 80% = trafic suspect
-- Peut indiquer du trafic généré artificiellement

15. Maintenance et Faux Positifs

Exceptions Connues

Source Faux Positif Solution
Googlebot/Bingbot Scan agressif mais légitime Filtrer par ASN + Reverse DNS
Monitoring interne Rate limit élevé Whitelist par IP/ASN
CDN/Proxy JA4 partagé (clients derrière proxy) Vérifier ASN (Cloudflare, Akamai)
Navigateurs anciens Headers modernes manquants Vérifier UA version

Reset des Scores

Les agrégats sont automatiquement purgés par TTL :

  • agg_*_1h : TTL 7 jours
  • agg_*_5m : TTL 1 jour
  • agg_*_1m : TTL 1 jour

Un IP bloquée par erreur retrouvera un score normal après expiration du TTL.


16. Synthèse des Vues de Détection

Vue Détection Threshold Impact
view_bruteforce_post_detected POST endpoints sensibles ≥10 en 5min 🔴 Haut
view_form_bruteforce_detected Query params variables ≥20 req, ≥10 patterns 🔴 Haut
view_header_missing_modern_headers Headers modernes manquants score < 70 🔴 Haut
view_header_ua_order_mismatch UA spoofing (ordre) >1 hash 🔴 Haut
view_header_minimalist_count Bot minimaliste < 6 headers 🔴 Haut
view_header_sec_ch_missing Chrome sans Sec-CH absent 🟡 Moyen
view_header_known_bot_signature Signature connue (botnet) 10+ IPs 🔴 Haut
view_alpn_mismatch_detected h2 déclaré, HTTP/1.1 parlé ≥80% mismatch 🔴 Haut
view_rate_limit_exceeded Rate limit dépassé >50 req/min 🔴 Haut
view_burst_detected Burst soudain >20 req/10s 🟡 Moyen
view_path_scan_detected Scanning de paths ≥5 sensibles 🔴 Haut
view_payload_attacks_detected Injections SQLi/XSS ≥1 tentative 🔴 Critique
view_ja4_botnet_suspected JA4 partagé (botnet) ≥20 IPs 🔴 Haut
view_high_orphan_ratio Trafic non-corrélé >80% orphans 🟡 Moyen
view_host_ja4_anomalies JA4 sur plusieurs hosts ≥3 hosts 🟡 Moyen
view_host_ip_ja4_rotation IP rotate JA4 ≥5 JA4 🟡 Moyen

17. Exemples de Requêtes d'Investigation

Top 10 des IPs les plus suspectes (score cumulé)

WITH threats AS (
    SELECT src_ip, ja4, 'bruteforce' AS type, sum(attempts) AS score
    FROM mabase_prod.view_bruteforce_post_detected GROUP BY src_ip, ja4
    UNION ALL
    SELECT src_ip, ja4, 'path_scan', sum(sensitive_hits)
    FROM mabase_prod.view_path_scan_detected GROUP BY src_ip, ja4
    UNION ALL
    SELECT src_ip, ja4, 'payload', sum(sqli_attempts + xss_attempts)
    FROM mabase_prod.view_payload_attacks_detected GROUP BY src_ip, ja4
)
SELECT src_ip, ja4, sum(score) AS total_score, groupArray(type) AS threat_types
FROM threats
GROUP BY src_ip, ja4
ORDER BY total_score DESC
LIMIT 10;

Historique d'une IP suspecte

SELECT 
    hour,
    host,
    countMerge(hits) AS requests,
    uniqMerge(uniq_paths) AS unique_paths
FROM mabase_prod.agg_host_ip_ja4_1h
WHERE src_ip = '1.2.3.4'
  AND hour >= now() - INTERVAL 24 HOUR
GROUP BY hour, host
ORDER BY hour DESC;

Corrélation JA4 → User-Agent → Hosts

SELECT 
    ja4,
    any(first_ua) AS user_agent,
    groupArray(DISTINCT host) AS hosts,
    sum(countMerge(hits)) AS total_requests
FROM mabase_prod.agg_host_ip_ja4_1h
WHERE hour >= now() - INTERVAL 1 HOUR
GROUP BY ja4
ORDER BY total_requests DESC
LIMIT 20;

18. Installation et Maintenance

Installation

# Exécuter après init.sql
clickhouse-client --multiquery < sql/hosts.sql

Vérification

-- Compter les enregistrements
SELECT count(*) FROM mabase_prod.agg_host_ip_ja4_1h;
SELECT count(*) FROM mabase_prod.agg_header_fingerprint_1h;

-- Tester les vues
SELECT * FROM mabase_prod.view_host_identification LIMIT 10;
SELECT * FROM mabase_prod.view_bruteforce_post_detected LIMIT 10;
SELECT * FROM mabase_prod.view_payload_attacks_detected LIMIT 10;

Monitoring

-- Vues les plus actives (dernière heure)
SELECT 
    'bruteforce_post' AS view_name, count() AS alerts 
FROM mabase_prod.view_bruteforce_post_detected
UNION ALL
SELECT 'path_scan', count() FROM mabase_prod.view_path_scan_detected
UNION ALL
SELECT 'payload_attacks', count() FROM mabase_prod.view_payload_attacks_detected
UNION ALL
SELECT 'ja4_botnet', count() FROM mabase_prod.view_ja4_botnet_suspected
ORDER BY alerts DESC;