From 95e87149aa431018af1dfd330ad1b1d0f884f4f6 Mon Sep 17 00:00:00 2001 From: toto Date: Sat, 11 Apr 2026 02:40:41 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20mise=20=C3=A0=20jour=20th=C3=A8se=20?= =?UTF-8?q?=E2=80=94=20capture=20HTTP/2=20passive=20et=20colonnes=20indivi?= =?UTF-8?q?duelles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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> --- docs/THESIS_HTTP_Traffic_Detection.md | 70 ++++++++++++++++++++------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/docs/THESIS_HTTP_Traffic_Detection.md b/docs/THESIS_HTTP_Traffic_Detection.md index 5a0a17c..0049429 100644 --- a/docs/THESIS_HTTP_Traffic_Detection.md +++ b/docs/THESIS_HTTP_Traffic_Detection.md @@ -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.