Having fun with IP addresses
16. Februar 2020
In one of my projects, I had to deal with IP address filtering.
During my research, I came across a Wikipedia article about IPv4 addresses. In the section "Address representations" I read the following:
IPv4 addresses may be represented in any notation expressing a 32-bit integer value. They are most often written in dot-decimal notation, which consists of four octets of the address expressed individually in decimal numbers and separated by periods.
The part of the definition that I found very interesting was: "be represented in any notation expressing a 32-bit integer value". What does that mean exactly? I wanted to figure out which formats are supported and what I can do with this.
So I started trying different address formats with the "ping" command. All the following examples use the IP address 172.217.23.36 (one of the IP addresses of google.com).
Representations with different numeral systems
Decimal representation
172.217.23.36 can be converted to the decimal number (DWORD) 2899908388. The ping command can handle this format.
$ > ping 2899908388
PING 2899908388 (172.217.23.36): 56 data bytes
64 bytes from 172.217.23.36: icmp_seq=0 ttl=54 time=26.883 ms
64 bytes from 172.217.23.36: icmp_seq=1 ttl=54 time=26.915 ms
Octal representation
Octal numbers start with a zero followed by the octal value. Both of the shown options work fine:
$ > ping 0254.0331.0027.0044
$ > ping 025466213444
Hex representation
So it is not surprising that hex format works fine as well. The number must be prefixed with "0x" to mark it as hex a number.
$ > ping 0xac.0xd9.0x17.0x24
$ > ping 0xacd91724
Binary representation
Is it also possible to use the binary format as well? First I tested the dot-notation:
$> ping 10101100.11011001.00010111.00100100
ping: cannot resolve 10101100.11011001.00010111.00100100: Unknown host
So this format is not supported. Next, I omitted the dots.
$ > ping 10101100110110010001011100100100
PING 10101100110110010001011100100100 (91.188.38.4): 56 data bytes
Request timeout for icmp_seq 0
The ping command was able to find an address, but it is not the address I expected. The reason for this is that in this case the number is interpreted as a decimal number. If the number starts with a zero, the number is interpreted as an octal number. The ping command uses only the last 32 bit to get the IP address to be pinged. So this format does not work as expected.
Mix numeral systems
In my next attempt, I tried to use different numeral systems for the individual components. I mixed decimal, hex and octal numbers. This worked well. The example below shows one of the combinations I tested.
$ > ping 0xac.0331.23.0x24
Omit parts
I can omit different parts of the IP address. These parts are interpreted as zeros. The following ping command pings the loopback adapter:
$ > ping 127.1
$ > ping 0x7f.1
$ > ping 127.0x1
The following address is also valid:
$ > ping 192.168.1
PING 192.168.1 (192.168.0.1): 56 data bytes
64 bytes from 192.168.0.1: icmp_seq=0 ttl=63 time=8.358 ms
Add parts or characters
Will it be possible to add characters that do not change the value of the address like leading characters? The following examples show some combinations that work.
$ > ping 0254.0331.00000000000000027.0044
$ > ping ping 0254.0331.0000000000000000000000027.0044
$ > ping 0xaabbccacd91724
$ > ping 0xa00000000000ffffffffffffffffffffffffffffffffacd91724
$ > ping 02525674625466213444
$ > ping 012313123123123123123123123123123123025466213444
$ > ping 48057233788442404
They work well because the ping command uses only the last 32 bits to calculate the IP address.
Browser test
Do all these addresses also work in Google Chrome or any other web browser?
I tested a lot of combinations in different browsers. Not all of the mentioned address formats also work in web browsers. But there are many that do. So you can enter the following URL in Google Chrome and you will be redirected to https://www.google.com.
http://2899908388
Conclusion
There are some (minor) restrictions in the representation of an IP address. Despite these limitations, many different types of representation can be used. As a result, a correct IP address is difficult to recognize. This makes it very difficult to implement various components such as filters for preventing Cross-Site Scripting Attacks (XSS). Hackers can expect that these filters do not cover all IP address representations and thus allow them to run XSS attacks.