SolarCity に光を当てる: X2e IoT デバイスの実用的な活用 (パート 2)

Uninterruptable U-Boot bootloader output news

この投稿では、 SolarCity ConnectPort X2e Zigbee デバイス (全体で X2e デバイスと呼ばれます) の分析を続けます。パート 1では、X2e について高レベルで説明し、最初のネットワーク ベースの攻撃を実行した後、非特権システム ユーザーとして X2e デバイスでリモート シェルを取得するために使用されるハードウェア手法について説明しました。このセグメントでは、パワー グリッチ攻撃を使用してデバイス上で特権シェルをローカルで取得する方法について説明し、 CVE-2020-12878を調べます。これは、ルートユーザーへのリモート権限エスカレーションを許可する脆弱性であることが判明しました。 CVE-2020-9306 (パート 1 で説明) と組み合わせると、X2e デバイスの完全なリモート侵害が発生します。

テクニカル分析

要約

次のステップに入る前に、中断したところをおさらいしましょう。

  • X2e には公開されたユニバーサル非同期送信/受信 (UART) インターフェイスがあり、物理的に接続されたユーザーが Das U-Boot (U-Boot) ブート プロセスを表示 (ただし、中断はしない) し、適切な資格情報を与えて、Linux に対して認証することができます。オペレーティング·システム。ルート認証情報がないため、このスレッドを後回しにします。
  • ブート構成、ブートローダー ファームウェア、ファイルシステム、および Linux カーネル イメージを含む、Spansion raw フラッシュの完全な NAND ダンプがあります。これは、前のパート 1 で、 pythonユーザーのハードコードされた資格情報を取得するために使用されました。

UART が存在し、ブートローダーへのアクセスが非常に重要であることを知っていたので、そのスレッドを再検討することにしました。

特権アクセスをローカルで取得する

ブートローダーの再検討

図 1 は、UART 接続を介して接続されているときに表示される U-Boot ブート プロセスを示しています。場合によっては、ブートローダーが「Hit any key to stop autoboot」というメッセージを表示する設定期間中 (通常は 1 ~ 4 秒) にキーボード入力をデバイスに送信することができます。これにより、ブート プロセスが中断され、ユーザーが削除されます。 U-Boot シェルに。 X2e では、U-Boot 構成パラメーターCONFIG_BOOTDELAY0設定することで、この機能が無効になっています。

Uninterruptable U-Boot bootloader output
図 1: 中断のない U-Boot ブートローダーの出力

自動起動を妨害することに成功したと報告されている攻撃の 1 つは、起動プロセス中にフラッシュ ストレージにアクセスするブートローダーの機能を操作することです。 U-Boot ブートローダーが自身の構成にアクセスできない特定の状況では、制限が緩和されている可能性があるデフォルト環境に失敗します。これが X2e で可能かどうかを確認することにしました。

グリッチ攻撃 (正式にはフォールト インジェクション) として知られるこれらの攻撃は、マイクロコントローラ ユニット (MCU) に命令をスキップさせたり、間違った命令を実行させたり、フラッシュ メモリへのアクセスに失敗させようとする一種のサイド チャネル攻撃です。電気、熱、放射線など、さまざまなタイプのグリッチ攻撃が存在します。私たちの目的に基づいて、MCU と Spansion NAND フラッシュの間の電力をグリッチすることを選択しました。グリッチ攻撃は、多くの場合、ボード上のコンポーネントに損傷を与えたり、デバイスを使用不能な状態にする可能性があることに注意してください。これらのタイプの攻撃は、最後の手段として、または損傷しても問題のないセカンダリ デバイスに対してテストする必要があります。

ブートローダーの不具合

このドメインでの以前の調査に基づいて、MCU と NAND フラッシュ間のデータ ライン (I/O) をターゲットにすることにしました。パート 1 で説明したように、X2e の NAND フラッシュは Spansion S34ML01G1 で、これは 63 ピンのボール グリッド アレイ (BGA) パッケージでした。このチップは、使用される I/O ラインの数に対応する 8 ビットと 16 ビットの両方のバス幅をサポートできます。フラッシュのデータシートを使用し、チップの ONFI デバイス ID を照会することで、チップが 8 ビット構成を使用していることを確認しました。これは、NAND フラッシュと MCU の間に 8 つの I/O ラインが存在することを意味します。この攻撃では、最初の ( I/O0 ) データ ラインの電力を操作することに焦点を当てました。図 2 は、 I/O0が強調表示された BGA-63 ピンの構成を示しています。

Spansion データシートで NAND チップの I/O0 を特定する
図 2: Spansion データシートでの NAND チップの I/O0 の特定

ピンは実際にはフラッシュ パッケージの下にあるため、PCB 上の他の場所にあるI/O0 に対応する露出したリードを見つける必要がありました。 PCB 全体の接続をトレースする方法の 1 つに、導通テストがあります。導通テスト (マルチメーターを使用) では、2 つのポイント間で低電流の電気信号が送信され、ポイントが接続されている場合はビープ音が発生します。この手法を使用して、露出したテスト ポイント (ビアと呼ばれる) を PCB の底面に配置しました。図 3 は PCB の上部 (NAND チップの下) にある I/ O0ピンを示し、図 4 は PCB の下部に露出したI/O0ピンを示しています。

PCB 上の I/O0 (NAND チップの下)
図 3: PCB 上の I/O0 (NAND チップの下)
PCB の下部にある I/O0
図 4: PCB の下部にある I/O0

I/O0への露出したアクセスを見つけて、ブート プロセス中のさまざまなポイントで、このピンを既知のグランド ( GND ) ピンに直接接続する実験を行いました。図 5 は、金属ピンセットでI/O0GNDに接続してデバイスの電源を入れている様子を示しています。

I/O0 を GND に短絡
図 5: I/O0 を GND に短絡

UART インターフェイスに接続している間、いくつかの異なる結果が得られました。電源投入直後にピンを短絡すると、デバイスは出力または起動を生成できませんでした。ブートローダーのロードが完了した後 (および Linux カーネルにハンドオフした後) にショートすると、デバイスも強制的に再起動されます。ただし、ブートローダーの読み込みとその構成の読み取り試行の間のタイミングが完全に一致すると、ブートローダーが異なる出力を提示し、ブート プロセスを中断するオプションが 4 秒の遅延で可能であることに気付きました。キーボード入力を押すことで、U-Boot シェルに正常にドロップすることができました (図 6 参照)。

U-Boot ブートローダー シェルへのアクセス
図 6: U-Boot ブートローダー シェルへのアクセス

これは大きな進歩でしたが、現在のフェイルバック ブートローダー構成は完全に動作不能であり、特定の NAND ブロックが (予想どおり) 不良としてマークされていることに気付きました。デバイスを動作状態に戻すには、パート 1 で生成した NAND ダンプを再確認する必要がありました。

ブートローダー構成の修復

現在の構成でシェルが機能するようになりましたが、私たちが行った損傷を修正する必要がありました。これは、誤ってマークされた不良ブロックを修正し、構成を再構築するという 2 つの手順で実行されました。私たちの場合、 nandユーティリティとそのサブコマンドreadwrite 、およびScrubを使用して、NAND のページとブロックを検査および操作できました。有効なオフセットとサイズを指定したnand Scrubコマンドを使用して、NAND のセグメントを完全にリセットし、不良ブロック マーカーを削除できました。次の課題は、損傷したブロックの何を交換する必要があるかを判断し、構成を再構築することでした。

有効な NAND イメージがあったので、ブートローダーによって読み取られたセクションを再検討して、必要な変更を特定しました。この形式は既知の形式と一致しなかったため、バイナリ構造を読み取る単純なパーサーを Python で作成しました (図 7 参照)。

フラッシュからのブートローダー nvram 構成の解析
図 7: フラッシュからのブートローダー nvram 構成の解析

構成がどのように見えるべきかの詳細とともに、 nand writeを使用して、正しい詳細でバイトごとにこのセクションを再構築しました。また、ブート遅延を 4 秒に設定して、新しい構成がコミットされたらいつでもブートローダーを中断できるようにしました。変更が安定していることを確認したら、構成をフラッシュに保存し、前述のグリッチ攻撃を実行せずにブートローダーにアクセスできるようにしました。

root ユーザーとして Linux にアクセスする

ブートローダーに無制限にアクセスできるようになったので、最終的に残りのブート プロセスに影響を与え、特権シェルを実現できます。これについてはパート 1 で触れましたが、アンロックされた U-Boot シェルをルートLinux シェルに変える最も簡単な方法は、U-Boot が Linux カーネルに渡すブート引数を調整することです。私たちの場合、これはsetenvユーティリティを使用してstd_bootarg環境変数をinit=/bin/shに変更し、U-Boot に標準のブート プロセスを再開するように指示することによって達成されました。図 8 は、UART 経由で表示される Linux シェルを示しています。

ブートローダー後の root シェル
図 8: ブートローダー後のルート シェル

この時点で、ローカル権限昇格を達成するための反復可能な方法を示しました。最後のセグメントでは、権限をリモートでエスカレートする方法を探ることで攻撃を完了します。

特権アクセスをリモートで取得する

X2e には利用可能なリッスン ネットワーク サービスが 2 つしかないため、これらのサービスを再調査することは理にかなっています。パート 1 では、限定ユーザーpythonのハードコードされた資格情報を特定しました。これは、実行中のデバイスの初期プローブに役立ちましたが、ここからどこへ行くのでしょうか?

通常、組み込みデバイスには少数のユーザーしか存在せず、ほとんどの機能はrootユーザーによって実行されます。これは、 Pythonユーザーが所有および管理するコンテンツに対してrootユーザーが実行するアクション間の重複を悪用する興味深い機会を提供します。

起動プロセスを確認したところ、/etc/ init.d / ディレクトリに多数のカスタムinitスクリプトがあることに気付きました。これらのスクリプトは、システムの起動時にrootユーザーによって実行され、デーモンの起動と、ディレクトリまたはファイルの存在の確認を担当していました。特に 1 つのファイル/etc/init.d/S50dropbear.shは、 $PYTHON_HOME変数で指定されたディレクトリ ( /WEB/python/ ) 内のファイルに対して多くのアクションを実行しているように見えたため、私たちにとって興味深いものでした。図 9 に示します。

$PYTHON_HOME ディレクトリでの安全でない操作
図 9: $PYTHON_HOME ディレクトリでの安全でない操作

一見これは無害に思えるかもしれませんが、 /WEB/python/ディレクトリがpythonユーザーによって制御可能であることを考えると、 rootによって実行されるアクションを制御できる可能性があることを意味します。より具体的には、 chown操作は危険です。前のmkdirコマンドがサイレントに失敗し、安全でないchown操作が発生する可能性があるためです。これを兵器化するには、シンボリック リンクを使用して/WEB/python/.ssh/をファイル システムの他の領域にポイントし、ルートプロセスに強制的にこれらのファイルをchownして、 pythonユーザーが所有するようにします。これを悪用するために私たちが取ったプロセスは次のとおりです。

  1. ハードコーディングされたPythonユーザー資格情報を使用して SSH 経由で認証します。
  2. /etc/init.d/を指すシンボリック リンク/WEB/python/.sshを作成します。
  3. X2e を再起動し、システムに強制的に/etc/init.d/S50dropbear.shを再実行させます。
  4. 起動が完了したら、悪意のあるinitスクリプトを/etc/init.d/pythonユーザーとして作成します。
  5. X2e を再起動して、システムに新しいinitスクリプトを強制的に実行させます。

最もクリーンなアプローチではありませんが (2 回の再起動が必要です)、 rootとしてコードを実行するという目標を達成します。図 10 は、概念実証の出力を示しています。この場合、悪意のあるinitスクリプトが TCP ポート 8080 でバインド シェルを生成し、 rootとして接続できるようにしました。

chown の脆弱性を悪用して、ユーザー root としてシェルを取得する
図 10: chown の脆弱性を悪用して root ユーザーとしてシェルを取得

2 つの個別の脆弱性を悪用して、root としてリモート接続します。このシリーズでは検討していませんが、別の実行可能な攻撃手段として、TCP ポート 80 および 443 でリッスンしている Web サーバーの潜在的な脆弱性を調査することが考えられます。ただし、これは私たちが取ったアプローチではありませんでした。

結論

この 2 部構成のシリーズでは、次のようなさまざまなトピックを取り上げました。

  • 物理デバイス検査
  • 物理デバッグ インターフェイス (UART) の特定と探索
  • NAND ストレージを削除するためのチップオフ技術
  • ファイルシステムとブートローダー構成のバイナリ分析
  • U-Boot ブートローダーに対する電源グリッチ攻撃
  • Linux ユーザー空間の権限昇格

読者が X2e での経験から学び、これらの手法を独自の分析に使用するよう促されることを願っています。最後に、Mandiant は、Tesla/SolarCity と Digi International の両方に、これらの脆弱性を修正するための努力と、このブログ シリーズのリリースへの協力に感謝したいと思います。

参照: https://www.mandiant.com/resources/blog/solarcity-exploitation-of-x2e-iot-device-part-two

Comments

Copied title and URL