Turn One Internal IP Into Every Form A Filter Misses

Naive SSRF and URL allow/deny lists compare the raw string 127.0.0.1 and stop there. The operating system resolver does not: it packs the four octets into a single 32-bit number first, so a dozen other spellings resolve to the exact same host. Paste a target below to see them, computed live in your browser — nothing is sent anywhere.

How the packing works

An IPv4 address is not four numbers — it is one 32-bit unsigned integer, written in dotted-quad form only for humans. Given octets a.b.c.d the integer is:

N = a×16777216 + b×65536 + c×256 + d  (that is a×2^24 + b×2^16 + c×2^8 + d).

For 127.0.0.1 that is 127×16777216 + 1 = 2130706433. Because 2130706433, 0x7f000001 and 017700000001 are the same number, the classic inet_aton() resolver (used by curl, ping, PHP, and many HTTP libraries) accepts all of them as the same host. This tool reverses the packing to emit each equivalent spelling.

The class-based short forms. inet_aton() also accepts fewer than four parts and stretches the last one to fill the remaining bytes: a.b.c reads the final part as 16 bits, a.b reads it as 24 bits, and a lone a is the full 32 bits. So 127.0.0.1 is also 127.0.1, 127.1 and 2130706433.

The octal trap. A leading 0 makes inet_aton() read an octet as octal, while browsers and the WHATWG URL parser may read the same token as decimal or reject it. That disagreement is the whole point: a filter that parses one way and a fetch client that parses the other lets the request through. Zero-padded forms are flagged below where the two interpretations diverge.

IPv4-mapped IPv6. The address also lives inside IPv6 as ::ffff:a.b.c.d, equal to ::ffff:HHHH:HHHH where the two 16-bit groups are the high and low halves of N. Filters that only understand IPv4 text never see it.

For authorised testing only. Send obfuscated internal addresses only against targets whose program scope explicitly permits SSRF research.