Building

Should IPv6 Packets With Source Address ::1 Be Processed When Received on an External Interface?

This is a guest post from Antonis Atlasis.

Most of you are probably aware of the recently discovered/-closed severe ntpd vulnerabilities (CVE-2014-9293, CVE-2014-9294, CVE-2014-9295, CVE-2014-9296, see also the initial ntp.org security notice). Some days ago the Project Zero team at Google published a blog post “Finding and exploiting ntpd vulnerabilities” with additional details. In this one they mentioned a seemingly minor but quite important detail: on a default OS X installation one of the built-in protection mechanisms of ntpd (that is the restriction to process certain packets only if they are sourced on the local machine) can easily be circumvented by sending IPv6 packets with a spoofed source address of ::1 (the equivalent to 127.0.0.1 in IPv4 which would be discarded by the kernel once received from an external source).

This brought up a number of more generic questions:

a) Should such packets having as source address the IPv6 loopback one be processed at all?
b) Which OSs process such packets?
c) How can we protect our systems from them?

Taking into account that a legitimate user or host has no reason to send packets to an external interface having as source address the IPv6 loopback one (::1/128), the answer to the first question is , in my opinion, “No”. Several services, like ntpd, listen by default to this address and so, if the underlying OS processes such packets, these services are reachable even if they are (should) not by other addresses. So, let’s try now to answer the second questions. Which modern OSs process such packets? For our study, the following OSs were tested:

  • Centos 6.6, 2.6.32-504.3.3.el6.i686
  • Windows 2012R2 64bit
  • FreeBSD 10.1-RELEASE #0 r274401 amd64
  • FreeBSD 8.4-RELEASE #0 r251259 amd64
  • OpenBSD 5.6 GENERIC#310 amd64
  • Centos 7, kernel 10.0-123.13.2.el7.x86_64
  • Fedora 20, 3.17.7-200.fc20.i686
  • OS-X Yosemite, version 10.10.1 (before and after applying the ntpd patch, just in case)

 

To keep things simple, I tried to use a network-wise way to find out if the discussed packets are processed or not. To this end, I used the following two steps.

  1. Send a TCP SYN packet to a port where there is a listening service (e.g. http, ssh, or smb, depending on the OS) by following the normal procedure (perform Neighbor Solicitation first before sending the TCP SYN packet).
  2. Send the TCP SYN packet by specifying manually the correct target and source MAC addresses, to avoid the Neighbor Solicitation process.

To verify that the packets were processed, I checked the following:

  • Whether there is a Neighbor Advertisement response to the Neighbor Solicitation packet.
  • Whether there is a TCP SYN-ACK, or TCP RST (for non-listening services) as a response to the TCP SYN packet.

To generate the spoofed packets, I used Chiron, and specifically its scanner module.

Let’s start with Centos 6.6. For the 1st test, I used the following command:

./chiron_scanner.py vboxnet0 -sS -d fe80::a00:27ff:fed1:d17a -p 80 -s ::1

where:

vboxnet0 is the interface to use,

and fe80::a00:27ff:fed1:d17a is the link-local address of the target (I could use the global one too, but I wanted to make the test more generic).

The source MAC address of the attacker is 0a:00:27:00:00:00.

A screenshot of a Wireshark capture at the outer interface is displayed below:

Screenshot - 01042015 - 103515 PM

As we can see:

a) Chiron performs Neighbor Solicitation using as source IPv6 address the ::1 (packet 1)

b) Target responds to ::1 with a Neighbor Advertisement (but using the attacker’s MAC address as a destination address). => It processes the Neighbor Solicitation message directed to ::1 (packet 2)

c) Attacker (Chiron) sends a TCP SYN to ::1 (packet 3)

d) Target initiates its own Neighbor Solicitation to ::1 => processes the TCP SYN? (packets 4-6)

Obviously, there is no response to these last Neighbor Solicitation messages to ::1 and hence, no further communication.

Now, let’s continue with the 2nd test mentioned above:

./chiron_scanner.py vboxnet0 -sS -d fe80::a00:27ff:fed1:d17a -p 80 -s ::1 -tm 08:00:27:D1:D1:7A -m 0a:00:27:00:00:00

The corresponding Wireshark output is displayed below:

Screenshot - 01042015 - 104126 PM

As we can observe:

a) Chiron sends a TCP SYN to ::1 (directly to target’s MAC address) (packet 1).

b) The target sends a SYN-ACK to ::1 (packet 2)!

c) The target, using as source address the ::1, RESETs the connections since it never really initiated it. (packet 3)

The two tests above demonstrate that Centos 6.6 processes incoming packets from external interfaces having as source address the ::1/128.

To make a long story short, this was also the case for the rest of the tested Linux systems (Centos 7, Fedora 20). These Linux distros were chosen as representatives of different Linux kernel generations.
This was also the case for OS-X Yosemite, version 10.10.1 , both before and after applying the ntp patch (which, of course, patches just the ntpd vulnerabilities and not that OS-X processes IPv6 packets from external interfaces having as source address the ::1/128 one).
On the contrary, all the rest (FreeBSD tested variants, OpenBSD and Windows 2012R2) do not process them.
So, how serious is the aforementioned issue? Well, it allows an attacker to access and interact with a connectionless service (e.g. based on UDP) even if this listens only to localhost (and there are plenty of them out there!).

How can we mitigate this risk? In my humble opinion, the best way would be the Operating Systems not to process such packets. But, when this is not the case, an alternative is to use the host firewall.
For instance, using ip6tables, to allow the IPv6 localhost packets only for the loopback interface, you can do the following:

ip6tables -A INPUT -s ::1 -d ::1 -i lo -j ACCEPT

ip6tables -A INPUT -s ::1 -j DROP

The above ip6tables commands simply accept IPv6 packets having as source address the ::1 only when they are destined to ::1 and only using the loopback interface, while they drop all the rest. Simple, but effective.

As always, comments and questions are welcome.
If you are interested in all the nice things that can be done with Chiron (incl. the IDPS evasion stuff we demonstrated at Black Hat) it might be a good idea to join my half-day Chiron workshop in the course of the upcoming Troopers IPv6 Security Summit in Heidelberg on Mar 16th and 17th.

Have a great week

Antonios

Comments

  1. Antonis,

    Nice walk through the issue. It’s interesting to “look over your shoulder” as you test. That’s also quite disturbing that Linux and OS X accept these packets by default. Apparently input validation is still an issue.

    –Jim

  2. Let’s not make this any more confusing than it needs to be, here’s a couple of typos 🙂

    > a) Chiron sends a TCP SYN to ::1 (directly to target’s MAC address)
    ^ from

    > b) The target sends a SYN-ACK to ::1

    No typo, but IUC this is Linux, violating the RFC that says not to send to ::1. Maybe this is the best lawyer-ly argument for dropping packets sourced from ::1 ?

    > c) The target, using as source address the ::1, RESETs the connections since it never really initiated it. (packet 3)
    ^ attacking machine

    . Interestingly c) above shows a clear violation of the RFC, sending a packet from ::1 on

    I’m surprised you didn’t have to disable rp_filter on Linux (strict RPF check). It’s apparently enabled by default on distros including RHEL.

    I don’t see the difference between test 1 and test 2 from the targets pov. I.e. why the target skips ND in test 2.

    Behavior does seem to differ from ipv4 and this can be seen in the source code.

    http://www.linuxquestions.org/questions/linux-security-4/can-127-0-0-1-be-spoofed-687743/

    http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/ipv4/route.c#n1699

    http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/ipv6/ip6_input.c#n115

    Certainly it’s an unnecessary difference when migrating from ipv4. And it should be legal to ignore packets which weren’t legal to send. It’s not like it’s a field that’s been reserved for future extensions.

Leave a Reply

Your email address will not be published. Required fields are marked *