Tuesday, November 23, 2010

IPv6 link-local host discovery concept

Recently I spoke about IPv6 security at the dc303 meeting.  I was trying to do a demo of the new metasploit module, but the local switch had IPv6 disabled.  Scott Hogg ended up using Scapy to send a spoofed router advertisement packet which would in turn force all hosts to do an IP auto discovery.  Think about how you can take this to the next level, and use it for host discovery in situations where hosts do not respond to ping's, and without having to brute force scan.

The idea behind this is that your OS/kernel deals with IP auto configuration; it is done using ICMP packets, and are packets that (for the most part) bust be responded to and processed.  Un-like IPv4, you cant just drop all ICMP.  If your machine is on a network without IPv6 turned on, it will not obtain a global address.  ifconfig will look something like (mac addresses have been modified):

$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:1a:a0:52:11:22  
          inet addr:  Bcast:  Mask:
          inet6 addr: fe80::21a:a0ff:fe52:1122/64 Scope:Link

Notice, you only have 1 IPv6 address.  

In order for your OS to start doing an IP auto-config, it will have to be directed by a router on the local segment to obtain an IP address via IP auto-config; it must see a ICMPv6 router advertisement message . There are a few things that come to mind when thinking about how to craft this spoofed packet:

1. Have it look like it was sent from the legitimate router (use the router MAC) 
2. Have it look like it was sent from someone else on the network - making it look like someone else is doing your dirty work
3. Completely random information
4. Completely legitimate information

I am going to use Scapy to create the router advertisement.  The packet will look like this:

>>> a = IPv6()/ICMPv6ND_RA()/ICMPv6NDOptPrefixInfo(prefix='2001:db8:dead:beef::', prefixlen=64)/ICMPv6NDOptSrcLLAddr(lladdr="04:1E:DD:AA:BB:73")

Broken down:
This is the IPv6 header
This says the packet is going to be an ICMPv6 Neighbor Discovery Router Advertisement
ICMPv6NDOptPrefixInfo(prefix='2001:db8:dead:beef::', prefixlen=64)
This is an ICMPv6 Option, of type Prefix Information.  The prefix/prefixlen says that during the auto-ip config process, each node will attempt to get a /64 with the prefix 2001:db8:50:50::
Another ICMPv6 Option, of type Source Link Local Address, or what MAC address is the default route/router.

To put this on the wire, you simply run:

>>> send(a)
Sent 1 packets.

Note: I have been having a lot of difficulty on OSX doing this, not sure the exact issues

This will cause all of the devices on the link-local to start auto-config'ing another interface.  ifconfig should look something like:

$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:1a:a0:52:11:22  
          inet addr:  Bcast:  Mask:
          inet6 addr: 2001:db8:dead:beef:21a:a0ff:fe52:1122/64 Scope:Global
          inet6 addr: fe80::21a:a0ff:fe52:1122/64 Scope:Link

Something interesting to notice is that on this host (Ubuntu) the IPv6 addresses have the same host portion of the IP address:

Note: New Windows randomize addresses, and periodically change them.

This concept can be used for a link-local host discovery even for hosts that are not responding to ICMPv6 PingRequest's.

1. Send out a Router Advertisement
2. Monitor for all Host Advertisements
3. Replace first half of seen IPv6 address with the first half of the link-local address
4. Send a ICMPv6 HostSolicitation to the link-local address for confirmation

metasploit module to follow.


  1. Please take a look at this discussion on your technique:


  2. lists [dot] si6networks [dot] com/pipermail/ipv6hackers/2012-April/000554.html