Bypassing IP Address Filters With Rare IPv4 Notations
Introduction
If you’re reading this you’d probably recognise an IPv4 address such as 127.0.0.1
however, this is just the dotted decimal representation of the underlying int32 that makes up an IPv4 address. There are a number of notations, each with a standard and dotted form:
- 127.0.0.1 [Dotted Decimal]
- 0177.00.00.01 [Dotted Octal]
- 0x7f.0x0.0x0.0x1 [Dotted Hex]
- 2130706433 [Decimal]
- 017700000001 [Octal]
- 0x7f000001 [Hex]
That leads to an interesting possibility that functionality requiring a user to provide an input referencing a resource may implement a deny list of IP addresses for sensitive internal resources such as 127.0.0.1
, or 169.254.169.254
. This type of deny list may fall short in not catering for the relatively unknown alternative notations.
Origins
These are briefly mentioned in RFC3986 - Section 7.4 as more of an acknowledgement of implementations, and not something explicitly defined by the spec itself. These implementations seem to have made their way to BSD, Linux, Windows, and Android (iOS untested) as such each of these should work in the same way when passed to something that expects an IPv4 address, go ahead and try it with something like ping
.
Optional Zero Values
In addition to just representing the address in a different base, elements of the address can also be ommited, originally design to deal with notations of different IP address classes, and in a similar way to IPv6 0 value segments being optional to display. This means there are a few more formats we can potentially add into the mix alongside the bases. Taking just the dotted decimal form we would have:
- 127.0.0.1
- 127.0.1
- 127.1