I’ve been (slowly) making my way through FOSDEM `23 presentations and caught up to Peter Lowe‘s “Bizarre and Unusual Uses of DNS • Rule 53: If you can think of it, someone’s done it in the DNS” talk. DNS oddities are items I collect whenever I see them, and while I knew about a good number of the ones in Peter’s presentation, the ones where DNS is used to retrieve your external IP address were oddly missing from my collection.
His presentation mentioned both a Google DNS hack and OpenDNS DNS hack, and I learned of a similar DNS hack from Akamai from John Payne. I keep saying “hack” because these folks are most certainly abusing the original intentions and design of DNS. “Hack” is not being used pejoratively, as this is a pretty cool and efficient way of discovering your external IP address vs setting up a full-blown HTTP TLS session, making a
GET request and retrieving the payload.
I’ve been Down and Out on COVID Street for the past few weeks (#4 brought it home from high school, making multiple years of being overly cautious and careful outside the house quite moot), and had a bit of a level drain relapse over the weekend, so I decided to get my mind directed away from malicious spike proteins and build a client for the existing services and then a server anyone could run to host the same type of service.
I’ve been nerding out on Rust for the past few years, but chose Go (also calling it “Golang” in this parenthetical for the sake of SEO) since I really wanted a small binary, and DNS ops are part of Go’s “batteries included” libraries (and, I’ve worked with them before).
dig-ging The Hacks
You don’t need a special client for these hacks.
dig can do all the hard work for you, and it is (for the most part) on every modern system (or easily installed).
Here are three shell executable statements that will return your external IP address into a shell variable (just remove the
VAR= and outer
$() to see the result vs store it):
MY_OPENDNS_IP="$(dig myip.opendns.com @resolver1.opendns.com +short)" MY_GOOGLE_IP="$(dig o-o.myaddr.1.google.com @ns1.google.com TXT +short | tr -d '"')" MY_AKAMAI_IP="$(dig +short TXT whoami.ds.akahelp.net @$(dig +short +answer NS akamai.com | head -1) | grep ns | sed -e 's/[^0-9\.\:]//g')"
The Akamai one is a bit longer since I didn’t want to lock it in to a pre-specified Akamai resolver (you never know when orgs are going to change things). So, it looks up the nameserver first, then does the IP check.
Remove the pipes to see the “raw” output.
[Client] Hacks In Go
I’ll eventually set up a GitHub Action to build out binaries for various platforms (and setup a Homebrew tap for it) but you can get started using the nascent Go CLI via:
go install -ldflags "-s -w" github.com/hrbrmstr/extip@latest
the extra flags are there to make the binary size smaller than it otherwise would be (Go and Rust both make larger binaries than I care for, but they do that for good reasons).
At present, there are no command line options, so when you run
extip, the executable makes the DNS calls to all three services and will return just your IP address if they all agree (if you’re being service intercepted in a really nasty way, that might not be the case). If any fail, the discrepancies are shown.
Serving Up Your Own Hack
Another reason to use Go is that building a DNS server in it is super straightforward, thanks to Miek Gieben‘s battle tested DNS library.
Now, thanks to this tiny, hacky DNS server I whipped up, you can:
go install -ldflags "-s -w" github.com/hrbrmstr/extip-svr@latest
and run it anywhere you’d like to have the same type of service.
TXT queries, though I’d use the
TXT one if I were you, since you don’t need to know what type of network you’re on or interface the request is coming from. I’ve got it running on one of my random internet nodes, so you can try it out before running it:
dig myip.is TXT @ip.rudis.net
(any FQDN ending in
.is can be used)
Peter’s talk was super fun and informative, so you should 100% watch it. It was great being able to have something to focus on whilst getting better, and also cool to stretch some Golang muscles.
If you have any opines on the CLI argument parser I should use, drop a comment or issue on the repos. I’ll be tweaking both the client and server quite a bit over the coming weeks.
Pingback: “Bizarre” DNS Hacks For Fun And, Um…, Fun – CISO2CISO.COM & CYBER SECURITY GROUP