ログは嘘をつかない:監査ログに残る列挙活動の痕跡

WS、Azure、GCP 環境において、攻撃者が監査ログを悪用して列挙を行う手法

Bleon Proko

Bleon Proko

ログはしばしば、防御側にとって最良の味方だと称賛されます。ログは、フォレンジック上の重要な証跡、異常検知のシグナル、そしてアカウンタビリティの基盤です。セキュリティチームは、インシデントの再構築、アクティビティの監視、アラートのトリガーにログを活用しています。では、視点を反転させたらどうなるでしょうか。攻撃者がログを脅威ではなく、機会として見たらどうなるでしょうか。

本稿では、クラウドインフラにおけるログの見落とされがちな攻撃面を取り上げます。あらゆるログエントリには、単なるイベント情報以上のものが含まれています。送信元 IP アドレス、アイデンティティ、リソース名、リクエストパラメータ、レスポンスコード、ユーザーエージェントなどです。防御側にとって、これらのフィールドは手掛かりです。しかし攻撃者にとっては、インテリジェンス、ピボットポイント、さらには秘匿通信チャネルにさえなり得ます。

攻撃者がログを使って列挙を行い、ログデータの分析を通じてアイデンティティ、サービス、エンドポイント、リソース階層を把握していく方法を詳しく見ていきます。実際のシナリオ、ライブデモ、またはシミュレーション(該当する場合)を通じて、ログが防御ツールから攻撃ベクトルへと変わるとき、その影響がどこまで深く及ぶのかを示します。最後に、防御側がこの種の悪用をどのように検出できるか、避けるべき設定は何か、そしてゼロトラストの観点からログへのアクセスと可視性をどう見直すべきかという、実践的な緩和策を取り上げます。

ログはシステムの物語を語ります。しかし、どんな優れた物語もそうであるように、味方にも敵にも読まれ得ます。今こそ、私たちのデジタルの木々の年輪が、単なる履歴だけでなく、秘密までも語っているかもしれないと考えるべき時です。

クラウド環境におけるロギング

クラウドプロバイダーが提供するサービスは非常に多く、そのリソースを監視する必要もあるため、クラウド上で運用を担うセキュリティエンジニアは、膨大な種類のログとロググループに向き合うことになります。ほぼすべてのサービスにおいて、ほぼすべてのリソースが、その実行したアクティビティに応じてログを生成します。ID とアクセス管理に関わるもののように、クラウドプロバイダーの監査ログ機能によって生成・管理されるものもあれば、各リソースが独自形式で生成し、クラウドストレージや専用の保存・検索サービスに保持されるものもあります。

以下の表は、AWS、Azure、GCP におけるいくつかのログソースを示したものです。なお、これらはすべてのログ種別ではなく、各サービスとそのログのごく一部にすぎません。

Category AWS (Amazon Web Services) Azure (Microsoft) GCP (Google Cloud Platform)
Audit / Control Plane CloudTrail – API calls, console logins, IAM actions Azure Activity Log – control plane operations at subscription level Cloud Audit Logs – Admin Activity Logs, System Event Logs
Resource / Data Plane CloudTrail Data Events – S3 object access, Lambda invokes Azure Resource Logs – data plane events inside a resource Cloud Audit Logs – Data Access
VM / OS Logs CloudWatch Logs Agent / SSM Agent – syslog, application logs from EC2 Azure Diagnostics / Guest OS Logs – syslog, Windows event logs Ops Agent / Logging Agent – syslog, Windows event logs
Network Logs VPC Flow Logs – accept/reject network flows NSG Flow Logs – network security group traffic flows VPC Flow Logs – network traffic metadata
DNS Logs Route 53 Resolver Query Logs Azure DNS Logs Cloud DNS Logs
Load Balancer Logs ELB/ALB/NLB Access Logs Azure Load Balancer Metrics/Logs, App Gateway Logs Cloud Load Balancer Logs
Storage Access Logs S3 Server Access Logs, S3 Object-Level CloudTrail Storage Analytics Logs (Blob/Table/Queue), Diagnostic settings Cloud Storage Access Logs
Database Logs RDS Logs (MySQL/Postgres/Oracle/SQL Server), Aurora Logs, DynamoDB Streams/Logs Azure SQL Audit/Diagnostic Logs, Cosmos DB Diagnostic Logs Cloud SQL Logs, BigQuery Audit Logs, Spanner Logs
Container / Orchestration EKS Control Plane Logs, ECS CloudWatch Logs, Fargate Logs AKS Diagnostics, Container Insights Logs GKE Control Plane Logs, Container Logs
Serverless / Functions Lambda Logs (CloudWatch) Azure Functions Logs (App Insights/Monitor) Cloud Functions Logs (Cloud Logging)
App / Service Logs CloudWatch Logs (Custom, Application) App Service Logs, Application Insights Cloud Logging (Custom, App Engine Logs)
Security Logs GuardDuty Findings, Security Hub Findings Microsoft Defender for Cloud Alerts, Sentinel Logs Security Command Center Findings
Monitoring Metrics CloudWatch Metrics Azure Monitor Metrics Cloud Monitoring Metrics
Web / CDN Logs CloudFront Logs, WAF Logs Azure CDN Logs, Front Door Logs, WAF Logs Cloud CDN Logs, Cloud Armor Logs

本調査では、利用の多いクラウドプロバイダーである AWS、Azure、GCP に基づくインフラストラクチャのみを扱いますが、同じ考え方は他のクラウドプロバイダーにも適用できます。

AWS

AWS 組織またはアカウント内のイベント管理を担う主なサービスは、AWS CloudTrail と AWS CloudWatch の 2 つです。AWS CloudTrail は監査ログの保存と管理を行い、AWS CloudWatch は、必要に応じてさまざまなログソースを集約し、検索やダッシュボード化を可能にするサービスです。

AWS において監査ログを管理する主要なログサービスは AWS CloudTrail です。AWS CloudTrail は AWS API に関連するイベントを記録し、AWS 組織またはアカウント内のすべての管理アクティビティを監視します。一方で、VPC Flow Logs、サーバーレス実行ログ、EC2 インスタンスメトリクス、Route53 関連ログなど、CloudTrail で保存・管理されないイベントも生成されます。これらは、S3 バケットや CloudWatch に保存するよう設定できます。CloudWatch への保存はコストが高くなる一方で、イベントをより容易に検索できます。

AWS CloudTrail

AWS CloudTrail は、AWS API を使用して実行されたイベントによって生成されるログを管理し、特定のアイデンティティが特定のエンドポイントからアクセスしたアイデンティティ、サービス、リソースに関する情報を含みます。CloudTrail Logs はセキュリティ監査ログとして利用され、セキュリティエンジニアは、アカウントまたは組織全体において、あるアイデンティティがリソースやサービスに対してどのようなアクセスを行ったかを監視できます。以下のイベントは、IAM ユーザー作成時の AWS CloudTrail イベントの一例です。

AWS CloudWatch

AWS CloudWatch は、AWS リソースや AWS に統合された他者のサービスからログを収集・管理するサービスです。要するに、クラウドでホスト・管理されているサービスの多くは、オンプレミスで使われてきたサービスの延長線上にあります。ここで「クラウドとは、結局は誰か他人のコンピュータにすぎない」という言葉が当てはまります。従来のオンプレミスサービスと同様に、各サービスはそれぞれ独自のログ形式を持っており、必ずしも AWS のログ形式と互換性があるわけではありません。CloudWatch Logs は、こうしたログに対応する AWS の仕組みです。あらゆるリソースのログを収集・管理し、それらのイベントを特定のフィールドに整形またはカプセル化することで、管理者が扱いやすく、アクセスしやすい形にします。

以下のスクリーンショットは、Lambda 関数の実行開始から、出力が取得されるまでのログの流れを示しています。

Flor of logs for Lambda function
実行中の Lambda 関数の CloudWatch ログ

CloudWatch で扱えるすべてのログが、必ずしも CloudWatch で管理されるわけではありません。リソース作成時に、作成者はログを CloudWatch に送るか、S3 バケットに送るかを選択できます。後者のほうが低コストですが、CloudWatch が提供するダッシュボードなどの機能は利用できなくなります。また、Lambda 関数のように、作成時にデフォルトで CloudWatch のロググループを生成するリソースもあります。

Azure

Azure には、大きく 3 つの主要ライセンス群に分かれる複数のサービスがあります。

  • Azure Subscriptions は、IaaS および PaaS ソリューションを通じて、クラウドインフラストラクチャの展開と管理を可能にするすべてのサービスを含みます。
  • M365 services は、メールサーバー、ファイルストレージ、エンドポイントおよびクラウドセキュリティ、DLP など、ユーザー関連タスクの管理に使用される SaaS ソリューションを提供します。
  • Entra ID は、ユーザー、グループ、アプリ、サービスプリンシパル、それらのロール、ID プロバイダー関連タスクを含む、クラウド上の IAM を管理します。

Azure では、複数の種類のロググループを有効化し、管理する必要があります。

Azure(広義のプラットフォーム / Azure Monitor)

  • Activity Log(プラットフォーム / コントロールプレーンイベント)は、サブスクリプション、管理グループ、テナントレベルのイベント(リソース作成、ロール変更、デプロイ失敗、サービス正常性など)を記録します。コントロールプレーン操作の監査に使用されます。
  • Resource Logs(旧称「Diagnostic logs」)は、Azure サービスが出力するリソースごとの運用ログです。例として、ストレージ、NSG フロー、Application Gateway のアクセス / ファイアウォールなどがあります。各サービスは、独自のリソースログカテゴリやスキーマを公開しています。
  • Metrics は、CPU、1 秒あたりのリクエスト数、レイテンシーなど、リソースから出力される数値時系列データです。ログとは別のものですが、ログと一緒に取り込まれることがよくあります。

Microsoft Entra ID(Azure AD)アイデンティティプラットフォームログ

Entra ID のイベントは Diagnostic Settings で管理され、管理者は保存するログ種別と保存方法を選択できます。イベントは次の場所に保存できます。

  • Log Analytics
  • Storage Accounts
  • Event Hub へのストリーミング
  • 任意のパートナーソリューションへの送信(通常は Azure 経由でサービスとして提供)
AzureAD diagnostic setting
保持するログを設定するための Azure Entra ID Diagnostic Settings

ログ種別には、監査ログ、サインインログ、プロビジョニングログ、ネットワーク関連イベント、リスク関連イベントなどがあります。

  • AuditLogs - Entra ID テナントで行われた管理操作や変更(ユーザー作成、グループ変更、ポリシー更新など)を記録します。
  • SignInLogs - 対話型ユーザーサインイン試行を記録し、ログイン成功・失敗や、場所・デバイスなどの認証詳細を含みます。
  • NonInteractiveUserSignInLogs - トークン更新など、ユーザーの直接操作なしに、アプリケーションがユーザーの代わりに実行した自動サインインを追跡します。
  • ServicePrincipalSignInLogs - Azure リソースにアクセスするサービスプリンシパル(アプリケーションおよびマネージド ID)の認証アクティビティを記録します。
  • ManagedIdentitySignInLogs - Azure マネージド ID がサービスへ認証した際のサインインイベントを記録します。
  • ProvisioningLogs - Entra ID と接続アプリケーション間で行われるユーザーやグループのプロビジョニング処理(自動アカウント作成、同期など)を記録します。
  • ADFSSignInLogs - Entra ID とフェデレーションされた Active Directory Federation Services(ADFS)からのサインインイベントを記録します。
  • RiskyUsers - Identity Protection により、異常行動や認証情報侵害に基づいてリスクがあると判定されたユーザーを一覧表示します。
  • UserRiskEvents - 認証情報漏えい、匿名 IP の使用、あり得ない移動など、ユーザーに関する具体的なリスク検知を記録します。
  • NetworkAccessTrafficLogs - Microsoft の Global Secure Access(旧 Entra Private Access / Internet Access)を流れるネットワークトラフィックを記録します。
  • RiskyServicePrincipals - 侵害のおそれがある、または不審な挙動を示すサービスプリンシパルを特定します。
  • ServicePrincipalRiskEvents - 異常なサインインパターンや認証情報漏えいなど、サービスプリンシパルに関する具体的なリスク検知を記録します。
  • EnrichedOffice365AuditLogs - Entra ID の追加コンテキストや拡張情報を付与した Office 365 監査イベントを提供します。
  • MicrosoftGraphActivityLogs - Microsoft Graph API 経由で行われた API コールや操作を追跡し、モニタリングやセキュリティ分析に使用します。
  • RemoteNetworkHealthLogs - Global Secure Access 展開におけるリモートネットワーク接続の健全性と接続状態を監視します。
  • NetworkAccessAlerts - Microsoft の Global Secure Access サービスが生成する脅威検知用セキュリティアラートを含みます。
  • NetworkAccessConnectionEvents - Global Secure Access のネットワークトンネルを通過する個別の接続イベントとセッションを記録します。
  • MicrosoftServicePrincipalSignInLogs - Microsoft のファーストパーティ製サービスプリンシパルや内部アプリケーションに関するサインインアクティビティを記録します。
  • AzureADGraphActivityLogs - 旧 Azure AD Graph API(非推奨、Microsoft Graph の前身)に対して行われた API コールを追跡します。
  • NetworkAccessGenerativeAIInsights - Global Secure Access におけるネットワークアクセスパターンとセキュリティ態勢について、AI が生成した分析とインサイトを提供します。

Microsoft 365 / Office 365(監査ログおよびサービスログ)

Microsoft 365 / Office 365 には、プラットフォーム全体のユーザーアクティビティ、管理操作、サービスレベルのイベントを記録するさまざまなログがあります。これらのログを理解することは、コンプライアンス対応、セキュリティ調査、運用監視にとって重要です。以下は、主なログ種別と Microsoft 365 エコシステム内での位置付けです。

  • Unified Audit Log(Microsoft Purview Audit) は、Exchange、SharePoint / OneDrive、Teams、Azure AD / Entra、Power BI、Defender などのアクティビティを集約する中央監査ストアです。Microsoft 365 全体のユーザー / 管理者アクションの検索に使用されます。保持期間や機能はライセンス(E5 かその他 SKU か)によって異なります。
  • Exchange / Exchange Online logs
    • Mailbox audit logs は、メールボックス所有者、代理人、管理者によるメールボックスアクティビティ(メッセージ閲覧、Send As、フォルダアクセスなど)を記録します。
    • Exchange Admin Audit Log は、Exchange 管理センターまたはコマンドレット経由で行われた管理者変更を記録します。
    • Message trace / transport logs は、メール配信およびルーティングに関するメールフロー記録です。
  • SharePoint / OneDrive audit events は、ファイル / フォルダアクセス、共有、同期、管理者変更を記録します(Unified Audit に反映されます)。
  • Teams audit events は、チャネル、ファイル、チャット、チームメンバーシップの変更、会議、ポリシー変更を記録します(Purview Audit から確認可能です)。
  • Security product logs は、Defender for Office 365、Defender for Endpoint、Microsoft 365 Defender などが生成する独自のアラート、検知、テレメトリです。多くの場合、Compliance / Security center や統合監査 / アラートストリームと連携します。

GCP

Azure と同様に、Google は、クラウド展開のインフラ側を担う Google Cloud Platform(GCP)と、メール、DLP、Google ドキュメント、Drive などのユーザー関連サービスを含む Google Workspace を提供しています。そのため、実行されるアクティビティの種類に応じて、それぞれ異なる種類のログが生成されます。

GCP 監査ログ(コントロールプレーンおよびデータプレーンイベント)

Google Cloud Platform(GCP)は Cloud Logging を通じて統合ロギングを提供し、すべてのサービスのアクティビティ、システム、データ、セキュリティイベントを収集します。主なカテゴリは Audit Logs で、管理操作とデータアクセス操作を記録します。

  • Admin Activity Logs: コントロールプレーン操作(リソース作成 / 更新 / 削除)。常に有効です。
  • System Event Logs: Google システムが利用者に代わって行うアクション(自動スケーリング、保守など)。常に有効です。
  • Data Access Logs: データプレーンの読み取り / 書き込み(Cloud Storage オブジェクトの読み取り、BigQuery クエリなど)。ログ量が多いため、明示的に有効化する必要があります。
  • Policy Denied Logs: 組織ポリシー制約により拒否されたアクセス要求を記録します。

これらは、GCP プロジェクト、組織、請求先アカウント、プロジェクトフォルダの単位で生成・管理されます。

   projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2Factivity
   projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2Fdata_access
   projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2Fsystem_event
   projects/PROJECT_ID/logs/cloudaudit.googleapis.com%2Fpolicy

   folders/FOLDER_ID/logs/cloudaudit.googleapis.com%2Factivity
   folders/FOLDER_ID/logs/cloudaudit.googleapis.com%2Fdata_access
   folders/FOLDER_ID/logs/cloudaudit.googleapis.com%2Fsystem_event
   folders/FOLDER_ID/logs/cloudaudit.googleapis.com%2Fpolicy

   billingAccounts/BILLING_ACCOUNT_ID/logs/cloudaudit.googleapis.com%2Factivity
   billingAccounts/BILLING_ACCOUNT_ID/logs/cloudaudit.googleapis.com%2Fdata_access
   billingAccounts/BILLING_ACCOUNT_ID/logs/cloudaudit.googleapis.com%2Fsystem_event
   billingAccounts/BILLING_ACCOUNT_ID/logs/cloudaudit.googleapis.com%2Fpolicy

   organizations/ORGANIZATION_ID/logs/cloudaudit.googleapis.com%2Factivity
   organizations/ORGANIZATION_ID/logs/cloudaudit.googleapis.com%2Fdata_access
   organizations/ORGANIZATION_ID/logs/cloudaudit.googleapis.com%2Fsystem_event
   organizations/ORGANIZATION_ID/logs/cloudaudit.googleapis.com%2Fpolicy

GCP プラットフォームログ

GCP のプラットフォームログは、ユーザーワークロードを実行するインフラストラクチャやサービスによって生成される運用データおよび性能データを記録します。管理操作やアクセス操作に焦点を当てる監査ログとは異なり、プラットフォームログは、ネットワークトラフィック、コンピュートアクティビティ、アプリケーション性能など、システムの挙動を可視化します。例としては、ネットワークフローを示す VPC Flow Logs、ルール適用状況を示す Firewall Logs、リクエストやレイテンシーの詳細を示す Load Balancer Logs、接続追跡用の Cloud NAT Logs などがあります。これらのログは、性能チューニング、トラブルシューティング、異常なトラフィック急増や接続失敗といった異常検知に非常に有用です。プラットフォームログを Cloud Logging、BigQuery、SIEM にエクスポートすることで、組織は運用データをセキュリティやアプリケーションの分析結果と相関させ、フルスタックのオブザーバビリティを実現できます。

ログを用いたクラウド権限の列挙

実行されたイベント、イベントを実行したアイデンティティ、対象となったリソースに関する情報を含むフィールドは数多く存在します。

  • API コールを実行したアイデンティティの種類、ID、名前
  • API コールを実行したクライアントの送信元 IP とユーザーエージェント
  • この実行の対象となったリソース
  • 入力パラメータと出力値
  • そのイベントが許可されたか拒否されたか

監査ログを用いたリソース列挙

各クラウドプロバイダーの監査ログサービスには、保持期間とイベント取得手段があります。ログ種別やクラウドプロバイダーによって異なりますが、GCP のイベントは 30 日保持で、最大 10 年まで設定可能です。AWS と Azure のイベントは 90 日保持され、後から S3 バケットや Azure Storage などのクラウドストレージ、または CloudWatch や Log Analytics などのログ分析サービスへ保存することもできます。

Cloud Audit Log Service Default Retention Max Retention
AWS CloudTrail 90 days Indefinite (S3), configurable in CloudWatch
Azure Activity Logs 90 days Indefinite if exported
Entra ID Directory Audit Logs
M365 Unified Audit Logs
GCP Audit Logs (Admin Events, System Event, Policy Denied, Data Access) 30 days Can be configured up to 3650 days

ログを一覧取得するには、特定の権限が必要です。

  • AWS: cloudtrail:LookupEvents - 保持されているイベントを一覧取得します。
  • Azure Cloud Audit Logs:
    • Microsoft.OperationalInsights/workspaces/search/action: Log Analytics ワークスペースに対して検索クエリを実行し、ログデータを取得します。
    • Microsoft.Insights/eventtypes/values/read: サブスクリプションの Activity Log イベント(管理操作の監査証跡)を読み取ります。
    • Microsoft.Resources/subscriptions/providers/read: サブスクリプションに登録されたリソースプロバイダーを一覧または取得します。
  • Entra ID Audit Logs: AuditLog.Read.All
  • GCP: logging.logEntries.list - 特定スコープの GCP 監査ログを一覧取得します。

各監査ログからは、さまざまな情報を取得できます。

  • イベントを実行したアイデンティティに関する情報: 各イベントには、API コールを実行したアイデンティティに関する情報が含まれます。
    • AWS CloudTrail Logs では、アイデンティティの種類と ID(IAM ユーザーまたはロール)が CloudTrailEvent.userIdentity.principalId に記録され、権限を実行したアイデンティティの ARN は CloudTrailEvent.userIdentity.arn に記録されます。
    • Azure Activity Logs では、各イベントに caller フィールドがあり、コールを実行したアイデンティティ名が含まれます。さらに claims フィールド内には、フルネーム(claims.name)や送信元 IP(claims.ipaddr)が含まれます。また、claims 内の別のフィールドである http://schemas.microsoft.com/claims/authnmethodsreferences には、そのコールを実行したアイデンティティの認証方式が一覧表示されます。
    • GCP Audit Logs では、authenticationInfo フィールドに、コールを要求したアイデンティティ情報が含まれます。
  • 実行対象となったリソース: リソースに影響を与える各イベント(作成、更新、一覧取得、取得)には、それらのリソース一覧が Resources フィールドに含まれます。リソースに影響がない場合でも、このフィールド自体は存在しますが空です。
    • AWS では、このフィールドは Resource と呼ばれ、影響を受けた各リソースの名前とタイプが含まれます。
[
      {
          "ResourceType": "AWS::IAM::User",
          "ResourceName": "bleonUser"
      },
      {
          "ResourceType": "AWS::IAM::User",
          "ResourceName": "AIDA***************"
      },
      {
          "ResourceType": "AWS::IAM::User",
          "ResourceName": "arn:aws:iam::012345678901:user/bleonUser"
      }
  ]
  • resourceGroupName), resource type (resourceType) and resource id (resourceId) Azure では、イベントにリソースグループフィールド(resourceGroupName)、リソースタイプ(resourceType)、リソース ID(resourceId)が含まれます。
"resourceGroupName": "test-resource-group-name",
"resourceProviderName": {
    "value": "Microsoft.Resources",
    "localizedValue": "Microsoft Resources"
},
"resourceType": {
    "value": "Microsoft.Resources/subscriptions/resourceGroups",
    "localizedValue": "Microsoft.Resources/subscriptions/resourceGroups"
},
"resourceId": "/subscriptions/abcd1234-1234-4567-90ab-abcdef123456/resourceGroups/test-resource-group-name",
  • GCP にも resource というフィールドがあり、影響を受けたリソース情報が格納されます。
"resource": {
  "labels": {
    "email_id": "bsidesnyc-test-account@my-project-12345-123456.iam.gserviceaccount.com",
    "project_id": "my-project-12345-123456",
    "unique_id": "108093650973646504873"
  },
  "type": "service_account"
},
  • リソースを確認するもう一つの箇所は、API コールに必要な入力パラメータと、正常に実行された際に取得される出力情報です。これらのフィールドには、リソースだけでなく、ポリシードキュメントやタグなどの任意情報も含まれます。
    • AWS では、この情報は requestParametersresponseElements に含まれます。
"requestParameters": {
  "userName": "bleonUser"
},
"responseElements": {
  "user": {
    "path": "/",
    "userName": "bleonUser",
    "userId": "AIDA***************",
    "arn": "arn:aws:iam::012345678901:user/bleonUser",
    "createDate": "Aug 5, 2025, 8:02:49 PM"
  }
},
  • Azure では、実行内容に応じて、イベントにリクエスト本文(requestBody。リクエストパラメータを含む)やレスポンス本文(responseBody。出力値を含む)、その両方、またはいずれも存在しない場合があります。
"requestBody": "{\"id\":\"/subscriptions/abcd1234-1234-4567-90ab-abcdef123456/resourceGroups/test-resource-group-name\",\"name\":\"test-resource-group-name\",\"type\":\"Microsoft.Resources/resourceGroups\",\"location\":\"centralus\",\"tags\":{\"SomeKey\":\"SomeValue\"}",

"responseBody": "{\"id\":\"/subscriptions/abcd1234-1234-4567-90ab-abcdef123456/resourceGroups/test-resource-group-name\",\"name\":\"test-resource-group-name\",\"type\":\"Microsoft.Resources/resourceGroups\",\"location\":\"centralus\",\"tags\":{\"SomeKey\":\"SomeValue\"},\"properties\":{\"provisioningState\":\"Succeeded\"}}",
  • GCP では、この情報は requestresponse フィールドに格納されます。
"request": {
  "@type": "type.googleapis.com/google.iam.admin.v1.CreateServiceAccountRequest",
  "account_id": "bsidesnyc-test-account",
  "name": "projects/my-project-12345-123456",
  "service_account": {}
},

"response": {
  "@type": "type.googleapis.com/google.iam.admin.v1.ServiceAccount",
  "email": "bsidesnyc-test-account@my-project-12345-123456.iam.gserviceaccount.com",
  "etag": "MDEwMjE5MjA=",
  "name": "projects/my-project-12345-123456/serviceAccounts/bsidesnyc-test-account@my-project-12345-123456.iam.gserviceaccount.com",
  "oauth2_client_id": "108093650973646504873",
  "project_id": "my-project-12345-123456",
  "unique_id": "108093650973646504873"
},
  • API コールを実行したアイデンティティの送信元 IP と、その延長としての地理的位置情報は、送信元 IP フィールドを通じて確認できます。例: "sourceIPAddress": "1.2.3.4"
  • 特定のタスクの実行に使われた OS、コンテキスト、ツールなどは、ユーザーエージェントを通じて確認できます。例: "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:141.0) Gecko/20100101 Firefox/141.0"

権限追加イベントを確認してアイデンティティ権限を列挙する

各クラウドプロバイダーには API を通じてアクセスできます。アイデンティティがあるタスクを実行するには、そのタスクに対する権限が必要です。サービス、リソース、あるいは単一の API コールへのアクセスは、Azure と GCP ではロール、AWS ではポリシーによって付与されます。

アイデンティティに権限が追加されると、イベントが生成されます。こうしたイベントは通常、優先度の高い管理イベントとみなされるため、すべてのクラウドプロバイダーで記録されます。

Cloud API Prefix Privilege Assignment Action
AWS iam:* Attach*Policy, Put*Policy, AddUserToGroup, UpdateAssumeRolePolicy, PassRole, iam:SetDefaultPolicyVersion, iam:CreatePolicy, iam:CreatePolicyVersion
Azure Microsoft.Authorization/* roleAssignments/write, roleDefinitions/write, eligibleRoleAssignments/write, privilegedRoleAssignments/write
GCP setIamPolicy projects.setIamPolicy, folders.setIamPolicy, organizations.setIamPolicy, iam.roles.create, *.setIamPolicy

また、API 権限の追加とは別に、一部のリソースにはアクセスポリシーも存在します。これらのポリシーは、そのアイデンティティが同じサービス内の他リソースでタスクを実行する権限を持っていたとしても、特定のサービスリソースへのアクセスを許可または拒否します。

Cloud API Pattern Description
AWS *Put*Policy, *Set*Policy, *AddPermission Directly modifies resource policies granting access
Azure Microsoft.*/*/accessPolicies/write, Microsoft.*/*/*Policies/write, Microsoft.*/*/*Rules/write, authorizationRules/write Adds service-specific access control entries
GCP <resource>.setIamPolicy Overwrites or modifies the IAM policy on a specific resource

セキュリティログをたどってアイデンティティ権限を列挙する

アイデンティティが API コールに対して持つ権限を推定できます。各 API コールには errorCodeerrorMessage という 2 つのフィールドがあります。errorCode は実行失敗の理由を示し、errorMessage はそのエラーの説明を示します。API コールの実行が許可されていない場合、errorCodeAccessDenied になります。

"errorCode": "AccessDenied",
"errorMessage": "User: arn:aws:iam::012345678912:user/attacker is not authorized to perform: iam:CreateUser on resource: arn:aws:iam::012345678912:user/someuser with an explicit deny in a service control policy"

errorCodeAccessDenied でない場合、その権限は許可されている可能性が高いと考えられます。さらに、CloudTrail のログは Event History から取得した場合も S3 バケットから取得した場合も、新しいものから古いものへ降順に並ぶため、それらをたどって各イベントの最新のエラー状態を確認できます。

  • errorCodeAccessDenied であり、そのイベントが以前に許可されたことがなければ、そのイベントは拒否されていることを意味します。
  • errorCodeAccessDenied であり、そのイベントが以前に許可されたことがあれば、その権限は許可されていることを意味します。
  • errorCodeAccessDenied でなく、そのイベントが以前に拒否されたことがなければ、その権限は許可されていることを意味します。

この原則を理解すれば、cloudtrail:LookupEvents という 1 つの API コールだけで、アカウント内の任意のアイデンティティを列挙できます。

Decision chart using LookupEvents
LookupEvents を使用してアイデンティティの権限を判断するための決定チャート

AWS CloudTrail ログを用いた権限列挙の欠点

この列挙手法の欠点は、権限が許可または拒否されてから、その状態が実際に反映されるまでの時間差にあります。問題になるのは、イベント生成後に権限が追加または取り消された場合です。これは特に一時権限でよく起こります。あるアイデンティティに対して、特定権限が一定期間だけ付与されるケースです。攻撃者はイベントを取得し、対象のアイデンティティにタスクを実行する権限があると考えますが、実際にはその権限がない可能性があります。

Problematic flow
攻撃者が実際には持っていない権限を持っていると誤認する問題のあるフロー

サインインログを用いたアイデンティティ列挙

ユーザーがクラウド環境にサインインするたびに、サインインイベントが生成されます。そのログには、サインインしたユーザーに関する情報が含まれます。

  • サインインしたアイデンティティ
  • 送信元 IP
  • 認証メカニズム(SSO、フェデレーション、MFA を使用している場合)
  • ユーザーエージェントが含まれる場合もあります

クラウドプロバイダーのサインインログを読む権限を持つ攻撃者は、次のような情報を取得できます。

  • アイデンティティ名と、その利用している認証方式(MFA を含む)の一覧
  • 有効または無効なアイデンティティの一覧
  • サインイン失敗理由の一覧
  • アイデンティティの発信元と考えられる場所の一覧
  • アイデンティティが使用する IP の一覧

AWS のサインインイベント

AWS では、Management Console にアクセスするための方法が複数あります。

  • AWS ユーザーログインプロファイル。ログインプロファイルを持つユーザーは Management Console にログインし、それを通じてアカウントへ GUI でアクセスできます。
  • IAM ユーザーフェデレーション認証情報によるサインイン URL の生成(ここで説明されているとおり)。
  • AWS Identity Center 経由のログイン。この場合、ユーザーは認証情報または IDP を使用してログインし、ロールが関連付けられます。これにより、Management Console での管理アクセスが可能になります。

ユーザーが AWS Management Console にログインすると、signin:ConsoleLogin イベントが生成されます。このイベントには、サインインしたアイデンティティ、送信元 IP、ユーザーエージェント、AWS アカウントに関する情報が含まれます。

  • ログインプロファイルを使って IAM ユーザーとしてログインする場合、コールを実行するアイデンティティには IAM ユーザーの ARN が含まれます(userIdentity.arn フィールドは arn:aws:iam::012345678912:user/loginUser 形式)。
  • ログインはブラウザ経由で行われるため、ユーザーエージェントはブラウザになります(Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:143.0) Gecko/20100101 Firefox/143.0)。
  • additionalEventData フィールドには、ログインに使用されたコンソールログイン URL や、MFA 利用に関する情報も記録されます。
"additionalEventData": {
  "LoginTo": "https://console.aws.amazon.com/console/home?hashArgs=%23&isauthcode=true&state=hashArgsFromTB_us-east-2_addce6de859630d0",
  "MobileVersion": "No",
  "MFAUsed": "No"
},

ユーザーがフェデレーション認証情報でログインした場合、そのユーザーの ARN は arn:aws:sts::012345678912:federated-user/loginUserSessionName のような形式になります。認証情報は sts:GetFederationToken から取得されるため、イベントソースは STS になります。

また、この場合 additionalEventData には LoginTo フィールドが含まれません。これは、そのアイデンティティが Management Console へアクセスするために、必ずしもログインプロファイルを必要としないためです。

"additionalEventData": {
  "MobileVersion": "No",
  "MFAUsed": "No"
},

最後に、Identity Center 経由でアイデンティティがサインインした場合、ログインを実行するアイデンティティはロールであり、そのセッション名はサインインしたユーザーのメール名と同じになります(arn:aws:sts::0123456789012:assumed-role/AWSReservedSSO_AdministratorAccess_abcdef1234567890/someuser)。Identity Center では、通常、各ユーザーは 1 つのロールにのみアクセスします(別途設定されている場合を除く)。また、セッション名はログインしているユーザーのセッション名になります。ロール名の最も一般的な形式は AWSReservedSSO_AdministratorAccess_abcdef1234567890 ですが、Identity Center の作成時に任意の名前を設定することもできます。

Entra ID のサインインログ

Azure では、認証は Entra ID を通じて行われます。ログインを試行すると、各イベントには status が含まれ、Sign-In logs 内には status フィールドがあります。このフィールドには、エラーコード(status.errorCode)と、成功または失敗の理由(status.additionalDetails)が格納されます。ステータス理由には、サインインが許可または拒否された理由の説明が含まれます。理由には、以下のようなものがあります。

  • 想定どおり - 認可コード、リフレッシュトークン、セッションは時間経過またはユーザー / 管理者による取り消しで失効します。アプリはユーザーに再ログインを求めます。
  • ユーザーに再度サインインし、アプリへの同意を行ってもらいます。
  • ユーザーをテナントに招待するか、そのユーザーが本来テナントのメンバーでない場合は、このエラーを無視します。これは、テナントのメンバーでないユーザーが対象テナントのログイン URL に誘導された場合や、誤ったユーザーアカウントを選択した場合に起こり得ます。
  • Azure AD で MFA が完了しました。
  • トークン内のクレームにより MFA 要件が満たされました。
  • 対応不要です。これは、アプリケーションまたは条件付きアクセス要件に伴うデバイスアイデンティティ判定の一部として想定される挙動です。
  • ユーザーが MFA プロンプトを完了しませんでした。認証しないことを選んだ、別作業中にタイムアウトした、または認証設定に問題がある可能性があります。
  • ユーザーが正しい認証情報を入力しませんでした。ユーザーの入力ミスにより、この種のエラーが一定数ログに表示されることは想定されます。
  • ユーザーには、MFA を実行できるように連絡先オプションを設定する選択肢が提示されました。
  • これはログインフローの一部として想定される挙動です。今後のログインを容易にするため、このブラウザでサインイン状態を維持するかどうかをユーザーに確認するものです。
  • パスワードリセット情報の登録が必要なため、ユーザー認証はブロックされました。
  • 次回の対話型サインイン時にこれが求められ、アプリ側が次にそれをトリガーする想定です。
  • ユーザーは多要素認証を実行する必要があります。条件付きアクセスポリシー、ユーザー単位の強制、クライアントからの要求など、多要素認証を必要とする要因が複数ある場合があります。

イベントに保存されるもう一つの情報は位置情報です。Azure は、要求元の IP と ASN に基づいて位置情報を算出し、その情報を提供します。

"location": {
  "city": "Some City",
  "countryOrRegion": "US",
  "geoCoordinates": {
    "altitude": null,
    "latitude": 12.3456,
    "longitude": 65.4321
  },
  "state": "State"
},

Google のサインインログ

Google は、ユーザーのサインインイベントを組織の Data Access logs("logName": "organizations/123456789012/logs/cloudaudit.googleapis.com%2Fdata_access")に記録します。ログの型は AuditLog("protoPayload.@type": "type.googleapis.com/google.cloud.audit.AuditLog")であり、"serviceName": "login.googleapis.com" です。

Google では、protoPayload.methodName フィールドを使用して、成功または失敗でログをフィルタリングできます。

  • google.login.LoginService.loginSuccess
  • google.login.LoginService.loginFailure

失敗理由:

"event": [
  {
    "eventName": "login_failure",
    "eventType": "login",
    "eventId": "3484ada0",
    "parameter": [
      {
        "label": "LABEL_OPTIONAL",
        "value": "reauth",
        "type": "TYPE_STRING",
        "name": "login_type"
      },
      {
        "multiStrValue": [
          "none"
        ],
        "type": "TYPE_STRING",
        "label": "LABEL_REPEATED",
        "name": "login_challenge_method"
      },
      {
        "name": "dusi",
        "value": "INjZurSThIbFLg",
        "type": "TYPE_STRING",
        "label": "LABEL_OPTIONAL"
      }
    ]
  }
]

可視性の裏側

ログは今後もセキュリティ運用に不可欠です。検知、対応、フォレンジック調査における価値は疑いようがありません。しかし、本調査を通じて見てきたように、防御側にとってログを強力にしているあらゆる機能は、攻撃者にとっても価値があります。精緻なインシデント再構築を可能にする粒度の高さは、偵察にも有効です。迅速な脅威ハンティングを支えるアクセス性は、秘匿的な列挙にも利用できます。不都合な真実は、ログが敵対環境における共有リソースだということです。攻撃者が、ログ読取権限を伴う十分な権限で初期アクセスを得た時点で、組織自身が構築・維持してきた、出来合いのインテリジェンス基盤を引き継ぐことになります。CloudTrail、Azure Monitor、Cloud Logging は、読者が敵対者である可能性を前提として設計されたものではありません。しかし侵害シナリオでは、その前提は致命的に崩れます。

ログはシステムの物語を語ります。しかし、その物語は、アクセス権を持つ者であれば誰にでも読まれ、誤読され、悪用され得ます。本稿で示した手法は、単なる理論上の興味深い事例ではありません。実用的で効果的であり、しかも高度な脅威アクターの間で理解が進んでいます。可視性は両刃の剣です。ログアクセスをそれに見合う重大性で扱わない限り、防御側の最良の味方は、攻撃者の静かな協力者へと変わり得ます。

では、解決策は何でしょうか。防御側も盲目になることを引き換えに、攻撃者を盲目にするため、ログを一切取らないべきなのでしょうか。もちろんそうではありません。しかし、一定の制限は必要です。この種の攻撃に対する最善策は、言うは易く行うは難しですが、最小権限の原則を適用することです。ログ取得は、プログラム経由か否かを問わず、多くのアイデンティティが実行するタスクであり、制限が難しい領域です。ログにはデータが含まれます。ログに含まれるデータには、アイデンティティ情報、ユーザーエージェント、IP 関連情報、入出力パラメータなどがあります。このデータは防御側や脅威ハンターにとって価値がある一方、攻撃者にとっても重要です。

つまり、ログアクセスに対して最小権限を厳密に適用し、読み取り権限を書き込み権限と同じくらい重要に扱う必要があります。また、ある環境が侵害されても他環境のテレメトリまで露出しないよう、ログストレージを分離する必要があります。さらに、ログクエリそのものを監視し、異常なアクセスパターンに対する検知ルールを整備し、誰がどの理由でログを読めるのかを定期的に監査する必要があります。ロギング権限を持つすべてのサービスアカウント、CloudTrail へのアクセス権を持つすべてのアイデンティティ、logging.viewer を持つすべてのロールは、デフォルトで付与されるのではなく、正当性を確認したうえで定期的に見直されるべきです。

関連記事

理想のSOCチーム。
24時間365日、お客様とともに稼働します。

お客様の環境を一元的かつリアルタイムに把握する4つのエクサボットが、検出、トリアージ、調査、対応をカバーします。プラットフォームを自社で運用することも、エクサフォースに運用を任せることもできます。