Brute-force protections – designed to protect against attacks like password guessing – need to be carefully pitched and have associated pros and cons. Account lockouts, if poorly designed, can lead to denial of service attacks against users. CAPTCHAs can be annoying for users and may be inaccessible. Many popular protections these days rely upon monitoring and blocking malicious activity based on source IP address. This has many advantages over other methods – there is no impact on the activity of normal users when a malicious source is blocked, and as there’s no user interaction required it’s very accessible for all application consumers.
These types of source IP related blocks are often also used in conjunction with blocks against “known-bad” source IP addresses too – e.g., blocking of tor exit nodes, blocking of undesirable source geolocations or blocking of known proxy addresses. Combining these measures, many application providers hope that they can cut down on brute-force style attacks from most casual attackers. The assumed barrier at this point is that an adversary would need to control a distributed network (like a botnet) in order to be able to conduct such an attack – and that this will drastically reduce exposure. When IPv6 is involved, this assumption may not hold true.
IPv6 address space
IPv6 is designed to support every network-connected device having a globally-routable address, eliminating the need for abstractions such as Network Address Translation (NAT). The address space for IPv6 is very large – compared to the address space for legacy IPv4 which is now exhausted.
ISPs supporting native IPv6 connections for their customers tend to assign each customer with an allocated subnet block with a /48 prefix (from which customers can create up to 65,536 /64 subnets). Each of these typical /64 subnets has 264 (~18 quintillion) potential addresses – several orders of magnitude more possible addresses than the whole IPv4 address space.
In practice, what this means is that a user with a native IPv6 connection has access to a potentially huge IP address source address space.
IPv6 temporary addressing
In stateless address autoconfiguration (SLAAC), MAC addresses are used to create interface identifiers that form part of an IPv6 address. A MAC is assumed to be static and globally unique, and therefore is incorporated into the interface identifier for the IPv6 address. As MAC addresses are associated with a particular network interface (and do not change in normal circumstances) this means that addresses configured via SLAAC have the side effect of allowing devices to be tracked across different networks. If, for example, a user moved their laptop from one IPv6 network to another IPv6 network, their interface identifier would not change even though their prefix would. This results in obvious privacy concerns.
To address this, IPv6 Privacy Extensions (https://www.rfc-editor.org/rfc/rfc4941) was introduced. Most modern operating systems use IPv6 temporary addresses for outbound connectivity rather than their SLAAC address associated with their MAC. Temporary addresses are generated by a node based on time-varying random bit strings and have a short lifetime (typically not longer than a day). Due to their short lifetime, and random nature, they don’t allow users to be tracked across different networks, aiding privacy.
Abusing IPv6 to avoid rate limits
With a network connection supporting SLAAC and an IPv6 subnet, it turns out that it’s very easy for an adversary to launch an attack from a single source host which bypasses protective controls based on blocking single source IP addresses.
In a Linux host, for example, the following two kernel parameters control the lifetime of a temporary IPv6 address, in seconds:
net.ipv6.conf.all.temp_prefered_lft = 86400 net.ipv6.conf.all.temp_valid_lft = 604800
Altering these settings to a low value means that temporary addresses are refreshed every few seconds:
sysctl net.ipv6.conf.all.temp_prefered_lft=5 sysctl net.ipv6.conf.all.temp_valid_lft=5
We haven’t tested this with a Windows server, but the principal is the same.
Where automation protections block a source IP address that makes a certain number of requests within a time period, rotating temporary IPv6 addresses every few seconds allows an attack to be continued without interruption by blocks. In our experiment with Linux hosts and virtual machines, the behaviour of the IPv6 temporary address cycling became unreliable once we set the lifetime parameters down to somewhere below 5 seconds, so your mileage may vary in experimenting with this as a technique, but it certainly allowed us to bypass a control with ease.
There are some obvious limitations to this tactic. Unlike with using Tor, there’s no anonymity provided by the technique; your ISP will see the activity and be able to track these addresses back to you as a customer, but it does allow you to bypass source IP based blocks fairly quickly.
As a defender, if your assumption on barrier to entry for source IP address blocking controls is that an adversary would need a large botnet in order to conduct an attack, it’s an assumption you might want to revisit. You should look at other controls that you could implement to complement these blocks.