Microsoft 社の Azure Sphere IoT プラットフォームについてはこのブログで何度か取り上げてきました(ブログ記事 1、2、3、4 を参照)。今回もこの製品を取り上げていこうと思います。ハッキングコンテストではありませんのでじっくり腰を据えて取り組んでいます。
Cisco Talos は本日、Azure Sphere の新たな脆弱性を 10 件公開しました。そのうち 2 件は Linux、7 件は Security Monitor、1 件は Pluton セキュリティサブシステムの脆弱性です。
以前の記事ではアーキテクチャの概要をご紹介しましたが、今回は Azure Sphere を継続的に調査していく記事の一環として概要説明は省略させていただき、発見した脆弱性をシンプルに説明していきたいと思います。では Linux カーネルから見てみましょう。
カーネルにおける情報漏洩
Microsoft Azure Sphere カーネルの GPIO_SET_PIN_CONFIG_IOCTL における情報漏洩の脆弱性(TALOS-2021-1339/CVE-2021-41374)
Azure Sphere では ioctl を /dev/gpiochip0 に送信することで、マニフェストで宣言された GPIO ピンのセットをアプリケーションで管理することができます。この脆弱性が悪用されると、特権のない攻撃者が GPIO_SET_PIN_CONFIG_IOCTL を使用して任意の lineoffsets フィールドを指定することができます。それによってカーネル構造体から境界を越えた読み取りが行われ、カーネルメモリの一部がリークする危険性があります。
Microsoft Azure Sphere カーネルの GPIO_GET_PIN_ACCESS_CONTROL_USER における情報漏洩の脆弱性(TALOS-2021-1340/CVE-2021-41375)
前の問題と似ていますが、この脆弱性は GPIO_GET_PIN_ACCESS_CONTROL_USER ioctl に影響するものであり、攻撃者にはカーネルケーパビリティ CAP_SYS_ADMIN が必要です。通常、CAP_SYS_ADMIN を持つことは root 権限を持つことと同等ですが、Azure Sphere では異なります。この問題は符号なし整数から符号付き整数への変換に起因しており、同じく lineoffsets フィールドに影響を与えます。これが悪用されると攻撃者が任意にカーネルメモリをリークさせる危険性があります。
Pluton におけるサービス妨害
Microsoft Azure Sphere Pluton における同時 syscall によるサービス妨害の脆弱性(TALOS-2021-1347)
この脆弱性は、特権のないアプリケーションが Pluton の ioctl を同時に実行することで Pluton がレート制限に達し、デバイスが再起動する危険性があるというものです。これは意図した動作であると見なされているため Microsoft 社による修正は行われていません。
通常、アプリケーションがこのデバイスを再起動するにはケーパビリティが必要ですが、この脆弱性によってその要件を回避することができます。ただし Microsoft 社はこの種の特権昇格を脆弱性として認識しておらず、CVE を割り当てていません。
Security Monitor におけるサービス妨害
Microsoft Azure Sphere Security Monitor における SECTION_ABIDepends に起因するサービス妨害の脆弱性(TALOS-2021-1311)
デバイス上のすべてのファームウェアイメージにはメタデータセクションがあり、その複数のサブセクションにさまざまな情報が記録されています。現在 Talos が文書化しているメタデータサブセクションは次のとおりです。「*」が付いているものは Pluton または Security Monitor で解析されたものです。
-
* Debug = 0x4244
LegacyABIDepends = 0x4441
Identity = 0x4449
* ABIDepends = 0x444E
Legacy = 0x474C
* Signature = 0x4753
* Compression = 0x4D43
RequiredFlashOffset = 0x4F52
LegacyABIProvides = 0x5041
* ABIProvides = 0x504E
* TemporaryImage = 0x5054
Revocation = 0x5652
各サブセクションは独自の構造体になっていますが、まず 16 進ダンプでメタデータセクションを調べてみました。
- struct metadata_footer {
- uint32_t magic_header;
- uint32_t num_subsections;
- struct metadata_section[num_subsections];
- }
- struct metatdata_section {
- uint16_t tag;
- uint16_t size;
- <タイプごとのデータが開始>
- }
掲題の脆弱性がある ABIDepends サブセクションを調べると、そのデータは基本的に次のようになっていました。
- struct ABIDepends {
- uint32_t size;
- uint64_t ABIdata[size/8];
- }
これはとても明確なバグです。ABIDepends 構造体の size フィールドはまったくチェックされておらず、また読み取りループの唯一の終了条件になっています。フラッシュするアプリケーションでこのフィールドを十分高い値に設定すれば、マッピングされていないメモリへの境界外読み取りを簡単に発生させることができ、結果としてデバイスを再起動させることができます。起動時にイメージがフラッシュ(永続化)されるのでイメージ処理機能が直ちに実行されて、(手動でリカバリするまで)永遠に起動が繰り返されます。
Security Monitor における「カーネル後」のバグ
最後に説明する以下の脆弱性は、Linux Normal World ですべての権限を取得した攻撃者のみがエクスプロイトできます。11 月 26 日の Hitcon 2021 で Lilith Wyatt がこのエクスプロイトの仕組みについて詳しく説明しますので、ぜひ講演にご参加ください。当日の様子はブログ記事でも詳しく取り上げる予定です。
Microsoft Azure Sphere Security Monitor の SMSyscallPeripheralAcquire における情報漏洩の脆弱性(TALOS-2021-1309)
まず SMSyscallPeripheralAcquire から説明します。この syscall はさまざまなデバイスへのピン多重化を設定するために使用されます。この syscall では出力データが保存されるオブジェクトが初期化されていないため、出力バッファで情報漏洩が発生します。
設定する多重化ピンの数に応じてこの構造体のインスタンスが複数作成され、それらが出力バッファに直接コピーされます。これには、この構造体のオフセット 0xc にある 4 バイトのデータも含まれます。バイト 0xe と 0xf は初期化されていないため、設定するピンごとに 2 バイトずつ Security Monitor のヒープリークが発生します(出力バッファは設定するピンごとに 0x18 バイト確保されると仮定した場合)。
あまり重大な情報漏洩ではなかったかもしれませんが、次の脆弱性はより危険なものとなっています。
Microsoft Azure Sphere Security Monitor の SMSyscallWriteBlockToStageImage における情報漏洩の脆弱性(TALOS-2021-1310)
これは SMSyscallWriteBlockToStageImage 関数内の脆弱性です。この関数のプロトタイプは次のとおりです。
-
- int32_t SMSyscallWriteBlockToStageImage(int64_t* handle_value, size_t offset_into_staging_partition, size_t offset_into_srcbuffer, void * srcptr, size_t srcbuffer_size)
最初のパラメータである handle_value は基本的にファイル記述子で、SMSyscallOpenImageForStaging によって返されます。その関数のプロトタイプは次のとおりです。
-
- int32_t SMSyscallOpenImageForStaging(int32_t image_size, int32_t clobbered, uint64_t* output_handle)
image_size が渡され、使用可能なステージングメモリが十分にある場合は output_handle が使用されてイメージステージングの syscall が行われます。SMSyscallWriteBlockToStageImage に戻ると、offset_into_staging_partition 変数は現在のステージングイメージにフラッシュする際の距離を示しており、この値が SMSyscallOpenImageForStaging の image_size と照合されます。
4 番目の引数 srcptr と 5 番目の引数 srcbuffer_size はその名のとおりコピー元です。3 番目の引数である offset_into_srcbuffer は極端な異常値となっています。そもそも書き込めるのは 0x1020 バイトほどしかなく、しかも DMA メモリから Security Monitor のプライベートバッファにコピーする際には事実上のハード制限があって、syscall 構造体と内部のバッファの合計サイズは 0x1060 を超えることができません。
このオフセットが最大サイズのバッファ上にあるのであれば offset_into_srcbuffer はそもそも必要ないようにも思えます。存在理由はともかくとして、この値はチェックされていません。その結果、イメージを「ステージング」して Security Monitor のメモリ空間にある任意のデータでフラッシュすることができます。このデータは SMSyscallReadFlash syscall を使用して読み出すことができます。実質的に Security Monitor のメモリ空間全体からデータを読み取ることができるのです。
Microsoft Azure Sphere Security Monitor の SMSyscallStageBaseManifests オフセット計算における境界外読み取りの脆弱性(TALOS-2021-1343/CVE-2021-41376)
SMSyscallStageBaseManifests syscall はベースマニフェストのステージングに使用できます。マニフェストは標準の Azure Sphere イメージでラップされていますが、その内容は文書化されていません。Talos が見つけたすべてのベースマニフェスト内に、トラストキーストアおよび更新証明書ストアのイメージとコンポーネント ID がありました。このマニフェストをステージングした後でのみ、マニフェストに定義されているイメージをフラッシュできます。この syscall 関数のプロトタイプは次のとおりです。
-
- int32_t SMSyscallStageBaseManifests(uint32_t offset, char *src_buffer, uint32_t manifest_length)
manifest_length はマニフェストの長さを示します。マニフェストは src_buffer から offset パラメータで指定された長さだけ離れた位置にあるものと想定されています。Security Monitor の他の syscall と同様に、manifest_length は 0x1060 を超えることができません。しかし offset パラメータには制約がなく、syscall の実行前も実行中もチェックされません。攻撃者がこれを悪用して境界外のマニフェストを参照する危険性があります。マニフェストヘッダーにはいくつかの制約があるため、このエクスプロイトは簡単ではありません。アドバイザリで詳しく説明していますが、この境界外読み取りを悪用して DMA メモリにマニフェストをステージングし、セカンダリ M4 コアを使用してそれを読み取り、この syscall によってマニフェストがステージングされている間に TOCTTOU を使用してマニフェストを改変することができます。これによって情報漏洩が発生する危険性があります。
Microsoft Azure Sphere Security Monitor の SMSyscallStageBaseManifests イメージ検証における署名チェックのバイパスの脆弱性(TALOS-2021-1342/CVE-2021-42300)
SMSyscallStageBaseManifests syscall では、ベースマニフェスト(通常は Microsoft 社の署名があります)をステージングする前に検証することになっています。マニフェストは Azure Sphere イメージにバンドルされています。このイメージはファームウェアイメージ、アプリケーション、キーストアなどと同じファイルタイプです。Azure イメージのヘッダーフィールドの 1 つとしてイメージタイプがあり、ベースマニフェストの場合は特定の値を保持する必要があります。アドバイザリで詳しく説明していますが、イメージマニフェストのイメージタイプを変更することで SMSyscallStageBaseManifests の署名チェックを攻撃者がバイパスし、任意のマニフェストをステージングする危険性があります。これによって Microsoft 社が署名した任意のバイナリをフラッシュできるようになります。つまり、任意のファームウェア(またはデバイス全体)を以前のバージョンにダウングレードして、そのコードに存在する古い問題を標的にすることが可能になります。
Microsoft Azure Sphere Security Monitor の SMSyscallCommitImageStaging におけるマニフェストなしのステージングによるサービス妨害の脆弱性(TALOS-2021-1341)
トラストキーストアは起動時およびイメージのインストール時にイメージを検証するために使用されます。関連するベースマニフェストをフラッシュすることなく Microsoft 社が署名したトラストキーストアをフラッシュすることが可能となっています。これを悪用してバージョン 20.01 の古いトラストキーストアをフラッシュすることができます。その結果、インストールされたファームウェアイメージの検証ができなくなり、デバイスが起動しなくなります。このサービス妨害は手動によるリカバリが必要です。
注:この脆弱性は理論上のものであり、開発モードで発見されました。実稼働前環境または実稼働環境での確認は Talos も Microsoft 社も行っていません。詳細については、アドバイザリを参照してください。
Microsoft Azure Sphere Security Monitor の SMSyscallCommitImageStaging における 1BL ファームウェア ダウングレードの脆弱性(TALOS-2021-1344)
1BL は Azure Sphere で使用されるブートローダーです。通常はファームウェアがアップグレードされるたびに新しいバージョンがフラッシュされます。この脆弱性が悪用されると、どのファームウェアリリースにも含まれているリカバリマニフェストをステージングすることで、対応する任意の 1BL バージョンがインストールされる(つまりそのバージョンがダウングレードされる)危険性があります。これにより、攻撃者は 1BL をダウングレードし、そのコードに存在する古い問題を標的にすることができます。
注:この脆弱性は理論上のものであり、開発モードで発見されました。実稼働前環境または実稼働環境での確認は Talos も Microsoft 社も行っていません。詳細については、アドバイザリを参照してください。
Microsoft 社は上記の 2 つの脆弱性について次の声明を発表しています。
-
- 2020 年の Azure Sphere バグ発見コンテスト以来、Cisco Talos が Azure Sphere について継続的な調査を行い、その結果をお知らせいただいていることに感謝申し上げます。弊社にて TALOS-2021-1341 および TALOS-2021-1344 の調査結果を確認いたしました結果、当該アプローチは設計に従って実装されており、顧客の実稼働環境にセキュリティリスクをもたらすものではないと考えております。Cisco Talos の見解の詳細については、Cisco Talos アドバイザリに記載されている詳細な声明をご覧ください。
カバレッジ
脆弱性のエクスプロイトは、以下の SNORTⓇ ルールで検出できます。今後、脆弱性に関する新たな情報が追加されるまでの間は、ルールが追加されたり、現行のルールが変更されたりする場合がありますのでご注意ください。最新のルールの詳細については、Cisco Secure Firewall または Snort.org を参照してください。
Snort ルール:57745 ~ 57746、57266 ~ 57267、57747 ~ 57748、57888 ~ 57889、57899 ~ 57900、57934 ~ 57935、57963 ~ 57964
本稿は 2021 年 11 月 09 日に Talos Group のブログに投稿された「Cisco Talos finds 10 vulnerabilities in Azure Sphere’s Linux kernel, Security Monitor and Pluton」の抄訳です。