Plateforme
29 juillet 2020 Bonnes pratiques Vlad
TLS 1.3, ESNI, DoH, interception... it's not that complicated đ
Ce contenu vous plait
Partagez-le sur les réseaux
TLS 1.3
Bien que ce sujet ne soit finalement pas trĂšs nouveau, je profite des vacances pour parler dâun sujet souvent mal compris : TLS 1.3.
Avec NoLimitSecu, nous avions enregistré un épisode l'année derniÚre (https://www.nolimitsecu.fr/tls-1-3/), mais je trouve qu'il manque certains points que vous trouverez détaillés ci-dessous.
â ïž Petite parenthĂšse : pensez Ă la dĂ©prĂ©ciation de TLS 1.0 et 1.1 par presque tous les acteurs du web entre l'Ă©tĂ© et l'automne 2020.
SSL/TLS
Le sujet a déjà été traité de nombreuses fois : ce sont les noms des protocoles de chiffrement les plus utilisés pour sécuriser les échanges web (HTTP).
SSL (Secure Sockets Layer) est lâancienne version, tandis que TLS (Transport Layer Security) est la version plus rĂ©cente.
Lorsquâun client (navigateur) se connecte Ă un site web (par exemple : www.leroymerlin.fr ou www.bricoprive.com... oui, je fais des travaux đ), si lâaccĂšs nâest pas dĂ©jĂ chiffrĂ©, une redirection est gĂ©nĂ©ralement faite vers la version chiffrĂ©e du site, car Ă terme, les navigateurs nâaccepteront que les sites chiffrĂ©s.
TrÚs simplement, SSL et TLS offrent deux fonctionnalités principales :
Prouver lâidentitĂ© dâun service (site web, service mail, APIâŠ) grĂące Ă un mĂ©canisme de certificat. Le serveur envoie au client un certificat signĂ© par une autoritĂ© de certification de confiance, que le client peut vĂ©rifier ;
Chiffrer les échanges grùce à différentes suites cryptographiques symétriques comme le standard américain AES (et des mécanismes d'échange de clés que nous ne détaillerons pas ici).
SSL comporte de nombreuses failles et nâest donc plus recommandĂ©. Les premiĂšres versions de TLS sont Ă©galement vulnĂ©rables Ă diverses attaques. Il est donc recommandĂ© dâutiliser au minimum TLS 1.2.
Pour plus de détails, consultez « Fin de vie de TLS 1.0 et TLS 1.1 ».
Dans le passĂ©, il n'Ă©tait pas possible de proposer plusieurs services diffĂ©rents activĂ©s avec SSL sur une mĂȘme adresse IP, du moins pas sur le mĂȘme port. Par exemple, sur l'adresse IP 1.2.3.4 et le port 443 (port par dĂ©faut pour HTTPS), il n'Ă©tait pas possible d'hĂ©berger Ă la fois un site web chiffrĂ© https://www.something.com et un VPN SSL https://distantaccess.something.com.
En effet, lors de la négociation du chiffrement SSL, le processus était le suivant :
Résolution de l'adresse IP du serveur à partir de son nom de domaine (https://www.something.com se résolvant en l'adresse IP 1.2.3.4).
Connexion à l'adresse IP du serveur (sur le port 443, mais ignorons ce détail).
Réception en retour du certificat signé contenant, entre autres, un champ "Nom Commun / CN" avec le nom du serveur (https://www.something.com) pour prouver son identité.
Le problÚme était que le serveur n'avait aucun moyen de savoir quel nom le client essayait d'atteindre (https://www.something.com) et ne pouvait associer qu'un seul certificat, donc un seul nom de domaine, et par conséquent un seul service. (En réalité, c'est partiellement 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 contraints de dédier une adresse IP par service (car il n'était pas possible d'utiliser un autre port que le 443).
Une solution acceptable consistait Ă utiliser un certificat avec un nom principal (https://www.something.com) et contenant Ă©galement un champ "Subject Alternative Names / SAN". Dans ce champ, on ajoutait les noms des autres services (thing.thing.com, thing.thing.com, etc.). Cependant, cette solution ne permettait ni de s'adapter Ă grande Ă©chelle ni d'ĂȘtre dynamique (un certificat Ă©tant signĂ© pour une longue pĂ©riode, devoir en gĂ©nĂ©rer un nouveau dĂšs qu'on devait ajouter ou supprimer un service n'Ă©tait pas pratique).
Le problĂšme a Ă©tĂ© rapidement corrigĂ© grĂące Ă la fonctionnalitĂ© "Server Name Indication / SNI", une extension du protocole TLS datant de 2003 qui permet au client de spĂ©cifier dans sa requĂȘte le nom de domaine du service Ă atteindre. Pour les courageux, je recommande la lecture de la RFC 3546 : https://www.ietf.org/rfc/rfc3546.txt.
Une analogie pourrait ĂȘtre la suivante :
Avant, les facteurs avaient uniquement l'adresse et pas le nom. Il n'y avait qu'un destinataire possible par adresse postale.
Le SAN est comme un service de conciergerie ayant une liste de noms pour une adresse donnée et collectant le courrier pour les habitants.
Le SNI équivaut à ce que le facteur ait enfin le nom et que chaque habitant puisse gérer son propre nom sur sa boßte aux lettres.
Depuis, le champ SAN a simplement remplacé le champ CN, ce dernier n'étant plus pris en charge que par compatibilité rétroactive (source).
Voici un schéma tiré de CloudFlare pour illustrer cela :
De nos jours, cette fonctionnalité est largement utilisée, notamment par les fournisseurs de Cloud, les fournisseurs de SaaS et surtout les CDN (Content Delivery Network comme CloudFlare, 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-riennnnnn...
De nos jours, les messages chiffrĂ©s sont souvent accompagnĂ©s de donnĂ©es permettant de garantir leur intĂ©gritĂ©, c'est-Ă -dire d'assurer qu'ils n'ont pas Ă©tĂ© modifiĂ©s. Cela ne concerne pas l'authentification au sens utilisateur (mot de passe, authentification forte...), mais plutĂŽt l'authentification du message en lui-mĂȘme. En d'autres termes, cela prouve que le message n'a pas Ă©tĂ© altĂ©rĂ© et que son intĂ©gritĂ© reste intacte.
Généralement
(oui, deux fois en deux phrases, mais pourquoi pas đ), cette authentification repose sur un condensat (ou "digest") gĂ©nĂ©rĂ© Ă partir du message (chiffrĂ© ou non), de donnĂ©es techniques, et parfois de donnĂ©es alĂ©atoires, pour Ă©viter les attaques de type rejouement (on parle de "Nonce" en anglais ou parfois de "IV" pour "Initialization Vector").
Le terme courant pour ce mécanisme est MAC (Message Authentication Code).
Il existe plusieurs façons de mettre en Ćuvre ce processus d'authentification, dĂ©taillĂ©es ci-dessous :
Ne rien faire đ
Générer le condensat du message en clair, puis chiffrer l'ensemble :
MAC-then-Encrypt / Authenticate then Encrypt / MtEGénérer le condensat du message en clair, chiffrer le message et envoyer les deux :
Encrypt-and-MAC / Encrypt and Authenticate / E&MChiffrer le message, générer son condensat et envoyer les deux :
Encrypt-then-MAC / Encrypt then Authenticate / EtM
Les approches les plus courantes :
IPSec : utilise Encrypt-then-MAC
SSL (pas TLS) : utilise MAC-then-Encrypt
SSH : utilise Encrypt-and-MAC
1. Ne rien faire
Cette approche consiste littĂ©ralement Ă ne rien faire, et c'est la pire des solutions. Dans ce cas, les messages peuvent ĂȘtre modifiĂ©s ou rejouĂ©s sans aucun moyen de le dĂ©tecter. Bref, c'est catastrophique đ. Petite vidĂ©o illustrative : https://www.youtube.com/watch?v=PuCRGsC9XhU
2. MAC-then-Encrypt
Prenons un message en clair nommé msg
(ou Plaintext) et un nombre aléatoire random
(ou Nonce).
Le processus de MAC-then-Encrypt consiste Ă envoyer :
Encrypt(msg concaténé avec Hash(random + msg))
Le schĂ©ma de Wikipedia peut prĂȘter Ă confusion avec l'usage de Key1
et Key2
, mais il aide Ă visualiser le concept :
(Insérez une image si nécessaire)
Cette mĂ©thode a Ă©tĂ© critiquĂ©e dans certains cas, car l'intĂ©gritĂ© peut ĂȘtre compromise si le chiffrement n'est pas bien conçu. On prĂ©fĂšre gĂ©nĂ©ralement des mĂ©thodes plus robustes comme Encrypt-then-MAC.
Souhaitez-vous approfondir chaque méthode ou explorer d'autres concepts liés à la sécurité des messages chiffrés�
Cela garantit l'intégrité du message en clair, mais pas celle du message chiffré. Sans déchiffrement, il est impossible de savoir si le message a été modifié.
Ce mode est vulnérable à plusieurs attaques :
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 manipulant le texte chiffrĂ©. En revanche, l'intĂ©gritĂ© du texte en clair est garantie, mais il est nĂ©cessaire de le dĂ©chiffrer, ce qui peut entraĂźner des erreurs et ĂȘtre exploitĂ©.
Enfin, selon l'implémentation, si les données "random" ne contiennent pas de compteur, il est possible de mener des attaques par texte 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 de garantir l'intégrité du texte chiffré, mais si l'algorithme de condensation est compromis ou affaibli, il devient possible de réaliser des attaques de type "tampering" (modification).
Cela reste néanmoins le mode le plus robuste à ce jour.
TLS 1.3
La derniĂšre version sĂ©curisĂ©e de TLS Ă©tant la 1.2, sans entrer dans les dĂ©tails, il serait facile de croire que TLS 1.3 nâest quâune simple Ă©volution, alors quâen rĂ©alitĂ©, il sâagit dâune vĂ©ritable rupture. Il aurait Ă©tĂ© prĂ©fĂ©rable de lâappeler TLS 2.0, mais la dĂ©nomination est un sujet complexe (voir 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 Ă©change (contre deux auparavant), appelĂ© "RTT" (Round Trip Time Resumption). Et oĂč est le dernier R, vous demandez-vous ? Bonne question ! Si le client s'est dĂ©jĂ connectĂ© au serveur, on est alors dans un cas d'optimisation appelĂ© "0-RTT" (zero round trip) permettant de reprendre une connexion antĂ©rieure ;
DĂ©sactivation de toutes les suites cryptographiques faibles ou risquĂ©es, 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 fonctions de hachage ou les protocoles de chiffrement par blocs ;
Fin des clĂ©s statiques dans les Ă©changes de clĂ©s RSA et Diffie-Hellman. La confidentialitĂ© persistante est dĂ©sormais obligatoire, câest-Ă -dire que les clĂ©s changent tout au long de lâĂ©change et il nâest plus possible dâenregistrer le trafic, de retrouver la clĂ© et de dĂ©chiffrer le trafic ensuite ;
Alternatives cryptographiques aux recommandations de NIST et NSA, offrant plus de confiance. Cela est dĂ» au DualECDRBG, lâalgorithme de gĂ©nĂ©ration de nombres pseudo-alĂ©atoires compromis par la NSA, standardisĂ© dans le FIPS 140-2 et largement distribuĂ© (voir "Security NSA and PRNG", "FUN NSA backdoor in OpenSSL never worked (FIPS 140-2)", "Crypto NIST removes Dual EC DRBG (NSA) from its guide", "Security Dual EC DRBG all history / NSA"). La courbe elliptique 25519 est prise en charge et prĂ©sente une alternative libre aux courbes NIST et NSA ;
De mĂȘme, l'algorithme de chiffrement symĂ©trique libre ChaCha20 et lâasymĂ©trique EdDSA sont supportĂ©s, afin de fournir des alternatives aux deux courbes de NIST et NSA ;
Exigence d'authentifier les messages chiffrés, avec en particulier 2 modes : GCM (Galois Counter Mode) et CCM (Counter with CBC-MAC). Pour plus de détails, je vous réfÚre au schéma de Wikipedia qui est plutÎt bien fait : https://en.wikipedia.org/wiki/Galois/Counter_Mode ;
Et bien d'autres ajustements : optimisations des Ă©changes, rĂ©duction de la quantitĂ© de donnĂ©es Ă©changĂ©es en clair... Une autre diffĂ©rence longuement dĂ©battue est la possibilitĂ© dâintercepter des flux en les dĂ©cryptant. Cela est tout Ă fait possible avec TLS 1.3, et un protocole dĂ©diĂ© a mĂȘme Ă©tĂ© ajoutĂ© : ETLS (Enterprise TLS), parfois appelĂ© "TLS interception for grostocards".
Ce protocole, ou option de TLS 1.3, utilise, entre autres, une clĂ© Diffie-Hellman statique et permet Ă une tierce partie de rĂ©cupĂ©rer le trafic chiffrĂ© et une copie de cette clĂ©. Pour simplifier, cela dĂ©sactive la confidentialitĂ© persistante. Pour rendre les choses encore plus simples : c'est de la m**** đ©đ.
Si vous voulez faire une interception SSL/TLS propre, normale, éco-responsable et intelligente pour l'homme, faites ce que vous faisiez avant : faites passer tout le trafic par un proxy avec une autorité de certification qui signe dynamiquement des certificats (tous les proxys savent faire cela, que ce soit Bluecoat, Ironport ou Zscaler) et déployez la partie publique de cette autorité de certification dans le magasin de certificats de vos stations de travail, serveurs (qui ne devraient pas accéder directement à Internet en mode "party"), vos smartphones... comme une autorité racine de confiance.
Voici un document 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
En revanche, vous ne pourrez pas mettre dâIDS/IPS sur votre infrastructure exposĂ©e Ă Internet avec une rĂ©plication du trafic (TAP) pour le dĂ©chiffrer sans ĂȘtre dans la coupure (sauf en utilisant eTLS mais je ne vous raconte pas la galĂšre). Franchement, lâintĂ©rĂȘt dâun IDS/IPS dans ce cas me semble trĂšs limitĂ© si vous respectez les bonnes pratiques (mise Ă jour, partitionnement, audits...) et si vous avez par exemple 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 il avait encore deux faiblesses :
Pour se connecter Ă un service, il faut rĂ©soudre le nom de domaine, ce qui se fait avec le protocole DNS, qui nâest pas chiffrĂ© (Non, DNSSEC ne chiffre pas le DNS mais garantit seulement que l'intĂ©gritĂ© de la rĂ©ponse n'a pas Ă©tĂ© altĂ©rĂ©e) ;
Le nom de domaine que l'on essaie dâatteindre, situĂ© dans le champ SNI de TLS, n'est pas chiffrĂ©, car il est prĂ©sent dans la premiĂšre requĂȘte du client, avant l'Ă©tablissement du canal chiffrĂ©. Cette information seule (le nom de domaine) suffit Ă espionner un rĂ©seau Wi-Fi ou Ă effectuer une censure Ă lâĂ©chelle dâun Ătat. Heureusement, ESNI permet de rĂ©soudre ce problĂšme, ce que je vais dĂ©tailler maintenant.
Trusted Recursive Resolver / TRR
Avant de parler de DNS over HTTPS, il faut introduire une notion simple : les résolveurs DNS de confiance (les résolveurs malveillants sont malheureusement fréquents, sans parler nécessairement de hacking). En gros, plusieurs éditeurs de navigateurs se sont associés avec des entreprises comme CloudFlare pour créer des services de résolution de noms de domaine avec la garantie qu'ils ne modifieront pas les réponses. Ainsi, le navigateur, qui utilisait auparavant le serveur DNS configuré dans le systÚme d'exploitation, peut se passer de celui-ci et interroger directement des services de résolution DNS de confiance.
Il sâagit simplement dâune liste blanche de serveurs de confiance qui agissent comme relais pour les requĂȘtes DNS. Ces serveurs relaient ensuite la demande DNS Ă la partie appropriĂ©e.
En fait... il y en a deux đ : https://mozilla.cloudflare-dns.com/dns-query et https://dns.google.com/experimental(https://wiki.mozilla.org/Trusted_Recursive_Resolver).
Je passe rapidement sur le fait que ces serveurs de confiance permettent (partiellement) la gĂ©olocalisation, utile pour les CDN, et, idĂ©alement, 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 dans le RFC 8484, nécessite la prise en charge de HTTP/2 et de ses flux afin de ne pas perdre trop de temps de réponse.
Il s'agit d'une encapsulation de DNS dans HTTP sur TLS. Câest donc le contenu d'une requĂȘte DNS classique qui est envoyĂ© dans HTTP, encodĂ© en base64 dans le cas des requĂȘtes GET et sans encodage dans le cas des requĂȘtes POST.
Voici un outil en Perl (dĂ©solĂ©) effectuant ce type de requĂȘte : https://github.com/bagder/dns2doh
Sinon, il y a CURL (dans les versions récentes) :
arduino
Copier le code
~# curl -doh-url https://dns-server.example.com
Vous me direz que, pour pouvoir effectuer cette rĂ©solution de nom de domaine sur HTTPS, vous devez d'abord effectuer une requĂȘte DNS classique pour obtenir l'adresse IP correspondant au serveur TRR, ce qui n'est pas chiffrĂ© et ressemblerait au problĂšme du "Ćuf et de la poule", mais au final, ce nâest que la rĂ©solution du serveur DNS, ce qui ne fuit aucune information sur vos vraies requĂȘtes DNS. Pour avoir une solution parfaite, il faudrait coder en dur les adresses IP des serveurs, ce qui semble infaisable.
Encrypted Server Name Indication / ESNI
Pour chaque problÚme, il existe une solution. Il s'agit donc encore une fois d'une extension de TLS qui a résolu le problÚme des noms de domaine en clair lors de la connexion à un service : l'Encrypted Server Name Indication.
LâhĂŽte ou lâentreprise souhaitant utiliser lâESNI doit possĂ©der un enregistrement DNS contenant une structure de donnĂ©es avec notamment une clĂ© publique. Ă partir de cette clĂ© publique est dĂ©rivĂ©e une clĂ© symĂ©trique utilisĂ©e pour chiffrer le nom de domaine dans la requĂȘte.
Notez que cette norme potentielle est encore en brouillon : https://datatracker.ietf.org/doc/draft-ietf-tls-esni/?include_text=1
Par exemple, voici l'enregistrement DNS pour CloudFlare (la structure de données en rouge est encore en base64) :
arduino
Copier le code
~# dig TXT _esni.cloudflare.org +short "/wH7nPYtACQAHQAgGFV9e448B0Nkg0dLwKX3cMwHMcJ4PX29THIg/kguXXEAAhMBAQAAAAAXWlIAAAAAABdcTEAAAA="
Pour plus de détails, j'ai trouvé peu de codes sources détaillant la décomposition de la structure, voici un exemple en Python : https://gist.githubusercontent.com/mosajjal/c088d03225287115a2e1fffef82ed25b/raw/fc37b51ac4067975a1c7e70dc0fb61a5781b078b/esni_creator.py
Puisque lâobjectif est de cacher le nom du site visitĂ©, il est fortement recommandĂ© dâutiliser une clĂ© pour de nombreux services et non une par service. Comme vous pouvez le constater, cette fonctionnalitĂ© est particuliĂšrement utile et dĂ©fendue par les grands hĂ©bergeurs et les CDN comme CloudFront. Voici un article de CloudFlare Ă ce sujet : https://blog.cloudflare.com/esni/
TRR, DoH, ESNI... Tout cela complique Ă©normĂ©ment la cinĂ©matique de connexion Ă un site Web et repose sur peu d'acteurs, mais heureusement, il est encore possible de travailler avec le modĂšle ancien đ.
0-RTT et replay de paquets
GrĂące Ă lâoptimisation de lâĂ©change TLS, il est possible de rejouer le premier paquet TLS envoyĂ©, Ă condition que l'attaquant soit capable d'intercepter le trafic (WiFi...) :
Du cĂŽtĂ© client, le navigateur signalera une erreur rĂ©seau, transparente pour l'utilisateur car elle est gĂ©rĂ©e par le navigateur, qui rejouera la requĂȘte ; Du cĂŽtĂ© serveur, cette requĂȘte spĂ©cifique sera vue deux fois. En fait, 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 qui ne peuvent pas ĂȘtre rejouĂ©s pour des requĂȘtes sensibles telles que des transferts ou des paiements.
Comme le risque nâest pas nul, certains CDN comme CloudFlare ne rĂ©pondent quâĂ certaines requĂȘtes 0-RTT telles que les GET sans paramĂštres et ajoutent un en-tĂȘte HTTP spĂ©cifique : "Cf-0rtt-Unique: value-unique-liant-and-session-key-and-nego-Tls". Pour les autres paquets, rien đ±.
Conclusion
TLS 1.3 corrige de nombreuses failles et marque un tournant en abandonnant la rĂ©trocompatibilitĂ© avec des mĂ©canismes obsolĂštes. IdĂ©alement, configurez vos services pour nâautoriser que TLS 1.3, tout en maintenant TLS 1.2 pour Ă©viter de bloquer certains outils ou clients.
Pour aller plus loin, regardez cette présentation (47 min) : SSTIC 2017.