Skip navigation

Category Archives: hacks

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

Shaft Silhouette with Can You Dig It below

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

Go's mascot in a hacker hoodie

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.

It supports A, AAAA and 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)

FIN

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.

Andreas Diesner’s `#spiffy` [Fit2Tcx](https://github.com/adiesner/Fit2Tcx) command-line utility is a lightweight way to convert Garmin/ANT [FIT](http://www.thisisant.com/resources/fit) files to [TCX](http://en.wikipedia.org/wiki/Training_Center_XML) for further processing.

On a linux system, installing it is as simple as:

sudo add-apt-repository ppa:andreas-diesner/garminplugin
sudo apt-get update
sudo apt-get install fit2tcx

On a Mac OS X system, you’ll need to first grab the `tinyxml` package from `homebrew`:

brew install tinyxml

to install the necessary support library.

After a `git clone` of the Fit2Tcx repository, change the

DFLAGS +=  -s  $(CREATE_LIB) $(CREATE_DEF)

line in `Makefile.in` to

DFLAGS +=  $(CREATE_LIB) $(CREATE_DEF)

and then do the typical `./configure && make` (there is no `test` target).

You’ll now have a relatively small `fit2tcx` binary that you can move to `/usr/local/bin` or wherever you like command-line utilities to be put.

You can also grab the [pre-compiled binary](http://rud.is/dl/fit2tcx.gz) (built on `OS X 10.9.2` with “latest” `Xcode`).

I was helping a friend out who wanted to build a word cloud from the text in Google Groups posts. If you’ve made any efforts to try to get content out of Google Groups you know that the only way to do so is to ensure you subscribe to the group posts via e-mail, then extract all those messages. If you don’t e-mail subscribe to a group, there really is no way to create an archive of the content.

After hacking around a bit and failing, I pulled up the mobile version of the group. You can do that for any Google Group by using the following URL and filling in GROUPNAME for the group you’re interested in: https://groups.google.com/forum/m/#!topic/GROUPNAME.

input_text_not_updated_-_Google_Groups

Then, you’ll need to navigate to a thread, use the double-down arrow to expand all the items in the thread, open up the JavaScript inspector on one of the posts and look for <div dir="ltr">. If that surrounds the post, the following hack will work. Google only seems to add this left-to-right attribute on newer groups, so if you have an older group you need to work with, you’ll need to figure out a different selector (which is coming up in a bit).

With all of the posts expanded, paste the following code into the JavaScript console:

nl = document.querySelectorAll('[dir=ltr]');
s="" ; 
for (i=0; i<nl.length; i++) {
  s = s + nl[i].textContent + "<br/><br/>";
}; 
nw = window.open(); 
nd = nw.document; 
nd.write(s); 
nd.close()

and hit return (I have it spaced out in the code above just for clarity; it will all fit on one line which makes it easier to execute in the console).

Untitled_and_input_text_not_updated_-_Google_Groups

You should get a new browser window (so, you may need to temporarily enable popups on Google Groups for this to work) with the text of all the posts in it. I only put the double <br/> tags in there for the purposes of this example. I just needed the raw text, but you can mark the posts any way you’d like.

You can tweak this hack in many ways to pull as much post metadata as you need since it’s all wrapped in heavily marked <div>s and the base technique should work in a GreaseMonkey or TamperMonkey userscript for those of you with time to code one up.

This hack only lessens the tedium a small amount. You still need to go topic by topic in the group if you want all the content. There’s probably a way to get that navigation automation coded into the script as well. Thankfully, I didn’t need to do that this time around.

If you have other ways to free Google Groups content, drop a note in the comments.

As I was about to “buffer” a reference to a CSM article on “cyber war” (below), I paused to look for a “print view” or some other icon that would let me show the whole article as a single page vs the annoying multi-page layout view they normally are presented in (which also doesn’t work in my “hardened” Chrome config #meh).

A quick bout of googling got me to the CSM “text edition“. I found the same article there and noticed that there was some straightforward magic in the URL that could be applied to any article.

For any regular article URL like the following (you’ll need to prepend the “http://” part as I had to remove it so WP would stop interpreting and auto-linking the URLs):

www.csmonitor.com/USA/Military/2013/0915/Cyber-security-The-new-arms-race-for-a-new-front-line

Just insert the bolded bits (“layout/set/text/“) below right after the “www.csmonitor.com/” part:

www.csmonitor.com/layout/set/text/USA/Military/2013/0915/Cyber-security-The-new-arms-race-for-a-new-front-line

for an annoyance-free reading experience. You’ll lose any associated pictures, but you’ll be able to get all the real content in one, distraction free page. There’s probably a Chrome or Firefox extension that does this already, but my tolerance for add-ons is growing thin.