Breaking

Evasion of Cisco ACLs by (Ab)Using IPv6 & Discussion of Mitigation Techniques

This is a guest post of Antonios Atlasis.

During our blogpost regarding DHCPv6 Guard evasion, one of the side-effects was that Access Control Lists (ACLs) configured to block access to UDP ports 546 can be evaded by abusing (again) IPv6 Extension headers. Having that in mind, we decided to check the effectiveness of Cisco IPv6 ACLs under various scenarios. Our goal was to examine whether the IPv6 ACLs of Cisco routers can be evaded, as well as under which conditions this can take place. To this end, several representative scenarios from enterprise environments or other potential ones are examined.

The lab set-up used for the experiments is as following:


lab_setup

 

The exact version of the used router is displayed in the below “show version” output:

Router>show version                                                            

Cisco IOS Software, C1900 Software (C1900-UNIVERSALK9-M), Version 15.4(3)M, REL)
Cisco CISCO1921/K9 (revision 1.0) with 491520K/32768K bytes of memory.         

The tool used to launch the attacks is Chiron.

The testing scenarios that were examined are the following:

Case A: SSH is Blocked and Any Other IPv6 Connection is Allowed (Default Allow)

In this case we block a specific service (as for example SSH) and we allow any other IPv6 connection. This is a common scenario in enterprise environments where we want to restrict access to sensitive services running to the device itself or behind a device, like SSH, while all the other traffic is allowed. An output of the ACL configuration is given below.

Router#show ipv6 access-list                                                   

IPv6 access list protect_infrastructure
    deny tcp any any eq 22 sequence 10
    permit ipv6 any any sequence 20

In this case, the attacker’s goal is to reach the target’s SSH port as well as the SSH port of the router itself. This can be achieved by using the following generic way:

headers1

 

 

 

 

 

 

 

In the above figure, the “Other Extension Header” can be:

  1. When the target is an Operating System like Linux, a Destination Options header, a Hop-by-Hop header, a Routing header (even a Type-0 one), or another Fragment Extension header (with offset=0 and the M-bit unset).
  2. When the target is the router itself, all of the above but the Hop-by-Hop header. This is due to the fact that according to RFC 2460 the Hop-by-hop header MUST immediately follow the IPv6 main header, which is not the case here; it seems that Cisco IOS respects this recommendation and does not process packets when the Hop-by-hop header does not immediately follow the IPv6 main header. However, all the rest (Routing header, Destination Options header, or even Fragment header) can be used successfully.

One of the possible Chiron commands that can be used to replicate such an attack, is the following:

./chiron_scanner.py enp7s0 -d 2001:db8:1:2:be5f:f4ff:fede:d90d -gw 2001:db8:1:1::1 -sS -p 22 -lfE 60 -nf 2

A screenshot of a Wireshark capture that demonstrates the aforementioned attack is displayed below.

CiscoACL-evaded

 

 

Case B: A Hop-by-Hop Header is Allowed and a Default Deny Rule is Used

In this case we assume that there is a default deny rule but packets with a Hop-by-Hop header are allowed. An example of such an ACL is displayed below.

IPv6 access list myrule2

    permit hbh any any (1 match) sequence 10
    deny tcp any any eq 22 (1 match) sequence 20

The goal of the attacker is to reach any service (like SSH) which is nevertheless blocked by the default deny rule. This can be used by:

1. Adding a Hop-by-Hop header and leaving the IPv6 datagram unfragmented.

 

headers2

 

 

 

The corresponding Chiron command is the following:

./chiron_scanner.py enp7s0 -d 2001:db8:1:2:5a55:caff:fe24:933d -gw 2001:db8:1:1::1 -sS -p 22 -lfE 0

 

2. Adding a Hop-by-Hop header and splitting the IPv6 datagram in two (2) fragments.

 

headers3

 

 

The corresponding Chiron command is the following:

./chiron_scanner.py enp7s0 -d 2001:db8:1:2:5a55:caff:fe24:933d -gw 2001:db8:1:1::1 -sS -p 22 -lfE 0 -nf 2

 

Case C: Permit a Specfic Service Explicitly Tighted with an Extension Header and Use a Deafult Deny

In this case, if we want to allow a specific service (as for example WWW) as well as the use of an Extension header like Hop-by-Hop, we define such a ruleset that tights the use of this extension header with the specific service. Example:

IPv6 access list myrule4

    permit tcp any any eq www sequence 10
    permit tcp any any eq www hbh sequence 20

In the above example, a) we allow the use of www and b), we also allow the use of Hop-by-Hop Extension header (hbh) with www, but without allowing hbh on each own. The goal of the attacker is again to reach a service, like ssh, which otherwise is forbidden.

The above approach seems to work quite well (it cannot ve evaded), but it creates a few problems.

First, these combinations must be repeated for all the services that we want to allow, as well as for all the corresponding Extension headers. This makes the management of the ACL more difficult than usually.

Secondly, it creates some false alarms. For instance, if we add a Destination Options Header and fragment it in two fragments, these are  blocked even when we try to reach the www service. The corresponding Chiron command for such a case is the following:

./chiron_scanner.py enp7s0 -d 2001:db8:1:2:5a55:caff:fe24:933d -gw 2001:db8:1:1::1 -sS -p 80 -luE 0 -lfE 60 -nf 2

The same is also true if we just fragment an IPv6 datagram which includes a Hop-by-Ho header:

./chiron_scanner.py enp7s0 -d 2001:db8:1:2:5a55:caff:fe24:933d -gw 2001:db8:1:1::1 -sS -p 80 -lfE 0 -nf 2

The packets created by the above command are fully legitimate and hence, they should not be dropped.

Mitigation Techniques

Although the configuration of Case C can be used to block effectively evasion attacks as long as it is done properly, its complexity, which increase significantly with the necessity of adding more rules, may make it not that a feasible solution. Hence, the best approach seems to be the blocking of IPv6 fragmentation.

To block a specific Extension header, we can use a rule like the following:

deny 43 any any

This rule blocks packets that include a Routing header (next header value = 43). We should repeat similar rules for all known Extension headers, i.e. to block packets which include a Destination Options header, we should add:

deny 60 any any

and so on. However, the following rule is not enough to forbid fragmentation:

deny 44 any any

Although the next header value of the Fragment header is 44, this rule seems to be effective only when we encapsulate a Fragment Header in another fragment. Instead, to totally block fragmentation in IPv6, we should add:

deny ipv6 any any fragments

This last rule blocks IPv6 fragmentation completely and even on each own, it should be more than enough to block most of the attacks, if not all of them.

Another way of mitigating the risk of fragmented Extension headers and moving the layer-4 header at the second fragment, officially suggested by Cisco themselves, is to use the “undetermined transport“ feature. In this case, the corresponding ACL is modified as following:

IPv6 access list protect_infrastructure
deny ipv6 any any log undetermined-transport sequence 10
deny tcp any any eq 22 log sequence 20
permit ipv6 any any sequence 30

Such an ACL works effectively. It blocks access to ssh as well as any packets when layer-4 header is inot included in the first fragment.

Conclusions

Once more, it has been shown that IPv6 Extension headers and fragmentation can be abused by attackers to evade security or networking devices, like routers in this case (provided a certain insufficient configuration is present, which from our observations is a quite common case). So deep knowledge and careful configuration is required by the network administrators so as to enable IPv6 in their networks whilst protecting their assets from such attacks.

At IPv6 Security Summit at Troopers 15  I will have the pleasure to give a half-day hands-on workshop on using Chiron so as to use it efficiently for testing the security effectiveness of your configuration in your networks.

Antonios

Comments

  1. Hi, did you actually try to configure an ACL that drops destination-options header (deny 60 any any)? The reason why I am asking is, that if I try to configure the ACL on L2 or L3 switch (2960s, 3750x), I am not able to drop the traffic containing extension headers.

    I though, that following IPv6 ACL could block packets with destination-options header or hop-by-hop header:

    deny 0 any any
    deny 60 any any
    permit ipv6 any any

    However, it does not, which is quite bad.

Leave a Reply

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