クラウド環境
Azure Cloudの「使い終わった名前」が悪用されるリスク:ダングリング状態のリソースがサプライチェーン攻撃を誘発
Azureリソースを削除しても、DNS名はコードベースに残ることがあります。攻撃者が同じDNS名を再取得すれば、元の信頼性を逆手にサプライチェーン攻撃を仕掛ける恐れがあります。
- クラウドリソースを削除しても、そのDNS名への参照がコードベースやドキュメントに残り続けることがよくあります。こうした状態は「ダングリング(宙吊り)」と呼ばれており、クラウドシステムがグローバル共有DNS名前空間への依存を強めていく中で、構造的な弱点を生み出しています。
- 攻撃者は、削除後のクラウドリソースを自身のサブスクリプション内に再作成することで、元の信頼性を逆手に取ったサプライチェーン攻撃を仕掛ける可能性があります。
- TrendAI™ Researchは、Microsoftのオープンソースリポジトリやコンテナイメージ、npmパッケージを分析し、ダングリング状態のAzureリソース8,000件以上を特定しました。こうしたリソースは、さまざまなAzureサービスに紐づいていました。
- 本稿では、ダングリング状態にあるDNS名の悪用パターンについて、6つの事例を交えて解説します。例えば、Pythonパッケージの乗っ取り、インストーラのすり替え、CI/CDパイプラインの侵害などが挙げられます。
- 調査結果より、グローバルのDNS名前空間は、クラウドセキュリティの重要な論点であると言えます。実際、ダングリング状態のリソースを積極的に狙おうとする活動が確認されており、綿密な対策が強く望まれます。
- 本報告を受けてMicrosoftは、対象リソースの再確保、脆弱な参照の削除、リスクの高いリソース名の作成禁止、サービスレベルでのセキュリティ強化をはじめとする対策を実施しました。
はじめに
現代のクラウド環境は、グローバル共有のDNS名前空間に強く依存しています。ユーザが作成したリソースは、パブリックなDNSエンドポイントを通じてアクセスされます。こうした仕組みは利便性に優れる一方、構造的な弱点を生み出します。例えば、ユーザがクラウドリソースを削除すると、関連付けられていたDNS名は「空き状態(解放)」になります。しかし、そのDNS名への参照自体は、ソースコードやドキュメント、コンテナイメージ、CI/CDパイプライン、パッケージのマニフェストファイルなどに残されがちです。
このように「リソースは削除されたのに参照が残っている」という状態を、本稿では特に「ダングリング(Dangling:宙吊り)」と呼びます。ダングリング状態は、メモリ脆弱性として知られる「Use-After-Free(解放済み領域を再確保せずに使い続ける)」のクラウド版に近い問題を引き起こします。もし攻撃者が、空き状態になった名前のクラウドリソースを自らのアカウント(サブスクリプション)内に作成すれば、元の名前をそのまま参照し続けている各種システムからの「信頼」を、自動的に乗っ取れることになります。
TrendAI™ Researchでは、2024年1月から4月にかけてMicrosoftのGitHubリポジトリ、Microsoftコンテナレジストリ(MCR)内のコンテナイメージ、npmパッケージを横断的に調査しました。その結果、ダングリング状態のAzureリソースが、8,000件以上も発見されました。こうしたリソースの種類として、主だったAzureサービスが広く含まれていました。具体例として、ストレージアカウント、App Service、Container Registry、コンテンツ配信ネットワーク(CDN)、Front Door、トラフィックマネージャ、API Management、AzureパブリックIPアドレスなどが挙げられます。
本稿では、ダングリング状態となったAzureクラウドリソースのDNS名が攻撃者に再取得され、その名前を参照し続けていたシステムが侵害されるケースを分析します。具体的には、以下に示す6つの現実的なシナリオを取り上げます。
- Pythonパッケージをハイジャックし、コンテナのビルド環境を侵害する。
- チュートリアル・ドキュメントなどに見られる汎用的な名前を持つストレージアカウントを実際に作成し、参照を横取りする。
- CDNエンドポイントの取り違えに便乗し、ツール「WinGet」や「Azure CLI」のインストーラを不正なものとすり替える。
- ダングリング状態のAzureパブリックIPを悪用し、CI/CDのパイプラインに不正なJARファイルを送り込む。
- ダングリング状態となったPowerShellギャラリーのCDNを経由し、不正なPowerShellモジュールを紛れ込ませる。
- BLOBデータとしてホストされたPythonパッケージ(Wheelファイル)になりすまし、AI・機械学習(ML)環境を侵害する。
こうしたクラウドサービスプロバイダ(CSP)によるグローバルDNS名前空間の運用方式は、一見すると自然で使い勝手が良いように見えますが、重大なセキュリティリスクをはらんでいます。こうしたDNSゾーンは、エンドユーザ側である程度自由に名前を取得できる仕様となっています。そのため攻撃者は、空きとなった名前を悪用することで、元の「信頼性」を引き継ぎ、一種のクラウドリソース・テイクオーバー(乗っ取り)が可能になってしまうのです(図2)。図3は、重要なインフラリソースの稼働体系において、ユーザが設定したDNS名がどのように利用されているのかを示します。
今回、インターネットアーカイブ「コモン・クロール(Common Crawl)」のデータセットを調査し、ダングリング状態のAzureリソースを探索しました。結果、特にAzure BlobストレージやAzure App Serviceにおいて、乗っ取りの可能性の高いリソースが多く見られました。
一般に、「あるAzureリソースの名前解決ができず、NXDOMAIN(ドメインが存在しないという応答)が返ってくる場合、そのリソースは乗っ取り可能だ」と考えられがちです。しかし、DNS名前解決の可否だけでは、クラウドリソースが乗っ取り可能かを判定できないケースも多く見られます。そこで今回、Azureのリソースがどのようにプロビジョニング(作成、割り当て)されているのかを、詳しく分析しました。
例として、「test」という名前のストレージアカウントを作成するシナリオを考えましょう。Azureポータル上で作成したいストレージアカウント名(test)を入力すると、「management.azure.com」宛てに、POSTリクエストが送信されます。そして、以下に示す「X-MS-Command-Name」のヘッダーを用いて、Azure Batchサービスへの問い合わせが行われます。
{
Microsoft_Azure_Storage.Batch:0,
CreateStorageAccountHelper.validateStorageAccountNameForCreate:1,
UseAccountName.executeStorageNameCheck:1,
arm.policy:1
}
POSTリクエストの本文には複数のメッセージが含まれ、一括で送信されます。具体例を、以下に示します。
これらのメッセージにより、入力したストレージアカウント名がAzureの命名要件に沿った有効なものであるか、そして、そのストレージアカウントが作成可能であるかをチェックします。チェック処理が完了すると、全てのAPI呼び出しに対するレスポンス(応答)が返されます。その中には、エラーが発生したかを示すステータスコードが含まれます。
まず、1つ目のAPI呼び出しでは、ステータスコード「200」が返されます。これは、Microsoftが定めた命名規則に照らし合わせて、対象のストレージアカウント名が承諾されたことを示します。
2つ目のAPI呼び出しでもステータスコード「200」が返されますが、こちらには、固有のプロパティ「content」が含まれています(図4)。
「test」という名前のストレージアカウントはすでに登録済みのため、上図のように「nameAvailableがfalse」のレスポンスが返されます。一方、「testnswashere」のように未登録で作成可能なストレージアカウント名を指定した場合、「nameAvailableがtrue」のレスポンスが返されます(図5)。
調査中には、ストレージアカウント名に「Microsoft」などの商標や予約語が含まれているという、特殊なケースにも遭遇しました。その場合に返されるレスポンス例を、下図に示します。
上記の他、名前が有効であるかを確認する別の手段として、下図のように「Azure REST API」のメソッド「checkNameAvailability」も利用できます。
この機能により、特定のストレージアカウントがデフォルトのグローバルDNS名前空間に登録済みであるかを、より確実に判断できます。踏み込んで考えると、攻撃者は本機能を用いることで、標的のストレージアカウントが乗っ取りに脆弱であるかを確認できてしまいます。APIを利用するために攻撃者自身のAzureアカウントで認証する必要がありますが、それでも、確認は可能です。こうした確認手段はドキュメントとしても明確にまとめられており、下記に示す主要なAzureサービスに適用できます。
- Container Registry
- Front Door
- API Management
- パブリックIP
- トラフィックマネージャ
- キー・ボールト
- App Service
- CDN
今回、Azureの最大顧客のひとつであるMicrosoftを対象に、オープンソース経由で露出している参照を調査しました。データの取得源は、GitHubリポジトリ、MCRのコンテナイメージ、npmパッケージなどです。この結果、2024年1月から4月までの間に、ダングリング状態で放置されたままのクラウドリソースが8,000件以上も確認されました。つまり攻撃者は、こうしたリソースと同一名のリソースを自身のAzureサブスクリプション内に作成し、GitHubリポジトリなどのコードベースに残された参照を悪用できる状態となっていたのです。実際に乗っ取りが発生すれば、「依存元(参照元)システム」に対するサプライチェーン攻撃に発展する恐れがあります。
なお、「依存元システム」とは、ダングリング状態のクラウドリソースに依存し続けているコードベースを指します。コードベースの中には、BashスクリプトやPowerShellスクリプト、Dockerfile、CI/CDパイプラインの設定ファイル、コンテナイメージなどが含まれます。
調査結果
以降、調査結果から導かれる6つの攻撃シナリオを示します。いずれのシナリオも、システム内に残存する「暗黙の信頼」を悪用したものであり、依存元システムにおける不正なコード実行に繋がる恐れがあります。
Pythonパッケージの乗っ取りによるコンテナイメージの侵害
この攻撃シナリオでは、ダングリング状態のAzure App Serviceが悪用されることで、MCRのコンテナイメージや、そのビルドプロセスが侵害される恐れがあります。攻撃の流れを、図8に示します。コンテナイメージ内で利用する複数のPythonパッケージが乗っ取られる結果、MCR提供のコンテナイメージのビルド先システム上で、不正なコードが実行されます。
MCRにはさまざまなコンテナアーティファクトが格納されており、AzureやGitHubで広く利用されています。今回の調査では、公開されている各コンテナイメージからDockerfileを復元し、内容を分析しました。結果、コンテナイメージ「azure/devops/vsts-cli」に対応するDockerfileの中に、App Serviceのドメイン「vstscli[.]azurewebsites[.]net」を含む「RUNディレクティブ」が見つかりました(図9)。
- 対象イメージのタグ:0.1.3
- 対象イメージのSHA256値:1423fcf10f384bda1a970ce0961aea29786efb5d4cd7cb81f775f901e0b61866)
元のDockerfileから当該タグのコンテナイメージをビルドすると、上記のRUNディレクティブが実行されます。このディレクティブは、コマンド「pip」により、「vsts」というPythonパッケージをインストールするように動作します。「VSTS(Visual Studio Team Services)」とは、現在のAzure DevOpsの旧称です。そして、「vsts」という名前のパッケージは、Azure DevOpsサービスを操作するためのコマンドラインインターフェース(CLI)に相当します。
pipコマンドの中身を見てみましょう。オプション「--upgrade」は、対象パッケージがすでにインストールされていれば、「最新版」にアップグレードするように指示するものです。インストールされていなければ、指定のパッケージレジストリから最新版をインストールします。また、オプション「--no-cache-dir」は、キャッシュディレクトリを使用しないようにする設定です。これによってキャッシュデータが使われなくなり、常に指定のソースからパッケージを取得、インストールするようになります。
注目すべきは、オプション「--extra-index-url」です。これは、対象パッケージの検索場所となる追加のインデックスURLを指定するものです。今回の場合、「vsts」のパッケージや関連する依存関係の検索場所として、App ServiceのURL「https://vstscli[.]azurewebsites[.]net」が指定されていました。このURL側で提示されたパッケージのバージョンが、デフォルトのPyPIレジストリ「pypi.org/project/vsts」と比べて新しい場合、前者のエンドポイントから優先的に「vsts」や依存パッケージがインストールされます。
「vsts」の他に、以下のパッケージも同様の挙動でインストールされる可能性があります。
- certifi
- certifizer
- charset-normalizer
- idna
- isodate
- msrest
- oauthlib
- requests
- requests-oauthlib
- urllib3
問題のApp Serviceドメインについて、GitHubの更新履歴と突き合わせたところ、実際にAzure公式リポジトリのDockerfile内で参照されていたことが判明しました。また、このDockerfile自体は、2019年1月3日に削除されています(図11)
もし攻撃者が、正規のものより新しいバージョン番号で不正なパッケージを配信すると、「vstscli」というApp Serviceをパッケージの取得元(PyPIインデックス)として用いているシステム上で、任意のコードを実行されてしまう恐れがあります。ただし、この攻撃が成立するかどうかは、Microsoft側におけるビルドプロセスの実行条件に依存します。
本件はすでにMicrosoftに報告済みですが、弊社側での概念実証(PoC:Proof-of-Concept)の作成は控えました。というのも、PoCを作成・公開して、それが実際の攻撃者に利用されれば、MCRのイメージビルドプロセスや、問題のApp Serviceエンドポイントに依存している他システムにまで影響が波及し、被害の拡大を招きかねないためです。本件の報告と修正対応は、2024年1月から4月にかけて行われました。具体的にMicrosoftは、当該リソースの所有権を自ら再確保するとともに、ダングリング状態となっていたApp Serviceへの参照を、コンテナイメージから削除しました。
「accountname」という名前のストレージアカウント乗っ取り
調査中、「accountname」というストレージアカウントへの参照が発見されました。この名前は、ドキュメントやチュートリアル、設定サンプルによく見られる汎用的なものであり(図12)、参照元の多さを踏まえると、ダングリング状態にあるものと判断できます。そこで、実際に同一名のストレージアカウントを作成し、ログ記録を開始しました。続いて、グローバルDNS名前空間において、BLOBやファイルサービスのエンドポイントに流入するネットワークトラフィックを監視しました。
監視の結果、コンテナ名の特定を意図したブルートフォース攻撃や探索試行、トークンまたは認証情報といった機密ファイルの取得、既知のWebシェルの悪用をはじめとする活動が確認されました。これは、攻撃者が実際にAzureインフラを標的と見なし、積極的に情報収集していることを示す証拠と言えるでしょう。
「accountname」というストレージアカウントがダングリング状態にあるということは、Azureのサブスクリプションを有する誰しもが、その名前のストレージアカウントを作成し、BLOBやFile、Queue、Table、Web、DFSなどのサービスエンドポイントを保有できることを意味します。
先述の通り、本エンドポイントへの参照が多数発見されたため、今回は調査用に「accountname」のアカウントを作成し、それに対するアクセス傾向を調べました。さらに、送信元のユニークIPやユーザエージェント、要求されたパスなどの詳細情報を取得できるよう、ログ記録を開始しました(図13)。結果、4週間の間に、BLOBエンドポイントに対するリクエストが約54,000件発生しました。また、送信元パブリックIPが2,176個、ユーザエージェントが186種類も確認されました(図14)。
また、認証情報や機密情報を含むとされている一般的な設定ファイルにアクセスしようとする動きも見られました。こうした試みの大半は、「アルファベットの小文字3文字([a-z]{3})」のパターンでコンテナ名に対するブルートフォース攻撃を仕掛けるものでした。図15に示すように、WordPressやFirebase、Gitの設定ファイルパスをワードリストに沿って推測し、REST APIを悪用することで(URLパラメータから判断)、BLOBコンテナの内容一覧を取得する動きも観測されました。
また、少数ながら、拡張子が「.vhd(仮想ハードディスク)」で終わるファイルをストレージアカウントから取得する試みも見られました。これは、バックドアのアーティファクトをホストすることで、依存元システムを侵害する企みと考えられます(図16)。
受信したリクエストのリファラーヘッダーを解析したところ、以下のようなユーザエージェントを含む不正な通信も発見されました。
また、2つのIPアドレスから、Webシェルの悪用を意図したアクセスが行われました。ただし、こうした攻撃の試みがBLOBストレージサービスに影響を及ぼすことはありません。というのも、BLOBストレージは静的サイトをホストできる一方、サーバ側でコードを実行させるようなWebバックエンドを持たないためです。「accountname」というストレージアカウントを実践的に運用しているわけでもないのに、インターネット上のクラウドリソースを探索する「スキャナー」の存在が確認できたのは、奇妙で興味深い結果と言えます。
さらに、ユーザエージェント「OfficeWordCA」からの匿名アクセスが1,000件以上ありました。これは、図18のように、BLOBストレージのエンドポイントからUUIDv4形式の名前によるWordドキュメントを取得する試みです。当該リクエストでは、読み取り専用サービスのSASトークンが利用されていました。
上図のリクエストでは、コンテナパスとして「/tempblobcontainer」が指定されています。リクエストの送信元であるパブリックIPアドレスを調査したところ、すべて「ASN ID: 8075(MICROSOFT-CORP-MSN-AS-BLOCK)」に属するものでした。ここで、実際にあえて特殊なWordドキュメントを配備すれば、活動の目的や、背後にいる人物、システム関連の情報を得られる可能性がありますが、今回は見送ることにしました。
WinGet/AzCliボット間の連携不備を悪用したAzure CLI CDNの乗っ取り
ここでは、クラウドサービス間の移行プロセスについて、GitHubを通して確認された事例を解説します。前提知識として、コマンドラインツール「Azure CLI」のMSIインストーラを配布する手段として、Windows 10や11のパッケージマネージャ「WinGet」が利用されています。そして2024年4月から5月にかけて、当該MSIインストーラの配信元エンドポイントが「Azure CDN」から「Azure BLOBストレージ」に移行されました(図19、図20)。インストーラのダウンロードリンクや名前、バージョン情報を含むパッケージマニフェストは、YAML形式のファイルで定義されています。
上述した移行プロセスでは、2つのGitHubボット間でリリース情報の反映タイミングに差があり、内容上の不整合が生じていました。もしその間隙を攻撃者に狙われれば、WinGet経由でAzure CLIのMSIバイナリをインストールしているユーザやシステムに対し、サプライチェーン攻撃を仕掛けられた可能性があります。
WinGetを用いてAzure CLIをインストールするためのコマンドは、以下の通りです。
winget install --exact --id Microsoft.AzureCLI
このコマンドを実行すると、Windowsパッケージマネージャ(WinGet)のコミュニティリポジトリにあるYAML定義のマニフェストに従い、インストーラ取得の動作が行われます。マニフェストの例を、図21に示します。
注目すべきは、インストーラ(実行ファイル)の取得元URLを指すプロパティ「InstallerUrl」の内容です。上図はAzure CLIのバージョン2.58.0に対応するコミット内容であり、32ビット版と64ビット版の双方とも、InstallerUrlとして下記のCDNドメインが指定されています。
Azure CLIのリリース追加は、「azclibot」と呼ばれるボットサービスによって行われます。2024年4月30日、このボットによってプルリクエストが作成されました。しかし、そこに含まれるWinGetマニフェストのプロパティ「InstallerUrl」は、実体が削除されてダングリング状態となったCDNエンドポイント「azcliprod.azureedge.net」を指していました(図22)。
プルリクエストが作成されると、「wingetbot」と呼ばれるボットが動き、Azureパイプラインのワークフローに従ってマニフェストの内容を検証します。この際、図23の通り、URL関連のエラーが発生し、処理が停止しました。
このエラーが発生した理由は、配信元のエンドポイントが「Azure CDN(azureedge.net)」から「Azure BLOB」に切り替えられていたためです。関連するプルリクエストを追ったところ、2024年4月12日にまで遡っていました。そして、切り替え後もしばらくの間、azclibotがこの変更を認識しておらず、CDN側エンドポイント「azureedge.net」から最新版が配信されるものとしてプルリクエストを作成していたと推測されます(図24)。
過去のインストーラ配信に使用されていたCDNエンドポイント「azcliprod.azureedge.net」は、すでにダングリング状態であることが確認されました。つまり、不特定の第三者でも、本エンドポイントを新たに作成し、不正なMSIインストーラを公開できる状態だったということです。
GitHub上での履歴に基づくと、このCDNエンドポイントは4月11日から30日にかけてダングリング状態であった可能性があります(図25)。すでに配信元の移行は完了していることもあり、本調査では、「WinGetリポジトリのフォーク側(派生リポジトリ)において、古いAzure CDNエンドポイントが参照されたままになっていないか」という点に注目しました。そこで、実際に同じ名前のAzure CDNエンドポイントを作成し、そこに届くリクエストを記録しました。リクエストの発信元として、エンドユーザの他、wingetbotが起動するAzureパイプラインのCI/CDワークフローが考えられます。
今回確保したCDNエンドポイントに対しては、やはり、MSIインストーラの取得を意図するアクセスが見られました。おそらく、WinGet CLIや、CDNのURLが記載された他の情報源を経由してアクセスされたと考えられます。この問題は、突き詰めて考えると、依存元のシステム上で不正なコードが実行されるリスクを生み出すものです。実際、あるエンドユーザは当該エラーに遭遇し、GitHub上に「issue」を投稿していました(図26)。
グローバルDNS名前空間を悪用したCI/CDパイプラインの侵害
Azureのメッセージ伝達プロトコル「AMQP」について解説した複数のGitHubリポジトリから、ダングリング状態のAzureパブリックIPリソースが見つかりました。このリソースは、JARファイル配信用のバッチスクリプト内で参照されていました。JARファイルは、依存元システムに配信された後、そこで実行される仕組みとなっています。もし攻撃者がこのパブリックIPリソースを乗っ取り、配信対象として不正なJARファイルを配備しておけば、依存元システム上で任意のコードを実行できてしまいます。結果、図27のように、CI/CDパイプラインの侵害に至る可能性があります。
「パブリックIPサービス」は、「Virtual Machine(仮想マシン)」や「App Service」などのAzureサービスにパブリックIPアドレスを割り当てる機能です。そのDNSエンドポイントは、下記のようなフォーマットを持ちます。
{ユーザ入力}.{リージョン情報}.cloudapp.azure.com
ダングリング状態のパブリックIPリソースに対応するエンドポイントとして、下記が確認されました。
azure-iot-sdks-ci.westus.cloudapp.azure.com
本エンドポイントは、下記リポジトリから参照されていました。
問題のエンドポイントを実際に参照しているバッチスクリプトの一つが、「kick_jenkins.cmd」です。このスクリプトは、プロジェクトのJenkinsビルドの起動を自動化するものです。各種条件の確認やパラメータ設定を行った上で、最終的な基準をもとに、Jenkinsのビルドジョブを起動します。
スクリプト「kick_jenkins.cmd」が格納されたリポジトリは、メッセージングサービス「Azure Service Bus」の「AMQP 1.0サポート」に関する公式チュートリアル内で紹介されていました。こうした公式ドキュメントは、一般的に、暗黙のうちに信頼されやすい情報源の一つと言えるでしょう。
AMQPは、特定のベンダーや実装に依存しないオープンな標準プロトコルであり、クロスプラットフォーム対応のハイブリッドアプリケーションを構築するために利用されます。
注目すべきは、上述したJenkinsスクリプト「kick_jenkins.cmd」の挙動です。はじめに、リポジトリのフォルダ「tools」内に、JARファイル「jenkins-cli.jar」が存在するかを確認します(図28の34行目)。見つからない場合、PowerShellを用いてパブリックIPエンドポイントからのダウンロードを試みます(39行目)。ダウンロードに失敗すると、エラーメッセージを出力して処理を停止します(42-45行目)。JARファイルの取得に成功した場合、それをコマンド「java」経由で実行する仕組みになっています(図29の101行目)。
このパブリックIPリソースは乗っ取りに脆弱であったため、攻撃者が仮想マシン(VM)を作成して不正なJARファイルを配備し、HTTPの8080番ポート経由で配信できる状態となっていました。その際には、VMを下記のパブリックIPリソースに関連付ける必要があります。
azure-iot-sdks-ci.westus.cloudapp.azure.com
さらに、JARファイルはHTTP経由で取得されており、ダウンロード後の完全性チェック(改ざん確認)も行われていなかったため、ネットワーク経路上の中間者攻撃(MitM:Man-in-the-Middle)にも脆弱な状態となっていました。
問題点は、スクリプト内に記載されたパブリックIPリソースが、ダングリング状態になっていたことです。そのため、本スクリプトを使用しているシステムは、侵害のリスクに晒されていました。今回のシナリオで注意すべき点として、ダングリングの影響は、デフォルトでもGitHubのフォーク先リポジトリにまで及びます。実際、以下のようなフォークが脆弱な状態にありました。
「PowerShell Gallery」のCDN乗っ取りによるサプライチェーン攻撃
「PowerShell Gallery」は、PowerShell関連のパッケージを集約したリポジトリであり、PowerShellのスクリプトやコマンドレット、「Desired State Configuration(DSC)」のリソースなどを提供しています。その中には、Microsoftが作成したものと、PowerShellコミュニティが作成したものの双方が含まれます。PowerShell Galleryからパッケージをインストールする際は、モジュール「PowerShellGet」が使用されます。
公式ドキュメントによると、システムの稼働を安定させるために、4つのCDNエンドポイントが用意されています。そしてユーザは、これらエンドポイントへの通信をファイアウォールで許可するように、求められています。しかし調査の結果、図30の攻撃フローが示すように、4つのCDNのうちの1つが、乗っ取り可能な状態となっていました。
Microsoftは、「PowerShell Gallery」に関する公式ドキュメントを下記のGitHubリポジトリで管理しています。
今回、当該リポジトリを調査したところ、ファイル内の135行目に、Azure CDNのエンドポイント「psg-prod-centralus」が指定されていました(図31)。
上記ドキュメントに記載のAzure CDNエンドポイントが実際に存在するかを調べたところ、「psg-prod-centralus」については、存在しないことが判明しました。つまり、このエンドポイントはコード上に参照だけが残されており、乗っ取り可能な状態となっていたのです。攻撃者は、同一名のCDNエンドポイントを新規作成し、そこに不正なPowerShellリソースを配置する可能性があります。結果、フェイルセーフ(安全装置)の動作次第で、PowerShell Galleryを用いるユーザやシステムに対するサプライチェーン攻撃が成立してしまいます(図32)。
AI/ML向けPythonパッケージの乗っ取りによるサプライチェーン攻撃
Pythonのエコシステムには、機械学習のタスクに利用可能なパッケージが広範に存在します。一例として、予測処理などに使われるMicrosoft公認パッケージ「azuremlftk」が挙げられます。
実際にパッケージの説明を調べたところ、Microsoftの公式GitHubリポジトリに含まれるバッチスクリプトやAutoML(自動機械学習)設定、READMEドキュメントなどが、「azuremlpackages」という名前のBLOBストレージを参照していました(図33)。このBLOBストレージは、「pip」によるPythonパッケージの配布や、参考ドキュメントの提供に使われていたものです。しかし、このストレージ用エンドポイントは、乗っ取り可能な状態となっていました。もし悪用されれば、フィッシングサイトの運用や、Pythonパッケージへの偽装を通して、サプライチェーン侵害に至る可能性があります。
調査当時、プロジェクト説明のサンプルノートブック(Sample notebooks)にあたるGitHubリポジトリには、PythonのWheel(WHL)パッケージをインストールするためのバッチスクリプトが格納されていました(図34)。
同様のバッチスクリプトは、他のAzureリポジトリや、AutoMLのYAML設定ファイル内からも見つかりました(図35)。
「WHLファイル」の実体は、パッケージ情報やセットアップスクリプトを含むZIPアーカイブです。そのため攻撃者は、「azuremlpackages」という名前のストレージアカウントを作成し、そこに不正なWHLファイルを配備することを考えます。結果、機械学習環境や開発環境などの依存元システム上で、不正なコードを実行される恐れがあります。
- TrendAI™ Researchによって報告されたリソースを再確保した。具体的には、600件以上のGitHubリポジトリ、MCRコンテナイメージ、npmパッケージ内に残存していたドメイン8,000件以上を自ら再取得し、保護した。
- 対象となったGitHubリポジトリを削除またはアーカイブ化した。
- 脆弱な参照先を、Microsoftの管理下にあるクラウドリソースに置換した。
- 報告されたリソースについて、ユーザによる作成を禁止した。これは、当該クラウドリソースへの参照が依然として顧客環境や自社環境(フォーク、クローン、流動的な依存関係、オープンソースパッケージなど)のコードベースに残されている可能性を考慮し、そのリスク削減を目指したものである。
- 根本的な解決策として、Azureサービスについて、サービスレベルでの安全強化策を実施した。具体例として「Azure App Service」では、図38に示す変更が適用された。
まとめと推奨事項
本稿で取り上げたリスクは、理論のみに終始するものではありません。実際に今回の調査では、特定のダングリングリソースを再作成した結果、リソース探索、コンテナへのブルートフォース攻撃、そして既知のWebシェルの悪用を意図した動きが観測されました。これは、攻撃者がAzureのグローバルDNS環境に関心を寄せ続けている明確な証拠です。報告を受けたMicrosoftは、迅速に対応を行い、脆弱なリソースの再確保、古い参照の削除、ドキュメントの更新、特定名での作成禁止といった対策を実施した他、再発防止のためにサービスレベルで保護機能を強化しました。
本調査を通じて、グローバルDNSの名前空間は、見過ごされやすくも重要なセキュリティ境界であることが判明しました。コードベース内に残存している参照については、特にそのことが言えます。企業や組織がクラウド資産や自動化パイプラインへの依存を深めていく中、セキュリティチームでは、ダングリング状態のクラウドリソースがもたらす影響や、その悪用を誘発する「クラウド版UAF(Use-After-Free:解放後の不正利用)」と言うべき設計不備について、十分に注視し、対策を行うことが重要です。
「Trend Vision One™ - Cloud Security」によってクラウド環境の信頼経路を保護
見えにくいリスクを発見:「Trend Vision One™ - Cloud Security 」を用いることで、Azure環境に潜む危険なクラウド設定や、露出状態の信頼経路を可視化できます。 攻撃経路を削減:長期にわたって暗黙の信頼を置いているクラウド資産やサービスについて、悪用のリスクを特定します。 悪用される前に対処:乗っ取りやサプライチェーン攻撃の影響を受けやすいクラウドリスクを優先順位づけし、的確に対処します。
クラウドセキュリティを確保するためには、自身が保有する資産だけでなく、信頼対象と見なしてきたリソースや環境にも目を向け、それが安全に管理されているかを検証することが重要です。「Trend Vision One™ - Cloud Security 」は、そうした観点に基づくリスクを可視化し、対処するための機能を完備しています。
参考記事
It’s By Design - The Use-After-Free of Azure Cloud
By: Nitesh Surana (Senior Threat Researcher, TrendAI™ Research) and Nelson William Gamazo Sanchez (Senior Cloud Threat Researcher, TrendAI™ Research)翻訳:清水 浩平(Platform Marketing, Trend Micro™ Research)