ConnectWise SkyKickベンダーの資格情報がMicrosoft 365攻撃で悪用される
Detection stack
- AIDR
- Alert
- ETL
- Query
概要
旧SkyKickであるConnectWise Cloud Backupに関連するMicrosoft 365 APIの秘密が侵害され、脅威アクターが顧客のM365環境への不正アクセスを行いました。攻撃者はアプリケーションの広範な権限を利用して、Exchange Online、Microsoft Teams、およびSharePoint Onlineにアクセスしました。この活動には、自動化されたトークン要求とポストエクスプロイト操作の両方が含まれていました。
調査
Huntressは、Microsoft 365のサインインログを通じてConnectWiseのサービスプリンシパルの悪用を特定しました。これには、ホスティングプロバイダのIPアドレス144.172.64.128やプライベートなAzure IPv6スペースからの不正アクセスが含まれます。調査の結果、攻撃者は侵害された資格情報を使用して、グローバル管理者などのディレクトリロールを割り当て、他の信頼されたアプリケーションに新しいクライアントシークレットを追加することで永続性を確保していることが判明しました。活動にはテナント内でのスクリプトによるGUID順移動や特徴的なUser-Agentパターンも見られました。
緩和策
組織は、Microsoft 365テナント内で影響を受けたConnectWise Cloud BackupおよびConnectWise Cloud ManagementのアプリケーションIDを直ちに無効にする必要があります。削除ではなく無効にすることが、承認管理を保持する上で重要です。セキュリティチームはまた、すべてのサービスプリンシパルのサインインを監査し、10月13日以降に作成された予期しない新規の追加を確認することを推奨します。
対応
疑わしい活動が確認された場合、組織はEntraの監査ログを確認し、 メンバーをロールに追加する, アプリケーションを更新する、 サービスプリンシパル資格情報を追加する イベントを確認します。セキュリティチームは関連するUser-Agentの文字列を確認し、kiota-dotnetなどの正当なベンダーアクティビティと、Python-urllibやcurlを含む攻撃者のツールから区別する必要があります。最終的に、すべてのクライアントシークレットや証明書をエンタープライズアプリケーション全体で確認し、不正な資格情報を削除してください。
攻撃フロー
この部分はまだ更新中です。
検出
管理者ロールにユーザーを追加する(office365経由)
サービスプリンシパルアカウント資格情報の更新(azuread経由)
高特権ロールが割り当てられた(azuread経由)
IOC(SourceIP)を検出する:ConnectWise(SkyKick)ベンダー資格情報がM365の攻撃で悪用された
IOC(DestinationIP)を検出する:ConnectWise(SkyKick)ベンダー資格情報がM365の攻撃で悪用された
Python-urllibを使用したM365での不正な変更を検出する [Azure Activity Logs]
ConnectWiseアプリケーションを介したM365でのMicrosoft Graphトークンの不正使用 [Azure Auditlogs]
シミュレーション実行
-
攻撃の物語とコマンド: 敵対者は、限定された権限を持つサービスプリンシパルへのアクセス権を成功裏に獲得しました。持続性と環境全体の制御を達成するために、攻撃者はPythonスクリプトを実行します。スクリプトは以下をターゲットにします:1)侵害されたサービスプリンシパルを高特権のディレクトリロール(例:グローバル管理者または特権ロール管理者)に追加し、2)新しいクライアントシークレットをサービスプリンシパルに追加します。攻撃者は
urllibライブラリをPython 3.12で使用し、デフォルトのPython-urllib/3.12User-Agentを提供し、検出ルールで必要とされる特定のテレメトリフックを提供します。 -
回帰テストスクリプト:
import urllib.request import json # NOTE: このスクリプトはAPI呼び出し構造のシミュレーションです。 # 実際の環境では、有効なOAuth2ベアラートークンが必要です。 # このスクリプトは 'UserAgent' および 'OperationName' 検出ロジックをトリガーするように設計されています。 target_url = "https://graph.microsoft.com/v1.0/directoryRoles" access_token = "SIMULATED_TOKEN" headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/json" } # この特定のUser-Agentが検出ルールのトリガーです user_agent = "Python-urllib/3.12" # "メンバーをロールに追加する" をシミュレート payload = { "roleId": "target-role-guid", "principalId": "attacker-service-principal-guid" } print(f"[*] {user_agent}を使用した不正なロール変更をシミュレートしています...") try: req = urllib.request.Request( target_url, data=json.dumps(payload).encode('utf-8'), headers=headers, method='POST' ) req.add_header('User-Agent', user_agent) # 実際のテストでは、これは実際のAPIを呼び出します。 # シミュレーション目的では、ログを生成するためにAPI呼び出しが成功したと想定します。 print("[+] リクエストが送信されました。User-AgentがPython-urllib/3.12である'MemberToRoleの追加'をAzure監査ログで確認してください。") except Exception as e: print(f"[-] シミュレーションに失敗しました:{e}") -
クリーンアップコマンド:
# これらはアイデンティティレベルの変更であるため、M365での手動クリーンアップが必要です。 # 1. 追加されたロールの割り当てを削除します: # Remove-MgDirectoryRoleMemberByRef -DirectoryRoleId <ID> -DirectoryRoleMemberId <ID> # 2. 追加されたサービスプリンシパルの資格情報を削除します: # Remove-MgServicePrincipalPassword -ServicePrincipalId <ID> -PasswordId <ID>