Rescue Your Amazon Dash Buttons

Earlier this year, Amazon announced that they’ll discontinue Dash Buttons. I don’t know how successful Dash Buttons were for their intended use, but Home Automation hackers have loved (mis-)using them for everything from warming up their coffee pot to keeping track of bodily functions.

Unfortunately for us hackers, Amazon is an unforgiving god. Not only have they stopped selling Dash Buttons, but they’ve removed the part of their app used to set new ones up. Even worse, to any button unfortunate enough to connect to The Mothership, Amazon has promised to issue a firmware update that bricks the device. It is therefore critical that you set up your buttons in an environment where they will not be able to phone home.

Fortunately for us hackers, Amazon is not an infallible god. Versions of their dash button firmware built on May 2016 and earlier are vulnerable to a buffer overflow attack during the high-frequency audio setup (Hunz did some truly awesome reverse engineering work to find this).

We can exploit this vulnerability to complete the setup.

How-To

In the following section, I’ll go into more detail about how this works.

For now, let’s do this!

  1. Put Dash Button in setup mode by holding down the button until the LED flashes blue.
    1. Connect to the Amazon ConfigureMe WiFi network and visit http://192.168.0.1.
    2. You’ll see the button’s hardware (MAC) address. Block its Internet access in your router’s settings. If you don’t do this, the button will get an over-the-air update when it phones home and get bricked.
  2. While in setup mode, play this .wav file through some earbuds aimed at the Dash Button.
    • If the LED turns green, the exploit worked! Carry on to step (3).
    • If the LED turns off, you’re probably on a firmware version that fixed the vulnerability. Unfortunately, you’re out of luck if this is the case. (unless someone finds another vulnerability)
  3. Put the Button in setup mode again.
  4. Connect to the WiFi network it creates — Amazon ConfigureMe.
  5. Visit this URL*: http://192.168.0.1/?amzn_ssid=<wifi_network_name>&amzn_pw=<wifi_network_pw>. (obviously substituting wifi_network_name and wifi_network_pw for the desired values)

That’s it! It should work now.

[ * ]: Note that the setup AP is unsecured and this request is sent over HTTP. You’re sending this request in plaintext over the air. Don’t do this unless you’re comfortable with that. The buttons support a configuration flow that involves exchanging crypto keys, but this is far more involved. If there’s enough interest, I can write a script.

How this works

The Dash Button setup process has two high-level steps:

  1. Getting WiFi credentials from you.
  2. Exchanging a pair of secrets with The Mothership. Under normal operation, these are used to authenticate with Amazon when placing an order (it uses them to generate an HMAC secret).
    1. The button transfers a device secret baked into the firmware to Bezos HQ.
    2. The button retrieves and stores a customer secret from Amazon.

(1) is easy for us to fake. In fact, all we need is the final step from the previous section — visiting the URL with the amzn_ssid and amzn_pw parameters.

It’s (2) that’s keeping everyone from setting up their buttons. Amazon has stopped responding to these exchange requests, meaning the buttons will never complete the setup process unless we get creative.

The part of the firmware that handles high-frequency audio packets is vulnerable to a buffer overflow attack. From Hunz’s slides, you can see that it’s doing a memcpy without a length check:

Hunz put together some excellent scripts that pack an exploit payload in ARM assembly into an audio file.

I needed to do some reverse engineering of my own to find the function responsible for writing the customer secret to flash. I’d never so much as opened a disassembler, so this was a pretty fun challenge. Since IDA costs an arm, a leg, and the souls of any present and future offspring, I used Ghidra (I have no complaints, although a professional might). I put the archive file on Github.

The raw function that writes a customer secret to flash is at address 0x40FAA4:

It takes in a pointer and a length (which appears to always be 20). This function is normally wrapped in a bunch of code that calls Amazon’s servers, does validation, etc., but since we’ve got arbitrary code execution, we can just call it directly.

My exploit payload follows:

Since it doesn’t matter what the value of this secret is so long as we’re not intending to connect to Amazon, I pass an arbitrary address (0x400000 — the start of ROM) along with a length of 20 to the writeCustomerSecret function.

Then it sets the LED to green to indicate success. Firmware versions that have patched this vulnerability shut down when they receive the exploit.

Further fun

When starting on this effort, I soldered some magnet wire onto the UART test pads to get serial access. Hunz labels the pins in his talk:

Here’s a photo of my test rig:

The most interesting thing you can do with UART access is execute more code. The audio exploit payload is limited to a small number of instructions. Hunz supplied a payload that reads data from UART into SRAM and executes it (there may be a more convenient way to do this, but I’ve not dug in yet). Soldering onto these tiny pads is pretty challenging, so I modeled and 3D-printed a crude pogo pin fixture:

Pogo pin fixture. Connects to UART RX/TX pins. Gnd is connected separately.

I’d initially thought this was necessary in order to configure wifi credentials, but turns out you can do that using the setup AP, which is much easier.

You can’t do much of anything interesting in the serial console, but it at least appears that someone over at Amazon has a sense of humor:

Acknowledgements

  • Hunz’s reverse engineering work is incredible. If you’re into this sort of stuff at all (and if you’re reading this, you probably are), you’d very likely get a huge kick out of his 33c3 talk, which is where I learned about the audio vulnerability.

Future Work

The Dash Button hardware is pretty remarkable. It’s got a beefy microcontroller, (obviously) builtin wifi, a BLE chip, a microphone for the HFA audio configuration, and so on. I’ve not seen any official-looking estimates at the cost Amazon was paying for these things, but some have guessed in the ballpark of $20 — even at Amazon’s scale.

If we can find a way to flash custom firmware, they’d be perfect IoT buttons. As-is, they’re obviously a little janky. We’re monitoring networks for side-effects to trigger actions. This should theoretically be possible given that Amazon issues OTA firmware updates (the code that handles the OTA update process appears to be at 0x42391C).

I don’t know how much gas is left in my motivation-for-reading-assembly tank, but this is what I’d work on next with what’s left.

It’d be really neat if Amazon open-sourced an SDK. Yes, they’ve said they have a recycling program, but something tells me most buttons are gonna end up in the landfill.

Caveats

  1. Amazon fixed the buffer overflow vulnerability in a later version of the firmware, but almost every button I have uses the May 2016 version out of the box (there’s been ~1/20 exceptions).
  2. Buttons get OTA updates if they connect to the Internet. So if you have a button that’s been phoning home, in all likelihood it’s been patched.
  3. My setup triggers on 802.11 probe requests, meaning I don’t need (or want) the button to connect to a network, only to try. As far as I can tell, though, they will.

Donating

If this work has brought you happiness or utility, it’s more than enough for me to hear those words.

If you’re feeling especially generous, and are open to a charitable donation, that’d make me very happy. Here are some whose mission I support (in no particular order):

Join the Conversation

44 Comments

Your email address will not be published. Required fields are marked *

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  1. Hi there,
    I have an old Dash Button and luckily managed to get the LED green by playing the WAV file.
    Nevertheless, I am kind of reluctant to give the button my wifi password in plain text until. As far as I understand, the wifi password would be transmitted via http protocoll every time I push the button, right? That would expose my wifi password pretty extensively.
    Is there a more secure alternative?
    Thx,
    Sucipe

    1. The only time your wifi password is exposed in plaintext is during the one-time setup. There is a way to send the button the password w/ a secure exchange, but it’s quite involved (button supports a ecdh key exchange).

      After the button is set up, it connects to your wifi as every other device on your network does and attempts to communicate with Amazon HQ (it’s important that you block this).

  2. Method to hack all buttons with firmware 50018520_US. It’s a slight modification of Chris method:
    1.-) Press button until it flashes blue (programming mode).
    2.-) Connect to Amazon configure me AP.
    3.-) Save MAC and block MAC in your firewall or pihole. In my example my buttons MAC is: 78E10395A9E5
    4.-) Repeat same steps and connect again to Amazon configure me AP.
    5.-) This is the changed step: WHILE CONNECTED with a browser to the button: http://192.168.0.1 deploy the payload (WAV file) with VLC player and earbuds. (to be 100% sure play it several times).
    6.-) Blue Flashing led will power off after a while.
    7.-) Put the button in configuration mode again and connect to this page: http://192.168.0.1/?amzn_ssid=YOURWIFISID&amzn_pw=YOURWIFIPASSWORD
    😎 Button don’t even answer and goes off.
    9-) Now normal press the button (not to configure it) and look at your firewall/PiHole:

    Date Time
    2020-05-23 22:14:13
    Date
    2020-05-23

    Time
    22:14:13
    Level
    information information

    Sub Type
    dhcp
    ID
    26001

    IP Address
    192.168.0.89
    Message
    Assigns IP address/configuration parameters to the client

    Hostname
    N/A
    Direction
    Sent

    MAC
    78:E1:03:95:A9:E5
     
     

    10.-) TADAAAAAAAAAAAAAAAAAAA… button configured. Now every time I press the button and ping ip 192.168.0.89 it answers so I can use it with homeassistant, pimatic or whatever.
     
    Chris, thank you so much. Your work is AWESOME!.

  3. Great article!I finally got to play with my two buttons I ordered in July 2018. Never configured, one pulled out of the box yesterday for the first time. (I choose CLOROX button since some moron suggests to inject that substance to fight Covid-19 😉 ).
    The button responds to the sound from my ear bud: Switching from the “breathing blue” to “dark”. That may mean I am out of luck – late production buttons patched out of the box? If so – time to get that hack saw and open it up, right? Should have hacked them while still supported and then block Internet access.
    Also – may I ask for clarification? Blocking the Internet access is probably critical only when one approaches step 5. above, right? Before I provide network credentials the button has no way to call Bezos – if I am not missing anything.Thanks!
     

    1. Hi Martin,

      Yep, sounds like that button’s been updated. I had around 10% of the buttons I tried fresh out of the box do this.

      That’s correct. Buttons have no way of phoning home without user-provided network credentials as far as I’m aware.

  4. Hello!

    I tested this with one button, that was never configured and it was working fine. I can use it in Home Assistant now!
    Thank you very much!

    The strange thing is only the following behaviour:
    An older one that was enabled via Amazon last year is showing white light once and then it flashed rapidly a few time red and then it is off.
    This new one is flashing white slowly ca. 15sec then switching off and when I press a second time it flashed red rapidly and then switching off again.
    I have to switch it two times because it will only work with Home Assistant after the rapid red flashes.

    Does anyone know why it behaves in this way?

  5. Chris, 
    Great article, amazing work. 3 of my buttons blinked Red once and turned off however, I was able to set the SSID and see a screen that said : “Thank you for configuring your Device”. And vising the configure me SSID shows a web form where I can set it again.
    Are these successfully setup? I am trying to see them connect to my dummy router, which is not connected to internet (monitoring with Kismet and TCP Dump) but do not see anything.
    Thanks
    D

    1. Hey Derek,

      When do you see the red blinking? If it happens right after you press the button, I think that means they’ve not been set up.

      What happens after you play the sound during setup mode?

  6. Hey Chris,
    I run on FW 30017420_WS.
    I can go through Step 1-5.
    I don’t get feedback in Step5 when I visit the site?
    Should there any info?  The site is running in time out without any notification.
     
     

    1. Hi Kai, I’ve seen this intermittently as well. I’ve not been able to reproduce it reliably, but sometimes sending a request with the header Content-Type: application/json seems to help. (easiest for me to accomplish this via curl).

  7. Hi Chris! Great job, great hack, thanks for the instructions! Maybe you can help me with my dash button. It’s firmware v 30017420_EU.When I play the audio file the button doesn’t change its behaviour. It still flashes blue until the button goes off again. Best regards, Mani

    1. Hi Mani,

      It sounds like the dash button isn’t “hearing” the audio file. Are you able to hear anything when you play it? Should sound like a really terrible high-pitched screech.

      I had the best luck playing it over some earbuds. The dash button never responded when playing it over my laptop’s speakers.

  8. Hi, thanks for this. I can’t access the audio file. The player on the link has audio on zero seconds.
    Thanks for any help. 

    1. Hey Gary,

      My browser media player doesn’t seem to work with it. I’ve had better luck downloading it and playing it with VLC. If you haven’t already, give that a go.

  9. hello, i’m hella ignorant about IoT stuff. I was a huge fan of the Dash Button for it’s intended purpose. over the last couple years my household kinda came to rely on those things for certain items. i now find that the detergent bottle is empty too often, and it’s really grinding my gears. idk what even to search for because everything i try in google is all just stuff about the dash button. I need a solution that performs the same function… just a button that orders a specific item. I don’t alexa, and i don’t google home, i do however have some homekit stuff that works well for us. could someone point me towards something that might do that, or am i just SoL…?

    1. I’m not aware of another product that fits into a similar niche. Amazon kinda screwed everyone with this 🙁

  10. It’s really a shame that Amazon has committed to bricking these devices. What a waste. Should be illegal. Probably would be subject to legal action if there was the will for it.

  11. Thank you so much for this!
    I managed to protect some of my buttons by blocking internet access. Out of the bricked ones I also revived one using your attack! It had firmware version 30017420_WS. The ones on 50018520_WS (solid red 3 sec, blinking red, off) and 60019520_WS (solid blue 20 sec, blinking red, off) remained bricked.
    Note that the ones I preemptively saved have the same firmware versions but ending on _EU.
    Overall, this was an incredibly sissy move from Amazon. Absolutely disgraceful.

    1. Pretty much the same here. The 3-Firmware worked, the 6-Firmware also shows solid blue for 20s. Any progress on this?

      Cheers. 🙂

    2. Newer firmware fixed the vulnerability. I’m not really equipped or motivated to find a new vulnerability, unfortunately.

  12. Great work Chris and very well written – I’m sad that some of my buttons are now trashed by Amazon but pleased you’ve helped me rescue the rest.I don’t quite understand why they don’t sell the buttons anymore (even at a higher price / just the IoT version); or why they couldn’t have just OTA patched the URL to a blackhole if that was what was annoying them. BEZOS!!!!Does anyone have an alternative (of equivalent longevity / under $20 a button). 

  13. Has anyone encountered firmware “20014520”? Even the format of the firmware version number is different. The status page is different: no battery level. And when I play the wav file to it, it responds with 3 bursts, of 3 red LED flashes each, spread over 3 seconds. Then it exits setup mode. This is very different from how the newest firmware responds (by exiting setup mode with no LED flashes).
    I have two of these, among my seven buttons. They were my first Dash purchases, from early July 2016, are labeled as ordering Ziploc products, and have MAC addresses from the AC:63:BE range owned by Amazon. Another button bought at the same time is using 60019520_US firmware, like my other four buttons. They probably got updated along the way.
    So any hope of cracking this 20014520 firmware?

    1. Interesting. Do you know what hardware revision your older button has? Hard to tell what’s going on without a firmware dump.

    2. All my buttons, including these extra-old firmware buttons, are JK29LP. Which the internet seems to suggest only arrived in 2016. So it does seem odd that they have such old firmware. Maybe I got some of the very first of the new hardware?

      Yeah, I’m not going to re-Hunz this sucker to get at the firmware. The brief description of all his steps was exhausting.

      Instead of bricking them, I wish Amazon would open them up all the way and contribute to the hacker/maker community! What would they lose by doing that, now that they’ve stopped selling this hardware at a loss? Seems to be either mean-spirited or narrow-minded.

    3. Yep, it’s a lot of work. Had to do it myself to get this exploit working. 🙂

      My guess is that the subroutine addresses are different in that version of the firmware.

      Agreed. Don’t know what their calculus was. Guessing it’s just laziness. Amazon is not famous for contributing back to the OSS/maker community.

  14. Great article! I have a couple of buttons purchases circa 2 years ago, don’t know if they are too new …
    I played around with one of them today, wanting to control my Hue lights with it. I noticed it still communicated with the Amazon app which told me that the buttons no longer worked. Since it did the same with my phone’s wifi off, I figured it actually communicated with the Amazon server and not the phone. I did a network scan and found the IP of the button to be 192.168.1.71. So I pinged the IP from my hue node script to determine the button presses and fairly easily succeeded controlling my lights. I also blocked the request in my router so it could no longer reach the remote server.
    Then after 10-20 tests it stopped working! Instead of the blinking white light while trying to contact Amazon, the lamp showed a constant blue light. And I could no longer ping it.
    Is the battery low or is it bricked? If the latter it puzzles me since I blocked the outgoing requests in the router and it worked several times after that.
    Then I googles and found this article.
    And now I have a question 🙂
    What is the Amazon ConfigureMe network?

  15. Great work Chris! Applied the vulnerability to 8 never configured dash buttons. 10 buttons were purchased July 2017 and only 2 were previously configured. They all have firmware 30017420_WS on them. I used the speakers on the PC to apply the vulnerability.
    From previous experience I block dash-button-na.amazon.com and dash-button-na-aws-opf.amazon.com domains with the Pi-hole. Looking back at the logs during set up of the remaining 8 all the buttons only lookup these domains, time-c.nist.gov and dash-button-na.amazon.com. Of course NTP, time-c.nist.gov, is the only destination that works. Blocking the domains allows me to skip the step of looking up the MAC address to block them on the router.

  16. Is there a way to determine from the status page (the one where you get the MAC address) if the firmware version is one that should work?   A few data points…
    60019520_WS – does not work
    50018520_WS – does not work
    30017420_WS – works
     

    1. Yeah, I think I’ve found that anything above 4* is patched. All versions should respond to the audio, though. If the LED turns off immediately, it’s a patched version.

    2. I had four dash buttons boxed and unopened two were 4xxxxxxx_ws and I successfully applied the hack. The other two were 5xxxxxxx_ws and 6xxxxxxx_ws and neither worked.

  17. Even though I don’t have access to one of these buttons and probably don’t have the skills or time to execute a hack like this, I just wanted to say that the existence of this makes me happy. 

  18. How do you get connected to its and visit the URL in such a short window? I lose the network it creates as soon as the green light turns off and I just don’t have enough time to connect to it and hit the URL. Am I missing something? Thanks!!

    1. Think you might be missing step (3). You need to enter setup mode again after running the exploit.

      The button isn’t doing anything after the LED is turned green — it’s in a busy wait loop (see lines 24/25 in the exploit payload assembly).

  19. Wow!  It works!  (At least for some of my older buttons)   Awesome hacking!
    One thing to watch for is that in only works once. Then (apparently) the communication back from the mothership disables further presses.   I found that I had to go through the process twice:  First to learn the mac address.  Then, after disabling communication to the outside world from that address, I could go the process again and have it work indefinitely.

    1. Yeah, if your button manages to get an OTA update, it’ll probably get bricked. I tried to warn about that in the intro paragraph, but I also didn’t suggest a way to prevent the button from connecting (my setup doesn’t require a real AP for the buttons to connect to, so not something I have to deal with personally).

      You can actually get the mac addr from the setup UI the button serves. Connect to the AP and visit http://192.168.0.1. I’ll add this hint to the post.

      EDIT – post has been updated.