Friday, November 6, 2009

Bypassing firewalls with IPv6 tunnels

SkyHi @ Friday, November 06, 2009
Hello, it's Ryan. We've talked about IPv6 in blog entries and vulnerability notes before. But instead of focusing on IPv6 vulnerabilities, this blog entry will show how functional IPv6 tunneling protocols can be used to bypass IPv4-only firewalls and ACLs. If you'd like a demonstration, watch this video that we created.

For some background information, you may want to review Wikipedia's definition of IPv6 and our blog entry explaining why you should care about it. This post is primarily for users who may have IPv6 on their systems but have not actually deployed it.

To investigate IPv6 tunnels' effect on firewalls, we created a test to see how an IPv6 Teredo-compatible tunnel can be used to trivially bypass an IPv4-only firewall. The video referenced in the first paragraph shows our whole exercise in real time. We used a typical iptables firewall and appended the following rules to reject TCP connections that have the string "google" anywhere in the packet:

iptables -A OUTPUT -p tcp -m string --algo bm --string "google" -j REJECT
iptables -A INPUT -p tcp -m string --algo bm --string "google" -j REJECT

The rules work; browser connections to www.google.com fail. But the rules produce a large number of false positives, won't catch HTTPs connections, and are "expensive" to process, so don't paste them into your iptables script.

Lines 1-5 of this packet capture show exactly how the REJECT rule works (connections are closed, not discarded). There are also some interesting packets on lines 6 and 7. The packets in these lines are IPv6 packets being transported by IPv4 UDP. More specifically, the lines show a router solicitation (us asking for an IPv6 address) and a router advertisement (a router offering an IP prefix).

To see what happens when we browse to an IPv6-enabled website, let's go to http://ipv6.google.com. Looking at the capture file, you can see that the connection was successful. The HTTP GET string was transferred inside of a UDP packet and didn't trigger the iptables rules that were searching for that string inside of TCP packets (line 22).

We've illustrated the potential problem, but what about a solution? Trying to block ports can be effective but is likely to only work for specific brokers who are using the expected ports. Consider the following alternatives:

* IPv6-aware host-based firewalls can be effective. In our example, calling the ip6tables rules below would have blocked connections to http://ipv6.google.com.

ip6tables -A OUTPUT -p tcp -m string --algo bm --string "google" -j REJECT
ip6tables -A INPUT -p tcp -m string --algo bm --string "google"-j REJECT
*

If you're trying to block IPv6 tunnels on the network, you could look for router advertisements or solicitations. Those messages are sent to the all-nodes multicast address ff02::1. Here is an un-optimized example iptables rule that uses iptables:

iptables -I FORWARD 1 -p udp --dport 1024: -m string --hex-string "|ff 02 00 00 00 00 00 00 00 00 00 00 00 00 00 02|" --algo bm -j REJECT

One of our readers pointed out that blocking local IPv6 traffic could cause an operating system to activate an IPv6 tunnel. He is correct; however, this rule should not interfere with native IPv6—it only applies to IPv4 UDP connections that are going between two interfaces (the FORWARD chain).

*

We've heard that IPFilter development version 5.06 will decapsulate IPv6 in IPv4 packets and apply filtering rules. The following syntax, which we haven't tested, might block IPv6 in IPv4 tunnels:

decapsulate in on bge0 family inet6 proto ip all head ipinip6
block in all group ipinip6

*

Evan Wright from our Network Situational Awareness team pointed out that blocking protocols at border routers can stop some types of IPv6 connectivity. Using access control lists at border routers to block protocols 41 (used by 6to4), 43, 44, 58, 59, 60, and 192.88.99.1 (default anycast address of some 6to4 systems) would be a good place to start. Shown as an iptables example, it would look like this:

iptables -A FORWARD -p 41 -j REJECT
iptables -A FORWARD -p 43 -j REJECT
iptables -A FORWARD -p 44 -j REJECT
iptables -A FORWARD -p 58 -j REJECT
iptables -A FORWARD -p 59 -j REJECT
iptables -A FORWARD -p 60 -j REJECT

These examples may not directly apply to your network, but hopefully they illustrated the problem and gave you some suggestions that you can use as a starting point for improving the security of your firewalls.


Reference: http://www.cert.org/blogs/vuls/2009/04/bypassing_firewalls_with_ipv6.html