クラウド環境
分散処理プラットフォーム「Azure Service Fabric」のセキュリティギャップに関する注意喚起
本稿では、マイクロサービスやコンテナアプリケーションのデプロイ、管理、スケーリングに用いられる分散型プラットフォーム「Azure Service Fabric」に注目し、種々の設定状況に応じてセキュリティ事象が引き起こされるシナリオについて解説します。
「Kubernetes」は、コンテナアプリケーションのデプロイ機能に加え、コンテナオーケストレーション機能を提供するプラットフォームの筆頭として広く知られています。しかし、こうした機能を持つプラットフォームは、Kubernetesだけではありません。本稿では、コンテナオーケストレーション機能を持つもう1つのプラットフォームとして、Microsoft社のAzureクラウド上でサービスとして稼働する「Service Fabric」に着目します。前回のKubernetesに関する調査と同様の切り口により、今回は、Service Fabricの設定不備によってセキュリティ事象が引き起こされるさまざまなシナリオについて分析しました。
Azure Service Fabricは、マイクロサービスやコンテナアプリケーションのデプロイ、管理、スケーリングを行う分散処理プラットフォームです。WindowsとLinuxの双方に対応し、アプリケーションのデプロイ時にさまざまなオプションを設定することが可能です。Service Fabricのサービスとしては、「マネージド」と「非マネージド」の2種類が提供されています。このうち、「マネージド」のサービスでは、ノードの設定や管理といった作業がクラウドサービスプロバイダ側に委ねられます。従来型のクラスタ環境において、ノードの管理はユーザ自身に委ねられています。この場合、デプロイに絡む各種設定を、ユーザ自身の手で適切に行う必要があります。
Service Fabricでは、クラスタノードとして仮想マシン(VM:Virtual Machine)を使用します。各ノードでは、コンテナエンジンであるDockerに加えて、Service Fabricに関連する各種サービスが稼働します(図1)。ノードに配備された各コンテナ内では、デプロイ済みのアプリケーションが稼働します。今回の調査では、Service Fabricの動作環境として、Linux系OS「Ubuntu 18.04」を使用しました。
Service Fabricのクラスタを作成(図2)する際には、ユーザ名、パスワードなどを設定する必要があります。これらの認証情報は、ノードへのアクセスに使用されます。
アプリケーションのデプロイ
アプリケーションのデプロイに際しては、Service Fabricの公式コマンドライン・インターフェース(CLI:Command Line Interface)によって生成されるスクリプトを使用します。関連する設定情報は、XMLファイル「ServiceManifest」と「ApplicationManifest」に保存されます。その中には、リポジトリからコンテナイメージや公開ポート設定、分離モード設定を取得する際に必要な認証情報が含まれている場合もあります(図3)。
クライアント証明書
ユーザがクラスタと通信する際には、そのクラスタ用に用意されたクライアント証明書を使用し、認証を受ける必要があります。クライアント証明書は、ダッシュボードへのアクセスや、CLIアプリケーションのデプロイに使われるものであり、厳重に保護することが求められます。もし漏洩した場合、クラスタ全体が侵害される可能性があります。
今回、脅威シナリオをモデル化するにあたり、ユーザが作成したコードに脆弱性があり、侵害を受けたコンテナ内にリバースシェルが設置される状況を検討しました。これは、攻撃者が行う水平移動・内部活動のシミュレーションに相当します。まず、「ゼロトラスト(Zero Trust)」のポリシーや「侵害を想定する(Assume Breach)」パラダイムに基づき、下記のAzureによる公式文書に着目します。
“Service Fabricクラスターはシングルテナントとして設計されており、ホストされるアプリケーションは信頼できるものと見なされます。したがって、アプリケーションはService Fabricランタイムへのアクセスを許可され、そのマニフェストの形式は異なります。たとえば、アプリケーションファイルとFabricファイルに対応するホスト上のファイルパスを指す環境変数、コンテナーワークロードへの書き込みアクセスでマウントされたホストパス、アプリケーション固有の要求を受け取るプロセス間通信エンドポイント、アプリケーションがその認証に使用することをFabricが想定するクライアント証明書などです。”
上記の内容は、「侵害を想定する」パラダイムに則していないようにも見受けられます。今回、コンテナ環境を分析したところ、読み取り専用でマウントされた複数の領域上で、クラスタに関する機密情報が読み取り可能な状態で発見されました。この中には、コンテナレジストリへのログインに用いられる認証情報さえも含まれていました(図4)。
上記分析に用いたコンテナのデプロイ設定について、「分離モード(Isolation)」としてデフォルトの「プロセス分離」を選択しました。また、「緩和ポリシー(Mitigation Policy)」は適用しませんでした。これは、最小限のデフォルト設定のみを選択した結果です。先述のように認証情報が流出した場合、攻撃者はそれを用いてプライベートなコンテナリポジトリに不正アクセスし、全コンテナイメージの窃取、パッケージの改変、サービスの侵害に及ぶ恐れがあります。実際に本攻撃シナリオの影響がどこまで及ぶかについては、認証情報に紐づくコンテナレジストリのユーザロールや権限設定に依存すると考えられます。
次に、今回のコンテナではインターネットアクセスがデフォルトで有効化されていた点を踏まえ、ネットワークアクセスに関する分析を行いました。結果、コンテナからノード側にアクセスすることが可能であり、当該ノードに対してポートスキャンを行えることも判明しました(図5)。
上図より、今回のシミュレーションで侵害に遭ったと想定するコンテナの所属先ノードでは、ポート番号22が開かれ、SSH(Secure Shell)が稼働していることが見て取れます。このSSHは、公開鍵認証およびパスワード認証を受け付けるように設定されていました。また、登録されているSSHのユーザ名とパスワードは、クラスタ作成時に用いたものと同一であることが分かりました。この認証情報を用いて当該のポート番号22にアクセスすると、クラスタのノードにルート権限でログインすることが可能です。
実際の場面では、攻撃者がパスワードを知らない場合も多いでしょう。しかし、デフォルトのパスワード認証方式が使用されているため、攻撃者はノードに対してブルートフォース攻撃と辞書攻撃を実行し、パスワードを直接推定する可能性があります。公開鍵認証について、現段階ではノード上でのみ設定可能と考えられます。クラスタの管理責任がユーザに委ねられている点を踏まえ、安全性を高める上では、手動でノードにアクセスして公開鍵認証を設定することを推奨します。
先述のSSHにより、攻撃者はコンテナからノードにアクセスすることが可能です。調査を進めたところ、コンテナのエンジンとしてDockerが使用されていること、デフォルトのネットワークモード(NetworkMode)としてホスト(host)が設定されていることが分かりました(図6)。
ネットワークモードの設定について、Dockerの公式文書では下記のように述べられています。
コンテナのネットワークモード(NetworkMode)としてホスト(host)を設定すると、コンテナのネットワーク・スタックはDockerのホストから隔離されなくなります(コンテナとホスト間でネットワークの名前空間が共有される)。また、コンテナに対して固有のIPアドレスは割り当てられません。
セキュリティ観点として、コンテナとホスト間でIPアドレスが共有され、さらに厳重なファイアウォールが設定されていない場合を想定すると、コンテナからノード(10.0.0.4)にデフォルトでアクセスできることになります。ノード上には、クラスタに関する機密情報が格納されています。その代表例がクラスタ証明書であり、これが攻撃者の手に渡った場合、クラスタ全体がコントロールされることになります(図7)。
軽減策とセキュリティ強化
攻撃による影響の軽減策や侵入経路の封じ込め策は、ITシステムにおけるセキュリティの基盤をなすものです。例えば、通信の暗号化や、機密情報へのアクセスに際して認証を求めることは、必須と言えるでしょう。しかし、今回の調査から示されるように、アプリケーションの設定不備や、デフォルトのデプロイ設定では安全性が確保されないケースも多々存在します。ユーザはこの点を念頭に、アプリケーションのデプロイに際してはセキュリティ面での不備がないかどうか、十分に注意することを推奨します。
幸い、今回挙げたService Fabricに関する問題の一部は、設定ファイル「ApplicationManifest」を適切な方針に基づいて設定することで、解決できます。例えば、以下の設定項目について、
ServiceFabricRuntimeAccessPolicy
それを以下の属性値として「true」を設定することで、デプロイしたアプリケーション・コンテナ上にパス「/mnt/sfroot/」がマウントされなくなります。
RemoveServiceFabricRuntimeAccess
これにより、システム侵害が起きた際に、当該パス内の機密情報が流出する事態を回避できます。
一方、ネットワークポリシーの設定を変更しても、コンテナからノードへのアクセスを制限することは、できませんでした。さらに図8の通り、Linux環境では一部の設定が利用できない点も、注意が必要です。
さらに、Linuxホストで稼働するコンテナに対しては、「Hyper-V」のプロセス分離モードを設定できないことが分かりました。なお、本調査で示された主要な懸念事項である、認証情報を推測することでノード側へのアクセスが可能になる問題については、公開鍵暗号方式によるアクセスのみを許可するように手動設定し、適切な鍵のペアを生成することで、部分的に解決できる可能性があります。
以上の発見事項を踏まえ、「コンテナ・エスケープ」など、さらに深刻な影響に繋がるシナリオについて検討しました。具体的には、下記の可能性について分析しました。
- 修正パッチが適用されていないコンテナエンジンの脆弱性が不正利用される(CVE-2019-5736など)
- 修正パッチが適用されていないService Fabricの脆弱性が不正利用される(CVE-2022-30137など)
- 下記をはじめとする分離機能の脆弱性が不正利用される
- プロセス分離の場合はカーネル自体の脆弱性
- 仮想化の場合はハイパーバイザ自体の脆弱性
- 設定および設計上の不備が不正利用される
ほとんどのケースは可能性が低いと考えられたため、今回は、先述したノードへのアクセスが可能となる性質に焦点をあて、ノードに関する分析を進めました。この結果として発見されたのが脆弱性「CVE-2023-21531」であり、不正利用された場合、コンテナからクラスタへの不正アクセスに繋がります。
結論
クラウドサービスを利用する際は、クラウドサービスプロバイダ(CSP:Cloud Service Provider)がセキュリティの全てを担保するわけではない点について、注意する必要があります。サービスによっては、ユーザ自身でセキュリティ面に考慮した設定を行う必要があります。これにより、設定ミスや、保護されていない環境が作成される可能性が生じます。セキュリティの確保にはコストが付き物であり、それはCSPへの支払いだけで完結するものではありません。自発的な姿勢を持ってセキュリティ対策に取り組み、下記のようなベストプラクティスを推進していくことが重要です。
- 環境やプロジェクトのセキュリティ確保について、CSPからの推奨事項を遵守する
- コンテナやアプリケーションについて、「最小権限」の原則を遵守する
- 「侵害を想定した」パラダイムに基づいた設定、設計を行い、攻撃の影響を最小限に抑え込む
Service Fabricやコンテナレジストリ向けのベストプラクティスを遵守することで、セキュリティ事象が発生するリスクを軽減することが可能です。しかし、全てのアプリケーションが「ゼロトラスト」の発想で設計されているわけではありません。そのため、追加設定やセキュリティ強化をユーザ自身の手で行うことも、状況に応じて必要になってくるでしょう。
参考記事:
Gaps in Azure Service Fabric’s Security Call for User Vigilance
By: David Fiser
翻訳:清水 浩平(Core Technology Marketing, Trend Micro™ Research)