Je suis Charlie

Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

Mon livre « Cyberstructure »

Ève

RFC 7707: Network Reconnaissance in IPv6 Networks

Date de publication du RFC : Mars 2016
Auteur(s) du RFC : F. Gont (Huawei Technologies), T. Chown (University of Southampton)
Pour information
Réalisé dans le cadre du groupe de travail IETF opsec
Première rédaction de cet article le 11 mars 2016


Soit un pauvre petit réseau innocent, et un méchant attaquant qui va essayer de faire subir les derniers outrages au réseau en question. L'attaquant commence souvent par une phase de reconnaissance, où il cherche à améliorer sa connaissance du réseau visé. Un outil souvent utilisé dans cette phase est le balayage (scanning) systématique du réseau, à la recherche d'adresses IP de machines à attaquer. En IPv6, contrairement à IPv4, la tâche semble colossale, vu le nombre d'adresses IP possibles. Mais, comme l'avait déjà noté le RFC 5157, cette tâche n'est pas impossible. Ce nouveau RFC fait le point sur le balayage IPv6 et détaille les techniques utilisables.

Comme exemple de la différence de situation entre IPv4 et IPv6, prenons un réseau local typique. La densité de machines (nombre de machines réellement présentes par rapport au nombre d'adresses possibles) est bien inférieure en IPv6. Sur un /26 IPv4, on a 62 adresses théoriquement possibles et la plupart correspondront sans doute effectivement à une machine. Balayer ce /26 est à la fois très rapide et très avantageux. En IPv6, un simple /64 permet d'avoir plus de 10^19 adresses (c'est bien la principale motivation pour déployer IPv6 : avoir davantage d'adresses). Même si on a bien plus de machines, la densité sera infime. Si les adresses étaient attribuées au hasard et que le balayage se fasse également au hasard, les chances de tomber sur une machine réelle sont quasi-nulles. Heureusement pour l'attaquant, les adresses réelles ne sont pas attribuées au hasard, et le balayage n'est pas forcément fait au hasard. Ce nouveau RFC, deux fois plus long que l'ancien (le RFC 5157) fait le point sur ce que les défenseurs et les attaquants doivent savoir sur le balayage en IPv6.

Avant de tester, installons l'outil de balayage scan6, distribué avec le SI6 toolkit (et déjà utilisé dans mon article sur les attaques en IPv6) :

% wget http://www.si6networks.com/tools/ipv6toolkit/ipv6toolkit-v2.0.tar.gz
% tar xzvf ipv6toolkit-v2.0.tar.gz
% cd ipv6toolkit-v2.0
% make

C'est parti, en commençant par les techniques les plus classiques (section 3 de notre RFC). D'abord, lorsque le réseau visé configure les adresses IP avec le SLAAC du RFC 4862. Le SLAAC fonctionne en concaténant un préfixe appris du routeur avec un suffixe, l'IID (Interface IDentifier). Comment la machine choisit-elle son IID ? Il existe plusieurs techniques, qui ont des conséquences sur la facilité de balayage. Par exemple, une technique courante (mais de moins en moins employée) est de fabriquer l'IID à partir de l'adresse MAC de la machine, en mettant juste le bit 6 à 1 et en ajoutant au milieu 0xfffe. Ainsi, mon adresse MAC 38:59:f9:7d:b6:47 me donne actuellement une adresse IPv6 de 2003:88:6c71:c7f8:3a59:f9ff:fe7d:b647 (préfixe 2003:88:6c71:c7f8 chez Deutsche Telekom et IID 3a59:f9ff:fe7d:b647). A priori, il y a 64 bits possibles pour l'IID. Mais ce n'est pas tout à fait vrai. D'abord, 16 sont fixes (le 0xfffe). Ensuite, les 24 premiers bits identifient le vendeur de la carte via son OUI (sauf si, comme dans l'exemple ci-dessus, on a changé son adresse MAC...) Tous les OUI possibles n'étant pas encore affectés, cela réduit le champ de recherche. Et ceux qui sont affectés le sont souvent pour du matériel qui n'est plus fabriqué, réduisant encore ce champ. Enfin, un attaquant malin observera qu'une organisation donnée a souvent un parc matériel homogène (par exemple uniquement des ordinateurs Dell). Cela permet de réduire encore l'espace de recherche (option --tgt-vendor de scan6). En outre, si les machines ont été achetées en même temps, il est tout à fait possible qu'elles fassent partie du même lot et que leurs adresses MAC soient consécutives. Une fois qu'on en a trouvé une, on peut supposer que les autres sont proches.

Un cas particulier est celui des techniques de virtualisation. Par exemple, VirtualBox utilise l'OUI 08:00:27 et, avec le 0xfffe du milieu, cela fait que l'espace de recherche réel n'est que de 24 bits, bien moins que les 64 théoriques. VMware est encore pire, pour ses adresses MAC automatiques : l'OUI est 00:05:69, 16 bits sont tirés de l'adresse IPv4 de la console, 8 bits sont un condensat du nom du fichier de configuration. Il peut donc n'y avoir que 8 bits à chercher ! (Les adresses MAC manuelles de VMware ont 22 bits variables.)

Et les adresses temporaires du RFC 8981, n'avaient-elles pas été conçues justement pour éviter qu'on suive à la trace une machine ? L'IID est cette fois aléatoire, et change souvent (par exemple une fois par jour). Ces adresses temporaires sont une très bonne chose, mais elles ont quelques limites. D'abord, elles viennent en plus des adresses classiques, auxquelles la machine répond toujours. Les adresses temporaires étant utilisées pour les connexions sortantes, le risque de fuite de l'adresse globale permanente est plus faible mais elles n'empêchent pas le balayage, avec les techniques données plus haut.

C'est en partie pour combler les faiblesses des adresses temporaires que les adresses du RFC 7217 ont été développées. L'IID est un condensat de certaines caractéristiques de la machine et du réseau. Ces adresses sont stables tant que la machine ne change pas de réseau (ce qui permet de n'utiliser que ces adresses et d'oublier les adresses globales classiques). Du point de vue de la vie privée, elles représentent la meilleure solution, et devraient être systématiquement utilisées. Pour l'instant, comme l'indique « IPv6 Address Analysis - Privacy In, Transition Out », la grande majorité des clients IPv6 utilisent les adresses temporaires du RFC 8981 (et 7 % utilisent encore les adresses MAC).

Et DHCP ? La politique d'allocation des adresses dépend du serveur DHCP. Parfois, elle mène à des adresses prévisibles, mais pas toujours. Par exemple, si on configure un serveur DHCP pour allouer des adresses dans la plage 2001:db8:a35:b24::/64, et que le serveur DHCP décide qu'une allocation séquentielle (2001:db8:a35:b24::1 puis 2001:db8:a35:b24::2, puis 2001:db8:a35:b24::3...) est la meilleure solution, alors les adresses seront prévisibles. C'est pour cela que le RFC 5157 conseillait aux serveurs DHCP d'allouer au hasard à partir de la plage d'adresses configurée et ce conseil est répété ici.

Et les adresses attribuées manuellement, par l'administrateur système ? C'est utile pour les routeurs (qui ne peuvent pas utiliser SLAAC) et les serveurs (qui ne cherchent pas à se cacher, et pour qui il est très souhaitable d'avoir une adresse IP stable). En théorie, l'administrateur système peut choisir l'IID librement parmi 2^64 valeurs. En pratique, on observe que ces IID ne sont pas choisis au hasard mais que les ingénieurs suivent un de ces quatre schémas, utilisant :

  • Un nombre de faible valeur (schéma dit low byte) : PREFIX::1, PREFIX::2, etc. L'option --tgt-low-byte de scan6 permet de tester en premier ces valeurs. Dans le cas le plus simple, il suffit de tester les 256 valeurs correspondant aux huits bits finaux (certaines variantes de ce schéma utilisent les deux ou trois derniers octets, ce qui rend le balayage un peu plus long). Ce schéma est de loin le plus fréquent pour les serveurs et les routeurs (voir « IPv6 Network Reconnaissance: Theory & Practice », cité en section 3.1.5).
  • Une adresse IPv4, en profitant de ce que la représentation texte d'une adresse IPv6 peut se terminer par une adresse IPv4, comme dans 2001:db8:88:12a::192.0.2.21. Balayer ces adresses revient à balayer l'espace IPv4 correspondant (option --tgt-ipv4, de scan6).
  • Un numéro de port, le serveur DNS sera PREFIX::53, le serveur IMAP PREFIX::993, etc. Le cas le plus simple (numéro de port dans le dernier octet) est très rapide à balayer (option --tgt-port de scan6, il n'y a que quelques dizaines de ports populaires), certaines variantes sont un peu plus lentes.
  • Un terme amusant en hexspeak comme ::dead:beef ou ::a11. Balayer ces termes se fait à partir d'un dictionnaire.

Bon, armés de ces connaissances, voyons maintenant concrètement comment balayer un réseau. D'abord, un réseau distant (section 3.2). Un balayage par la force brute est impossible en IPv6 : un seul /64 peut avoir dans les 10^20 machines, ce qui, même à un million de paquets par seconde, prendrait trois millions d'années à examiner. Un balayeur IPv6 doit donc être plus astucieux que la force brute et exploiter les propriétés des adresses IPv6, qui font que l'espace réel à explorer est plus réduit que l'espace théorique. Ainsi, en balayant dans l'ordre, de PRÉFIXE:: puis PRÉFIXE::1, PRÉFIXE::2, etc, on tire profit des adressses de faible valeur. De même, on peut deviner le plan d'adresssage et utiliser les adresses IPv4 du réseau, les numéros des bâtiments, etc.

À noter que le balayage peut aussi être utilisé pour faire une attaque par déni de service. Certaines mises en œuvres d'IPv6 gèrent mal leur cache NDP et un grand nombre de requêtes pour des machines inexistantes peut planter certains routeurs IPv6 (RFC 6583).

Revenons au balayage fait dans le but de découvrir des adresses actives. Si on balaye le réseau local, celui où on se trouve, il y a encore d'autres possibilités, notamment les adresses multicast. Par exemple, en envoyant un seul paquet à l'adresse multicast ff02::1, on récupère plein de machines :

% ping6 -I eth0 ff02::1
PING ff02::1(ff02::1) from fe80::e349:a3a5:ad58:a21 eth0: 56 data bytes
64 bytes from fe80::e349:a3a5:ad58:a21: icmp_seq=1 ttl=64 time=0.250 ms
64 bytes from fe80::21e:8cff:fe76:29b6: icmp_seq=1 ttl=64 time=1.17 ms (DUP!)
64 bytes from fe80::f6ca:e5ff:fe4d:1f41: icmp_seq=1 ttl=64 time=4.96 ms (DUP!)
64 bytes from fe80::ce0d:dad3:6bc2:6da4: icmp_seq=1 ttl=64 time=4.96 ms (DUP!)
...
 

Ça ne marche pas avec les machines Windows, qui ne répondent pas à ce ping. Mais il y a d'autres astuces comme d'envoyer à cette adresse multicast un paquet IPv6 ayant une option inconnue et dont le type commence par 10 (qui signifie « si cette option n'est pas connue, jeter le paquet et envoyer une erreur ICMP », cf. RFC 2460, section 4.2). Windows répondra alors par un message ICMP Parameter problem. Voici le résultat de scan6 vu avec tcpdump, montrant cette technique :

19:01:06.204431 IP6 fe80::e349:a3a5:ad58:a21 > ff02::1: DSTOPT ICMP6, echo request, seq 34994, length 64
19:01:06.205469 IP6 fe80::21e:8cff:fe76:29b6 > fe80::e349:a3a5:ad58:a21: ICMP6, parameter problem, option - octet 42, length 120
19:01:06.214792 IP6 fe80::ba27:ebff:feaa:78b9 > fe80::e349:a3a5:ad58:a21: ICMP6, parameter problem, option - octet 42, length 120
...

Ces techniques ne sont pas purement théoriques. Certes, un outil comme nmap sait faire du balayage en IPv4 mais pas en IPv6 à distance, mais d'autres outils existent. Ces techniques sont mises en œuvre dans l'outil scan6 du SI6 toolkit, cité plus haut. Une fois compilé et installé, on peut utiliser cet outil pour découvrir ses voisins (sur le même réseau local) :

 % sudo scan6 -L -i eth0
 ...
2a01:f23:a65:6721:21e:8cff:fe76:29b6
2a01:f23:a65:6721::1
2a01:f23:a65:6721:666:6c7c:9bed:b390
2a01:f23:a65:6721:b5a5:dfd6:4e7b:2584
... 
 

Ou bien tester un réseau distant :

% sudo scan6 -d 2001:7b2:dc0:41::/64
2001:7b2:dc0:41::250
...
 

Le dernier exemple ci-dessus est évidemment complètement irréaliste (balayage d'un /64 en force brute), même si ici on a trouvé tout de suite une machine « low-byte ». Ne soyez pas trop optimiste : scan6, livré à lui-même, est très lent et vous trouverez rarement quelque chose. Un balayage d'un site où on connait le vendeur des cartes Ethernet (et donc l'OUI) :

 %  sudo scan6 --tgt-ieee-oui b8:27:eb -d 2001:db8:8469:a30::/64 -i eth0 -e print-global  
 

prend de très nombreuses heures et risque fortement d'être détecté. En pratique, pour utiliser scan6 avec succès, il faut récolter beaucoup d'informations sur le réseau qui vous intéresse, et guider scan6 en lui mettant beaucoup d'options. Un projet intéressant serait de tenter d'automatiser cette phase heuristique.

Une des conséquences de la difficulté de balayer en IPv6 est que la gestion de réseaux devient plus compliquée. L'administrateur réseaux ne peut pas découvrir facilement tout ce qui a été branché et fonctionne sur son réseau. Il doit donc changer ses pratiques. Une des approches, pour connaitre tout son réseau, est l'écoute passive, avec ndpmon, qui permet de se constituer automatiquement une base des machines et de leur adresse MAC.

Et l'administrateur réseaux qui veut défendre son réseau et limiter le balayage, que peut-il faire (section 3.5 du RFC) ? Il existe plusieurs techniques qui aident, en rendant les adresses moins prévisibles :

  • Utiliser les adresses stables mais opaques du RFC 7217. (Au passage, je ne connais pas encore de système d'exploitation où ce soit facile ou même possible.)
  • Utiliser un IDS pour détecter (ou un IPS pour bloquer) : les balayages IPv6 ne peuvent pas être faits discrètement, ils allument les systèmes d'alarme comme un arbre de Noël.
  • Peut-être filtrer certains types de paquets (avec prudence : voir le RFC 4890).
  • Configurer manuellement les adresses MAC (par exemple avec macchanger). Ainsi, même si les adresses IPv6 son dérivées de l'adresse MAC, elles ne seront plus prévisibles.
  • Si on utilise DHCP, configurer le serveur DHCP pour allouer dans un ordre aléatoire, et pas bêtement en partant de 1. (Je n'ai pas regardé les possibilités des serveurs DHCP actuels.)

Ces solutions ne sont pas parfaites. Consolez-vous avec l'idée que la sécurité de vos machines ne doit de toute façon pas dépendre uniquement de la résistance de votre réseau au balayage. Tôt ou tard, l'attaquant découvrira vos adresses IP, et les machines doivent donc être préparées à tout.

Le balayeur n'utilisera pas que des techniques de couche 3 comme décrit dans la précédente section, la section 3 du RFC. Il peut aussi se servir, par exemple, du DNS (section 4). Par exemple, s'il est possible de récupérer la zone DNS, le balayeur obtient beaucoup d'adresses IPv6. Mais il peut aussi tester des noms communs dans le DNS et obtenir ainsi des adresses (et, si votre algorithme d'allocation est prévisible, un petit nombre d'adresses lui permettra d'en déduire d'autres). Un tel balayage est facile à automatiser.

Mieux (du point de vue de l'attaquant), on peut énumérer les enregistrements PTR dans votre sous-arbre de ip6.arpa. (C'est automatisable, avec l'outil dnsrevenum6, qui fait partie de la boîte à outils THC.)

Outre le DNS classique, mDNS (RFC 6762) peut également aider (section 5) : des requêtes envoyées à la cantonade peuvent découvrir des machines qui se signaleraient imprudemment.

L'attaquant en mission de reconnaissance peut aussi utiliser des archives publiques (section 6). Par exemple, une liste de diffusion dont les messages seraient stockées intégralement, y compris les en-têtes Received:, qui contiennent souvent des adresses IP. Difficile d'être discret sur l'Internet !

Certaines applications peuvent également aider l'attaquant à récolter des adresses IP (section 7). Par exemple, BitTorrent ne fait aucun effort pour dissimuler l'adresse du pair avec qui on échange des fichiers. Même chose avec NTP, si les machines de votre réseau local se synchronisent directement à l'extérieur, ce qui les rend visibles à Shodan.)

On trouve également des adresses IP dans les caches NDP (section 8) - et ces caches peuvent parfois être examinés à distance avec SNMP (section 13), dans les journaux (gérer un serveur Web populaire permet d'en récolter beaucoup, cf. section 9), via les protocoles de routage (section 10), via traceroute (section 12)... Au passage, il est recommandé de lire l'excellent article de Bellovin, S., Cheswick, B., et A. Keromytis, « Worm propagation strategies in an IPv6 Internet » dans login: en 2006.

L'annexe A du RFC décrit une mise en œuvre des principales idées expliquées dans ce document. Si vous voulez tous les détails techniques sur le balayage en IPv6, c'est le texte à lire. Il faut par exemple être prudent : un balayage exhaustif en IPv6 peut nécessiter un nombre colossal de paquets et, si on les envoie trop vite, l'augmentation du trafic vous fera repérer (variante : vous surchargerez le réseau, des paquets seront perdsu et vous raterez ainsi des réponses). Cette annexe couvre également les méthodes de dissimulation, pour éviter d'être détecté (avec la plupart des IDS IPv6, il suffit d'ajouter des en-têtes d'extension au paquet). Le tout est évidemment très inspiré de l'expérience de l'un des auteurs du RFC avec l'outil scan6, déjà cité.

Je ne fais pas ici un résumé des différences avec son prédécesseur, le RFC 5157, car il y en a beaucoup trop (notre nouveau RFC est bien plus détaillé).


Téléchargez le RFC 7707

Version PDF de cette page (mais vous pouvez aussi imprimer depuis votre navigateur, il y a une feuille de style prévue pour cela)

Source XML de cette page (cette page est distribuée sous les termes de la licence GFDL)