エクスプロイト&脆弱性
Azure Machine Learning サービスに潜むセキュリティリスク - パート1
トレンドマイクロでは、Azure Machine Learning(AML)サービスを調査し、機密情報の漏えいを招く可能性のあるセキュリティ上の不備や脆弱性を明らかにしました。パート1となる本稿では該当の脆弱性の詳細について解説します。
Azure Machine Learning(AML)は、機械学習モデルを構築、デプロイ、そして管理するためのサービスプラットフォームです。Azure MLの前にはAzure Batch AIが同様のサービスを提供していましたが、その後廃止されました。AMLは、データの準備からモデルのトレーニング、デプロイメント、管理まで、幅広い機能を提供します。これにより、企業や組織はデータからの知見を得て、インテリジェントなアプリケーションを構築することが可能になります。また、AMLは機械学習の運用(MLOps)を容易にし、データサイエンティストや機械学習の専門家がワークフロー、インフラ、データセット、モデル、アルゴリズムを管理する手段を提供します。ユーザは、このプラットフォームを使用してパイプラインを構築することで、仮説検証のためのインフラストラクチャ作成にかかる時間を削減し、ニーズに応じて反復作業と規模の拡大が可能です。AMLは、その効率性から様々な業界のグローバル企業に広く利用されています。
さらに、AMLを活用することで、ユーザはカスタムデータセットに基づいたモデルの微調整、トレーニング、デプロイ、監視を行い、Microsoftが維持するインフラストラクチャを利用できます。これは、ChatGPTの基盤インフラストラクチャに関する最近のビデオ(英語)で紹介されています。
セキュリティの観点からこのサービスを調査した結果、今回の調査では、いくつかの脆弱性や安全でないプラクティスを確認しました。これらには、機密情報の保存とログ記録に関連する問題、特定のAML設定でのクラウドミドルウェアエージェントの使用による機密情報の漏えいをもたらす公開API、誤設定されたオープンソースコンポーネントの使用による機密アクセストークンの意図しないログ記録などが含まれます。これらは本稿のシリーズで詳しく取り上げる問題の一部です。これらのセキュリティ上の問題はMicrosoftに報告され、修正されました。
シリーズのパート1となる本稿では、AMLリソース上での認証情報のプレーンテキストによる保存およびログ記録に関するセキュリティ問題について、調査結果を詳しく紹介します。これらの問題がどのように発見され、AMLのような協働環境でどのようなリスクをもたらすのかについて明らかにします。
Azure Machine Learning(AML)の概要
AMLは、図2で詳細が示されているとおり、様々なコンポーネントで構成されています。
(出典:Microsoft.com)
AMLサービスは、ユーザが管理するサービスとMicrosoftが管理するサービスを組み合わせて使用します。ユーザがAMLサービスを基にリソースを作成する際にワークスペースが作成されます。AMLワークスペースは、機械学習に関連する活動やアーティファクトを管理するための中心的な場所となります。AML Studio、VSCodeの拡張機能、AML SDK、AML CLIを通じてこのワークスペースにアクセスできます。AML StudioはWebユーザインターフェースを提供し、開発者がリソースを容易に管理できるようにします。ユーザは、Jupyterノートブック、実験、データセット、モデル、トレーニングや推論の環境で作業を行い、MLモデルをエンドポイントとしてデプロイし、MLOpsを実行することができます。
ワークスペースを作成する際、ワークスペースがこれらのサービスに依存しているため、コンテナレジストリを除く以下のサービスのリソースを指定する必要があります。ユーザはこれらのサービスに対して既存のリソースを使用することも、ワークスペース専用に新たに作成することもできます。
- ストレージアカウント
- キーボルト
- コンテナレジストリ
- アプリケーションインサイト
AMLでのコンピュート
この場合、コンピュートの対象は、ユーザがスクリプトやノートブックを実行したり、MLモデルをエンドポイントとしてデプロイしたりするために使用するマシンとなります。それらは、ローカルコンピュータ、コンピュートクラスタ、コンピュートインスタンス、Azure仮想マシン、Azure Databricksなどがあり、一部はプレビューモードでの利用が可能です。今回の調査では、コンピュートインスタンス(CI)を対象に選びました。
コンピュートインスタンスは、Microsoftによって管理された開発環境であり、主に開発とテストに使用されます。デフォルトのオペレーティングシステムはUbuntuベースであり、Microsoftによってメンテナンスされています。Docker、Jupyter、Node.js、Python、NVIDIA CUDA-X GPUライブラリ、Condaパッケージ、TensorFlowなど、MLプロジェクトやアプリケーションに一般的に使用される開発ツールが標準でインストールされています。
(出典:Microsoft.com)
AMLでは、コンピュートインスタンスとコンピュートクラスタは、Batchによってセットアップされます。Batchを用いることで、Azure内で大規模なワークロードを実行することが可能となるからです。これにより、コンピュートノード(仮想マシン)のプールが作成・管理され、実行したいアプリケーションがインストールされ、ノード上でのジョブのスケジュール化が可能となります。タスクは、ジョブに関連する計算の単位となります。つまり、タスクはジョブ1回の実行と考えることができます。
AMLにおけるストレージ管理
AMLワークスペースには、それぞれ関連するストレージアカウントが設定されています。このストレージアカウントのファイル共有とBlobコンテナは、Jupyterノートブック、スクリプト、ログ、データセット、モデルなど、機械学習関連のアーティファクトやエンティティの保存に使用されます。AMLでは、これらの機械学習関連エンティティにコンピュートインスタンスからアクセスするために、データストアを提供しています。データストアは基本的に、ワークスペースのストレージアカウントへの参照点です。これにより、ユーザは、Blob、ファイル、データレイクなど、さまざまなストレージタイプとやり取りすることができます。データストアを利用することで、ユーザはストレージオプションにアクセスするために自身のスクリプトに接続情報(アクセスキー、SAS認証情報)を記述する必要がありません。
AMLワークスペースには、デフォルトでいくつかのデータストアが作成されます。これらのデータストアは、以下のように異なるストレージオプションにマッピングされています。
上記のデータストアのいずれかを詳しく見ると、参照されているストレージの種類がわかります。例えば、以下はBlobストレージを指しています。
workspaceartifactstore
さらに、AMLデータストアは、サポートされるストレージサービスへのアクセスに使用される以下の認証タイプをサポートしています。
(出典:MSDocs)
Azure File Shareの利用において、AMLデータストアは認証情報による認証はサポートしていますが、IDベースの認証には対応していません。Azure File Shareを操作する際の認証情報は、ストレージアカウント名(ユーザ名)とストレージアカウントのプライマリアクセスキー(パスワード)の組み合わせに基づいています。
ワークスペースのストレージアカウントにあるファイル共有は、ワークスペース内で作成されるすべてのコンピュートインスタンスにファイル共有がマウントされます。このドライブは、Jupyter、JupyterLab、RStudio、Posit Workbenchのデフォルト作業ディレクトリとして機能します。つまり、作成されたノートブックやその他のファイルは自動的にファイルシェアに保存され、他のコンピュートインスタンスでも利用可能となります。また、AMLサービスはユーザ間の協力を促進するため、ワークスペース内の任意のユーザが他のユーザのファイル(Jupyterノートブックやスクリプトなど)にアクセスできるように設計されています。
Azureサービスの多様性を踏まえ、今回の調査では、AMLの異なるコンポーネントを理解することに注力しました。当初から明らかだったのは、AMLが他の重要なAzureクラウドサービスに依存していることです。そのため、広く使用されているオープンソースコンポーネントの多様性を考慮し、それらのコンポーネントがどのように機能するかを分析することに価値があると考えました。侵害後のシナリオにおいて、攻撃者の視点から見ると、アタックサーフェスは顕著に拡大しており、今回の調査はこの点を裏付けることになります。
この背景およびAMLサービスの概要に基づき、今回確認されたセキュリティ上の問題の詳細については、Zero Day Initiative(ZDI)を通じてMicrosoft社に報告しました。その詳細について説明します。
機密情報のプレーンテキストでの保存
ストレージアカウントは、アカウントの設定とデータへのアクセスを承認するために、512ビットのアクセスキー2つを使用します。これらのキーの保護は非常に重要となります。AMLワークスペースに関連するストレージアカウントには機密情報が含まれているためです。コンピュートインスタンス上では、ストレージアカウントのファイル共有がマウントユーティリティを使用してマウントされます。そのコマンドは以下の通りです。
AMLワークスペースで作成されたコンピュートインスタンスにおいて、ストレージアカウントアクセスキーがプレーンテキストで保存されている事例は、以下のように4件確認されました。
1. ZDI-23-161:バッチエラーログについて
コンピュートインスタンスの調査とファイル共有のマウント方法の解明中に、スタートタスク実行時に生成されるログに遭遇しました。修正バッチでは、スタートタスクがノード(つまりコンピュートインスタンス)の運用環境を準備します。このタスクの実行結果は、以下に位置するstderr.txtとstdout.txtという2つのファイルに保存されます。
/mnt/batch/tasks/startup/stdout.txt
/mnt/batch/tasks/startup/stderr.txt
スタートタスクで実行されるコマンドの1つで、AMLワークスペースに関連するストレージアカウントのプライマリアクセスキーを含むコマンドラインが、プレーンテキストでstderr.txtのエラーログに記録されていることが判明しました。
2. ZDI-23-096:システム認証ログ
コンピュートインスタンスが起動するたびに、AMLワークスペースのストレージアカウントに関連付けられたAzureファイル共有が以下のパスにマウントされます。
/mnt/batch/tasks/shared/LS_root/mounts/clusters/CI_HOSTNAME/code
前述の事例では、バッチのエラーログから、実行されていたコマンドにストレージアカウントの認証情報がパスワードフィールドに含まれていることが明らかでした。コマンドが「sudo」として実行されているため、認証情報を含むコマンドがそのまま以下のシステム認証ログに記録されていることがわかりました。
/var/log/auth.log
認証ログは高い権限でアクセスする必要がありますが、コンピュートインスタンスのデフォルトユーザである「azureuser」はsudoersグループのメンバーであり、「sudo」権限を取得できます。さらに、上記の2つの問題を報告した後、パスワードフィールドの値がマスクされた事例に遭遇しました。
2. ZDI-23-095:エージェント構成ファイル
Microsoft社への報告後、上記の2つの問題が修正された後、コンピュートインスタンス上でプライマリアクセスキーがプレーンテキストで保存されている2つの事例に遭遇しました。AMLは、コンピュートインスタンスを管理、診断、監視するためにコンピュートインスタンス上にインストールされた特定のエージェントを使用します。これらはスタートタスクの以下の作業ディレクトリ に保存され、マイクロソフトによって管理されています。
/mnt/batch/tasks/startup/wd
これらはコンピュートインスタンス上でsystemdサービスとして動作し、そのアクションを実行するために特定の設定が必要です。「dsimountagent」と「dsiidlestopagent」という2つのエージェントについて、サービスが以下のファイルから環境変数を取得することがわかりました。
dsimountagent: /mnt/batch/tasks/startup/wd/dsi/dsimountagentenv
dsiidlestopagent: /mnt/batch/tasks/startup/wd/dsi/dsiidlestopagentenv
これらのストレージアカウントアクセスキーのログ記録事例は、以前報告された問題がどのように修正されたかを理解しようとしている間に見つかりました。
ストレージアカウントのプライマリアクセスキーを含んでいた環境変数は「PASSWD」という名称でした。この環境変数が特にそのような名前である理由を解明している間に、マウントユーティリティが「password」引数を指定しない場合、「PASSWD」という名前の環境変数から値を取得できることがわかりました。
4. ZDI-23-097:nginxアクセスログにおけるコンピュートオーナーのJWT
AMLサービスのユーザは、Jupyterノートブック、JupyterLab、ブラウザ組み込みのターミナル、VSCode IDE、SSHを使用して作成されたコンピュートインスタンスにアクセスできます。Jupyterはオープンソースのウェブベースのインタラクティブなコンピューティングプラットフォームであり、ユーザがブラウザベースのターミナルを作成し、コードの共同作業を行うことを可能にします。データサイエンティストの間では、Jupyterは非常に人気のある開発者向けツールです。
クライアントがAMLを利用したい場合、認証プロセスは以下の通りです。
クライアントがAzure ADからAzureリソースマネージャトークンを取得すると、AMLで作業するためにそのトークンを使用します。AMLサービスはAMLトークンを作成し、これを使用してアクション(例:コンピュートインスタンスでの作業、コンピュートクラスタなど)を実行します。コンピュートインスタンス上で、クリアテキストでログに記録される認証情報に関する問題が報告された後修正されたため、コンピュートインスタンスへの着信認証情報があるかどうかを調査しました。Jupyterターミナルセッションを終了した場合、ユーザのJSON Webトークン(JWT)がロードバランサーを通じてコンピュートインスタンスに伝播することがわかりました(図18参照)。
コンピュートインスタンス上のJupyterLabにアクセスするためのURLは次のようになります。
https://CI_HOSTNAME.REGION.instances.azureml.ms/lab.
コンピュートインスタンスでは、nginxをプロキシとして使用し、ロードバランサーからの着信リクエストを転送します。このプロキシは、すべてのインターフェースで、ポート44224で待ち受けています。nginxプロキシにはクライアント側認証が有効になっており、発行者と主体の識別名をチェックします。その後、「X-MS-Target-Port」という特定のヘッダの値がチェックされます。このヘッダの値には、着信リクエストが転送されるべきポートが含まれています。
変数「proxyhost」は「127.0.0.1」にポート番号を続けて設定されます。例えば、コンピュートインスタンス上のJupyterにアクセスするすべての着信リクエスト(8888ポートで動作)の場合、X-MS-Target-Portヘッダの値は8888であり、proxyhost変数は「127.0.0.1:8888」に設定されます。
「proxy_pass」ディレクティブでproxyhost変数が渡され、これによってリクエストはリクエスト内で参照されるURIに基づいて転送されます。JupyterターミナルはWebsocket経由で通信し、同じ理由で接続がアップグレードされます。
デフォルトの設定では、nginxはに以下にアクセス試行をログに記録します。
/var/log/nginx/access.log
今回の調整では、意外にもnginxアクセスログには既存のブラウザベースのターミナルを閉じたユーザのAML JWTが含まれていることに気づかされました。ユーザが既存のJupyterターミナルを閉じると、3つのリクエストが観察されます。
DELETEメソッドのリクエストの前にあるGETメソッドのリクエストには、「token」というURLパラメータ名でコンピュートオーナーのJWTが含まれています。これらのトークンは短命(平均90分)ですが、後にAzure REST APIやMicroBurstのようなさまざまなオープンソースツールを使用して、非Azure環境から悪用される可能性があります。これはユーザに割り当てられた役割に基づいています。
URLパラメータにJWTが表示される理由を探るために、Jupyterのドキュメントを参照しました。Jupyter ノートブック、JupyterLabへのアクセスはトークンを使用して管理され、デフォルトでバージョン4.3以降有効になっています。その設定ページでは、トークンをJupyterサーバに認証ヘッダ、URLパラメータ「token」、またはログインフォームでのパスワード使用で提供できることがわかります。この場合、コンピュートインスタンスオーナーのJWTを含む「token」というURLパラメータが確認されました。nginxがインラインプロキシとして使用され、アクセス試行がログに記録されていたため、アクセスログはJupyterへのアクセスを認証するために使用されていた可能性のあるベアラートークンを明らかにしました。2015年の Daniel Miessler氏のブログ投稿でも述べられているように、URLパラメータに機密情報を送信することは安全でない習慣であり、避けるべきものと言えるでしょう。
結論
上記の事例から、機密情報がファイルに記録されていること(CWE-532およびCWE-209で説明されているように)が確認されました。これらの確認事項は、重要な警告の兆候と言えます。TeamTNTのようなクラウドを狙う攻撃グループが、MITRE ATT&CKで「ファイル内の認証情報」(別名:T1552.001- Enterprise)に分類された手法を利用することが知られているからです。さらに言えば、ファイルや環境変数から認証情報を窃取する不正なパッケージにより、広く使用されたMLフレームワーク(例:PyTorch)が狙われる中、認証情報におけるサイバーハイジーンは継続的に実践されるべきでしょう。こうしたプラクティスには、セキュリティ対策が確保されていない場所において、アクセストークン、キー、ログなどをプレーンテキストで保存しないことも含まれます。したがって、クラウドリソースの安全性とセキュリティを確保するために、認証情報のセキュリティ管理の習慣を確立することが不可欠と言えます。以下は、ファイルに認証情報やログを保存することで生じるセキュリティリスクの例です。
ここでは、Azure Batch AIサービスのコードとCLIサンプルを含む、アーカイブされたリポジトリに関するGitHubの問題が示されています。特筆すべき点は、/mnt/batch/tasks/startupのパスからエラーログと出力ログが要求されていることです。GitHubのようなプラットフォームでは、問題の理解とトラブルシューティングを助けるために、開発者間でデバッグやエラーログを交換することがよくあります。また、ログに認証情報が含まれている可能性があるという事実を開発者が認識していない場合(以前にAzure MLで発見したように)セキュリティの侵害につながる可能性がある点も注目が必要です。
ファイル内に認証情報がログされたり保存されたりする問題は、最初はそれほど深刻には見えないかもしれません。しかし、一見するとインパクトの低い問題も、AMLサービスが提供する機能と組み合わせると、深刻な影響は明確になります。設計上、ユーザは他のユーザのJupyterノートブックやスクリプトを変更することができ、AMLはコラボレーションが可能な環境を提供しています。コンピュートインスタンスオーナーのAMLトークンが含まれるnginxアクセスログの問題を考慮すると、ユーザが簡単に他のユーザのAML JWTを確認し、そのユーザになりすますことが可能です。AMLワークスペース内の単一のコンピュートインスタンス、ユーザ、またはファイル共有が侵害された場合、ワークスペース全体が侵害されたと見なすべきでしょう。
これらの問題はZDIを通じてMicrosoft社に報告されました。そして、脆弱性「CVE-2023-23382」に採番され、修正対応が施されました。修正後には、以下の点が再確認されました。
- ストレージアカウントのプライマリアクセスキーは、コンピュートインスタンス内のいかなるファイルにもログとして保存されたりすることはありません。
- AML JWTがコンピュートインスタンスに届いている様子は観察されず、アクセスログやその他のファイルにもログとして記録されることはありません。
次回のパート2では、Microsoft社がコンピュートインスタンスを管理するために使用しているクラウドエージェントで確認された情報漏えい関連の脆弱性について詳しく説明します。トレンドマイクロでは、この脆弱性を「MLSee」と名付けました。
参考記事:
Uncovering Silent Threats in Azure Machine Learning Service - Part 1
By: Nitesh Surana
翻訳:与那城 務(Core Technology Marketing, Trend Micro™ Research)