TLS 1.3, ESNI, DoH, interception... ce n'est pas si compliquĂ© đ

â ïž Le blog a Ă©tĂ© dĂ©placĂ© vers le site Patrowl, vous serez redirigĂ© automatiquement dans 3 secondes, sinon cliquez sur ce lien : https://patrowl.io/tls-1-3-esni-doh-interception-ce-nest-pas-si-complique-đ/
đ Vous y retrouverez toutes les nouvelles publications
Bien que finalement peu nouveau, je profite des vacances pour aborder un sujet souvent mal compris : TLS 1.3.
Avec NoLimitSecu, nous avons enregistrĂ© un Ă©pisode l'annĂ©e passĂ©e (https://www.nolimitsecu.fr/tls-1-3/) mais je trouve quâil manque quelques Ă©lĂ©ments que vous trouverez dĂ©taillĂ©s ci-dessous.
â ïž C'est un peu hors sujet, mais pensez Ă la dĂ©prĂ©ciation de TLS 1.0 et 1.1 par la quasi totalitĂ© des acteurs du web entre l'Ă©tĂ© et l'automne 2020.
SSL/TLS
Le sujet Ă dĂ©jĂ Ă©tĂ© traitĂ© maintes fois : ce sont les noms des protocoles de chiffrement les plus utilisĂ©s et servant en particulier Ă chiffrer les Ă©changes web (HTTP). SSL (Secure Sockets Layers) Ă©tant lâancienne version et TLS (Transport Layer Security) la nouvelle.
Lors de la connexion dâun client (navigateur) Ă un site web (www.leroymerlin.fr , www.bricoprive.comâŠ. Oui, je fais des travaux đ), si l'accĂšs n'est pas dĂ©jĂ chiffrĂ©, en gĂ©nĂ©ral, une redirection est effectuĂ©e vers la version chiffrĂ©e du site car Ă terme, les navigateurs ne tolĂ©reront plus que les sites chiffrĂ©s.
Pour faire trÚs trÚs simple, SSL et TLS proposent surtout deux fonctionnalités :
- Prouver l'identitĂ© d'un service (site web, service mail, API...) avec un mĂ©canisme de certificats. Le serveur envoie au client un certificat signĂ© par une autoritĂ© de certification de confiance et lâappareil du client est capable d'en vĂ©rifier lâauthenticitĂ© ;
- Chiffrer les échanges grùce à différentes suites cryptographiques symétriques comme le standard américain AES (et des mécanismes d'échange de clefs que je ne détaillerai pas ici).
SSL est bourrĂ© de failles et nâest donc plus recommandĂ©. De leur cĂŽtĂ©, les premiĂšres versions de TLS sont Ă©galement vulnĂ©rables Ă diverses attaques et il est plutĂŽt recommandĂ© dâutiliser au minimum TLS 1.2.
Pour les détails, je vous renvoie vers "[Sécurité] Fin annoncée de TLS 1.0 et TLS 1.1".
Server Name Indication / SNI et TLS
Par le passĂ©, il nâĂ©tait pas possible de fournir plusieurs services diffĂ©rents fonctionnant avec SSL sur une mĂȘme adresse IP, tout du moins, pas sur le mĂȘme port. Sur lâadresse IP 1.2.3.4 et le port 443 (port par dĂ©faut de HTTPS), il nâĂ©tait par exemple pas possible dâhĂ©berger un site web chiffrĂ© https://www.machin.com et un VPN SSL https://accesdistant.machin.com.
En effet, lors de la négociation du chiffrement SSL, le client :
- RĂ©solvait lâadresse IP du serveur Ă partir de son nom de domaine (www.machin.com   rĂ©sous d'adresse IP 1.2.3.4)
- Se connectait Ă lâadresse IP du serveur (sur le port 443 mais passons ce dĂ©tail)
- Et recevait en retour le certificat signé contenant, entre autres, un champ "Common Name / CN" avec le nom du serveur (www.machine.com) et permettant de prouver son identité.
Le problĂšme Ă©tait que le serveur nâavait pas moyen de connaĂźtre le nom que cherchait Ă atteindre le client (www.machine.com) et ne pouvait y associer quâun seul certificat, donc un seul nom de domaine, donc un seul service (dans les faits câest en partie faux car certains outils comme OpenVPN permettaient dâhĂ©berger plusieurs services mais ce nâest pas le sujet, la dĂ©tection se faisant aprĂšs la nĂ©gociation SSL/TLS).
Nous Ă©tions alors obligĂ©s de dĂ©dier une IP par service (car il nâĂ©tait pas envisageable dâutiliser un autre port que le 443).
Une solution acceptable consistait Ă utiliser un certificat avec un nom principal (www.machine.com) et contenant aussi un champ "Subject Alternative Names / SAN". Dans ce champ Ă©taient mis les noms des autres services (truc.machin.com, bidule.machin.com...). Mais cette solution ne permettait pas un passage Ă lâĂ©chelle ni d'ĂȘtre dynamique (un certificat est signĂ© pour une longue durĂ©e et devoir en gĂ©nĂ©rer un nouveau, dĂšs que lâon doit ajouter ou supprimer un service, nâest pas pratique).
Le problĂšme a Ă©tĂ© rapidement corrigĂ© avec la fonctionnalitĂ© « Server Name Indication / SNI », extension du protocole TLS datant de 2003 et permettant au client de spĂ©cifier dans sa requĂȘte le nom de domaine du service Ă joindre. Pour les courageux, je vous recommande la lecture de la RFC 3546 https://www.ietf.org/rfc/rfc3546.txt.
Une analogie pourrait ĂȘtre la suivante :
- Avant, les postiers nâavaient que lâadresse et pas de nom. Il yâavait quâun seul destinataire possible par adresse postale ;
- Le SAN revient Ă avoir une conciergerie qui dispose dâune liste des noms des habitants Ă une adresse postale donnĂ©es et qui rĂ©cupĂšre le courrier de la main du postier ;
- Le SNI Ă©quivaudrait Ă ce que le postier dispose enfin du nom et que chaque habitant puisse lui-mĂȘme gĂ©rer son nom sur sa boite aux lettres.
Depuis, le champ SAN a tout simplement remplacé le champ CN qui n'est supporté que par rétrocompatibilité (https://groups.google.com/a/chromium.org/forum/#!msg/security-dev/IGT2fLJrAeo/csf_1Rh1AwAJ)
Voici un schĂ©ma que jâai repris de CloudFlare :

A prĂ©sent, la fonctionnalitĂ© est largement utilisĂ©e, en particulier par les fournisseurs de Cloud, de services SaaS et surtout les CDN (Content Delivery Network comme Cloud Flare, Akamai, CD Network, CloudFrontâŠ) qui hĂ©bergent des centaines de services (sites) sur des bataillons de serveurs identiques (ou presque).
Encrypt-then-MAC, MAC-then-Encrypt, Je-comprends-riennnnnnn...
En gĂ©nĂ©ral, lors dâĂ©changes de messages chiffrĂ©s, afin de protĂ©ger lâintĂ©gritĂ© du message (quâil nâa pas Ă©tĂ© modifiĂ©), le message chiffrĂ© est accompagnĂ© de donnĂ©es permettant de lâauthentifier. Il ne sâagit pas ici de lâauthentification au sens dâun utilisateur (mot de passe, authentification forteâŠ) mais dâauthentifier le message, câest-Ă -dire de prouver quâil nâa pas Ă©tĂ© modifiĂ©, que son intĂ©gritĂ© nâa pas Ă©tĂ© altĂ©rĂ©e.
En gĂ©nĂ©ral (ça fait 2 fois, peut-on dire « en gĂ©nĂ©raux » ?đ ), il sâagit dâun condensat gĂ©nĂ©rĂ© Ă partir du message (chiffrĂ© ou pas, nous verrons cela aprĂšs), de donnĂ©es techniques et parfois de donnĂ©es alĂ©atoires afin de rendre impossible le rejeu (« Nonce » en anglais ou parfois notĂ© IV pour « InitializationVector»).
Le terme employé est « MAC » pour Message Authentication Code.
Il existe alors plusieurs moyen de rĂ©aliser ce traitement dâauthentification (c'est dĂ©taillĂ© juste aprĂšs):
- Je ne fais rien đ ;
- Je génÚre le condensat du message en clair, puis je chiffre le tout : MAC-then-Encrypt  / Authenticate then Encrypt / MtE
- Je génÚre le condensat du message en clair, chiffre le message et envoie les deux (message chiffré + condensat) : Encrypt-and-MAC / Encrypt and Authenticate / E&M
- Je chiffre mon message, génÚre son condensat et envoie les deux (message chiffré + condensat du chiffré) : Encrypt-then-MAC / Encrypt then Authenticate / EtM
Voici les exemples les plus communément cités :
- IPSec fait Encrypt-then-MAC
- SSL (et non pas TLS) fait MAC-then-Encrypt
- SSH fait Encrypt-and-MAC
Je ne fais rien
Je ne vais pas mâattarder sur le sujet, câest le pire des cas car les messages peuvent ĂȘtre modifiĂ©s et/ou rejouĂ©s, sans possibilitĂ© de le savoir, câest de la merde đ : https://www.youtube.com/watch?v=PuCRGsC9XhU
MAC-then-Encrypt
Supposons un message en clair « msg » (ou Plaintext) et un nombre aléatoire « random » (ou Nonce).
MAC-then-Encryption revient à envoyer (attention aux parenthÚses) : Encrypt(msg concaténé avec Hash(random + msg))
Je trouve les schĂ©mas de Wikipedia perturbant du fait de lâutilisation confusante de Key1 et Key2 mais cela permet dâillustrer :

Cela permet dâassurer lâintĂ©gritĂ© du texte en clair, mais pas de celle du chiffrĂ©. Sans dĂ©chiffrer, il nâest pas possible de savoir si le message a Ă©tĂ© modifiĂ©.
Ce mode est susceptible dâĂȘtre vulnĂ©rable Ă plusieurs attaques http://cseweb.ucsd.edu/~mihir/papers/oem.htmlet https://eprint.iacr.org/2001/045.
Encrypt-and-MAC
Encrypt-and-MAC revient à envoyer :  Encrypt(msg) concaténé avec Hash(random + msg)

LâintĂ©gritĂ© du texte chiffrĂ© nâest pas assurĂ©e, ce qui permet de lancer des attaques en choisissant le chiffrĂ©. Par contre, lâintĂ©gritĂ© du texte clair est assurĂ©e, mais il est nĂ©cessaire de dĂ©chiffrer, ce qui peut gĂ©nĂ©rer des erreurs et ĂȘtre exploitĂ©.
Enfin, suivant les implĂ©mentations, si dans les donnĂ©es « random » il nây a pas de compteur, il est possible de rĂ©aliser des attaques en clair connu sur le condensat.
Encrypt-then-MAC
Encrypt-then-MAC revient à envoyer :  Encrypt(msg) concaténé avec Hash(random + Encrypt(msg))

Ce mode permet dâen garantir lâintĂ©gritĂ© du texte chiffrĂ© ainsi mais si lâalgorithme de condensat est cassĂ© ou affaibli, il devient alors possible de rĂ©aliser des attaques sur « random » de type « tampering » (que je ne sais pas traduire simplement en français, en trĂšs simplifiĂ©, il sâagit de modifier le contenu afin de tenter de retrouver la clef de chiffrement).
Cela reste le mode le plus robuste Ă ce jour.
TLS 1.3
La derniĂšre version sĂ»re de TLS Ă©tant la 1.2, sans rentrer dans les dĂ©tails, il serait aisĂ© de croise que TLS 1.3 nâest quâune simple Ă©volution alors quâil sâagit en fait dâune rĂ©elle rupture et il aurait Ă©tĂ© prĂ©fĂ©rable de lâappeler TLS 2.0 mais le nommage est quelque chose de compliquĂ© (cf. la vidĂ©o Ă la fin, Ă 38:54).
Cette version apporte plusieurs changements notables :
- Meilleure vitesse lors de la nĂ©gociation, en rĂ©duisant les allers-retours entre le client et le serveur Ă un seul Ă©changes (contre deux prĂ©cĂ©demment) nommĂ©s « RTT   » (Round Trip Time Resumption   pour aller/retour et oĂč est le dernier R me demanderez-vous ? Bonne question !). Si le client s'est dĂ©jĂ connectĂ© au serveur, alors nous sommes dans un cas d'optimisation nommĂ© "0-RTT" (zĂ©ro aller/retour) permettant de reprendre une connexion passĂ©e;
- DĂ©sactivation de toutes les suites cryptographiques faibles   ou Ă risque, encore supportĂ©es par TLS 1.2. Avec TLS 1.3, vous ĂȘtes obligĂ© d'utiliser des algorithmes forts, que ce soit pour le chiffrement, les condensats (hash) ou les protocoles de chiffrements bloc par bloc ;
- Fin des clefs statiques lors des échanges de clefs par RSA  et Diffie-Hellman. A présent, le "Forward   Secrecy" est obligatoire, c'est à dire que les clefs changent tout au long des échanges et qu'il n'est plus possible d'enregistrer le trafic, trouver la clef et déchiffrer de trafic aprÚs coup;
- Des alternatives cryptographiques aux recommandations du NIST et de la NSA, apportant plus de confiance. Ceci grùce/à cause de Dual_EC_DRBG, l'algorithme de génération de nombres pseudos aléatoire, compromis par la NSA, normalisé dans FIPS 140-2 et diffusé trÚs largement (cf. "[Sécurité] NSA et PRNG", "[FUN] La backdoor de la NSA dans OpenSSL n'a jamais marché ( FIPS 140-2 )", "[Crypto] Le NIST supprime Dual EC DRBG NSA) de son guide", "[Sécurité] Dual EC DRBG toute l'histoire / NSA"). La courbe elliptique 25519 est supportée et présente une alternative libre aux courbes du NIST et de la NSA;
- De la mĂȘme maniĂšre, l'algorithme   de chiffrement symĂ©trique libre ChaCha20 et l'asymĂ©trique EdDSA sont supportĂ©s, pour fournir des alternatives Ă deux du NIST et de la NSA;
- Obligation dâauthentifier les messages   chiffrĂ©s avec en particulier 2 modes : GCM (Galois Counter Mode) et CCM (Counter with CBC-MAC). Pour les dĂ©tails, je vous renvoie vers le schĂ©ma de Wikipedia   qui est plutĂŽt bien fait : https://fr.wikipedia.org/wiki/Galois/Counter_Mode   ;
- Et bien d'autres ajustements : optimisations des échanges, réductions des quantités de données échangées en clair...
Une autre diffĂ©rence longtemps dĂ©battue est la possibilitĂ© de rĂ©aliser une interception des flux en les dĂ©chiffrant. C'est tout Ă fait possible avec TLS 1.3 et un protocole dĂ©diĂ© Ă cela a mĂȘme Ă©tĂ© ajoutĂ© : ETLS (Enterprise TLS), parfois appelĂ© "TLS interception for grostocards".
Ce protocole, ou option de TLS 1.3, utilise, entre autre, une clef Diffie-Hellman statique et autorise un tiers Ă rĂ©cupĂ©rer le trafic chiffrĂ© et une copie de cette clef. Pour faire simple, cela dĂ©sactive le "Forward Secrecy". Pour le faire encore plus simple : c'est de la crotte đ©đ.
Si vous souhaitez faire de l'interception SSL/TLS propre, normale, respectueuse de l'environnement et de lâintelligence humaine, il suffit de faire comme avant : faire passer tout le trafic par un proxy disposant d'une autoritĂ© de certification qui signe les certificats dynamiquement (tous les proxy savent faire, que ce soit du Bluecoat, de l'Ironport ou du Zscaler) et dĂ©ployer la partie publique de cette autoritĂ© de certification dans le magasin de certificat de vos postes de travail, serveurs (qui ne doivent pas accĂ©der directement Ă internet en mode fĂȘte du slip), vos smartphones... en tant qu'autoritĂ© racine de confiance.
Voici une documentation de Symantec sur l'interception "Ă©thique" đ : https://www.symantec.com/content/dam/symantec/docs/other-resources/responsibly-intercepting-tls-and-the-impact-of-tls-1.3-en.pdf
Par contre, vous ne pourrez plus mettre d'IDS/IPS sur votre infrastructure exposĂ©e Ă Internet avec une rĂ©plication du trafic (TAP) pour le dĂ©chiffrer sans ĂȘtre en coupure (sauf Ă utiliser eTLS mais je ne vous raconte pas l'usine Ă gaz). Franchement, l'intĂ©rĂȘt d'un IDS/IPS dans ce cas-lĂ me parait trĂšs limitĂ© si vous respectez bien les bonnes pratiques (mise Ă jour, cloisonnement, audits...) et si vous disposez par exemple d'un WAF ou Ă©quivalent portant le chiffrement (ou s'il est portĂ© avant, comme par exemple avec un CDN).
TLS 1.3 est donc un trÚs bon protocole mais présentait encore deux faiblesses :
- Pour se connecter Ă un service, il faut rĂ©soudre le nom de domaine, ce qui est rĂ©alisĂ© avec le protocole DNS, qui nâest pas chiffrĂ© (Non, DNSSEC ne permet pas de chiffrer DNS mais uniquement de sâassurer que lâintĂ©gritĂ© de la rĂ©ponse nâa pas Ă©tĂ© altĂ©rĂ©e);
- Le nom de domaine que lâon chercher Ă joindre, situĂ© dans le champ SNI de TLS nâest pas chiffrĂ©, car prĂ©sent dans la premiĂšre requĂȘte du client, avant lâĂ©tablissement dâun canal chiffrĂ©.
Cette seule information (le nom de domaine) suffit Ă rĂ©aliser de lâespionnage sur un rĂ©seau WiFi ou Ă lâĂ©chelle dâun Ă©tat, ainsi quâĂ censurer. Heureusement, ESNI permet de palier Ă cette problĂ©matique, que je vous dĂ©taille juste aprĂšs.
Trusted Recursive Resolver / TRR
Avant de parler de DNS over HTTPS, il faut juste introduire une notion finalement simples : les rĂ©solveurs DNS de confiance (les rĂ©solveurs qui mentent sont malheureusement frĂ©quents, sans forcĂ©ment parler de piratage). En gros, plusieurs Ă©diteurs de navigateur se sont associĂ©s avec des entreprises comme CloudFlarepour quâils crĂ©ent des services de rĂ©solution de noms de domaine avec la garantie quâils ne modifieront pas les rĂ©ponses. Ainsi le navigateur, qui prĂ©cĂ©demment utilisait le serveur DNS configurĂ© dans le systĂšme dâexploitation, peut sâen passer et interroger directement les services de rĂ©solution DNS de confiance.
Cela revient tout simplement Ă une liste blanche de serveurs de confiance qui font office de relai des requĂȘtes DNS. Ce sont eux ensuite qui relaient la requĂȘte DNS Ă qui de droit.
Dans les faits⊠il yâen a deux đ : https://mozilla.cloudflare-dns.com/dns-queryet https://dns.google.com/experimental  (https://wiki.mozilla.org/Trusted_Recursive_Resolver).
Je passe rapidement sur le fait que ces serveurs de confiance permettent la gĂ©olocalisation (partielle), utile aux CDN et, dans lâidĂ©al, câest le serveur le plus proche de lâutilisateur qui est utilisĂ© (avec un fonctionnement classique de type CDN).
DNS over HTTPS / DoH
Ce protocole, dĂ©crit par la RFC 8484, nĂ©cessite le support dâHTTP/2 et de ses flux (streams) afin de ne pas trop perdre en temps de rĂ©ponse.
Il sâagit dâune encapsulation de DNS dans de lâHTTP sur TLS. Câest donc bien le contenu dâune requĂȘte DNS classique qui est envoyĂ©e en HTTP, encodĂ©e en base64 dans le cas de lâemploi de requĂȘtes de type GET et sans encodage dans le cas de requĂȘtes POST.
Voici un outil en Perl (dĂ©solĂ©) faisant ce type de requĂȘte : https://github.com/bagder/dns2doh
Sinon, il yâa CURL (en version rĂ©cente) :
~# curl --doh-url https://dns-server.example.com
Vous me direz quâafin de pouvoir rĂ©aliser cette rĂ©solution de noms de domaine sur HTTPS, il faut tout dâabord rĂ©aliser une requĂȘte DNS classique afin dâobtenir lâadresse IP correspondant au serveur TRR, ce qui nâest pas chiffrĂ© et reviendrait au problĂšme de lâĆuf et de la poule mais il ne sâagit finalement que de la rĂ©solution du serveur DNS, ce qui ne laisse pas fuiter dâinformation sur vos requĂȘtes DNS rĂ©elles. Pour avoir une solution parfaite, il faudrait mettre en dur dans le code les adresses IP des serveurs ce qui semble infaisable.
Encrypted Server Name Indication / ESNI
Pour tout problĂšme, il existe une solution, câest donc Ă nouveau une extension de TLS qui a rĂ©solu le problĂšme des noms de domaine en clair lors de la connexion Ă un service : Encrypted Server Name Indication.
L'hĂ©bergeur ou l'entreprise qui souhaite utiliser ESNI doit disposer d'un enregistrement DNS contenant une structure de donnĂ©es avec en particulier une clef publique. De cette clef publique est dĂ©rivĂ©e une clef symĂ©trique servant Ă chiffrer le nom de domaine dans la requĂȘte.
A noter que ce potentiel futur standard est encore à l'état de brouillon :  https://datatracker.ietf.org/doc/draft-ietf-tls-esni/?include_text=1
Voici par exemple l'enregistrement DNS pour CloudFlare (la structure de données en rouge est encore en base64) :
~# dig TXT _esni.cloudflare.org +short
"/wH7nPYtACQAHQAgGFV9e448B0Nkg0dLwKX3cMwHMcJ4PX29THIg/kguXXEAAhMBAQQAAAAAXWlIAAAAAABdcTEAAAA="
Pour les détails, j'ai trouvé peu de codes sources détaillant le découpage de la structure, en voici un exemple en python : https://gist.githubusercontent.com/mosajjal/c088d03225287115a2e1fffef82ed25b/raw/fc37b51ac4067975a1c7e70dc0fb61a5781b078b/esni_creator.py
Ătant donnĂ© que le but est de dissimuler le nom du site visitĂ©, il est fortement recommandĂ© d'utiliser une clef pour de nombreux services et non pas une par service. Vous l'aurez compris, cette fonctionnalitĂ© est surtout utile et prĂŽnĂ©e par les gros hĂ©bergeurs et CDN comme CloudFront. Voici d'ailleurs un article de CloudFlare sur le sujet : https://blog.cloudflare.com/esni/
TRR, DoH, ESNI... Tout ceci complexifie grandement la cinĂ©matique de connexion Ă un site web et repose sur peu dâacteurs, mais il est heureusement toujours possible de fonctionner avec lâancien modĂšle đ.
0-RTT et le rejeu de paquet
Du fait de l'optimisation de l'échange TLS, il est possible de rejouer le premier paquet TLS envoyé, à condition que l'attaquant soit en capacité d'intercepté le trafic (WiFi...) :
- CĂŽtĂ© client, le navigateur va signaler une erreur rĂ©seau, transparente pour l'utilisateur car gĂ©rĂ©e par son navigateur qui rejouera la requĂȘte;
- CĂŽtĂ© serveur, cette requĂȘte spĂ©cifique sera vue deux fois.
Dans les faits, il est possible de rejouer n'importe quel paquet TLS : https://vnhacker.blogspot.com/2015/12/bad-life-advice-never-give-up-replay.html
Les risques sont limitĂ©s car les cas d'exploitation sont trĂšs rares et la plupart des applications web ajoutent des identifiants uniques non rejouable pour les requĂȘtes sensibles comme les virements ou paiements.
Le risque n'Ă©tant pas nul, certains CDN comme CloudFlare ne rĂ©pondent qu'Ă certaines requĂȘtes 0-RTT comme les GET sans paramĂštre et ajoutent un entĂȘte HTTP spĂ©cifique : "Cf-0rtt-Unique: valeur-unique-liant-la-clef-de-session-et-la-nĂ©go-tls". Par contre, pour les autres paquets, rien đ±.
Conclusion
Vous l'aurez compris, TLS 1.3 vient corriger de nombreuses faiblesses des versions prĂ©cĂ©dentes et marque un changement important avec l'abandon d'une rĂ©trocompatibilitĂ© devenue gĂȘnante.
Dans l'idéal, il faudrait autoriser uniquement TLS 1.3 sur tous vos services mais afin d'éviter de bloquer certains clients ou outils non compatibles, il est préférable de continuer à autoriser TLS 1.2, voire 1.1 dans certains cas.
Si vous disposez de 47 minutes, je vous invite à regarder cette présentation en anglais à la conférence SSTIC de 2017 : https://www.sstic.org/2017/presentation/2017_invite_2/ et les slides https://lab.dsst.io/slides/33c3/slides/8348.pdf