
D-Link Komfy スマートスイッチから BLE 経由で Wi-Fi SSID/パスワードを取得する方法を示す概念実証(PoC)と解説記事。iOS アプリのカスタム base64 エンコーディングをリバースエンジニアリングすることで実現します。
はじめに
このレポートでは、D-Link の Komfy Switch with Camera において、Bluetooth 4.0(BLE)経由でデバイスに関連付けられた Wi-Fi SSID とパスワードを取得した発見について詳述します。Komfy スイッチは、家庭用セキュリティおよびオートメーション製品で、家の壁スイッチを置き換えて、ビデオ監視、温度・湿度レベル・空気質のモニタリング、照明スイッチのリモートコントロールを提供します。
Bluetooth BLE プロファイリング
さらに深く掘り下げる前に、LightBlue iOS アプリを使って BLE デバイスの簡単なプロファイリングを行いました。この時点で、Komfy デバイスはオンラインであり、典型的なユースケース設定で構成されていました。LightBlue で Komfy に接続すると、非標準の GATT サービスがあり、8 つのカスタムキャラクタリスティック(または機能)が公開されていることに気づきました。そのうちのいくつかのキャラクタリスティックは、BLE 仕様では最大 20 バイトであるにもかかわらず、異常な量のデータを受信していました。ペリフェラルデバイスとマスターデバイスの両方が対応していれば、より高い MTU をネゴシエートして、一般に「ロング」リード/ライトと呼ばれるものをサポートできます。最初のスクリーンショットは、GATT サービスとキャラクタリスティック(0xB002 から 0xB00A まで)を示しています。次の 2 つのスクリーンショットは、このレポートが焦点を当てる 2 つのキャラクタリスティック(0xB006 と 0xB007)を示しています。0xB006 と 0xB007 のキャラクタリスティックには、Wi-Fi SSID と、ASCII にデコードした結果 base64 エンコードされたように見える文字列が表示されていました。しかし、その文字列を base64 デコードしても、最後のスクリーンショットに示されているように、読み取り可能なデータは明らかになりませんでした。
Komfy アプリ:メソッド呼び出しのトレース
Komfy デバイスが実装する GATT キャラクタリスティックをより深く理解するために、class-dump-z を使用して Komfy iOS アプリのメソッドをダンプし、関心のあるメソッドのメソッドトレースを設定しました。完全なクラスダンプはこちらで参照できます。特に BLEDevice クラスと、Bluetooth を参照する他のメソッドに注目しました。メソッドトレースは、Prateek によって詳しく説明されている Logify.pl Perl スクリプトを使用して設定できます。こちら。
上のスクリーンショットは、Komfy を新規インストールして設定したときのメソッドトレース出力を示しています。平文の Wi-Fi パスワード "chipotlemakesmehappy" と、先ほど LightBlue アプリが 0xB007 GATT キャラクタリスティックから取得したあの base64 のような文字列が再び表示されていることに注目してください。トレースには実際に +[Base64 encode:] メソッドへの呼び出しが示されており、標準ライブラリでは base64 デコードできなかったため、最初は混乱しました。base64 デコードされた値は暗号化されているか、さらにエンコードされているとほぼ判断されましたが、+[Base64 encode:] が(NSData クラスではなく)プライベートに実装されたメソッドであることに気づきました。この変わったエンコーディングに対処する必要がありました。
Hopper による逆アセンブル
次に、D-Link が実装した「base64」エンコーディング方式のリバースエンジニアリングに取り掛かりました(最終的な結果からすると、「リバースエンジニアリング」というと実際よりずっと難しく聞こえます)。Hopper で Komfy アプリを読み込み、-[BLEDevice getWifiPassword:] と +[Base64 decode:] メソッドを解析するのが明らかな出発点でした。-[BLEDevice getWifiPassword:] の解析により、0xB007 GATT キャラクタリスティックが確かに Wi-Fi パスワードを取得していることが検証されました。
+[Base64 decode:] の ARM アセンブリを見てみると、標準の NSData クラスの実装と非常によく似ていたため、+[Base64 encode:] のスキャンに切り替えました。すると Hopper がすぐに答えを示してくれました。標準の base64 アルファベットの全文字が含まれているが、完全に順序が入れ替わった文字列定数が、あるアセンブリ命令の近くに表示されていました。元のシーザー暗号と同程度の簡単な置換に気づかなかったことを少し恥ずかしく思いながら、base64 の文字を解読するスクリプトを作成しました。すると出来上がり!画面に "chipotlemakesmehappy" が表示されました。
つまり、基本的に文字列を解読して base64 デコードする方法は次のとおりです:

完全な autopwn スクリプトはこちら。
そして、その通り、Chipotle は本当に私を幸せにしてくれます。
Ubertooth BLE キャプチャはこちらからダウンロードできます。