docs: mise à jour thèse — capture HTTP/2 passive et colonnes individuelles
Sections mises à jour : - Architecture §3.1 : H2 capture déplacé de ja4sentinel vers mod_reqin_log - §3.5 Couche L7 : description du hook process_connection (APR_HOOK_FIRST, AP_MODE_SPECULATIVE), parsing preface, notes c1/c2, colonnes individuelles - Tableau des 12 colonnes H2 dans ja4_logs.http_logs avec types et conventions - §3.9 Browser Matcher : statut mis à jour (capture [impl.], scoring [partiel]) - §3.9.1 : mécanisme de capture via process_connection au lieu de filtre connexion - §3.9.4 : h2_window_update_value, h2_has_priority, h2_pseudo_order → [impl.] - §6.6 Roadmap : dépendance capture H2 résolue, travail restant = browser_match_* - Contribution 3 : description de l implémentation technique ajoutée - Tableau récapitulatif : F8 passe de 0/8/0 à 3/5/0 (70 impl. / 5 partiel) - Résumé quantitatif : 82% impl. (était 79%), 6% partiel (était 9%) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@ -803,15 +803,17 @@ httpcloak est un outil d'évasion qui tente d'imiter l'empreinte TLS de Chrome.
|
||||
│ (Source B) │ (Source A) │
|
||||
│ │ │
|
||||
│ libpcap, CAP_NET_RAW │ Module Apache personnalisé │
|
||||
│ Couches L3/L4/L5 │ Couche L7 HTTP │
|
||||
│ Couches L3/L4/L5 │ Couches L7 HTTP + L5 HTTP/2 │
|
||||
│ - IP header (TTL, DF) │ - src_ip, src_port │
|
||||
│ - TCP SYN (MSS, Window, │ - timestamp_ns (nanoseconde) │
|
||||
│ Options, Scale) │ - méthode, chemin, query │
|
||||
│ - TLS ClientHello │ - version HTTP │
|
||||
│ (JA4, JA4T, ALPN, SNI) │ - en-têtes (bruts + ordre) │
|
||||
│ - HTTP/2 frames │ - statut, taille, durée_ms │
|
||||
│ (SETTINGS, WU, │ │
|
||||
│ PRIORITY, pseudo-hdr) │ │
|
||||
│ │ - statut, taille, durée_ms │
|
||||
│ │ - HTTP/2 preface passif : │
|
||||
│ │ SETTINGS (7 params individuels), │
|
||||
│ │ WINDOW_UPDATE, PRIORITY flag, │
|
||||
│ │ ordre pseudo-headers │
|
||||
└───────────────────────────┴──────────────────────────────────────┘
|
||||
│ │
|
||||
└─────────────┬─────────────┘
|
||||
@ -934,6 +936,34 @@ La couche L7 constitue la couche la plus riche en features comportementales. Le
|
||||
|
||||
Données capturées par mod_reqin_log : `src_ip`, `src_port`, `timestamp_ns` (nanoseconde absolu), `method`, `path`, `query_string`, `http_version`, `headers_raw` (en-têtes bruts dans leur ordre d'émission), `header_order_signature` (hash de l'ordre), `status_code`, `response_size`, `duration_ms`. L'horodatage nanoseconde est critique pour le calcul des features temporelles F8 (cadence_cv, lag1_autocorrelation, benford_deviation, root_to_first_asset_delay).
|
||||
|
||||
**Fingerprinting HTTP/2 passif intégré** : pour les connexions HTTP/2, mod_reqin_log capture passivement le preface client via un hook `ap_hook_process_connection` enregistré en priorité `APR_HOOK_FIRST`, exécuté avant `mod_http2`. Ce hook effectue une lecture spéculative (`AP_MODE_SPECULATIVE`) de 512 octets sur les filtres d'entrée de la connexion, qui déclenche transparentement le handshake TLS (`mod_ssl`) et retourne les données déchiffrées sans les consommer. Le preface H2 est ensuite parsé pour en extraire :
|
||||
- Les 7 paramètres SETTINGS individuels (IDs 1–6 et 8), chacun stocké dans une colonne ClickHouse dédiée (`h2_header_table_size`, `h2_enable_push`, `h2_max_concurrent_streams`, `h2_initial_window_size`, `h2_max_frame_size`, `h2_max_header_list_size`, `h2_enable_connect_protocol`), avec la valeur -1 pour les paramètres absents du preface client
|
||||
- L'incrément `h2_window_update` de la frame WINDOW_UPDATE sur la connexion (stream ID 0)
|
||||
- Le flag `h2_has_priority` indiquant la présence d'un champ PRIORITY dans la frame HEADERS
|
||||
- L'ordre des pseudo-headers `h2_pseudo_order` (ex. `m,a,s,p`) extrait par décodage HPACK partiel de la première frame HEADERS
|
||||
- Le fingerprint composite `h2_fingerprint` au format Akamai et la chaîne brute `h2_settings_fp`
|
||||
|
||||
Les données H2 sont stockées dans les notes de la connexion primaire (`c->notes`). Pour les connexions HTTP/2, `mod_http2` crée des connexions secondaires (c2) par stream ; le hook `log_request` accède aux notes H2 via `r->connection->master` (connexion primaire c1). Le hook retourne `DECLINED` après stockage, laissant `mod_http2` gérer la suite normalement.
|
||||
|
||||
**Colonnes HTTP/2 dans `ja4_logs.http_logs`** :
|
||||
|
||||
| Colonne ClickHouse | Type | Défaut | Description |
|
||||
|---------------------|------|--------|-------------|
|
||||
| `h2_fingerprint` | String | `''` | Fingerprint composite au format Akamai (ex. `1:65536,2:0,4:6291456,6:262144\|15663105\|0\|m,a,s,p`) |
|
||||
| `h2_settings_fp` | String | `''` | Chaîne brute des entrées SETTINGS (ex. `3:100,4:65536,2:0`) |
|
||||
| `h2_header_table_size` | Int32 | `-1` | SETTINGS ID 1 — HEADER_TABLE_SIZE (octets). -1 = absent du preface |
|
||||
| `h2_enable_push` | Int32 | `-1` | SETTINGS ID 2 — ENABLE_PUSH (0/1). -1 = absent |
|
||||
| `h2_max_concurrent_streams` | Int32 | `-1` | SETTINGS ID 3 — MAX_CONCURRENT_STREAMS. -1 = absent |
|
||||
| `h2_initial_window_size` | Int64 | `-1` | SETTINGS ID 4 — INITIAL_WINDOW_SIZE (octets). -1 = absent |
|
||||
| `h2_max_frame_size` | Int32 | `-1` | SETTINGS ID 5 — MAX_FRAME_SIZE (octets). -1 = absent |
|
||||
| `h2_max_header_list_size` | Int32 | `-1` | SETTINGS ID 6 — MAX_HEADER_LIST_SIZE (octets). -1 = absent |
|
||||
| `h2_enable_connect_protocol` | Int32 | `-1` | SETTINGS ID 8 — ENABLE_CONNECT_PROTOCOL (RFC 8441). -1 = absent |
|
||||
| `h2_window_update` | UInt32 | `0` | Incrément WINDOW_UPDATE connexion (stream ID 0). 0 = absent |
|
||||
| `h2_has_priority` | UInt8 | `0` | 1 si le flag PRIORITY est présent dans la frame HEADERS |
|
||||
| `h2_pseudo_order` | String | `''` | Ordre des pseudo-headers (ex. `m,a,s,p` pour Chrome) |
|
||||
|
||||
La convention `-1` pour les paramètres SETTINGS absents est essentielle : elle distingue un paramètre non envoyé par le client (valeur par défaut RFC implicite) d'un paramètre explicitement fixé à 0 (ex. `ENABLE_PUSH = 0` signifie « Server Push désactivé » vs `-1` signifie « non envoyé, le serveur utilise la valeur par défaut RFC de 1 »).
|
||||
|
||||
Toutes les features des familles F1–F6 et F8 proviennent de cette couche, agrégées sur des fenêtres temporelles de 300 secondes (5 minutes) par session (src_ip).
|
||||
|
||||
### 3.6 Corrélation inter-couches (logcorrelator)
|
||||
@ -1054,7 +1084,7 @@ La valeur `percentile_5` du historique des scores négatifs (anomalies confirmé
|
||||
|
||||
## 3.9 Browser Signature Detection (browser_matcher)
|
||||
|
||||
`[partiel]` **Statut global : à implémenter**
|
||||
`[partiel]` **Statut global : capture H2 implémentée, module de scoring à compléter**
|
||||
|
||||
Le système `browser_confidence` à 6 axes (§3.8) fournit un score agrégé utile comme feature ML, mais sa logique de bypass (seuil 0,55) manque de précision face aux outils d'évasion modernes — notamment `httpcloak`, `curl_cffi` et `python-requests` patchés — qui reproduisent les couches TLS et HTTP/1.1 sans reproduire les subtilités HTTP/2. `browser_matcher` adresse cette lacune en implémentant une correspondance structurée par famille de navigateur, fondée sur l'empreinte passive du protocole HTTP/2.
|
||||
|
||||
@ -1069,7 +1099,9 @@ Le système `browser_confidence` à 6 axes (§3.8) fournit un score agrégé uti
|
||||
- **Compression d'en-têtes HPACK** : [RFC 7541](https://www.rfc-editor.org/rfc/rfc7541) définit HPACK, une compression d'en-têtes HTTP par table d'indexation. L'ordre des entrées dans la table statique HPACK est normalisé, mais l'ordre de sérialisation des pseudo-headers est laissé à l'implémentation.
|
||||
- **Contrôle de flux** : mécanisme de fenêtres (`WINDOW_UPDATE`) limitant le débit pour éviter la saturation du récepteur.
|
||||
|
||||
Après terminaison TLS par Apache (`mod_ssl`), le flux HTTP/2 est déchiffré et disponible pour `mod_http2` en clair. Ceci permet le **fingerprinting passif** des paramètres de connexion HTTP/2 sans aucune injection de code côté client.
|
||||
Après terminaison TLS par Apache (`mod_ssl`), le flux HTTP/2 est déchiffré et disponible en clair. Le fingerprinting passif est réalisé directement par **mod_reqin_log** via un hook `process_connection` enregistré en priorité `APR_HOOK_FIRST`. Ce hook s'exécute **avant** `mod_http2` et effectue une lecture spéculative (`AP_MODE_SPECULATIVE`, 512 octets) sur `c->input_filters`, déclenchant transparentement le handshake TLS. Si les données commencent par le magic HTTP/2 (`PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n`), le parser binaire extrait les frames SETTINGS, WINDOW_UPDATE et HEADERS du preface client, stocke les résultats dans `c->notes`, puis retourne `DECLINED` pour laisser `mod_http2` gérer la connexion. Cette approche ne consomme pas les données et n'interfère pas avec le traitement HTTP/2 normal.
|
||||
|
||||
**Note architecturale** : l'approche par filtre de connexion (`AP_FTYPE_CONNECTION`) a été abandonnée car `mod_http2` prend le contrôle complet de la connexion via son propre hook `process_connection` — les filtres d'entrée de connexion ne sont jamais invoqués pour les connexions HTTP/2. Le hook `process_connection` à priorité haute est la seule technique fiable pour intercepter le preface H2 avant `mod_http2`.
|
||||
|
||||
#### Frame SETTINGS
|
||||
|
||||
@ -1352,12 +1384,12 @@ Le module `browser_matcher` génère les features suivantes dans le vecteur feat
|
||||
| `browser_match_safari` | Float32 | Score de correspondance Safari (0–1) | `[partiel]` |
|
||||
| `browser_match_max` | Float32 | max(chrome, firefox, safari) | `[partiel]` |
|
||||
| `browser_family_detected` | String | Famille détectée ou chaîne vide | `[partiel]` |
|
||||
| `h2_window_update_value` | UInt32 | Valeur WINDOW_UPDATE observée | `[partiel]` |
|
||||
| `h2_has_priority_frames` | UInt8 | 1 si frames PRIORITY présentes | `[partiel]` |
|
||||
| `h2_pseudo_order` | String | Ordre observé (ex. `m,a,s,p`) | `[partiel]` |
|
||||
| `h2_window_update_value` | UInt32 | Valeur WINDOW_UPDATE observée | `[impl.]` (colonne `h2_window_update` dans `http_logs`) |
|
||||
| `h2_has_priority_frames` | UInt8 | 1 si frames PRIORITY présentes | `[impl.]` (colonne `h2_has_priority` dans `http_logs`) |
|
||||
| `h2_pseudo_order` | String | Ordre observé (ex. `m,a,s,p`) | `[impl.]` (colonne `h2_pseudo_order` dans `http_logs`) |
|
||||
| `tls_h2_family_mismatch` | UInt8 | 1 si JA4 dit Chrome mais H2 SETTINGS dit Firefox/outil | `[impl.]` (feature F4) |
|
||||
|
||||
La feature `tls_h2_family_mismatch` est déjà implémentée dans le vecteur feature global (famille F4 — TLS features) car elle se calcule à partir des données JA4 existantes et du champ h2_settings_id4 disponible dans `ja4_processing.sessions`. Les features `browser_match_*` requièrent l'exécution complète du module `browser_matcher.py`.
|
||||
Les features `h2_window_update_value`, `h2_has_priority_frames` et `h2_pseudo_order` sont désormais capturées par mod_reqin_log et stockées dans des colonnes individuelles de `ja4_logs.http_logs`. De plus, chaque paramètre SETTINGS HTTP/2 dispose de sa propre colonne (`h2_header_table_size`, `h2_enable_push`, `h2_max_concurrent_streams`, `h2_initial_window_size`, `h2_max_frame_size`, `h2_max_header_list_size`, `h2_enable_connect_protocol`) avec la valeur -1 pour les paramètres absents du preface client. La feature `tls_h2_family_mismatch` est implémentée dans le vecteur feature global (famille F4 — TLS features) et se calcule à partir des données JA4 existantes et des colonnes H2 individuelles disponibles dans `ja4_logs.http_logs`. Les features `browser_match_*` requièrent l'exécution complète du module `browser_matcher.py`.
|
||||
|
||||
### 3.9.5 Maintenance des signatures
|
||||
|
||||
@ -2906,9 +2938,9 @@ Un seul utilisateur réel alterne quelques connexions (2–6 ports source actifs
|
||||
|
||||
**browser_matcher complet (§3.9)** :
|
||||
- État actuel : modules `[partiel]` (logique de score partielle, base de signatures incomplète)
|
||||
- Travail requis : compléter `browser_signatures.py` avec signatures Firefox et Safari complètes, implémenter le rechargement ClickHouse toutes les 24h, intégrer les 8 features dérivées dans le vecteur feature global
|
||||
- Dépendances : capture des frames H2 SETTINGS via `mod_h2` Apache (requires `mod_http2` avec hook de logging personnalisé)
|
||||
- Estimation : 3–4 semaines de développement
|
||||
- Données H2 brutes : `[impl.]` — capture des 7 paramètres SETTINGS individuels, WINDOW_UPDATE, flag PRIORITY et ordre pseudo-headers par mod_reqin_log via hook `process_connection` (APR_HOOK_FIRST, AP_MODE_SPECULATIVE). Colonnes individuelles dans `ja4_logs.http_logs` (`h2_header_table_size`, `h2_enable_push`, `h2_max_concurrent_streams`, `h2_initial_window_size`, `h2_max_frame_size`, `h2_max_header_list_size`, `h2_enable_connect_protocol`, `h2_window_update`, `h2_has_priority`, `h2_pseudo_order`)
|
||||
- Travail restant : compléter `browser_signatures.py` avec signatures Firefox et Safari complètes, implémenter le rechargement ClickHouse toutes les 24h, intégrer les 5 features `browser_match_*` dérivées dans le vecteur feature global
|
||||
- Dépendances : ~~capture des frames H2 SETTINGS~~ (réalisé) ; reste le module `browser_matcher.py`
|
||||
|
||||
**DNS Shadow Analysis (§5.6)** :
|
||||
- État actuel : `[todo]` non implémenté
|
||||
@ -2976,7 +3008,9 @@ L'**explainabilité** est assurée par ExIFFI ([Frizzo et al., 2024](https://arx
|
||||
|
||||
Extension du système `browser_confidence` à 6 axes vers une correspondance structurée par famille de navigateur, fondée sur l'analyse passive de 7 dimensions H2 : frame SETTINGS (7 paramètres), WINDOW_UPDATE, ordre des pseudo-headers, frames PRIORITY, cohérence des en-têtes HTTP, structure TLS, et lookup JA4 par dictionnaire.
|
||||
|
||||
Cette technique détecte détecter des outils d'évasion qui reproduisent correctement la couche TLS (curl_cffi, httpcloak) mais échouent à reproduire les subtilités H2 — notamment l'ordre des pseudo-headers et la valeur WINDOW_UPDATE.
|
||||
La capture passive est réalisée par mod_reqin_log via un hook `ap_hook_process_connection` (APR_HOOK_FIRST) qui intercepte le preface HTTP/2 avant `mod_http2` par lecture spéculative. Chaque paramètre SETTINGS est stocké dans une colonne ClickHouse individuelle (`h2_header_table_size`, `h2_enable_push`, `h2_max_concurrent_streams`, `h2_initial_window_size`, `h2_max_frame_size`, `h2_max_header_list_size`, `h2_enable_connect_protocol`) avec -1 pour les paramètres absents, complétés par `h2_window_update`, `h2_has_priority` et `h2_pseudo_order`.
|
||||
|
||||
Cette technique permet de détecter des outils d'évasion qui reproduisent correctement la couche TLS (curl_cffi, httpcloak) mais échouent à reproduire les subtilités H2 — notamment l'ordre des pseudo-headers et la valeur WINDOW_UPDATE.
|
||||
|
||||
La stabilité des empreintes H2 de Chrome sur 2+ ans (novembre 2023 – 2026) contraste favorablement avec JA4 TLS (instable à chaque mise à jour de ciphersuites), justifiant l'investissement dans cette dimension additionnelle.
|
||||
|
||||
@ -3010,17 +3044,17 @@ Architecture de données fondée sur ClickHouse avec **AggregatingMergeTree view
|
||||
| F5 — Comportement temporel | hit_velocity, temporal_entropy, cadence_cv, lag1_autocorrelation, burst_ratio, benford_deviation, ja4_drift_ratio (7 features) | 7 | 0 | 0 |
|
||||
| F6 — Navigation L7 | path_diversity_ratio, path_transition_entropy, asset_ratio, root_to_first_asset_delay, asset_load_stddev, post_ratio, error_4xx_ratio (7 features) | 7 | 0 | 0 |
|
||||
| F7 — Browser Confidence | browser_confidence (6-axis agrégé) | 1 | 0 | 0 |
|
||||
| F8 — Browser Matcher | browser_match_chrome, browser_match_firefox, browser_match_safari, browser_match_max, browser_family_detected, h2_window_update_value, h2_has_priority_frames, h2_pseudo_order (8 features) | 0 | 8 | 0 |
|
||||
| F8 — Browser Matcher | browser_match_chrome, browser_match_firefox, browser_match_safari, browser_match_max, browser_family_detected, h2_window_update_value, h2_has_priority_frames, h2_pseudo_order (8 features) | 3 | 5 | 0 |
|
||||
| F9 — Fleet / Graphe | fleet_score, community_size, edge_density (3 features) | 3 | 0 | 0 |
|
||||
| F10 — Multi-domaine | host_diversity, host_sweep_speed, host_coverage_uniformity, cross_domain_path_similarity (4 features) | 4 | 0 | 0 |
|
||||
| F11 — Futures (non impl.) | dns_shadow_ratio, compression_ratio_invariant (2 features) | 0 | 0 | 2 |
|
||||
| **Total** | **85** | **67** | **8** | **2** + meta |
|
||||
| **Total** | **85** | **70** | **5** | **2** + meta |
|
||||
|
||||
**Résumé quantitatif** : ~79 % des features entièrement implémentées (`[impl.]`), ~9 % partiellement implémentées (`[partiel]`, toutes dans browser_matcher), ~2 % non implémentées (`[todo]`, §5.6 et §5.7).
|
||||
**Résumé quantitatif** : ~82 % des features entièrement implémentées (`[impl.]`), ~6 % partiellement implémentées (`[partiel]`, les 5 features `browser_match_*` de browser_matcher), ~2 % non implémentées (`[todo]`, §5.6 et §5.7). Les 3 features H2 brutes (`h2_window_update_value`, `h2_has_priority_frames`, `h2_pseudo_order`) sont passées de `[partiel]` à `[impl.]` suite à l'intégration de la capture HTTP/2 passive dans mod_reqin_log.
|
||||
|
||||
### Perspective
|
||||
|
||||
Le système atteint ses objectifs opérationnels actuels. Les axes d'amélioration prioritaires sont l'achèvement de `browser_matcher` (`[partiel]` → `[impl.]`), l'extension DNS Shadow Analysis pour la couverture DNS (`[todo]` → `[partiel]`), et le passage à l'apprentissage en ligne pour XGBoost. À plus long terme, le support HTTP/3 (QUIC) deviendra nécessaire à mesure que la proportion de trafic HTTP/3 augmente dans la baseline.
|
||||
Le système atteint ses objectifs opérationnels actuels. La capture HTTP/2 passive est désormais intégrée avec 12 colonnes individuelles dans `ja4_logs.http_logs`. Les axes d'amélioration prioritaires sont l'achèvement du module de scoring `browser_matcher` (`[partiel]` → `[impl.]` pour les 5 features `browser_match_*`), l'extension DNS Shadow Analysis pour la couverture DNS (`[todo]` → `[partiel]`), et le passage à l'apprentissage en ligne pour XGBoost. À plus long terme, le support HTTP/3 (QUIC) deviendra nécessaire à mesure que la proportion de trafic HTTP/3 augmente dans la baseline.
|
||||
|
||||
La technique la plus prometteuse parmi les travaux futurs est le **PARD-SSM** ([Hiremath et al., 2026](https://arxiv.org/abs/2604.12345)), qui permettrait de modéliser explicitement les phases d'attaque séquentielles — comblant la lacune actuelle entre la détection de sessions individuelles et la détection de campagnes d'attaque coordonnées multi-phases.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user