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>
This commit is contained in:
111
idees/champs.md
Normal file
111
idees/champs.md
Normal file
@ -0,0 +1,111 @@
|
||||
time
|
||||
log_date
|
||||
|
||||
src_ip
|
||||
- ip source de la connexion
|
||||
src_port
|
||||
- port source de la connexion
|
||||
dst_ip
|
||||
- ip de destination de la connexion
|
||||
dst_port
|
||||
- port de destination de la connexion
|
||||
|
||||
src_asn
|
||||
- Numero d'AS de l'ip source
|
||||
src_country_code
|
||||
- Code Pays de l'ip source
|
||||
src_as_name
|
||||
- Nom de l'AS de l ip source
|
||||
src_org
|
||||
- Organisation de l AS source
|
||||
src_domain
|
||||
- domaine de l'AS de l ip source
|
||||
|
||||
method
|
||||
- Methode HTTP [GET, POST, ... ]
|
||||
scheme
|
||||
- Type de connexion http [http, https]
|
||||
host
|
||||
- Hostname demandé dans l'url
|
||||
path
|
||||
- Path demandé dans l'url
|
||||
query
|
||||
- Query demandé dans l'url
|
||||
http_version
|
||||
- Version du protocol http utilisé
|
||||
|
||||
orphan_side
|
||||
- Indique si le log HTTP a pu etre enrichi avec les informations ip_, tcp, ja3_ et ja4_
|
||||
- "A" indique que seul le log HTTP est present, sans enrichissement
|
||||
correlated
|
||||
- l'algorithm de correlation log http + parametres tcp a il réussi (tcp + ja4/3)
|
||||
keepalives
|
||||
- Numero de desquance dans une connexion http avec keepalive.
|
||||
a_timestamp
|
||||
b_timestamp
|
||||
conn_id
|
||||
|
||||
ip_meta_df
|
||||
- Flag dont fragement
|
||||
ip_meta_id
|
||||
- id du packet ip
|
||||
ip_meta_total_length
|
||||
- Taille des metadata dans pe packet ip
|
||||
ip_meta_ttl
|
||||
- TTL du packet ip vu par le serveur destinataire du packet
|
||||
|
||||
tcp_meta_options
|
||||
- options du packet TCP vu par le serveur destinataire du packet
|
||||
tcp_meta_window_size
|
||||
- TCP window size vu par le serveur destinataire du packet
|
||||
tcp_meta_mss
|
||||
- TCP mss vu par le serveur destinataire du packet
|
||||
tcp_meta_window_scale
|
||||
- TCP windows scale vu par le serveur destinataire du packet
|
||||
syn_to_clienthello_ms
|
||||
- durée en ms entre le 1er packet SYN et le ClienHello du TLS
|
||||
|
||||
tls_version
|
||||
- Version de TLS negocié avec le serveur destinataire du packet
|
||||
tls_sni
|
||||
- SNI, nom de domaine demandé pour le cerificat TLS
|
||||
tls_alpn
|
||||
- ALPN annoncé lors du TLS
|
||||
ja3
|
||||
- liste des agos utiliés pour la signature ja3
|
||||
ja3_hash
|
||||
- hash ja3
|
||||
ja4
|
||||
- hash ja4
|
||||
|
||||
client_headers
|
||||
- liste des headers envoyés par le client http sous forme de liste Header,Header2,Header3,...
|
||||
|
||||
header_user_agent
|
||||
- Header HTTP User-Agent
|
||||
header_accept
|
||||
- Header HTTP Accept
|
||||
header_accept_encoding
|
||||
- Header HTTP Accept-Encoding
|
||||
header_accept_language
|
||||
- Header HTTP Accept-Language
|
||||
header_content_type
|
||||
- Header Content-Type
|
||||
header_x_request_id
|
||||
- Header X-Request-ID
|
||||
header_x_trace_id
|
||||
- Header X-Trace-ID
|
||||
header_x_forwarded_for
|
||||
- Header X-Forwarded-For
|
||||
header_sec_ch_ua
|
||||
- Header Sec-Ch-UA
|
||||
header_sec_ch_ua_mobile
|
||||
- Header -Sec-Ch-UA-Mobile
|
||||
header_sec_ch_ua_platform
|
||||
- Header Sec-Ch-UA-Plateform
|
||||
header_sec_fetch_dest
|
||||
- Header -Sec-Fetch-Dest
|
||||
header_sec_fetch_mode
|
||||
- Header Sec-Fetch-Mode
|
||||
header_sec_fetch_site
|
||||
- Header Sec-Fetch-Site
|
||||
30
idees/idees.txt
Normal file
30
idees/idees.txt
Normal file
@ -0,0 +1,30 @@
|
||||
1. Incohérences de Signatures (Spoofing)
|
||||
|
||||
User-Agent vs TLS : Le header_user_agent prétend être un navigateur (Chrome/Safari) mais le ja3/ja4 correspond à un outil de script.
|
||||
User-Agent vs Headers modernes : Le header_user_agent indique un navigateur récent, mais les headers header_sec_ch_ua_* sont vides ou absents de client_headers.
|
||||
User-Agent vs ALPN : Le navigateur déclaré ne correspond pas au protocole négocié dans tls_alpn (ex: Chrome sans h2).
|
||||
OS vs TTL TCP : L'OS déclaré dans le header_user_agent (ex: Windows) contredit la valeur de ip_meta_ttl (ex: 64, typique de Linux).
|
||||
Host vs SNI : Le nom de domaine dans le header host ne correspond pas au tls_sni demandé lors du handshake TLS.
|
||||
|
||||
2. Anomalies de Headers (HTTP Fingerprinting)
|
||||
|
||||
Empreinte d'ordre (Fingerprint) : Apparition soudaine d'une disposition de client_headers (ordre exact) très rare, générant beaucoup de trafic.
|
||||
Pauvreté des headers : Le nombre total de headers dans client_headers est anormalement bas (ex: < 5), typique des scripts basiques.
|
||||
Absence de headers vitaux : Le trafic prétend être humain mais n'envoie pas header_accept_language ou header_accept_encoding.
|
||||
Combinaison fatale : Le croisement d'un ja4 spécifique avec un ordre de client_headers inédit (détection de bots modifiant leur TLS mais trahis par l'applicatif).
|
||||
|
||||
3. Anomalies Réseau et TCP (Couche 3 & 4)
|
||||
|
||||
Mécanique TCP de masse : Une même combinaison (tcp_meta_window_size, tcp_meta_window_scale, tcp_meta_mss) vue sur des milliers d'IP différentes.
|
||||
Handshake robotique : Un délai syn_to_clienthello_ms anormalement constant (variance quasi nulle) sur un grand nombre de connexions, typique d'un bot en datacenter.
|
||||
Options TCP atypiques : Des paramètres tcp_meta_options inhabituels pour le trafic web classique de tes vrais utilisateurs.
|
||||
|
||||
4. Anomalies Comportementales et Volumétriques (Côté Requête)
|
||||
|
||||
Rafale de requêtes (Spike) : Volume d'appels (count) par src_ip ou par ja4 dépassant drastiquement le 99ème percentile historique sur 5 minutes.
|
||||
Scraping furtif distribué : Un même ja4 (non standard) utilisé par des centaines de src_ip différentes, chacune faisant très peu de requêtes.
|
||||
Balayage aveugle (Scanner) : Un volume anormal de path uniques (ou path + query) visités par une même IP ou un même ja4 en quelques minutes (remplace la détection des erreurs 404).
|
||||
Acharnement sur cible (Brute force aveugle) : Une concentration extrême de requêtes ciblant uniquement les path sensibles (login, API, password-reset) sans navigation normale sur le reste du site (remplace la détection des 401/403).
|
||||
Méthodes suspectes : Utilisation massive ou inhabituelle de method non standards (PUT, DELETE, OPTIONS, TRACE) par rapport à la baseline.
|
||||
Payloads suspects : Présence de patterns d'injection ou de caractères très inhabituels dans query ou path (longueur extrême, encodages multiples).
|
||||
Bot "Low and Slow" : IP ou ja4 qui passe sous les radars sur 5 minutes, mais dont le volume cumulé sur 24h ou 7 jours est mathématiquement improbable pour un humain.
|
||||
521
idees/views.md
Normal file
521
idees/views.md
Normal file
@ -0,0 +1,521 @@
|
||||
# 🛡️ 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** | `<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`**
|
||||
```sql
|
||||
-- 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`**
|
||||
```sql
|
||||
-- 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`**
|
||||
```sql
|
||||
-- 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é)
|
||||
```sql
|
||||
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
|
||||
```sql
|
||||
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
|
||||
```sql
|
||||
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
|
||||
```bash
|
||||
# Exécuter après init.sql
|
||||
clickhouse-client --multiquery < sql/hosts.sql
|
||||
```
|
||||
|
||||
### Vérification
|
||||
```sql
|
||||
-- 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
|
||||
```sql
|
||||
-- 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;
|
||||
```
|
||||
Reference in New Issue
Block a user