Le protocole de contrôle de transmission (TCP), formalisé dans la RFC 793 en 1981, constitue le pilier fondamental des échanges de données sur Internet. Lors d'une défaillance logicielle de socket ou de l'arrêt inopiné d'un point de terminaison, TCP utilise le drapeau de réinitialisation (RST) pour clore immédiatement la connexion et libérer les mémoires tampons du noyau. Cependant, les en-têtes TCP d'origine ne comportant aucune signature cryptographique, tout équipement intermédiaire capable d'observer ou d'extrapoler les paramètres d'une session peut forger des paquets RST arbitraires.
Cette méthode d'interférence s'appelle l'injection TCP RST (TCP RST Injection). Les passerelles d'inspection approfondie (DPI), les pare-feu d'opérateurs et les assaillants sur le chemin réseau l'utilisent couramment pour interrompre des transferts de fichiers volumineux, briser des connexions SSH ou de bases de données, et entraver le trafic web sans accéder aux hôtes émetteurs.
Comprendre pourquoi le protocole TCP standard s'avère vulnérable aux attaques aveugles dans la fenêtre de réception (blind in-window attacks) requiert d'étudier l'arithmétique de la fenêtre de réception, les mécanismes de la RFC 5961 et la protection par encapsulation chiffrée de couche 3.
[Traitement standard dans la fenêtre selon la RFC 793 d'origine]
Fenêtre de réception : [RCV.NXT = 10 000] <─────── 1 048 576 octets ───────> [1 058 576]
▲
Paquet RST forgé : SEQ = 450 000
(Accepté ! La connexion est interrompue)
─────────────────────────────────────────────────────────────────────────────────────────────
[Vérification stricte de réinitialisation selon la RFC 5961]
Fenêtre de réception : [RCV.NXT = 10 000] <─────── 1 048 576 octets ───────> [1 058 576]
▲ ▲
Seul SEQ == 10 000 clôt le socket ! RST dans la fenêtre déclenche un Challenge ACK ;
La session demeure stable et protégée.
Fonctionnement de l'injection TCP RST et faiblesse de la fenêtre de réception
Dans la spécification initiale RFC 793, un point de terminaison TCP en état de session établie (ESTABLISHED) traitant un paquet portant le drapeau RST applique une simple vérification de frontière de fenêtre. Le segment est validé dès lors que la condition suivante est satisfaite :
$$\text{RCV.NXT} \le \text{SEG.SEQ} < \text{RCV.NXT} + \text{RCV.WND}$$
Dans cette formule, $\text{RCV.NXT}$ représente le numéro de séquence attendu par le récepteur et $\text{RCV.WND}$ la taille déclarée de la fenêtre de réception.
À l'époque de la rédaction de la RFC 793, les mémoires tampons ne dépassaient guère 64 Ko. Les liaisons contemporaines à haut débit activent cependant systématiquement l'option d'échelle de fenêtre TCP Window Scale (RFC 7323), étendant la fenêtre de réception à plusieurs mégaoctets (fréquemment entre 256 Ko et 4 Mo).
Cette expansion affaiblit dramatiquement la sécurité face aux attaques par prédiction :
- Réduction de l'espace de recherche : Dans un espace d'adressage de 32 bits ($2^{32} \approx 4,29 \times 10^9$ valeurs), cibler un numéro exact nécessite des millions d'essais. En revanche, pour atteindre une fenêtre de 2 Mo, il suffit d'atteindre une plage continue de $2,097,152$ numéros.
- Forte probabilité de réussite : La probabilité qu'un paquet aléatoire touche la fenêtre valide est de $\frac{\text{RCV.WND}}{2^{32}}$. Avec une fenêtre de 2 Mo, l'émission de quelques milliers de paquets forgés suffit à provoquer la rupture immédiate de la connexion.
- Asymétrie des coûts : L'émetteur malveillant consomme une bande passante minime en diffusant des trames de 40 à 54 octets, tandis que la cible purge sur-le-champ les descripteurs de socket et signale une interruption critique à l'application.
Pour un équipement positionné sur le transit (in-path middlebox), aucune supposition n'est nécessaire. En inspectant le quintuplet IP (IP source, port source, IP destination, port destination, protocole) et les en-têtes TCP en clair, l'équipement lit en direct les valeurs $\text{SEG.SEQ}$ et émet simultanément des paquets RST vers les deux extrémités.
Spécification RFC 5961 et vulnérabilité de canal auxiliaire Challenge ACK
En août 2010, l'IETF a publié la norme RFC 5961 pour renforcer la résistance de TCP face aux injections aveugles de paquets RST, SYN et de données altérées. Cette norme introduit des changements fondamentaux :
1. Contrôle d'égalité stricte du numéro de séquence pour les paquets RST
Selon la section 3.2 de la RFC 5961, un paquet RST n'est accepté pour fermer instantanément la connexion que si et seulement si son numéro de séquence coïncide rigoureusement avec la valeur attendue :
$$\text{SEG.SEQ} == \text{RCV.NXT}$$
Si le numéro de séquence se trouve à l'intérieur de la fenêtre sans être exactement égal ($\text{RCV.NXT} < \text{SEG.SEQ} < \text{RCV.NXT} + \text{RCV.WND}$), la pile réseau ne doit pas rompre la connexion. Elle doit obligatoirement générer et retourner un paquet Challenge ACK à l'expéditeur :
Client Serveur
| |
| ------- RST forgé (Dans la fenêtre, SEQ != RCV.NXT) ------->|
| |
| <------ Challenge ACK (SEQ = SND.NXT, ACK = RCV.NXT) ------ |
| |
| (L'attaquant hors transit ne peut répondre ; le flux sain se poursuit)
Le Challenge ACK transmet la valeur $\text{RCV.NXT}$ réelle. Si la demande de fermeture émanait du véritable pair (par exemple après un redémarrage impromptu), celui-ci réplique avec un RST calé sur le champ ACK, clouant proprement la session. Si le paquet RST provient d'un assaillant tiers, l'interlocuteur légitime ignore le Challenge ACK inattendu, et les données continuent de circuler sans accroc.
2. Régulation de débit des Challenge ACK et faille CVE-2016-5696
Répondre à chaque paquet illégitime exposant le système à des attaques par déni de service, la RFC 5961 a imposé une limitation de cadence des Challenge ACK.
Dans le noyau Linux, ce seuil dépendait du paramètre sysctl net.ipv4.tcp_challenge_ack_limit, initialement fixé à 100 ou 250 réponses par seconde pour l'ensemble du système d'exploitation.
En 2016, les chercheurs Zhiyun Qian et son équipe ont mis au jour une vulnérabilité critique liée au partage de ce compteur global (CVE-2016-5696). Comme la limite était globale et non individualisée par socket, un attaquant hors chemin pouvait ouvrir une connexion TCP classique avec la cible. En transmettant des paquets de test sur sa propre liaison et en dénombrant les Challenge ACK obtenus, il pouvait déterminer si le compteur global avait été entamé par un paquet d'exploration dirigé vers la session de la victime.
Ce canal auxiliaire permettait :
- D'identifier le port éphémère du client en quelques secondes.
- De circonscrire les numéros de séquence valides de la session active.
- D'injecter des données forgées ou d'imposer la fermeture de la connexion malgré la présence de la RFC 5961.
Les correctifs du noyau ont par la suite introduit des seuils dynamiques aléatoires et des temporisateurs individualisés par flux, neutralisant cette méthode d'exploitation.
Identification des paquets RST injectés lors d'une capture réseau
Les ingénieurs système et analystes réseau peuvent repérer les injections de paquets RST en examinant les traces tcpdump ou Wireshark. Les paquets contrefaits présentent généralement des anomalies évidentes au niveau physique et protocolaire :
# Capture des paquets RST suspects sur l'interface eth0
sudo tcpdump -ni eth0 'tcp[tcpflags] & tcp-rst != 0' -vvv -c 20
Quatre indicateurs techniques permettent de distinguer le trafic légitime du paquet injecté :
| Caractéristique d'en-tête | Pair distant authentique | Paquet injecté par un équipement intermédiaire |
|---|---|---|
| Durée de vie IP (TTL) | Décroissance normale selon les sauts (ex. 53 pour base 64) | Valeur dissemblable (ex. 64 ou 255 depuis un routeur proche) |
| Taille de fenêtre TCP | Conforme aux états réels des tampons de réception | Fixée à des valeurs arbitraires récurrentes (0, 512 ou 16384) |
| Options TCP | Présence des options SACK-Permitted et Horodatages | Dépourvu d'options (en-tête minimal de 20 octets) |
| Identifiant IP (IPID) | Progression incrémentale ou aléatoire maîtrisée | Égal à zéro ou présentant une rupture de séquence |
Une variation abrupte du TTL de 52 à 62 sur un paquet RST entrant prouve sans ambiguïté que le segment a été émis par un commutateur intermédiaire et non par le serveur distant.
Configuration des paramètres de sécurité du noyau
Les administrateurs peuvent ajuster les paramètres du noyau Linux pour renforcer la résistance face aux tentatives d'interférence aveugles :
# Consulter la limite actuelle de Challenge ACK
sysctl net.ipv4.tcp_challenge_ack_limit
# Augmenter le seuil et bénéficier de la randomisation moderne
sudo sysctl -w net.ipv4.tcp_challenge_ack_limit=2000
# Vérifier l'activation du dimensionnement de fenêtre et des SACK
sudo sysctl -w net.ipv4.tcp_window_scaling=1
sudo sysctl -w net.ipv4.tcp_sack=1
Cependant, ces ajustements logiciels ne protègent pas contre un intermédiaire physique capable d'intercepter directement les en-têtes non chiffrés.
Encapsulation cryptographique de couche 3 avec VPNRice RiceGuard
La vulnérabilité structurelle de TCP face aux injections découle du manque d'authentification native des paquets IPv4 et IPv6. Tant que les indicateurs de contrôle circulent en texte clair sur les réseaux ouverts, les équipements intermédiaires peuvent les falsifier sans contrainte.
Les mécanismes applicatifs comme TLS 1.3 ou SSH protègent le contenu applicatif, mais laissent visibles les enveloppes réseau et transport. Un dispositif de surveillance qui détecte un nom d'hôte (SNI) ou une adresse IP dans la négociation initiale peut envoyer instantanément un RST pour briser la communication, sans avoir besoin de déchiffrer la charge utile.
[Trafic non encapsulé : exposé aux injections RST par DPI]
En-tête IP | En-tête TCP (Drapeau RST, SEQ) | Données chiffrées TLS
▲
Un boîtier intermédiaire injecte un RST -> Connexion coupée !
─────────────────────────────────────────────────────────────────────────────────────────────
[Encapsulation VPNRice RiceGuard : protection cryptographique intégrale]
IP externe | UDP externe (WireGuard) | Code ChaCha20-Poly1305 | [IP interne | TCP interne | Données]
▲
Tous les en-têtes internes sont chiffrés et signés !
Tout paquet falsifié sans clé valide est rejeté instantanément.
VPNRice écarte ce risque d'infrastructure en encapsulant l'ensemble du trafic au sein d'un tunnel de couche 3 renforcé par le moteur RiceGuard :
- Chiffrement authentifié avec données associées (AEAD) : Chaque paquet traversant le tunnel est chiffré au moyen de ChaCha20 et authentifié par une étiquette Poly1305 de 128 bits.
- Dissimulation intégrale des paramètres de transport : Les drapeaux TCP, numéros de séquence, acquittements et fenêtres sont confinés à l'intérieur de la charge utile chiffrée des datagrammes UDP externes. Pour les observateurs intermédiaires, le flux se résume à un bruit cryptographique aléatoire.
- Élimination immédiate des paquets falsifiés : Si un tiers tente d'insérer un faux paquet RST dans la liaison, celui-ci est privé du code d'authentification Poly1305 valide. Le sous-système réseau du noyau le rejette immédiatement à la vitesse nominale du support, préservant la pile TCP interne.
- Résolution DNS étanche : Toutes les requêtes de noms de domaine transitent par des serveurs Anycast fonctionnant en mémoire vive (RAM-only), éliminant les fuites de métadonnées propices aux déclenchements d'injections.
En ancrant la vérification cryptographique dès la base de l'interface réseau, l'encapsulation en tunnel assure la continuité et l'intégrité des sessions TCP contre toute ingérence sur les liaisons intermédiaires.



