Amazon Dash Button でのハックについて自分なりに調べてみた


ダンボール入りのペットボトル飲料水を毎回スーパーに行って買うのは面倒だなと思っていたところ、そういえば Amazon Dash Button あるじゃん！と思って衝動買いしてみました。

いざ手元に届いて調べてみると、Amazon Dash Button は商品を注文するだけでなく、ハックで色々なことができるということを知り、率直に面白そうだなと思いました。

そこで今更感はありますが、Amazon Dash Button でハックすることについて自分なりに調べてみました。

## Amazon Dash Button 初期設定

Amazon Dash Button を使えるようにするには、まず初期設定が必要です。 
<a href="https://www.amazon.co.jp/gp/help/customer/display.html/ref=amb_link_1?ie=UTF8&nodeId=201746340&pf_rd_m=AN1VRQENFRJN5&pf_rd_s=merchandised-search-leftnav&pf_rd_r=TSXWXYC79BGFWDKJCQD3&pf_rd_r=TSXWXYC79BGFWDKJCQD3&pf_rd_t=101&pf_rd_p=cf13d39a-e3f0-4ff4-a61f-037a02d68c1d&pf_rd_p=cf13d39a-e3f0-4ff4-a61f-037a02d68c1d&pf_rd_i=4752863051" target="_blank" rel="nofollow noopener">Amazon公式サイトに記載された初期設定方法</a>を参照してください。

大まかに説明すると以下のような設定を実施します。

* スマートフォンの Amazon アプリから WiFi ネットワーク接続情報を Amazon Dash Button に登録
* ボタン押下時に注文する商品を設定

**※ 最後に注文する商品のセットアップを完了させずに終了することに注意してください！
そうしないと、ボタンを押すごとに商品注文が走ってしまいます。。**

## Amazon Dash Button 仕組み概要

Amazon Dash Button が押下されてから商品を注文するまでの仕組みの概要は以下の通りです。
DHCPでWiFiネットワークに接続するために、ARPプローブを送信しているところがミソです。

1. ボタン押下で電源起動
2. ボタンに設定された Wifi ネットワークに接続
3. ARP(Address Resolution Protocol) プローブをネットワーク内にブロードキャストし、他マシンとIPアドレスが重複していないかチェック
4. 商品注文リクエストを送信

参考：<a href="https://qiita.com/dkawashi/items/e6621c4b712b509c73ec" target="_blank" rel="nofollow noopener">Amazon Dash Buttonの仕組みとハック</a>

## Amazon Dash Button ハック概要

**ボタン押下することで送信される ARP プローブをキャプチャし、それをフックに別の処理をかます**というのが、Amazon Dash Button ハックの概要のようです。

こちらのハックでは、Amazon Dash Button はあくまで ARP プローブを送信するトリガーとして扱っているため、ARP プローブをキャプチャして別処理を実行するには、別途サーバが必要となります。

自前の PC でももちろん OK ですが、Raspberry Pi が用途にマッチしているようで人気のようでした。

## 具体的にどうハックするか

### ARP プローブをキャプチャする

まずどうやって ARP プローブをキャプチャするのかというと、同じルーターで同一ネットワーク内にいるマシンから、パケットキャプチャするとできます。

簡易的にやるなら `tcpdump` ですぐできます。(`root` 権限が必要です)

```
sudo tcpdump -e arp -q -n
```

`-e arp` で ARP プロトコルのキャプチャのみ表示、`-n` で IPアドレスを名前解決しない、 `-q` で簡略表示にしています。

上記コマンドを起動した状態で、Amazon Dash Button をポチッとしてみて、その際に現れた ARP プローブを送信している MAC アドレスが Amazon Dash Button です。

出力結果は以下のような感じです。

```
$ sudo tcpdump -e arp -q -n
12:42:22.370234 b4:7c:xx:xx:xx:xx > ff:ff:ff:ff:ff:ff, ARP, length 42: Request who-has 192.168.11.1 tell 192.168.11.13, length 28
```

ちなみに先程取得した MAC アドレスに紐付いた IP アドレスに対して ping を実行し、その状態でAmazon Dash Button をポチッとしてみると、
ボタン押下後数秒だけ通信できていることが確認できます。

```
$ ping 192.168.11.13
PING 192.168.11.13 (192.168.11.13): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
ping: sendto: No route to host
Request timeout for icmp_seq 4
... ボタン押下...
64 bytes from 192.168.11.13: icmp_seq=0 ttl=64 time=5082.194 ms
64 bytes from 192.168.11.13: icmp_seq=1 ttl=64 time=4077.590 ms
64 bytes from 192.168.11.13: icmp_seq=2 ttl=64 time=3077.494 ms
64 bytes from 192.168.11.13: icmp_seq=3 ttl=64 time=2073.094 ms
64 bytes from 192.168.11.13: icmp_seq=4 ttl=64 time=1070.754 ms
64 bytes from 192.168.11.13: icmp_seq=6 ttl=64 time=2.207 ms
64 bytes from 192.168.11.13: icmp_seq=7 ttl=64 time=3.568 ms
64 bytes from 192.168.11.13: icmp_seq=8 ttl=64 time=19.452 ms
... ボタンランプ消灯...
Request timeout for icmp_seq 13
Request timeout for icmp_seq 14
Request timeout for icmp_seq 15
Request timeout for icmp_seq 16
Request timeout for icmp_seq 17
```

## キャプチャをフックして処理を実行する

あとはキャプチャをフックに処理を実行させればOKです。

<a href="https://blog.theodo.fr/2018/02/making-amazon-dash-buttons-useful-building-doorbell/" target="_blank" rel="nofollow noopener">tcpdump をそのまま使ってシェルスクリプトで処理する例</a>もありましたが、できれば使い慣れた言語で扱えた方が便利かと思います。

パッと調べてみたところ、Amazon Dash Button をハックしやすくするライブラリが複数言語で開発されているようです。Python が人気っぽいですね。

どのライブラリも上述した ARP プローブ のキャプチャの仕組みを利用していました。

※スター数、最終更新コミット日は2018/09/17現在

言語|ライブラリ|スター数|最終更新日
:--|:--|:--|:--
Python|https://github.com/Nekmo/amazon-dash|259|2018/09/04
JavaScript|https://github.com/ide/dash-button|125|2018/04/27
Ruby|https://github.com/kenyonj/dashed|50|2015/10/10

## おわりに

調べてみると、ボタンを押すというシンプルな動作に様々なことを実行させることができそうで、やはり面白そうだなと思いました。また色々遊んでみようと思います。