Storm-2949はどのようにして侵害されたアイデンティティをクラウド全体の侵害に変えたか
Detection stack
- AIDR
- Alert
- ETL
- Query
概要
Storm-2949は、ソーシャルエンジニアリングとセルフサービス パスワード リセットの悪用を利用してMicrosoft Entra IDアカウントを侵害しました。特権アクセスを取得した後、脅威アクターはAzure管理プレーンのアクションを使用して、App Services、Key Vaults、Storageアカウント、SQLデータベースにアクセスしました。その後、データはMicrosoft 365、Azureストレージおよびその他のクラウドリソースから外部に送信されました。侵害はさらに進み、ScreenConnectリモートアクセスツールが仮想マシンにデプロイされ、さらなる偵察や資格情報の窃取をサポートしました。
調査
Microsoftのアナリストは、攻撃者がMicrosoft Graph APIをカスタムPythonツールで使用し、ユーザーとアプリケーションを列挙しているのを観察しました。彼らはAzure App Servicesから公開プロファイルを取得し、Key Vaultsから秘密を抽出し、ファイアウォールルールを変更し、VMAccess拡張機能を使用して仮想マシンにローカル管理者アカウントを作成しました。後の段階では、PowerShellスクリプトがScreenConnectをインストールし、ログをクリアし、サービスを偽装して可視性を低下させました。調査では、このアクティビティが3つの攻撃者管理のIPアドレスと関連付けられました。
緩和策
組織はMFAを有効にし、特権アカウントにはフィッシング抵抗性のある認証を要求すべきです。Azure RBACの権限は厳密に制限され監視されるべきであり、特にKey VaultsとApp ServicesへのOwnerレベルのアクセスが必要です。不要なAzure VM拡張機能を無効にし、Run CommandおよびVMAccessアクティビティのログを強制すべきです。また、Microsoft Defender for CloudとDefender for Endpointは改ざん防止とブロックモードで有効にすべきです。
対応策
防御者は直ちに特定の悪意のあるIPアドレスをブロックし、侵害された資格情報を取り消すべきです。影響を受けたアカウントのパスワードとMFA登録をリセットし、Key Vaultsに保存されているすべての秘密を回転させる必要があります。セキュリティチームはAzure RBACの割り当てを全面的に見直し、過剰な特権を削除するべきです。検出ルールは、疑わしい公開プロファイルのリクエスト、Key Vault秘密へのアクセス、予期しないVM拡張機能のアクティビティを識別するために更新されるべきです。
攻撃の流れ
検出
Invoke-RestMethodの疑わしい使用(PowerShell経由)
表示
珍しいプロセスによるAzure Vaultへの問い合わせの可能性(dns_query経由)
表示
IOCs(SourceIP)を検出:Storm-2949が侵害されたアイデンティティをクラウド全体の侵害に変える方法
表示
IOCs(DestinationIP)を検出:Storm-2949が侵害されたアイデンティティをクラウド全体の侵害に変える方法
表示
Azure管理プレーンのデータ漏洩のための操作の検出 [Azure Activity Logs]
表示
シミュレーションの実行
前提条件: テレメトリおよびベースラインの事前チェックを通過していること。
-
攻撃の概要とコマンド:
有効なAzure ADアカウント(またはデフォルトのサービスプリンシパル)を取得した攻撃者は、アプリケーションのソースコードとデータベースのスナップショットを外部に送信したいと考えています。攻撃者は、完全にAzure CLIを介して以下の手順を実行し、正確な
操作名ルールが監視するイベントを生成します:- Web App XMLの公開 – Web Appの設定(デプロイ資格情報を含む)を抽出します。
- 新しいStorage Accountを作成 – 外部データをステージングするためのコンテナを提供。
- SQLサーバーにファイアウォールルールを追加 – 攻撃者のIP範囲にサーバーを開放し、直接データコピーを可能にします。
各ステップは、
操作名ルールのホワイトリストに一致し、それにより検出がトリガーされます。 -
回帰テストスクリプト:
#!/usr/bin/env bash # 前提条件: az CLIは侵害された/有効なAzure ADプリンシパルでログインしていること。 set -euo pipefail # 変数 – テストテナントに必要に応じて変更してください RG="test-rg-$(date +%s)" WEBAPP="test-webapp-$RANDOM" STORAGE="teststorage$RANDOM" LOCATION="eastus" SQLSERVER="testsql$RANDOM" MY_IP=$(curl -s https://api.ipify.org) echo "=== リソースグループを作成 ===" az group create --name "$RG" --location "$LOCATION" echo "=== ダミーWeb Appのデプロイ ===" az appservice plan create --name "${WEBAPP}Plan" --resource-group "$RG" --sku B1 --is-linux az webapp create --resource-group "$RG" --plan "${WEBAPP}Plan" --name "$WEBAPP" echo "=== XML設定の公開(検出をトリガー) ===" az webapp config backup create --resource-group "$RG" --webapp-name "$WEBAPP" --backup-name "xmlbackup-$(date +%s)" --output none echo "=== ストレージアカウントの作成(検出をトリガー) ===" az storage account create --name "$STORAGE" --resource-group "$RG" --location "$LOCATION" --sku Standard_LRS --kind StorageV2 --output none echo "=== SQLサーバーの作成(ファイアウォールルールに必要) ===" az sql server create --name "$SQLSERVER" --resource-group "$RG" --location "$LOCATION" --admin-user "sqladmin" --admin-password "P@ssw0rd1234!" --output none echo "=== SQLサーバーにファイアウォールルールを追加(検出をトリガー) ===" az sql server firewall-rule create --resource-group "$RG" --server "$SQLSERVER" --name "AllowMyIP" --start-ip-address "$MY_IP" --end-ip-address "$MY_IP" --output none echo "=== シミュレーション完了。Azure Sentinelでアラートを確認してください。 ===" -
クリーンアップコマンド:
#!/usr/bin/env bash set -euo pipefail # 変数はシミュレーションスクリプトで使用したものと一致しなければなりません RG="test-rg-..." # 既に実行していた場合は、前の実行の名前をそのまま使用するため、プレースホルダーを適切に置き換えてください。 echo "=== リソースグループとそのすべてのリソースを削除 ===" az group delete --name "$RG" --yes --no-wait echo "クリーンアップが開始されました。"