# đŸ›Ąïž 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 ```sql -- 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) ```sql -- 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 ```sql -- 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` ```sql -- 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` ```sql -- 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 ```sql -- 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Ă© ```sql -- 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 ```sql -- 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 ```sql -- 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 ```sql -- 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`** ```sql -- 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` ```sql -- 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` ```sql -- 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`** ```sql -- 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** | `