This is a guest post from Antonios Atlasis.
Hi all,
during our BlackHat US 2014 talk titled “Evasion of High-End IPS Devices in the Age of IPv6”, among others we discussed a Snort preprocessor rule (116:456) which, when enabled (not the case by default), triggers an alert when an IPv6 datagram with nine (9) or more IPv6 Extension Headers is used (such a header was used by us to evade Snort). However, we mentioned that:
a) This was not the best way to handle the risk of evasion by abusing IPv6 Extension Headers.
b) In theory there can be nine or more Extension Headers in an IPv6 chain (although in the real world I would be really surprised if we would see that number in production traffic).
Later, at our BlackHat EU 2014 talk (this is the whitepaper with the detailed commands we used) we showed, in the course of our demos, how you can evade Snort by using up to five (5) IPv6 Extension Header per fragment, including the Fragment Extension Header. So, in this case the IPv6 Extensions Headers hard limit described above was actually useless.
When Snort 2.9.7.0 was released on 23rd of October, a few days after BlackHat EU (coincidence?), in the changelog it was written that “a new config option `max_ip6_extensions` to change the maximum number of IPv6 extension headers decoded” was added. We do not know if this was a reaction to our comment about how Snort handles IPv6 Extension Headers during our first talk or, to the vulnerability disclosed in our second one (for which, by the way, we had informed promptly the Sourcefire/Cisco guys) but in either case, this was definitely good news. So, we decided to try it out.
First, let’s see how you can configure it. At the beginning it wasn’t that clear to me (but I am not the most experienced Snort user either); finally, I found out that you have to add a line like the following to the snort.conf file:
config max_ip6_extensions: 2
Using the aforementioned configuration option, when you send a datagram that contains more than two (2) IPv6 Extension Headers, the following WARNING is triggered:
01/11-16:40:33.391730 [**] [116:456:1] (snort_decoder) WARNING: too many IP6 extension headers [**] [Classification: Misc activity] [Priority: 3] {IPV6-OPTS} fe80::800:27ff:fe00:0 -> fe80::a00:27ff:fe74:ddaa
You can easily reproduce this by using the following Chiron command, which adds a Hop-by-Hop and two Destination Options Headers (please, do not forget to enable the 116:456 Snort preprocessor rule before testing it):
./chiron_scanner.py vboxnet0 -d fe80::a00:27ff:fe74:ddaa -sn -lfE 0,60,60
Of course, you can even minimise the amount of accepted IPv6 Extension Headers by changing the max_ip_extensions to zero (0), as following:
config max_ip6_extensions: 0
Using the latest configuration, a WARNING will be triggered even when just one IPv6 Extension Header is included in an IPv6 datagram. Of course, the number of maximum Extension Headers which each organisation or company will accept/allow in their network depends on their security policy and the IPv6 operational capabilities they want to deploy.
Is this the proper way to fix the security issue of evading Snort by abusing IPv6 Extension Headers? I believe not. The optimum solution would be to avoid evasion even when several IPv6 Extension Headers are accepted. But certainly, it is much better than before, especially taking into consideration that we do not expect to see (at least not yet) even more than one IPv6 Extension Header in Internet/WAN connections in the “real world”.
At the IPv6 Security Summit which will be held during Troopers 15 in the beautiful city of Heidelberg, Rafael Schaefer and I will have the pleasure to review and update the status of two high-end commercial IDPS devices (Tipping Point and Sourcefire) and two open-source ones, including Snort regarding their (in)ability to handle IPv6 Extension Headers properly.
See you all there 🙂
Antonios