Sécurité sérieuse : comment des fautes de frappe délibérées pourraient améliorer la sécurité DNS

Sécurité sérieuse : comment des fautes de frappe délibérées pourraient améliorer la sécurité DNS

Au fil des ans, nous avons code écrit ainsi que parlé sur Naked Security à plusieurs reprises sur l'épineux problème du DNS otage.

DNS, comme vous le savez probablement, est l'abréviation de Système de noms de domaines, et vous l'entendrez souvent décrit comme l'« annuaire téléphonique » ou le « répertoire géographique » d'Internet.

Si vous n'êtes pas familier avec le mot répertoire géographique, il fait référence à l'index au dos d'un atlas où vous recherchez, disons, à Monrovia, au Libéria dans une liste alphabétique pratique, et il dit quelque chose comme 184 - C4. Cela vous indique de passer directement à la page 184 et de suivre les lignes de la grille depuis la lettre C en haut de la carte et en face du numéro 4 sur la gauche. Là où les lignes se croisent, vous trouverez Monrovia.

Pour la plupart des utilisateurs, la plupart des recherches DNS contiennent un nom de serveur, demandant une réponse qui inclut ce que l'on appelle son enregistrement A ou son enregistrement AAAA.

(Les enregistrements A sont utilisés pour les numéros Internet IPv32 4 bits, tels que 203.0.113.42; Les enregistrements AAAA sont les réponses équivalentes pour les adresses IPv128 6 bits, telles que 2001:db8:15a:d0c::42 – dans cet article, nous n'utiliserons que les enregistrements A et les numéros IPv4, mais les mêmes problèmes de sécurité s'appliquent au processus de recherche dans les deux cas.)

Voici un exemple, où nous recherchons le nom de domaine imaginaire naksec.test via un serveur DNS spécialement créé pour suivre et vous renseigner sur le trafic DNS.

Nous avons utilisé l'outil Linux à l'ancienne dig, court pour domaine internet tâtonneur, pour générer une simple requête DNS (dig recherche par défaut les enregistrements A) pour le serveur que nous voulons :

$ creuser +noedns @127.42.42.254 naksec.test ;; SECTION DES QUESTIONS : ;naksec.test. DANS UN ;; SECTION DE RÉPONSE : NAKSEC.TEST. 5 IN A 203.0.113.42 ;; Temps de requête : 1 msec ;; SERVEUR : 127.42.42.254#53(127.42.42.254) (UDP) ;; QUAND : Lundi 23 janvier 14:38:42 GMT 2023 ;; TAILLE MSG reçu : 56

Voici comment notre serveur DNS a traité la requête, montrant un vidage hexadécimal de la requête entrante et la réponse réussie qui a été renvoyée :

---> Requête de 127.0.0.1:57708 à 127.42.42.254:53 ---> 00000000 62 4e 01 20 00 01 00 00 00 00 00 00 06 6e 61 6b |bN. .........nak| 00000010 73 65 63 04 74 65 73 74 00 00 01 00 01 |sec.test..... | Recherche DNS : enregistrement A pour naksec.test ==> A=203.0.113.42 <--- Réponse de 127.42.42.254:53 à 127.0.0.1:57708 <--- 00000000 62 4e 84 b0 00 01 00 01 00 00 00 00 06 6e 61 6b |bN...........nak| 00000010 73 65 63 04 74 65 73 74 00 00 01 00 01 06 4e 41 |sec.test......NA| 00000020 4b 53 45 43 04 54 45 53 54 00 00 01 00 01 00 00 |KSEC.TEST.......| 00000030 00 05 00 04 cb 00 71 2a |......q* |

Notez que, pour des raisons de performances, la plupart des requêtes DNS utilisent UDP, le protocole de datagramme utilisateur, qui fonctionne sur une base d'envoi et d'espoir : vous envoyez un paquet UDP sur le serveur avec lequel vous souhaitez parler, puis attendez de voir si une réponse revient.

Cela rend UDP beaucoup plus simple et plus rapide que son grand cousin TCP, le protocole de contrôle de transmission, qui, comme son nom l'indique, prend automatiquement en charge de nombreux détails qu'UDP ne prend pas en charge.

Notamment, TCP s'occupe de détecter les données perdues et de les redemander ; s'assurer que tous les blocs de données arrivent dans le bon ordre ; et fournir une connexion réseau unique qui, une fois configurée, peut être utilisée pour envoyer et recevoir en même temps.

UDP n'a pas le concept de « connexion », de sorte que les demandes et les réponses voyagent essentiellement de manière indépendante :

  • Une requête DNS arrive au serveur DNS dans un paquet UDP qui lui est propre.
  • Le serveur DNS conserve un enregistrement de quel ordinateur a envoyé ce paquet particulier.
  • Le serveur se met à trouver une réponse à renvoyer, ou décider qu'il n'y en a pas.
  • Le serveur envoie une réponse à l'expéditeur d'origine, à l'aide d'un second paquet UDP.

Au niveau du système d'exploitation ou du réseau, ces deux paquets UDP ci-dessus sont des transmissions indépendantes et autonomes - ils ne sont pas liés dans le cadre de la même connexion numérique.

C'est au serveur de se rappeler à quel client envoyer chaque réponse ; et c'est au client de déterminer quelles réponses se rapportent aux demandes qu'il a initialement envoyées.

Comment peux-tu être sûr?

À ce stade, en particulier en regardant la taille réduite de la requête DNS et de la réponse ci-dessus, vous vous demandez probablement : "Comment le client peut-il être sûr qu'il correspond à la bonne réponse, et non à celle qui a été brouillée en transit ou mal dirigée ? par erreur, soit par accident, soit à dessein ? »

Malheureusement, de nombreuses requêtes DNS, sinon la plupart (en particulier celles de serveur à serveur, lorsque le premier serveur auquel vous demandez ne connaît pas la réponse et doit en trouver un qui la connaît afin de formuler sa réponse) ne sont pas cryptées, ou autrement étiqueté avec n'importe quel type de code d'authentification cryptographique.

En fait, par défaut, les requêtes DNS incluent une seule « étiquette d'identification », qui est désignée dans la documentation du format de données DNS simplement comme ID.

Étonnamment, bien qu'ayant reçu de nombreuses mises à jour et suggestions d'améliorations au fil des ans, la RFC Internet officielle (demande pour des commentaires) document qui fait office de spécification DNS est toujours RFC 1035 (nous sommes actuellement dans les RFC au milieu des années 9000), datant de novembre 1987, il y a un peu plus de 35 ans !

À l'époque, la bande passante et la puissance de traitement étaient rares : les vitesses typiques du processeur étaient d'environ 10 MHz ; les ordinateurs de bureau avaient environ 1 Mo de RAM ; les vitesses d'accès à Internet, pour les organisations qui pouvaient se connecter du tout, étaient souvent de 56 kbits/sec ou 64 kbits/sec, partagées entre tous ; et 1200bits/sec était le choix abordable pour la connectivité personnelle via les modems commutés de l'époque.

C'est pourquoi les en-têtes de requête et de réponse DNS étaient - et sont toujours - écrasés dans un maigre 12 octets, dont la balise d'identification occupe les deux premiers, comme le mignon RFC 1035 Art ASCII précise:

 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+ --+--+--+--+--+--+--+ | identifiant | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QR| Code opération |AA|TC|RD|RA| Z | RCODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QDCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | COMPTE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | NSCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | COMPTE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Vous pouvez voir l'ID en action dans les vidages hexadécimaux illustrés ci-dessus, où les paquets de demande et de réponse commencent par les deux mêmes caractères. bN, qui correspondent à l'identifiant 16 bits 62 4e en hexagone.

En gros, ces 16 bits sont tout ce que le protocole DNS officiel fournit en termes d'"authentification" ou de "détection d'erreurs".

Intervenir par conjecture

Comme vous pouvez l'imaginer, compte tenu de la simplicité de bout en bout du trafic DNS normal, toute personne ayant un soi-disant boîtier de médiation or proxy d'analyse qui peut intercepter, examiner et modifier votre trafic réseau peut se mêler trivialement de votre trafic DNS.

Cela inclut le renvoi de réponses qui vous donnent délibérément des informations inexactes, telles que votre équipe informatique vous redirigeant vers des serveurs qu'elle sait être jonchés de logiciels malveillants.

Cela peut également inclure que votre FAI se conforme à la législation de votre pays qui exige que certains serveurs soient signalés comme inexistants, même s'ils sont actifs et fonctionnent correctement, car ils figurent sur une liste noire de contenus illégaux tels que du matériel pédopornographique.

Mais, à première vue, ce type de marquage d'ID DNS ultra-faible semble également le rendre trivial même pour les attaquants qui n'ont aucune visibilité sur votre trafic réseau pour envoyer de fausses réponses DNS à vos utilisateurs ou à vos serveurs…

… avec une chance de succès dangereusement élevée.

Après tout, si les attaquants savent que quelqu'un sur votre réseau aime visiter régulièrement naksec.test, ce serveur peut sembler être un endroit juteux pour implanter de fausses nouvelles, des mises à jour douteuses ou du code JavaScript malveillant.

Et si les attaquants ne parviennent pas à pirater le naksec.test serveur lui-même, que se passerait-il s'ils lançaient régulièrement et fréquemment des paquets UDP sur votre serveur DNS, en utilisant une étiquette d'identification inventée, qui prétendait répondre à la question, "Quel est l'enregistrement A pour naksec.test« ?

De cette façon, ils pourraient être en mesure de détourner la requête DNS, de fournir une fausse réponse et donc de détourner votre prochaine visite sur le site Web - en détournant essentiellement le site lui-même sans jamais avoir besoin d'attaquer le naksec.test serveur du tout.

Un peu de chance requis

Ils devraient avoir un peu de chance, bien sûr, bien qu'ils puissent essayer encore et encore d'augmenter leurs chances globales, étant donné qu'ils n'ont besoin de réussir qu'une seule fois, alors que vous devez obtenir une réponse DNS véridique à chaque fois.

Pour réussir, ils doivent envoyer leur réponse DNS non fiable :

  • Pendant une période où votre propre serveur ne connaissait pas déjà la réponse à la question. Les réponses DNS incluent un nombre 32 bits appelé TTL, abréviation de temps de vivre, qui indique combien de temps l'autre extrémité peut continuer à réutiliser la réponse. Si vous ou quelqu'un d'autre sur votre réseau ytour avez demandé naksec.test récemment, votre serveur DNS a peut-être la réponse dans son cache. Aucune autre recherche ne serait nécessaire, et il n'y aurait aucune demande sortante pour que les attaquants détournent.
  • Entre le moment où vous avez envoyé votre demande et la réponse officielle est revenue de l'extérieur. Même autrefois, les temps de recherche DNS dépassaient rarement quelques secondes. Aujourd'hui, ils sont mieux mesurés en millisecondes.
  • Avec le bon numéro dans ses 16 premiers bits. Vous pouvez adapter 65536 (216) différentes valeurs en 16 bits, les attaquants devraient donc être un peu chanceux. Mais avec les bandes passantes du réseau d'aujourd'hui, envoyer 65536 fausses réponses différentes à la fois, couvrant ainsi tous les numéros d'identification possibles, prend une infime fraction de seconde.

Heureusement, les serveurs DNS décents prennent aujourd'hui une mesure supplémentaire pour rendre le piratage difficile par défaut.

Du moins, c'est ce qu'ils font depuis 2008 environ, lorsque le feu Dan Kaminsky a souligné que de nombreux serveurs DNS à l'époque n'étaient pas seulement configurés pour écouter les requêtes entrantes sur un port UDP fixe (presque toujours le port 53, officiellement attribué au DNS)…

…mais aussi pour recevoir des réponses entrantes sur un port fixe, souvent aussi le port 53, ne serait-ce que pour créer une symétrie agréable dans le trafic.

La raison de l'utilisation d'un port fixe dans les deux sens était probablement à l'origine pour la simplicité de programmation. En écoutant toujours les réponses sur le même numéro de port UDP, vous n'avez pas besoin de savoir quels ports doivent être ouverts pour quelles réponses. Cela signifie que le gestionnaire de requêtes et les composants générateurs de réponses de votre logiciel DNS peuvent fonctionner indépendamment. L'écouteur de la demande n'a pas besoin de dire à l'expéditeur de la réponse : "Cette réponse particulière doit revenir sur un port spécial, pas celui habituel."

Utiliser les numéros de port comme ID supplémentaire

De nos jours, presque tous les serveurs DNS basés sur UDP écoutent sur le port 53, comme toujours, mais ils gardent une trace du soi-disant «port source» utilisé par le demandeur DNS, qu'il s'attend à choisir au hasard.

Les ports sources UDP, qui sont un peu comme un "numéro de poste" dans un central téléphonique de bureau à l'ancienne, sont destinés à être utilisés pour vous aider, ainsi que le réseau, à différencier les demandes les unes des autres.

Les ports de protocole Internet (TCP les utilise également) peuvent fonctionner de 1 à 65535, bien que la plupart des connexions sortantes n'utilisent que les ports source 1024-65535, car les numéros de port 1023 et inférieurs sont généralement réservés aux processus avec des privilèges système.

L'idée est que l'expéditeur de toute recherche DNS doit non seulement insérer un identifiant 16 bits vraiment aléatoire au début de chaque demande, mais également choisir un numéro de port source UDP vraiment aléatoire sur lequel il écoutera la réponse associée.

Cela ajoute un niveau supplémentaire de conjectures que les escrocs doivent ajouter à leur liste de "piratage de chance" ci-dessus, à savoir qu'ils doivent envoyer une fausse réponse qui coche toutes ces cases :

  • Il doit s'agir d'une requête qui a été posée récemment, généralement dans les dernières secondes.
  • Doit être une recherche qui n'était pas dans le cache du serveur local, ce qui signifie généralement que personne d'autre n'a posé de questions à ce sujet au cours des dernières minutes.
  • Doit avoir le bon numéro d'identification 16 bits au début du paquet de données.
  • Doit être envoyé au bon port de destination au numéro IP du serveur concerné.

Et autre chose

En fait, il y a encore une autre astuce que les demandeurs DNS peuvent faire, sans changer le protocole DNS sous-jacent, et donc (pour la plupart) sans rien casser.

Cette astuce, étonnamment, était premier proposé en 2008, dans un article glorieusement intitulé Résistance accrue à la falsification DNS grâce à l'encodage 0x20 bits : SÉCURITÉ via les requêtes LeET.

L'idée est étrangement simple et repose sur deux détails du protocole DNS :

  • Toutes les réponses DNS doivent inclure la section de requête d'origine au début. Les requêtes ont évidemment une section de réponse vide, mais les réponses doivent refléter la question d'origine, ce qui permet de s'assurer que les demandes et les réponses ne se mélangent pas accidentellement.
  • Toutes les questions DNS sont insensibles à la casse. Que vous demandiez naksec.testou NAKSEC.TESTou nAksEc.tESt, vous devriez obtenir la même réponse.

Maintenant, il n'y a rien dans le protocole qui dit que vous DEVEZ utiliser la même orthographe dans la partie de la réponse où vous répétez la requête d'origine, car DNS ne se soucie pas de la casse.

Mais bien que la RFC 1035 vous oblige à faire des comparaisons insensibles à la casse, elle suggère fortement que vous ne change pas vraiment la casse de tous les noms de texte que vous recevez dans les requêtes ou que vous récupérez dans vos propres bases de données pour les utiliser dans les réponses.

En d'autres termes, si vous recevez une demande de nAKsEC.tEST, et votre base de données l'a stocké en tant que NAKSEC.TEST, ces deux noms sont néanmoins considérés comme identiques et correspondent.

Mais lorsque vous formulez votre réponse, la RFC 1035 suggère que vous ne changez pas la casse des caractères des données que vous mettez dans votre réponse, même si vous pourriez penser que cela aurait l'air plus net, et même s'il correspondrait toujours à l'autre bout, grâce à la comparaison insensible à la casse exigée par DNS.

Donc, si vous mélangez au hasard la casse des lettres dans une requête DNS avant de l'envoyer, la plupart des serveurs DNS refléteront fidèlement cet étrange mélange de lettres, même si leur propre base de données stocke le nom du serveur différemment, comme vous le voyez ici :

$ dig +noedns @127.42.42.254 nAkSEc.tEsT ;; SECTION DES QUESTIONS : ;nAKSEc.tEsT. DANS UN ;; SECTION DE RÉPONSE : NAKSEC.TEST. 5 IN A 203.0.113.42 ;; Temps de requête : 1 msec ;; SERVEUR : 127.42.42.254#53(127.42.42.254) (UDP) ;; QUAND : Lundi 23 janvier 14:40:34 GMT 2023 ;; TAILLE MSG reçu : 56

Notre serveur DNS stocke le nom naksec.test tout en majuscules, et donc la section de réponse de la réponse inclut le nom sous la forme NAKSEC.TEST, ainsi que son numéro IPv4 (l'enregistrement A) de 203.0.113.42.

Mais dans la partie "voici les données de la requête qui vous sont renvoyées pour vérification croisée" de la réponse renvoyée par notre serveur DNS, le mashup caractère-casse utilisé à l'origine dans la recherche DNS est conservé :

---> Requête de 127.0.0.1:55772 à 127.42.42.254:53 ---> 00000000 c0 55 01 20 00 01 00 00 00 00 00 00 06 6e 41 6b |.U. .........nAk| 00000010 53 45 63 04 74 45 73 54 00 00 01 00 01 |SEc.tEsT..... | Recherche DNS : enregistrement A pour nAkSEc.tEsT ==> A=203.0.113.42 <--- Réponse de 127.42.42.254:53 à 127.0.0.1:55772 <--- 00000000 c0 55 84 b0 00 01 00 01 00 00 00 00 06 6e 41 6b |.U...........nAk| 00000010 53 45 63 04 74 45 73 54 00 00 01 00 01 06 4e 41 |SEc.tEsT......NA| 00000020 4b 53 45 43 04 54 45 53 54 00 00 01 00 01 00 00 |KSEC.TEST.......| 00000030 00 05 00 04 cb 00 71 2a |......q* |
Sécurité sérieuse : comment des fautes de frappe délibérées pourraient améliorer la sécurité DNS PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Au dessus. Requête DNS dans Wireshark.
Section de question avec CAS MIXTE illustré.
Sécurité sérieuse : comment des fautes de frappe délibérées pourraient améliorer la sécurité DNS PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Au dessus. Réponse DNS dans Wireshark.
Notez comment les données de la requête sont copiées exactement à partir de la requête, même si la base de données du serveur a fourni un nom TOUT EN MAJUSCULES.

Marquage de sécurité supplémentaire, gratuit

Bingo!

Il y a plus de "marquage d'identification" qu'une recherche DNS peut ajouter !

Avec environ 15 bits de port source choisis au hasard et 16 bits de données de numéro d'identification choisis au hasard, le demandeur peut choisir les majuscules et les minuscules pour chaque caractère alphabétique du nom de domaine.

Et naksec.test contient 10 lettres, chacune pouvant être écrite en majuscules ou en minuscules, pour 10 bits supplémentaires de "balisage" aléatoire.

Avec ce détail supplémentaire à deviner, les attaquants devraient avoir de la chance avec leur timing, le numéro de port UDP, la valeur de la balise d'identification et la capitalisation du nom de domaine, afin d'injecter une fausse "réponse de piratage" que le serveur demandeur accepterait.

D'ailleurs, le nom Codage 0x20 ci-dessus est un peu une blague: 0x20 en tête décimale est 00100000 en binaire, et le bit solitaire dans cet octet est ce qui différencie les lettres majuscules et minuscules dans le système de codage ASCII.

Les lettres A à I, par exemple, sortent de 0x41 à 0x49, tandis que a à i sortir comme 0x61 à 0x69.

 Tableau de codage ASCII sous forme de texte ASCII +------+------+------+------+------+------+- -----+------+ |00 ^@ |10 ^P |20 |30 0 |40 @ |50 P |60 ` |70 p | |01 ^A |11 ^Q |21 ! |31 1 |41 A |51 Q |61 a |71 q | |02 ^B |12 ^R |22 " |32 2 |42 B |52 R |62 b |72 r | |03 ^C |13 ^S |23 # |33 3 |43 C |53 S |63 c |73 s | |04 ^D |14 ^T |24 $ |34 4 |44 D |54 T |64 d |74 t | |05 ^E |15 ^U |25 % |35 5 |45 E |55 U |65 e |75 u | |06 ^F |16 ^V |26 & |36 6 |46 F |56 V |66 f |76 v | |07 ^G |17 ^W |27 ' |37 7 | 47 G |57 W |67 g |77 w | |08 ^H |18 ^X |28 ( |38 8 |48 H |58 X |68 h |78 x | |09 ^I |19 ^Y |29 ) |39 9 |49 I |59 Y |69 i |79 y | |0A ^J |1A ^Z |2A * |3A : |4A J |5A Z |6A j |7A z | |0B ^K |1B ^ [ |2B + |3B ; |4B K |5B [ |6B k |7B { | |0C ^L |1C ^ |2C , |3C < |4C L |5C |6C l |7C | | |0D ^M | 1D ^] |2D - |3D = |4D M |5D ] |6D m |7D } | |0E ^N |1E ^^ |2E . |3E > |4E N |5E ^ |6E n |7E ~ | | 0F ^O |1F ^_ |2F / |3F ? |4F O |5F _ |6F o |7F | +------+------+------+--- ---+------+------+------+------+

En d'autres termes, si vous ajoutez 0x41 + 0x20 pour obtenir 0x61, vous tournez A développement a; si vous soustrayez 0x69-0x20 pour obtenir 0x49, vous tournez i développement I.

Pourquoi maintenant?

Vous pourriez, maintenant, vous demander, "Pourquoi maintenant, si l'idée est apparue il y a 15 ans, et est-ce que ça ferait du bien de toute façon ?"

Notre intérêt soudain, il se trouve, vient d'un e-mail public récent des techniciens de Google, admettant que leurs expérimentations de 2022 avec cette astuce de SÉCURITÉ à l'ancienne ont été déployées dans la vraie vie :

Comme nous l'avons annoncé précédemment, Google Public DNS est en train d'activer la randomisation des cas des noms de requête DNS envoyés aux serveurs de noms faisant autorité. Nous l'avons déployé avec succès dans certaines régions d'Amérique du Nord, d'Europe et d'Asie en protégeant la majorité (90 %) des requêtes DNS dans les régions non couvertes par DNS sur TLS.

Curieusement, Google suggère que les principaux problèmes rencontrés avec ce réglage simple et apparemment non controversé sont que, bien que la plupart des serveurs DNS soient systématiquement insensibles à la casse (cette astuce peut donc être utilisée avec eux) ou systématiquement non (ils sont donc bloqués), comme on pouvait s'y attendre...

… quelques serveurs principaux passent occasionnellement en mode « sensible à la casse » pendant de courtes périodes, ce qui ressemble au genre d'incohérence que vous espérez que les principaux fournisseurs de services éviteraient.

Est-ce que ça aide vraiment ?

La réponse a la question, "Est-ce que ça vaut le coup?" n'est pas encore clair.

Si vous avez un joli nom de longue date, comme nakedsecurity.sophos.com (22 caractères alphabétiques), alors il y a beaucoup de puissance de signalisation supplémentaire, car 222 différentes capitalisations signifient 4 millions de combinaisons à essayer pour les escrocs, multipliées par les 65536 32000 numéros d'identification différents, multipliées par les quelque 64000 XNUMX à XNUMX XNUMX ports sources différents à deviner…

… mais si vous avez payé une petite fortune pour un nom de domaine super court, comme celui de Twitter t.co, vos attaquants n'ont qu'un travail 2x2x2=8 fois plus dur qu'avant.

Néanmoins, je pense que nous pouvons dire "Chapeau" à Google pour avoir essayé cela.

Comme les observateurs de la cybersécurité aiment à le dire, les attaques ne font que s'accélérer, donc tout ce qui peut prendre un protocole existant et lui ajouter du temps de craquage supplémentaire, presque "gratuitement", est un moyen utile de riposter.


Horodatage:

Plus de Sécurité nue