前回(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)に影響を与えるほどの深刻な脆弱性ではないため、アドバイザリ公開は不要と判断いたしました。
次回:発見してしまった、本当の脆弱性 ¶
えーっと…はい。そういうことです。
次回。真の脆弱性。公開準備が整い次第、公開します。お楽しみに。