Hacking the Dash Button

I got an Amazon Dash button in the post today!

And nope, I don't have a Nerf gun -- I'm just grabbing the button because it's super-hackable. I got the Nerf one because, uh, it looks pretty sweet. That's it.

Setting this thing up was surprisingly easy -- I just went in through the Amazon app on my phone and within four or five taps the button was all set up to order a £5-ish refill pack of Nerf darts.

(Which I promptly bought -- Amazon takes £5 off the first order so the button is effectively free. I don't have much use for Nerf darts, but I'll probably just throw them at freshers or something.)

Right, hacking. Okay, so this thing connects to your home WiFi network and sends an ARP request each time it orders something. Here's my current understanding: I can't really block the router from also responding to that ARP, so I've re-enabled the Nerf button without finalizing the setup by choosing a product. This way I don't lose £££s on Nerf darts I don't want.

I get a push notification each time I press the button reminding me that the setup isn't complete yet... but that's a pretty minor annoyance. I imagine I could use Android's settings to just block all notifications from Amazon, but that seems kinda hardcore.

What I can do is run a server which listens for those ARP requests. Luckily I don't have to do any heavy lifting (I was dreading using Scapy, there's some really ugly example code out there) -- some kind soul has released a Node library called 'node-dash-button'.

Here's a bit of Node-code I threw together from the docs to ping an external API when the button's pressed:

Save it as dash_listener.js and run it like sudo node dash_listener.js. It's gotta have root for the hardware WLAN interface.

(You'll notice the API isn't over HTTPS. You'll also see the security token hardcoded. Potentially, you'll have noticed a lack of comments in the code, or even a suite of unit tests. I have also noticed these things, but chosen not to beef up the security or maintainability of my "Increment A Number" API. On my own head be it, I suppose.)

Anyhow, I've written a quick Flask app to be served at 'nerf.bede.io'. It's very simple, just incrementing a value for each authenticated POST and returning it with each GET.

Again, pretty poor code quality and error-handling, but it does the job. Note that it's not specific to the Dash button, I could be POSTing from anything -- not just the Dash button listener. Slight annoyance: the whole system has a fair amount of lag -- about 4 seconds adjusting for my reaction time. (Don't ask, ugly bash scripts abound...)

So, then, it's working. Albeit kinda slowly. Now I've gotta find out if I have any real use cases for it, without buying a damn Philips Hue bulb. (but they do look cool though, so watch this space.)