It has been already almost three years than I last checked and presented (at BlackHat Asia 2012 and Troopers 13) the Operating Systems (OS) behaviour in case of non-compliant (according to RFC 2460) usage of IPv6 Extension headers. One of the cases that examined (briefly) at that time was a kind of “nested” IPv6 fragmentation. In this blog post I will present my latest results regarding this topic by trying to also extend the previous work with some more potentially interesting cases.
Starting from the very basic, fragmentation fields in IPv6 have been removed from the IP main header (where they used to be in IPv4); instead, a specific IPv6 Extension header, the so called Fragment Extension header, is used for fragmentation purposes in IPv6. This header, incorporates, among else, the Offset field, the Fragment Identification Number field and the “More Fragment to Follow” (M) bit. Normally, there should be only one Fragment Extension header per IPv6 fragment (why a legitimate sender should use more than one?), but RFC 2460 is not that strict with this: “Each extension header should occur at most once, except for the Destination Options header which should occur at most twice”. In any case though, I am not aware and I cannot think any kind of a legitimate case that an OS could incorporate more than one IPv6 Fragment header in one fragment.
In my last experiments I tested the following Operating Systems:
Windows 10 Home, Version 1511, OS Build 10586.36, x64
Centos 7, kernel 3.10.0-327.3.1 x86_64
Fedora 23, kernel 4.2.8-300 x86_64
FreeBSD 10.2-RELEASE-p7, amd64
OpenBSD 5.8, GENERIC#1170 amd64
The tool used for the testing was, what else, Chiron.
As a layer 4 protocol, ICMPv6 Echo Request was used (since it is the easiest way to trigger a response).
Let's start from defining a baseline by examining which OS accept Atomic fragments. These are fully compliant cases (by the way, there is a current, ongoing effort to deprecate them, but that is another story). Atomic fragments are the ones whose offset is equal to 0, and the M bit is also equal to 0, implying that this is the first and at the same time the last fragment. They are used in the very special cases (which, however, our out of the scope of our discussion). Such a use case can be reproduced by using the following Chiron command:
./chiron_scanner.py vboxnet0 -d 2001:db8:1:1::1,2001:db8:1:1::2 -lfE 44 -sn
vboxnet0 is the network interface to use.
2001:db8:1:1::1 and 2001:db8:1:1::2 are (some of) our targets (obviously using a comma-separated list, more targets can also be tested using a single command, but they are not written here for brevity reasons).
-lfE 44 adds an “Atomic” Fragment Extension header (44 is the next header value of a Fragment Extension header), and
-sn is used for sending ICMPv6 Echo Request as a layer 4 header (nmap notation).
As expected (since this is a fully legitimate case), all OS respond to such fragments.
In this blogpost for convenience reasons I use the term “Atomic Fragment Extemsion header” an IPv6 Fragment Extension header which is used in Atomic fragments, that is one which has Offset=0 and M=0.
Tested Case 1: Two “Atomic” Fragment Extension headers in a single IPv6 datagram
First, let's see what happens when using two “Atomic” IPv6 Fragment Extension headers in a row in the same IPv6 datagram (figure 1).
Figure 1: Two “Atomic” Fragment Extension headers in a single IPv6 datagram (the length of the headers in the figure are not in scale)
The above case can be reproduced by using the following Chiron command:
./chiron_scanner.py vboxnet0 -d 2001:db8:1:1::1,2001:db8:1:1::2 -lfE 44,44 -sn
The results showed that it is all OS except from OpenBSD that respond to them. While typically such a case “could” be typically considered RFC compliant )according to the aforementioned RFC 2460 quote”, there is definitely no real, legitimate usage of such a case.
Test Case 2: Fragmented Atomic Fragments
In this case, a ...fragmented (in two fragments) Atomic fragment is sent. These fragments looks like:
Figure 2a: A ...fragmented Atomic fragment (the length of headers in the figure are not in scale)
The reassembled IPv6 datagram will look like:
Figure 2b: A reassembled ...fragmented Atomic fragment (the length of headers in the figure are not in scale)
This case can be reproduced with the following Chiron command:
./chiron_scanner.py vboxnet0 -d 2001:db8:1:1::1,2001:db8:1:1::2 -lfE 44 -sn -nf 2
In the above command, while we have already added an “Atomic” Fragment Extension header using the -lfE 44 switch, we further fragment it using the -nf 2 switch.
No need to say that such a case should not be accepted in the real world :-)
The results showed that Fedora, Centos and Windows 10 accept these fragmented Atomic fragments.
Test Case 3: “Atomic Fragmentation”
In this case, an Atomic Fragment Extension header is added in front of each fragment of an otherwise normally fragmented IPv6 datagram. Specifically, let's assume that we have the following initial IPv6 datagram:
Figure 3a: A simple IPv6 datagram that incorporates one IPv6 Extension header (the length of headers in the figure are not in scale)
In the above datagram, a Destination Options Extension header was added to send the layer 4 header (ICMPv6 Echo Request in our case) to the second fragment (when fragmented, of course). So, when fragmented, the above datagram will look like:
Figure 3b: A fragmented IPv6 datagram that incorporates one IPv6 Extension header (the length of headers in the figure are not in scale)
Now, let's add an Atomic Fragment Extension header just after the IPv6 main header. So, now our fragments are turn into the following:
Figure 3c: “Atomic Fragmentation” (the length of headers in the figure are not in scale)
The above case can be reproduced using the following Chiron command:
./chiron_scanner.py vboxnet0 -d 2001:db8:1:1::1,2001:db8:1:1::2 -luE 44 -lfE 60 -sn -nf 2
In the above command:
-lfE 60 adds a Destination Options Extension header in the fragmentable part (60 is the next header value of a Destination Options header),
-luE 44 adds an “Atomic” Fragment Extension header in the unfragmentable part (44 is the next header value of a Fragment Extension header), and
-nf 2 splits it in two fragments.
Which OS responds to such fragments? Just Windows 10!
Potential security implications?
The typical ones. Remote OS fingerprinting, potential IDPS evasion, fuzzing of the targeted OS.
Can we make it even more complicated? Possibly. Using IPv6 Extension headers, sky is the limit ;-)
In a next blogpost I will discuss IPv6 Jumbodatagrams and how these can be sent (in very specific cases) over normal (e.g. Ethernet) MTU links.