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>
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
cityHash64pour 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_fingerprintET le mêmeja4, 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 leSYNet leClientHelloTLS. - 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 leja4(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 (commeutls). - 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 headerHost(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'attaquerapi-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
queryetpath(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_seendate 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
hitsactuels 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 joursagg_*_5m: TTL 1 jouragg_*_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;