HEMSハック #02 PV-DR004Jの破壊と復旧

2025-07-10 embedded device web

前回(HEMSハック #01 PV-DR004Jと内部API)の続きです。

PV-DR004J「計測ユニット」の破壊と復旧について記します。

PV-DR004Jをお持ちで解析したいあなたを同じ目に遭わせないために。

何が起こったのか 

PV-DR004J「計測ユニット」を再起動したところ、二度と起動しなくなりました。

故障原因の心当たり 

そういえば、一緒に解析していた、私の友人RyotaK ✨️Security Researcher✨️ が、長大なURLを持つリクエストを、計測ユニット側Webサーバーに投げまくりやがっていました。

私がUser-Agentまで合わせて、丁寧に、ゆっくりと、リクエストしてたのに。

具体的に何をしたのか 

本人に聞いたところ、こんなことをしていたらしいです。

curl http://当該機器のインターフェース/$(perl -E 'say "a" x 10000')

RyotaKさん???

以下、言い訳 

あねてあさんが困ってそうだったからシェル取れないかなーと思ってガチャガチャやってたんです!

……。そっからシェル取ってみてくれ。

理論上は取れるよ

そうだね?虎屋の羊羹はおいしかったよ。

取り外しと観察 

さて、せっかく壊れてくれたのであれば、何をしてもよいということです。まずは分解。

大まかな構成は以下の通り。

SoC Texas Instruments AM1808B 375MHz
RAM NANYA 64MB DDR2 NT5TU32M16DG-AC 150MHz
ROM Intel 32MB TSOP56 NOR Flash JS28F256M29EWH
マイコン NEC D78F1162A (詳細不明)
無線? SK 4 KM2611044 (詳細不明)
RTC 日清紡マイクロデバイス R2025

気になるのはそう!そこのデバッグ端子です!

とってもUARTに見えますよね!実際に通信を見てみると…UARTでした!

しかし、ブートローダー (U-Boot) がブートループしてます。

どうやらLinux カーネルに入る前・もしくは直後に何らかの原因により再起動しているようです。

ソフトウェアエンジニアとしての挫折 

かろうじてブートローダーには入れます。

しかし、

  • 有益なリセット直前のエラーログがないこと
  • Linuxカーネルすら上がってないこと

には手も足も出ません。

これでは「恐らくFlash ROMに焼かれている内容が壊れている」ということしかわかりません。

親父の協力 

なんと、

  • 新品のPV-DR004J
  • ROMライター(正確には既にあるROMライターXGecu T48用アダプタ)

を買ってきてくれた上、正常品と故障品、それぞれのFlash ROMを基板から剥がし、ファイルとしてダンプしてくれました。

ありがとう親父。TSOP56剥がしたり載せたりする芸当は私にはまだできません…。

ROMのダンプ・解析 

Flash ROMもファイルになってしまえば、単なるソフトウェアです。

故障品・正常品のファームウェアをImHexにて比較すると以下の差分がありました:

  • ソフトウェアバージョンが異なる (CramFSなどにDiffが出る)
  • 0x80000から0x9FFE0にかけて480bytes毎に32/64bytesほど0x00で上書きされている

前者は差分が出て当然として、後者は明らかにおかしいです。

この現象は、バッファオーバーランの発生を裏付けていると言っても過言ではないでしょう。

ROMの修復 

ところで、その領域に本来書かれていたデータの復元が必要です。

正常品のデータと比較すると、上書きされたのは「一箇所」を除き不要そうなFFばかりでした。

問題は、その「一箇所」。アドレスにして0x800000直後の領域です。そこには大変に意味がありそうなものが書き込まれていました。

本体基板上、本体外装、その他情報などを元に、ぐっと睨むと、以下のことを書き込めば良さそうであることがわかりました。

0x800000 パワーモニターを意味する `1100` (null-terminated string)
0x800020 製造番号 `7913030012` など (null-terminated string)
0x800030 無線LAN MACアドレス `88 30 8A 44 23 01` など (6 bytes)
0x800036 RTC子基板上シリアルコード `132001321` など (null-terminated string)
0x8007D0 謎 `0111` (null-terminated string)

RTC子基板上のシリアルコードを入れるフィールドがあるとは思いもよらず、突き止めるのが大変でした。

復旧 

0x800000 - 0x9FFFFFまでFFで埋めた後、先ほどの値を埋め、復旧済みファームウェアを作成しました。

復旧済みファームウェアを親父に渡し、焼き戻し、Flash ROMを載せ戻してもらいました。(ありがとう…。)

その結果、無事復旧!Linuxが起動し、ログインプロンプトが表示されました!

また、計測ユニットとして正常に動作を再開しました!やったー!

実際のログなど

まとめ 

RyotaKが発見したバッファオーバーランと思われる未知のバグにより、ROMが破壊され、最終的に起動不良に陥っていました。

脆弱性である可能性がある本バグについて、RyotaKが三菱電機株式会社に報告した際には以下の回答を得ており、CVEの採番・アドバイザリの公開はありません。

なお、今回ご指摘いただいた件につきましては、当社として個別具体的な評価を行った結果、EHS(Environment, Health and Safety)に影響を与えるほどの深刻な脆弱性ではないため、アドバイザリ公開は不要と判断いたしました。

次回:発見してしまった、本当の脆弱性 

えーっと…はい。そういうことです。

次回。真の脆弱性。公開準備が整い次第、公開します。お楽しみに。