Tester la robustesse des serveurs DNS avec Scapy



Documents pareils
Le Tunneling DNS. P.Bienaimé X.Delot P.Mazon K.Tagourti A.Yahi A.Zerrouki. Université de Rouen - M2SSI. 24 février 2011

Télécommunications. IPv4. IPv4 classes. IPv4 réseau locaux. IV - IPv4&6, ARP, DHCP, DNS

INTERNET & RESEAUX. Dino LOPEZ PACHECO lopezpac@i3s.unice.fr

Réseaux IUP2 / 2005 DNS Système de Noms de Domaine

Scapy en pratique. Renaud Lifchitz. «Scapy en pratique» PyCON FR 17 Mai Renaud Lifchitz 1

1 Présentation du module sr005 2 I Administration d un serveur DNS... 2 II Organisation... 2

Sécurité d IPv6. Sécurité d IPv6. Stéphane Bortzmeyer AFNIC bortzmeyer@nic.fr. Stéphane Bortzmeyer AFNIC bortzmeyer@nic.fr

Le service de nom : DNS

V - Les applications. V.1 - Le Domain Name System. V Organisation de l espace. Annuaire distribué. Définition. Utilisation par le resolver

Il est recommandé de fermer les serveurs DNS récursifs ouverts

LOSLIER Mathieu. Filière Informatique et Réseau 1 ère année. TP DNS. Responsable : LOHIER Stephane. Chargé de TD : QUIDELLEUR Aurélie

RFC 7011 : Specification of the IP Flow Information export (IPFIX) Protocol for the Exchange of Flow Information

FILTRAGE de PAQUETS NetFilter

Chapitre 2: Configuration de la résolution de nom

(Third-Man Attack) PASCAL BONHEUR PASCAL 4/07/2001. Introduction. 1 Domain Name Server. 2 Commandes DNS. 3 Hacking des serveurs DNS

Capture, Filtrage et Analyse de trames ETHERNET avec le logiciel Wireshark. Etape 1 : Lancement des machines virtuelles VMWARE et de Wireshark

Exemple d application: l annuaire DNS Claude Chaudet

Sécurité des réseaux Les attaques

Nouvelle version de Zonecheck, la 3.0, avec tests DNSSEC

Étude de l application DNS (Domain Name System)

Gestion centralisée d un réseau de sites discrets. Nicolas JEAN

Domain Name System. F. Nolot

Les commandes relatives aux réseaux

ZERO CONF. Exposé option Réseaux et Interconnexion d'ordinateurs P.BLEDU FA 08 C.PERROTIN TTN 08. p1/14

DNS. Pierre BETOUIN ( betouin@et.esiea.fr ) 31 mars

REPARTITION DE CHARGE LINUX

TP4 : Firewall IPTABLES

M Architecture des réseaux

Outils d'analyse de la sécurité des réseaux. HADJALI Anis VESA Vlad

DNS Poisoning. Pollution de cache sur des serveurs DNS. Xavier Dalem, Adrien Kunysz, Louis Plair. 15 mars Université de Liège

Domain Name System ot ol F. N 1

Première approche d'un outil merveilleux hping

7.3 : Ce qu IPv6 peut faire pour moi

Attaque contre les systèmes de suivi de connexions

Représentation d un entier en base b

Administration Système & Réseau. Domain Name System Historique & Concepts Fonctionnalités & Hiérarchie Requêtes & Base de donnée DNS

IPFIX (Internet Protocol Information export)

Il est possible d associer ces noms aux langages numérique grâce à un système nommé DNS(Domain Name System)

Cours admin 200x serveur : DNS et Netbios

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

Algorithmique et langages du Web

Projet 8INF206 : Sécurité réseau informatique Attaque de l homme du milieu (MITM) Guillaume Pillot

Internet Group Management Protocol (IGMP) Multicast Listener Discovery ( MLD ) RFC 2710 (MLD version 1) RFC 3810 (MLD version 2)

Configuration Routeur DSL pour Xbox LIVE ou PlayStation-Network

Gérer son DNS. Matthieu Herrb. tetaneutral.net. Atelier Tetaneutral.net, 10 février

Les clés d un réseau privé virtuel (VPN) fonctionnel

Master d'informatique 1ère année Réseaux et protocoles

DNS et Mail. LDN 15 octobre DNS et Mail. Benjamin Bayart, Fédération FDN. DNS - fichier de zone. DNS - configuration

SIP. Plan. Introduction Architecture SIP Messages SIP Exemples d établissement de session Enregistrement

Fonctionnement Kiwi Syslog + WhatsUP Gold

TARMAC.BE TECHNOTE #1

Master 1 ère année. UE Réseaux Avancés I. Corrections décembre Durée : 2h Documents autorisés

B1-4 Administration de réseaux

TP SECU NAT ARS IRT ( CORRECTION )

TD n o 8 - Domain Name System (DNS)

Protection des protocoles

Powershell. Sommaire. 1) Étude du cahier des charges 2) Veille technologique 3) Administration sur site 4) Automatisation des tâches d administration

Systèmes et Réseaux (ASR 2) - Notes de cours Cours 14

Développement d un logiciel de messagerie instantanée avec Dotnet (version simplifiée)

Corrigé des exercices sur les références

Manuel de l utilisateur

Introduction au DNS. Les noms de domaine s'écrivent de la gauche vers la droite, en remontant vers la racine et sont séparés par un "." (point).

STS SE. FreeRTOS. Programmation réseau WIFI. Programmation réseau. Socket Tcp. FlyPort smart Wi-Fi module

Internet Le service de noms - DNS

Domaine Name System. Auteur: Congduc Pham, Université Lyon 1. Figure 1: Schéma des salles TP11 et TD4

La supervision des services dans le réseau RENATER

Plan. Programmation Internet Cours 3. Organismes de standardisation

TAGREROUT Seyf Allah TMRIM

Ce cours est la propriété de la société CentralWeb. Il peut être utilisé et diffusé librement à des fins non commerciales uniquement.

OpenPaaS Le réseau social d'entreprise

TP Wireshark. Première approche de Wireshark. 1 ) Lancer Wireshark (double clic sur l icône sur le bureau). La fenêtre

Formation Iptables : Correction TP

Haka : un langage orienté réseaux et sécurité

Chapitre I. La couche réseau. 1. Couche réseau 1. Historique de l Internet

Métrologie des réseaux IP

Programmation Réseau. ! UFR Informatique ! Jean-Baptiste.Yunes@univ-paris-diderot.fr

Master 1 UE Réseaux Avancés II. Les Fourberies de Scapy P-F. Bonnefoi

Corrigé du TP 6 Réseaux

Algorithmique des Systèmes Répartis Protocoles de Communications

Réalisation d un portail captif d accès authentifié à Internet

Réseaux. Moyens de sécurisation. Plan. Evolutions topologiques des réseaux locaux

SECURIDAY 2012 Pro Edition

CREER UN ENREGISTREMENT DANS LA ZONE DNS DU DOMAINE

Partie 2 (Service de téléphonie simple) :

Problème physique. CH5 Administration centralisée

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

DIFF AVANCÉE. Samy.

Service de noms des domaines (Domain Name System) Cours administration des services réseaux M.BOUABID,

pare - feu généralités et iptables

Domain Name Service (DNS)

AUTORISER LES PARTAGES RESEAUX ET IMPRIMANTE SOUS L'ANTIVIRUS FIREWALL PRO V1

Arbres binaires de recherche

Domain Name System. Schéma hiérarchique. Relation

FusionInventory. I-Détails et explication de l installation de l agent FusionInventory

Machines virtuelles. Brique ASC. Samuel Tardieu Samuel Tardieu (ENST) Machines virtuelles 1 / 40

(51) Int Cl.: H04L 29/06 ( ) G06F 21/55 ( )

Réseaux. 1 Généralités. E. Jeandel

DIGITAL NETWORK. Le Idle Host Scan

Introduction...3. Objectifs...3 Contexte...3 nslookup/dig/host...3 whois...3. Introduction...4

Transcription:

Tester la robustesse des serveurs DNS avec Scapy Stéphane Bortzmeyer <stephane+blog@bortzmeyer.org> Première rédaction de cet article le 4 mars 2010 Comme aime le dire Paul Vixie, l Internet est, pour les serveurs réseau, plutôt l équivalent de New York que celui du petit village tranquille où tout le monde se connait. Si on s évanouit de peur à chaque truc bizarre qui passe, on ne va pas loin. Un serveur réseau connecté à l Internet doit être robuste : il va voir des tas de paquets mal formés et ne devra pas planter (ou, pire, ouvrir une voie de pénétration) lorsqu un de ces paquets arrive. Un des outils pour tester facilement la robustesse d un serveur est Scapy. Voyons son application à des serveurs DNS. Un serveur DNS reçoit des paquets UDP et TCP qui sont normalement conformes à la description qu en fait le RFC 1035 1 et quelques RFC ultérieurs (notamment le RFC 2671). Suivre à la lettre ces RFC devrait mener à du code parfait. Ainsi, pour analyser un nom de domaine figurant dans la section Question d un paquet, on lit la section 4.1.2 du RFC 1035, qui dit que le nom est représenté par une suite de composantes, chaque composante étant faite d un octet (qui indique la longueur de la composante) et d une suite d octets pour le texte. On arrive à du code qui ressemble à (en Go) : for { labelsize, error := buf.readbyte() if labelsize == 0 { break label := make([]byte, labelsize) n, error := buf.read(label) nlabels += 1 labels = labels[0:nlabels] labels[nlabels-1] = string(label) ou bien (en C) : 1. Pour voir le RFC de numéro NNN, http://www.ietf.org/rfc/rfcnnn.txt, par exemple http://www.ietf.org/ rfc/rfc1035.txt 1

2 for (sectionptr = qsection;!end_of_name;) { labelsize = (uint8_t) * sectionptr; if (labelsize == 0) { sectionptr++; end_of_name = true; else { strncat(fqdn, ".", 1); strncat(fqdn, (char *) sectionptr + 1, labelsize); fqdn_length += (labelsize + 1); fqdn[fqdn_length] = \0 ; sectionptr = sectionptr + labelsize + 1; Ces codes (simplifiés) marchent avec des paquets normaux. Mais l expérience montre clairement que, dans le vrai Internet, il existe une minorité non négligeable de paquets anormaux. On les voit indirectement dans les alertes de sécurité de Wireshark <http://www.wireshark.org/security/ >. Pour le cas du DNS, l usage d un outil comme DNSmezzo <http://www.dnsmezzo.net> sur un serveur de noms public montre rapidement des milliers de paquets qui violent le RFC. D où viennent ces paquets? Certains sont issus d erreurs de programmation (il y a des tas d amateurs incompétents qui programment), d autres sont des essais par des étudiants en plein TP d écriture d un client DNS, d autres enfin sont d authentiques tentatives de piratage, par exemple en cherchant à provoquer un débordement de tampon chez le serveur. Tout code réel (i.e. pas les deux exemples plus haut) va donc chercher à se protéger contre de tels paquets. On vérifie donc, on regarde si un pointeur de compression ne sort pas du paquet, on teste si on est arrivé au bout du paquet avant de continuer aveuglément, etc. C est le B. A. BA de la programmation réseau. Mais comment tester que ces protections sont efficaces? Il faudrait pouvoir fabriquer facilement des paquets anormaux. Et la plupart des bibliothèques de programmation réseau sont au contraire conçues pour faciliter la production de paquets normaux. C est là que Scapy devient utile. Scapy est un outil d analyse de paquets existants et de fabrication de paquets, offrant une très grande souplesse de manipulation. Scapy fait tout tout seul... mais laisse le programmeur intervenir où il veut. C est l outil rêvé des programmeurs qui veulent tester un logiciel (ou des pirates qui veulent l attaquer). S appuyant sur Python, il nécessite de connaitre ce langage. Lisez la documentation <http://www.secdev.org/projects/scapy/doc/usage.html>. Puis utilisons-le en interactif pour commencer : # scapy >>> p = IP(dst="203.0.113.162")/UDP(sport=RandShort(),dport=53)/\... DNS(rd=1,qd=DNSQR(qname="www.slashdot.org", qtype="aaaa")) On a fabriqué une requête DNS (demande de l adresse IPv6 - AAAA - de www.slashdot.org). Notez qu un certain nombre de paramètre n ont pas été fournis (par exemple l adresse IP source), Scapy les fournira. Vérifions : >>> p.show() ###[ IP ]### version= 4

3... chksum= 0x0 src= 203.0.113.69 dst= 203.0.113.162 options= ###[ UDP ]### sport= <RandShort> dport= domain len= None chksum= 0x0 ###[ DNS ]### id= 0 qr= 0 opcode= QUERY aa= 0 tc= 0 rd= 1 ra= 0 z= 0 rcode= ok qdcount= 1 ancount= 0 nscount= 0 arcount= 0 \qd\ ###[ DNS Question Record ]### qname= www.slashdot.org qtype= AAAA qclass= IN an= None ns= None ar= None Le champ src (adresse IP source) a bien été rempli. Des champs comme la longueur du paquet UDP (len, actuellement None, la valeur indéfinie en Python) seront remplis automatiquement lors de l émission du paquet. De même, l appel à RandShort() ne sera évalué qu au moment de l envoi du paquet (et produira un nombre aléatoire). D ores et déjà, je peux interactivement modifier tous les champs, par exemple : >>> p.rd = 0 et p.show() (ou bien tcpdump si on envoie le paquet) montrera bien que la requête n est plus récursive. Ah, justement, envoyons le paquet : >>> sr1(p) Begin emission:.finished to send 1 packets. * Received 2 packets, got 1 answers, remaining 0 packets <IP version=4l ihl=5l tos=0x0 len=62 id=0 flags=df frag=0l ttl=63 proto=udp chksum=0xb1bb src=203.0.113.162 dst=

4 Le paquet a été transmis et la réponse ( il n y a pas d adresse IPv6 pour www.slashdot.org ) reçue et analysée. Bien, tout cela, c étaient des paquets DNS normaux. Maintenant, essayons de fabriquer des paquets anormaux, pour voir si le serveur DNS réagit bien. Je vais tester avec un serveur DNS très sommaire, qui a peu de protections, GRONG <http://www.bortzmeyer.org/dnsserver-en-go.html>. Si je lance GRONG et que je lui envoie le paquet ci-dessus, le serveur affiche : %./server -debug=4 34 bytes packet from 203.0.113.69:24007 Query is true, Opcode is 0, Recursion is true, Rcode is 0 FQDN is www.slashdot.org, type is 28, class is 1 Replying with ID 0... Place maintenant à un paquet DNS malformé. Changeons qdcount (dans la section DNS) qui indique la taille de la section Question (normalement, 1) : >>> p[dns].qdcount=0 et envoyons ce paquet incohérent (qdcount ne correspond plus à la taille de la section Question), le résultat ne se fait pas attendre, le serveur, programmé de manière insuffisamment défensive, plante : 34 bytes packet from 203.0.113.69:23287 throw: index out of range panic PC=0x40078b90 throw+0x46 /usr/local/go/src/pkg/runtime/runtime.c:74 throw(0x80bcd88, 0x0) runtime.throwindex+0x24 /usr/local/go/src/pkg/runtime/runtime.c:47 runtime.throwindex() main.parse+0x407 /home/stephane/src/go/dns/grong/server.go:137 main.parse(0x40046c00, 0x0, 0x0) main.generichandle+0x5d /home/stephane/src/go/dns/grong/server.go:147 main.generichandle(0x40046c00, 0x400475c0, 0x40042270, 0x0, 0x0,...) main.udphandle+0x136 /home/stephane/src/go/dns/grong/server.go:191 main.udphandle(0x400414c8, 0x400475c0, 0x40042270, 0x40046c00, 0x0,...) goexit /usr/local/go/src/pkg/runtime/proc.c:140 goexit() 0x400414c8 unknown pc Heureusement, Go nous fournit une belle pile d appels, qui nous permettra d améliorer le serveur (ce sera pour un autre article). Changer uniquement un champ est amusant mais on peut aussi modifier plus drastiquement le paquet. Par exemple, si je veux le tronquer? Il faut pour cela sérialiser le paquet en une chaîne de caractères (avec str()), le modifier puis le retransformer en paquet : >>> s = str(p) >>> p2 = IP(s[:-4]) >>> sr1(p2)

5 Ce code transforme p dans la chaîne s puis retransforme en paquet la chaîne privée de ses quatre derniers octets. Mais le paquet n arrive pas au serveur de noms, qui semble ne rien recevoir. C est parce que le gros problème de cette approche est que la sérialisation gèle les valeurs flottantes comme la longueur indiquée dans l en-tête, qui est désormais invalide. Remettons tout cela à zéro, ainsi que les sommes de contrôle et Scapy le recalculera proprement : >>> del p2[udp].len >>> del p2[ip].len >>> p2[udp].sport=randshort() >>> del p2[udp].chksum >>> del p2[ip].chksum >>> sr1(p2) Désormais, le paquet tronqué est bien reçu... et plante le serveur : 30 bytes packet from 203.0.113.69:12662 Error in Read of an int16: EOF (0 bytes read) Et si je veux modifier une valeur quelconque, non accessible depuis un champ nommé, par exemple la longueur d une des composantes du FQDN? Là encore, on sérialise, on fabrique une nouvelle chaîne en changeant un des octets (ici, le n 44) et on refait le paquet. >>> s=str(p) >>> s E\x00\x00>\x00\x01\x00\x00@\x11\xf0\xfb\xc0\x86\x04E\xc0\x86\x04au*\x1fu\x00*\xce\x18\x00\x00\x01\x00\x00\x01\x0 >>> s[44] \x08 >>> s2 = s[:44] + \x030 + s[45:] >>> s2 E\x00\x00>\x00\x01\x00\x00@\x11\xf0\xfb\xc0\x86\x04E\xc0\x86\x04au*\x1fu\x00*\xce\x18\x00\x00\x01\x00\x00\x01\x0 >>> p2 = IP(s2) >>> del p2[udp].chksum >>> del p2[ip].chksum >>> sr1(p2) À noter que cette erreur particulière ne pose pas de problème à GRONG qui ignore ce paquet, reconnu comme invalide. Bien sûr, il y a des tas de tests que l on souhaite ainsi faire. Scapy fournit d ailleurs des moyens de faire varier certains paramètres ( fuzzy testing ). On a donc intérêt à mettre ces tests dans un programme Python normal, qui utilisera Scapy pour faire tourner tous les tests... et vérifier ainsi le serveur. Pour un exemple d un tel programme, voir (en ligne sur http://www.bortzmeyer.org/files/ test-dns-scapy.py). Je n ai pas de scrupule à livrer ce programme de test de robustesse car BIND et nsd, bien écrits, y survivent sans problème. Ah, un petit gag avec Scapy, qui est dans la FAQ mais qui m avait coûté quelque temps de recherche. Au début, on commence souvent par tester un serveur qui figure sur la même machine et on teste donc l adresse IP locale, 127.0.0.1. Mais l interface locale a quelques particularités et Scapy exige donc qu on indique, dans ce cas :

6 >>> conf.l3socket=l3rawsocket Cette instruction ne marche pas, à l heure actuelle, depuis un programme Python, uniquement en interactif (bogue Scapy #193 <http://trac.secdev.org/scapy/ticket/193>). Depuis un programme, on obtient un NameError: global name Ether is not defined. La correction est d ajouter from scapy.layers.l2 import Ether dans les importations de scapy/supersocket.py (merci à rmkml). Autre piège où j ai passé du temps en apprenant Scapy : = ne fait pas une copie des paquets, le nouveau paquet, si j écris p2 = p est juste un pointeur. Pour copier réellement un paquet : >>> p2 = p.copy() Merci à Pierre-François Bonnefoi pour son aide. Il est par ailleurs l auteur d un excellent support de cours Scapy en français <http://ishtar.msi.unilim.fr/uploads/media/scapy_handout_2009_ 2010_TOC.pdf>. L exposé Network packet forgery with Scapy <http://www.secdev.org/conf/ scapy_pacsec05.pdf>, de Philippe Biondi, contient plein de techniques utiles.