情報漏えいを引き起こす可能性があるAWS リソースベースのポリシー API を確認

By

Category: Unit 42

Tags: , ,

This conceptual image illustrates some of the security and configuration issues involved with the cloud, such as the issue with AWS resource-based policy APIs discussed here.

This post is also available in: English (英語)

概要

パロアルトネットワークスの脅威インテリジェンスチームUnit 42 のリサーチャーは、任意のアカウントで AWS Identity and Access Management (IAM) ユーザーとロールを漏えいする目的で悪用されうるアマゾン ウェブ サービス (AWS) のAPIクラスを発見しました。リサーチャーは、16の異なるAWSサービスにまたがる22のAPIが同様に悪用されうること、エクスプロイトが3つのAWSパーティション (aws、aws-us-gov、aws-cn) すべてで機能することを確認しました。攻撃者に悪用される可能性のある AWS サービスには、Amazon Simple Storage Service (S3)、Amazon Key Management Service (KMS)、Amazon Simple Queue Service (SQS) などがあります。

この攻撃を通じて、悪意のあるアクターがアカウント名簿を取得して組織の内部構造を学習し、標的型攻撃を開始する可能性があります。最近のレッドチーム演習(現実に近いサイバー攻撃を仕掛け、企業のセキュリティ対策を検証すること)では、Unit 42リサーチャーがこのテクニックを使い、誤った IAM ロールを特定して使用することにより、何千個ものワークロードを持つ顧客クラウド アカウントを侵害することに成功しました。

問題の根本原因は、AWS バックエンドが、Amazon Simple Storage Service (S3) バケットやカスタマーの管理するキーなどのリソースにアタッチされているすべてのリソース ベースのポリシーを事前に検証する点にあります。リソース ベースのポリシーには通常 [Principal](プリンシパル) というフィールドが含まれており、このフィールドが、リソースへのアクセスを許可する ID (ユーザーまたはロール) の指定に使われています。ポリシーに実在しない ID が含まれていれば、ポリシーを作成・更新する API 呼び出しはエラー メッセージを出して失敗します。ただしこの機能は、AWS アカウントにある ID が存在するかどうかの確認にも悪用できます。攻撃者は、プリンシパルをさまざまに変えながらこれらの API を繰り返し呼び出すことで、対象アカウントのユーザーやロールを列挙することができます。しかも、APIログとエラー メッセージは、リソース ポリシーを操作している攻撃者アカウントにしか表示されないため、対象アカウントからは列挙されていることを観測できません。

つまり、このテクニックのもつ「ステルス」特性のせいで、検出と予防は困難となります。攻撃者は、気づかれる心配も時間制限もなく、ランダムないし特定の AWS アカウントへの偵察活動を実行可能です。

AWS のリソースベースのポリシー

AWS IAM はさまざまなタイプのポリシーを使用してユーザー、リソース、アプリケーション間のアクセス権限を管理しています。リソースベースのポリシーは、AWS サービス内のリソースに紐づくタイプのポリシーです。各 AWS サービスは複数のリソースを持つことができ、各リソースには異なるポリシーをアタッチすることができます。たとえばS3 サービスは複数のバケットリソースを作成でき、SQS サービスは複数のメッセージ キュー リソースを作成できます。本稿執筆時点ではリソースベースのポリシーをサポートするAWS サービスは26種類あります (付録セクション表 1参照)。ポリシーは、アタッチされたリソースに対し、プリンシパルが実行可能なアクションを決定します。プリンシパルはAWS ユーザー、ロール、またはサービスのいずれかです。実行できるアクションは、サービスのタイプによって異なります。

図 1.リソースベースのポリシー
図 1.リソースベースのポリシー

図 2 は、S3 バケットにアタッチされたリソースベースのポリシーのサンプルです。ここでは、アカウント 123456789012 のユーザー「Bob」と、アカウント 98765431098 の IAM ロール「qa-role」の 2 つのプリンシパルがバケットにアクセスできます。プリンシパルは、S3 バケット「awsexamplebucket」に対しGetObject、GetBucketLocation、ListBucketという 3 つのアクションを実行できます。なお、プリンシパルはバケットと同じアカウントに含まれていなくてもよいという点にも留意してください。これはつまり、ポリシーはリソースに対し、クロスアカウントでのアクセスを許可できるということです。

図 2 はごく単純な形式のポリシーです。より複雑なポリシーの場合、複数のステートメントや条件が含まれていることがあります。人為的エラーをなくすため、AWS ではポリシー内のすべてのフィールドを検証してからポリシーをリソースに適用するようになっており、Policy Validatorが指定されたプリンシパルが実在することや、サービスが指定されたアクションをサポートしていることを確認しています。図 2 では「GetFiles」がサポートされたアクションではないことからエラー メッセージが上げられています。

図 2. S3 バケットポリシー(左)とアクションに誤りがあるときのエラーメッセージ例(右)。
図 2. S3 バケットポリシー(左)とアクションに誤りがあるときのエラーメッセージ例(右)。

リソースベースのポリシー API の悪用

ポリシーの検証はユーザーエクスペリエンスを高める AWS の機能です。ほとんどのユーザーがこの機能からの恩恵を受ける一方で、攻撃者はこの機能をアカウントの偵察に便利に使う可能性があります。Policy Validatorは指定したプリンシパルの有無を確認するので、これを使えば攻撃者は対象アカウントの名簿を少しずつ作成できるようになります。これ以降私たちが示していくとおり、攻撃者は、リソースベースのポリシーをサポートする複数の AWS サービスで Policy Validatorを悪用する可能性があります。

リソースベースのポリシーでプリンシパルを定義する場合、ユーザーは AWS に対し、AWS アカウントのリソースにアクセスするためのプリンシパルの認証と承認を AWS に要求します。無効なユーザー名やロール名を指定すると認証は失敗します。認証プロセスをセキュアなものにする認証ベスト プラクティスの 1 つは、エラー メッセージ内でアカウント固有の情報を提供しないことです。

AWS の Policy Validatorは意図せずエラー メッセージ内のアカウント固有情報を漏えいします。リソースポリシーを作成ないし更新する際、Policy Validatorは指定されたプリンシパルの存在の有無を明示します。これにより攻撃者は、ユーザーまたは IAM ロールが対象のアカウントに存在するかどうかを確認する目的でエラーメッセージを利用することができます。このプロセスを単語リストを使って繰り返すことで、攻撃者は対象アカウントの既存 ID を列挙・検出することができます。図 3 と図 4 は、さまざまな AWS サービスのリソースポリシーで、実在しない IAM ロールを指定した場合のエラーメッセージを示したものです。これらのポリシーは拒否されて保存できません。このプロセスはAWS API でプログラム的に実行できるので、列挙をスケールさせることができます。

このテクニックのもつ特性上懸念されるのが、対象となったアカウントや被害者からは、このプロセスがまったく観測できないという点です。リソースポリシーを変更する場合、AWS CloudTrail のログとエラーメッセージは、リソースの所有者か攻撃者のアカウントにしか表示されません。この「ステルス」特性は、検出と防止をほぼ不可能にしてしまいます。

同様のテクニックは Rhino Security Labs のブログが最初に公開していまます。このブログでは、IAM ロールの信頼ポリシーを使用し、クロスアカウント IAM ロールが存在するかどうかを確認していました。今回Unit 42 リサーチャーは16 種類の AWS サービスにまたがる少なくとも 22 の API が悪用可能なことを特定・確認しました(表 1 参照)。これら API に共通するのは、すべての API がリソース ポリシーを入力として受け取り、そのポリシーに有効な [Principal] フィールドが必要であるということです。

図 3.実在しないプリンシパルを持つリソース ポリシー。AWS SQS (左) とAWS SNS (右)。
図 3.実在しないプリンシパルを持つリソース ポリシー。AWS SQS (左) とAWS SNS (右)。
図 4.実在しないプリンシパルを持つリソース ポリシー。AWS KMS (左) とAWS Glue右)。
図 4.実在しないプリンシパルを持つリソース ポリシー。AWS KMS (左) とAWS Glue右)。

結論

対象となるアカウントに監視可能なログが残らないことから、このテクニックを使用した ID偵察の検出・防止は困難です。ただしIAM のセキュリティ衛生が良好なら、この手の攻撃による脅威を効果的に緩和することができます。攻撃者による AWS アカウント内のID列挙を防止することはできませんが、列挙をより困難にし、偵察後に行われる不審なアクティビティを監視することは可能です。

考えられる対策は以下の通りです。

  • アクティブでないユーザーやロールを削除して攻撃面を縮小します。
  • ランダム文字列をユーザー名とロール名に追加することで推測を難しくします。
  • AWS アカウントに追加ユーザーが作成されないようID プロバイダーとフェデレーションでログインします。
  • すべての ID 認証アクティビティをログに記録して監視します。
  • すべてのユーザーと IAM ロールに対して 2要素認証 (2FA) を有効にします。

付録

AWS サービス リソースポリシー更新用API (Python Boto3) 悪用可能API
Amazon Elastic Container Registry (Amazon ECR) set_repository_policy() あり
Amazon Elastic Inference AIMを介して構成 なし
AWS Lambda add_permission() あり
AWS Serverless Application Repository プリンシパルにアカウントIDが必要 なし
AWS Backup put_backup_vault_access_policy() あり
Amazon Elastic File System (Amazon EFS) put_file_system_policy() あり
Amazon FSx AIMを介して構成 なし
Amazon S3 Glacier set_vault_access_policy() あり
Amazon Simple Storage Service (Amazon S3) put_bucket_policy() あり
AWS Cloud9 AIMを介して構成 なし
AWS CodeBuild ポリシーのプリンシパルにはアカウント ID 番号、組織単位(OU)、組織のいずれかを指定 なし
AWS Identity and Access Management (IAM) create_role()
update_assume_role_policy()
あり
AWS Key Management Service (AWS KMS) put_key_policy() あり
AWS Secrets Manager put_resource_policy()

validate_resource_policy()

あり
Amazon CloudWatch Logs AIMを介して構成 なし
AWS Database Migration Service KMSを介して構成 なし
Amazon API Gateway create_rest_api()

update_rest_api()

あり
Transit Gateway Network Manager AIMを介して構成 なし
AWS Elemental MediaLive AIMを介して構成 なし
AWS Elemental MediaStore put_container_policy() あり
Amazon Elasticsearch Service create_elasticsearch_domain()

update_elasticsearch_domain_config()

あり
AWS Glue put_resource_policy() あり
Amazon Simple Notification Service (Amazon SNS) create_topic()

set_topic_attributes()

あり
Amazon Simple Queue Service (Amazon SQS) create_queue()

set_queue_attributes()

あり
AWS IoT AIMを介して構成 なし
Amazon Simple Email Service (Amazon SES) put_identity_policy() あり

表 1.リソースベースのポリシーをサポートする AWS サービス。
Unit 42リサーチャーが16のAWSサービスにまたがって悪用される可能性のある22のAPIを特定