世界を動かす技術を、日本語で。

犬を監視したかったが、TP-Linkを監視することになった

概要

Tapoカメラのセットアップに苦戦し、独自にオンボーディングフローを解析。 APKのデコンパイルやTLSセッションのMITMによる通信解析を実施。 デフォルトパスワードの特定とAPI暗号化の仕組みを解明。 Pythonスクリプトで通信内容の復号・解析を自動化。 最終的にクラウド不要なセットアップスクリプトを作成し、カメラの仕組みを詳細に把握。

Tapoカメラ逆解析の経緯

  • Tapo室内カメラ を安価に購入し、外出時の犬の行動確認を目的とした導入。
  • Frigateへの組み込み が困難で、オンライン情報も乏しく設定に苦戦。
  • 2way音声対応 にはrtsp://ではなくtapo:// go2rtc構成が必須という独自仕様。
  • TP-Link独自API でのみ2way音声を実装しているため、標準プロトコル非対応。
  • オンボーディング後に クラウドパスワード変更 しても、デバイス側は同期されない挙動を確認。
  • デバイスAPIは admin:<Tapoクラウドパスワード> で認証するが、パスワード変更後も古い情報のまま運用される仕様。

オンボーディングの仕組み推測

  • 初期セットアップ時に クラウドパスワード同期APIコール が存在。
  • 同期以前は 未認証またはデフォルトパスワード でアクセス可能。
  • Tapo Careサブスクリプション の強制表示など、クラウドレス運用の必要性を痛感。

MITMによる通信解析

  • オンボーディング時の通信内容 を把握するため、アプリとカメラ間のMITM(中間者攻撃)を実施。

  • mitmproxy をPC上で起動し、 Frida でアプリの証明書ピンニング回避を実装。

  • スマホの全HTTPS通信をプロキシ経由で記録・解析する環境を構築。

    • 通信フロー:
      • Tapo App(Frida hooks)→ Laptop(mitmproxy)→ Tapo Camera
      • リクエスト・レスポンスの全記録と転送

通信内容の解析結果

  • 初回ログイン時、 adminユーザーでパスワード未設定 の状態を確認。
  • 以降のAPI通信は securePassthrough による暗号化ペイロードでやりとり。
  • Tapoカメラはデフォルトパスワード を持ち、クラウド同期前に完全ログイン可能。
  • API通信の暗号化 で外部解析を防止。

APKデコンパイルとパスワード特定

  • JADXでAPKを解析 し、"admin"文字列を検索。
  • CameraOnboardingViewModelクラス 内でパスワード生成ロジックを発見。
  • encrypt_type: 3 の場合、デフォルトパスワードは TPL075526460603 であると特定。

mitmproxy用スクリプト開発

  • デフォルトパスワード判明後、 セッションキー導出・API復号化 が可能に。
  • PyTapo をリファレンスに、mitmproxy上で復号スクリプト(tapo_decrypt_pretty.py)を作成。
    • ログインハンドシェイク(cnonce, nonce, device_confirm)監視
    • セッションキー自動生成・API復号化
    • mitmproxy UI上で平文表示・JSON保存

オンボーディングAPIコールの全貌

  • 主なAPIコール一覧:
    • scanApList(Wi-Fi一覧取得)
    • setAccountEnabled / changeThirdAccount(RTSP/ONVIFアカウント有効化)
    • changeAdminPassword(パスワード変更)
    • connectAp(Wi-Fi接続)
  • その他:タイムゾーン設定、クラウドバインド、記録プラン等は本質的でない付帯機能。

クラウドレスセットアップ自動化

  • Bashスクリプト(tapo_onboard.sh)で以下を自動化:
    • デフォルトadminパスワードでログイン
    • Wi-Fiアクセスポイント選択・接続
    • OSDロゴ非表示化
    • RTSP/ONVIF有効化
    • パスワード変更
    • Wi-Fi接続完了

Tapoファームウェアの所感

  • APIエンドポイントごとに SHA-256とMD5が混在 し、暗号化仕様が統一されていない。
  • パスワード送信用の公開鍵が 2種類存在 し、どちらを使うかは不明確。
  • アプリとデバイス間のパスワード同期 は一貫性に欠け、仕様が曖昧。
  • 全体的に 暗号実装の品質が低く、コスト重視の設計を感じさせる。
  • 価格相応の品質だが、 最終的にはクラウドレス運用を確立

犬の行動観察の結末

  • 解析作業の末、 犬はソファやベッドで寝ているだけ という事実に到達。

Hackerたちの意見

ちょっと関連がある話だけど、Tapo C200の研究プロジェクトだね。https://drmnsamoliu.github.io/ (https://news.ycombinator.com/item?id=37813013)PyTapo: Tapoカメラとの通信のためのPythonライブラリだよ。https://github.com/JurajNyiri/pytapo (https://news.ycombinator.com/item?id=41267062)

これも少し関連してるかも: (TP-Linkのファームウェア復号化 C210 V2クラウドカメラのブートローダー) https://watchfulip.github.io/28-12-24/tp-link_c210_v2.html?u...

もうハードコードされた管理者パスワードを見つけるのは大したことじゃないね。

スマホは一部の人には最初の敵対的なデバイスと見なされることもある。ネットワークデバイスは少なくともこうやって監視したり発見したりできるしね。

セットアップ後に普通の流れで更新されるから、まあそれはいいかな。ここ5年で家にできるだけ「IoT/スマートホーム」関連のものを作ってきた中で、ほとんどのベンダーが「パーティートリック」としての使い道しかないゴミを売ってるってことに気づいたよ。全てを一つのベンダーから揃えないと、スマートホームのセットアップはイライラするけど、どのベンダーも全てのニーズに応えるのが得意ってわけじゃないし。俺のスマホには、Ecobee、Lutron、Hue、4つの別々のカメラのベンダー[1]、Meross、Smart Lifeのアプリが入ってる。多分、他にもいくつか忘れてるのがあるけど。LutronとHueだけは、ハブやHomeKitでかなり包括的なコントロールができるから、そのアプリを使わずに済むのがいいね。MatterとThreadが新しい制御とネットワーキングの標準として決まったのは何年も前だけど、市場は互換性のあるデバイスで溢れるどころか、安いWi-Fiデバイスでいっぱいで、それぞれがクラウド依存で、日常的に使うためにはゴミみたいなモバイルアプリを通じて管理しなきゃいけないっていう状況だよ。そのアプリの主な目的は、クラウドサービスを売りつけることだからね。[1] 4つ持ってるのは、安いカメラを機会主義的に買った俺のせいだけど、たくさんの人にはいい言い訳があるかも。例えば、あるベンダーが最高のドアベルカメラを作ってる一方で、別のベンダーがより良いPTZ屋内カメラを作ってるかもしれないし。

これはハードコードされたデフォルトパスワードで、永久的なバックドアじゃないよ。投稿を正しく理解していれば、ユーザーはオンボーディングフローの一部としてそれを変更するんだ。デフォルトパスワードがあるアプリは、ほとんどがユーザーに変更させるようになってるからね。

デバイスを使い始めるために変更しなきゃいけないハードコードされた管理者パスワードは、実際には問題じゃないよ。

でも、彼らはここにはいないよね…この技術にイライラしたかっただけなんじゃない?

FridaやmitmproxyをAndroidアプリで使うテクニックは、来年の署名要件が施行された後も可能なのかな?

全体的にはそうだけど、認証が必要なアプリにはもっと厳しくなるね。良いことか悪いことかは別として。私の知る限り、Pixelみたいにいつも許可されている端末ではOEMアンロックやルート化はできるけど、そうするとアンロックされたってマークされてGoogleの認証に失敗するんだよね。アプリを持ってきて、解凍して、Fridaを注入して、自分の開発者アカウントでサイドロードすることもできるはず(今のiOSみたいにね)。でも、これも認証に失敗するし、アプリレベルでの改ざん防止やデバッグ防止コードに弱いんだ。

もうすでに実現が難しい状況だよ。Fridaを使うにはデバイスをルート化する必要があるけど、ますます多くのモデルでそれが不可能になってるし、非常に優れたルート検出SDKが市場に無限にあるからね。Play Integrityのことも忘れちゃいけない。

その変更が直接影響することはないと思うよ。リバースエンジニアリングは、ほとんどがルート化されたデバイスやエミュレーターで行われてるから、そもそもGoogleの制限には引っかからないしね。非ルートデバイスを使いたい(例えば、FridaをAPKに注入する場合)っていう少数派のケースはちょっと難しくなるけど、実際には開発者が開発者モードを有効にして自分のAPKを作ったりインストールしたりする方法は残ると思う。これからは厳しくなるだろうけど、その制限を取り除いたらAndroid開発が不可能になっちゃうから、そんなことはないと思う。おそらく、非開発者デバイスではサイドローディングをブロックするか、開発用の自分の開発者証明書を追加できるようにするんじゃないかな(これなら開発やリバースエンジニアリングには問題ないけど、アプリの実際の配布には大変だろうね)。もっと大きな問題はデバイスの認証で、これが進むとルート化されたデバイスや認証されていないデバイスがどんどん使いにくくなる可能性がある。今は主に大手の金融系アプリに限られてるけど、もっと広がるかもしれないね。これにはいくつかのデメリットもあって、GrapheneOSユーザーからのクレームがたくさん来たり、信頼性を確保するためにサーバー側の作業が必要だったりするけど。

関係ないけど、OPの犬がベッドから床に移動するのはラジエーターがつくからかな?もっとセンサーデータが必要かも :D

それとも、ただ寒いのに気づいたからかもね。

このブログの書き方がすごく好き。最近はこういう内容がLLMによって生成されることが多くて、読むのがちょっと疲れるんだけど、これは嬉しいサプライズだった。技術的な部分とリラックスした感じのバランスが良いね(表紙の画像がAI生成なのは知ってるけど、それは内容とは関係ないし)。

不要なリソースの使用を避けるために、uBlock Originでデフォルトで大きなメディアファイルをブロックしてるよ。カバー画像は通常ブロックされるし、そもそも役に立たないことが多いからね。今、みんながそれを生成するためにエネルギーを使ってるのは残念だな。

おお、これ私のFridaスクリプトを使ってるんだ!これだよ: https://github.com/httptoolkit/frida-interception-and-unpinn.... いいプロジェクトだね、スクリプトが実際に役立ってるのを見るのは嬉しい。もし動作させるために追加の調整が必要だったら、ぜひ教えてほしいな。

HTTP Toolkitは素晴らしい!ティム、いい仕事してるね!

Http toolkitは、私が使った中で最高のソフトウェアの一つだよ。mitmproxy、proxyman、charles proxyも使ったけど、httptoolkitが一番だし、オープンソースでもある。

このサイトの投稿はどれも読む価値があるよ。電子機器のハッキングはめっちゃ楽しい! :)

IoTのセキュリティは一般的にひどいけど、消費者向けルーターが基本的に監査されていないブラックボックスで、すべてのネットワークトラフィックを処理しているっていうのは本当に心配だよ。ほとんどの人は、自分のルーターのファームウェアが何年も更新されていないことや、既知のCVEが動いている可能性があることに気づいていないんだ。ネットワークハードウェアのサプライチェーンの信頼モデルは壊れてるね。

解決策はpfsenseだよ。

IoTの「S」は「セキュリティ」の略だよ!